use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SU3File method verifyAndMigrate.
/**
* One-pass verify and extract the content.
* Recommend extracting to a temp location as the sig is not checked until
* after extraction. This will delete the file if the sig does not verify.
* Throws IOE on all format errors.
*
* @param migrateTo the output file, probably in zip format. Null for verify only.
* @return true if signature is good
*/
public boolean verifyAndMigrate(File migrateTo) throws IOException {
InputStream in = null;
FileOutputStream out = null;
boolean rv = false;
try {
in = new BufferedInputStream(new FileInputStream(_file));
// read 10 bytes to get the sig type
in.mark(10);
// following is a dup of that in verifyHeader()
byte[] magic = new byte[MAGIC_BYTES.length];
DataHelper.read(in, magic);
if (!DataHelper.eq(magic, MAGIC_BYTES))
throw new IOException("Not an su3 file");
skip(in, 1);
int foo = in.read();
if (foo != FILE_VERSION)
throw new IOException("bad file version");
skip(in, 1);
int sigTypeCode = in.read();
_sigType = SigType.getByCode(sigTypeCode);
if (_sigType == null)
throw new IOException("unknown sig type: " + sigTypeCode);
// end duplicate code
// rewind
in.reset();
MessageDigest md = _sigType.getDigestInstance();
DigestInputStream din = new DigestInputStream(in, md);
in = din;
if (!_headerVerified)
verifyHeader(in);
else
skip(in, getContentOffset());
if (_verifySignature) {
if (_signerPubkey == null)
throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
}
if (// else verify only
migrateTo != null)
out = new SecureFileOutputStream(migrateTo);
byte[] buf = new byte[16 * 1024];
long tot = 0;
while (tot < _contentLength) {
int read = in.read(buf, 0, (int) Math.min(buf.length, _contentLength - tot));
if (read < 0)
throw new EOFException();
if (// else verify only
migrateTo != null)
out.write(buf, 0, read);
tot += read;
}
if (_verifySignature) {
byte[] sha = md.digest();
din.on(false);
Signature signature = new Signature(_sigType);
signature.readBytes(in);
int avail = in.available();
if (avail > 0)
throw new IOException(avail + " bytes data after sig");
SimpleDataStructure hash = _sigType.getHashInstance();
hash.setData(sha);
// System.out.println("hash\n" + HexDump.dump(sha));
// System.out.println("sig\n" + HexDump.dump(signature.getData()));
rv = _context.dsa().verifySignature(signature, hash, _signerPubkey);
} else {
rv = true;
}
} catch (DataFormatException dfe) {
IOException ioe = new IOException("foo");
ioe.initCause(dfe);
throw ioe;
} finally {
if (in != null)
try {
in.close();
} catch (IOException ioe) {
}
if (out != null) {
// so do a POSIX flush and sync to ensure it will be there.
try {
out.flush();
out.getFD().sync();
} catch (IOException ioe) {
}
try {
out.close();
} catch (IOException ioe) {
}
}
if (migrateTo != null && !rv)
migrateTo.delete();
}
return rv;
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SU3File method write.
/**
* One-pass wrap and sign the content.
* Writes to the file specified in the constructor.
* Throws on all errors.
*
* @param content the input file, probably in zip format
* @param fileType 0-255, 0 for zip
* @param contentType 0-255
* @param version 1-255 bytes when converted to UTF-8
* @param signer ID of the public key, 1-255 bytes when converted to UTF-8
*/
public void write(File content, int fileType, int contentType, String version, String signer, PrivateKey privkey, SigType sigType) throws IOException {
InputStream in = null;
DigestOutputStream out = null;
boolean ok = false;
try {
in = new BufferedInputStream(new FileInputStream(content));
MessageDigest md = sigType.getDigestInstance();
out = new DigestOutputStream(new BufferedOutputStream(new FileOutputStream(_file)), md);
out.write(MAGIC_BYTES);
out.write((byte) 0);
out.write((byte) FILE_VERSION);
DataHelper.writeLong(out, 2, sigType.getCode());
DataHelper.writeLong(out, 2, sigType.getSigLen());
out.write((byte) 0);
byte[] verBytes = DataHelper.getUTF8(version);
if (verBytes.length == 0 || verBytes.length > 255)
throw new IllegalArgumentException("bad version length");
int verLen = Math.max(verBytes.length, MIN_VERSION_BYTES);
out.write((byte) verLen);
out.write((byte) 0);
byte[] signerBytes = DataHelper.getUTF8(signer);
if (signerBytes.length == 0 || signerBytes.length > 255)
throw new IllegalArgumentException("bad signer length");
out.write((byte) signerBytes.length);
long contentLength = content.length();
if (contentLength <= 0)
throw new IllegalArgumentException("No content");
DataHelper.writeLong(out, 8, contentLength);
out.write((byte) 0);
if (fileType < 0 || fileType > 255)
throw new IllegalArgumentException("bad content type");
out.write((byte) fileType);
out.write((byte) 0);
if (contentType < 0 || contentType > 255)
throw new IllegalArgumentException("bad content type");
out.write((byte) contentType);
out.write(new byte[12]);
out.write(verBytes);
if (verBytes.length < MIN_VERSION_BYTES)
out.write(new byte[MIN_VERSION_BYTES - verBytes.length]);
out.write(signerBytes);
byte[] buf = new byte[16 * 1024];
long tot = 0;
while (tot < contentLength) {
int read = in.read(buf, 0, (int) Math.min(buf.length, contentLength - tot));
if (read < 0)
throw new EOFException();
out.write(buf, 0, read);
tot += read;
}
byte[] sha = md.digest();
out.on(false);
SimpleDataStructure hash = sigType.getHashInstance();
hash.setData(sha);
Signature signature = _context.dsa().sign(hash, privkey, sigType);
if (signature == null)
throw new IOException("sig fail");
// System.out.println("hash\n" + HexDump.dump(sha));
// System.out.println("sig\n" + HexDump.dump(signature.getData()));
signature.writeBytes(out);
ok = true;
} catch (DataFormatException dfe) {
IOException ioe = new IOException("foo");
ioe.initCause(dfe);
throw ioe;
} finally {
if (in != null)
try {
in.close();
} catch (IOException ioe) {
}
if (out != null)
try {
out.close();
} catch (IOException ioe) {
}
if (!ok)
_file.delete();
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class I2CPMessageProducer method connect.
/**
* Send all the messages that a client needs to send to a router to establish
* a new session.
*/
public void connect(I2PSessionImpl session) throws I2PSessionException {
updateBandwidth(session);
CreateSessionMessage msg = new CreateSessionMessage();
SessionConfig cfg = new SessionConfig(session.getMyDestination());
cfg.setOptions(session.getOptions());
if (_log.shouldLog(Log.DEBUG))
_log.debug("config created");
try {
cfg.signSessionConfig(session.getPrivateKey());
} catch (DataFormatException dfe) {
throw new I2PSessionException("Unable to sign the session config", dfe);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("config signed");
msg.setSessionConfig(cfg);
if (_log.shouldLog(Log.DEBUG))
_log.debug("config loaded into message");
session.sendMessage_unchecked(msg);
if (_log.shouldLog(Log.DEBUG))
_log.debug("config message sent");
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class HostTxtEntry method hasValidRemoveSig.
/**
* Verify with the "dest" property's public key using the "sig" property
*/
public boolean hasValidRemoveSig() {
if (props == null)
return false;
boolean rv = false;
// don't cache result
if (true) {
StringWriter buf = new StringWriter(1024);
String sig = props.getProperty(PROP_SIG);
String olddest = props.getProperty(PROP_DEST);
if (sig == null || olddest == null)
return false;
try {
writeProps(buf, true, true);
} catch (IOException ioe) {
// won't happen
return false;
}
byte[] sdata = Base64.decode(sig);
if (sdata == null)
return false;
Destination d;
try {
d = new Destination(olddest);
} catch (DataFormatException dfe) {
return false;
}
SigningPublicKey spk = d.getSigningPublicKey();
SigType type = spk.getType();
if (type == null)
return false;
Signature s;
try {
s = new Signature(type, sdata);
} catch (IllegalArgumentException iae) {
return false;
}
rv = DSAEngine.getInstance().verifySignature(s, DataHelper.getUTF8(buf.toString()), spk);
}
return rv;
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class NamingService method lookupBase64.
/**
* If the host name is a valid Base64 encoded destination, return the
* decoded Destination. Useful as a "fallback" in custom naming
* implementations.
* This is misnamed as it isn't a "lookup" at all, but
* a simple conversion from a Base64 string to a Destination.
*
* @param hostname 516+ character Base 64
* @return Destination or null on error
*/
protected Destination lookupBase64(String hostname) {
try {
Destination result = new Destination();
result.fromBase64(hostname);
return result;
} catch (DataFormatException dfe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Bad B64 dest [" + hostname + "]", dfe);
return null;
}
}
Aggregations