use of net.i2p.data.Signature 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.Signature in project i2p.i2p by i2p.
the class SelfSignedGenerator method generate.
/**
* @param cname the common name, non-null. Must be a hostname or email address. IP addresses will not be correctly encoded.
* @param altNames the Subject Alternative Names. May be null. May contain hostnames and/or IP addresses.
* cname, localhost, 127.0.0.1, and ::1 will be automatically added.
* @param ou The OU (organizational unit) in the distinguished name, non-null before 0.9.28, may be null as of 0.9.28
* @param o The O (organization)in the distinguished name, non-null before 0.9.28, may be null as of 0.9.28
* @param l The L (city or locality) in the distinguished name, non-null before 0.9.28, may be null as of 0.9.28
* @param st The ST (state or province) in the distinguished name, non-null before 0.9.28, may be null as of 0.9.28
* @param c The C (country) in the distinguished name, non-null before 0.9.28, may be null as of 0.9.28
*
* @return length 4 array:
* rv[0] is a Java PublicKey
* rv[1] is a Java PrivateKey
* rv[2] is a Java X509Certificate
* rv[3] is a Java X509CRL
*
* @since 0.9.34 added altNames param
*/
private static Object[] generate(PublicKey jpub, PrivateKey jpriv, SigningPrivateKey priv, SigType type, String cname, Set<String> altNames, String ou, String o, String l, String st, String c, int validDays) throws GeneralSecurityException {
String oid;
switch(type) {
case DSA_SHA1:
case ECDSA_SHA256_P256:
case ECDSA_SHA384_P384:
case ECDSA_SHA512_P521:
case RSA_SHA256_2048:
case RSA_SHA384_3072:
case RSA_SHA512_4096:
case EdDSA_SHA512_Ed25519:
case EdDSA_SHA512_Ed25519ph:
oid = type.getOID();
break;
default:
throw new GeneralSecurityException("Unsupported: " + type);
}
byte[] sigoid = getEncodedOIDSeq(oid);
byte[] tbs = genTBS(cname, altNames, ou, o, l, st, c, validDays, sigoid, jpub);
int tbslen = tbs.length;
Signature sig = DSAEngine.getInstance().sign(tbs, priv);
if (sig == null)
throw new GeneralSecurityException("sig failed");
byte[] sigbytes = SigUtil.toJavaSig(sig);
int seqlen = tbslen + sigoid.length + spaceFor(sigbytes.length + 1);
int totlen = spaceFor(seqlen);
byte[] cb = new byte[totlen];
int idx = 0;
// construct the whole encoded cert
cb[idx++] = 0x30;
idx = intToASN1(cb, idx, seqlen);
// TBS cert
System.arraycopy(tbs, 0, cb, idx, tbs.length);
idx += tbs.length;
// sig algo
System.arraycopy(sigoid, 0, cb, idx, sigoid.length);
idx += sigoid.length;
// sig (bit string)
cb[idx++] = 0x03;
idx = intToASN1(cb, idx, sigbytes.length + 1);
cb[idx++] = 0;
System.arraycopy(sigbytes, 0, cb, idx, sigbytes.length);
if (DEBUG) {
System.out.println("Sig OID");
System.out.println(HexDump.dump(sigoid));
System.out.println("Signature");
System.out.println(HexDump.dump(sigbytes));
System.out.println("Whole cert");
System.out.println(HexDump.dump(cb));
}
ByteArrayInputStream bais = new ByteArrayInputStream(cb);
X509Certificate cert;
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) cf.generateCertificate(bais);
cert.checkValidity();
} catch (IllegalArgumentException iae) {
throw new GeneralSecurityException("cert error", iae);
}
X509CRL crl = generateCRL(cert, validDays, 1, sigoid, jpriv);
// some simple tests
PublicKey cpub = cert.getPublicKey();
cert.verify(cpub);
if (!cpub.equals(jpub))
throw new GeneralSecurityException("pubkey mismatch");
// todo crl tests
Object[] rv = { jpub, jpriv, cert, crl };
return rv;
}
use of net.i2p.data.Signature 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.Signature in project i2p.i2p by i2p.
the class I2PDatagramDissector method loadI2PDatagram.
/**
* Load an I2P repliable datagram into the dissector.
* Does NOT verify the signature.
*
* Format is:
* <ol>
* <li>Destination (387+ bytes)
* <li>Signature (40+ bytes, type and length as implied by signing key type in the Destination)
* <li>Payload
* </ol>
*
* For DSA_SHA1 Destinations, the signature is of the SHA-256 Hash of the payload.
*
* As of 0.9.14, for non-DSA_SHA1 Destinations, the signature is of the payload itself.
*
* @param dgram non-null I2P repliable datagram to be loaded
*
* @throws DataFormatException If there's an error in the datagram format
*/
public void loadI2PDatagram(byte[] dgram) throws DataFormatException {
// set invalid(very important!)
this.valid = false;
if (dgram.length < MIN_DGRAM_SIZE)
throw new DataFormatException("repliable datagram too small: " + dgram.length);
ByteArrayInputStream dgStream = new ByteArrayInputStream(dgram);
try {
// read destination
rxDest = Destination.create(dgStream);
SigType type = rxDest.getSigningPublicKey().getType();
if (type == null)
throw new DataFormatException("unsupported sig type");
rxSign = new Signature(type);
// read signature
rxSign.readBytes(dgStream);
// read payload
rxPayloadLen = dgStream.read(rxPayload);
// calculate the hash of the payload
if (type == SigType.DSA_SHA1) {
if (rxHash == null)
rxHash = new byte[Hash.HASH_LENGTH];
// non-caching
hashGen.calculateHash(rxPayload, 0, rxPayloadLen, rxHash, 0);
// assert this.hashGen.calculateHash(this.extractPayload()).equals(this.rxHash);
} else {
rxHash = null;
}
} catch (IOException e) {
// log.error("Error loading datagram", e);
throw new DataFormatException("Error loading datagram", e);
// } catch(AssertionError e) {
// Log log = I2PAppContext.getGlobalContext().logManager().getLog(I2PDatagramDissector.class);
// log.error("Assertion failed!", e);
}
// _log.debug("Datagram payload size: " + rxPayloadLen + "; content:\n"
// + HexDump.dump(rxPayload, 0, rxPayloadLen));
}
use of net.i2p.data.Signature in project i2p.i2p by i2p.
the class I2PDatagramMaker method makeI2PDatagram.
/**
* Make a repliable I2P datagram containing the specified payload.
*
* Format is:
* <ol>
* <li>Destination (387+ bytes)
* <li>Signature (40+ bytes, type and length as implied by signing key type in the Destination)
* <li>Payload
* </ol>
*
* Maximum datagram size is 32768, so maximum payload size is 32341, or less for
* non-DSA_SHA1 destinations. Practical maximum is a few KB less due to
* ElGamal/AES overhead. 10 KB or less is recommended for best results.
*
* For DSA_SHA1 Destinations, the signature is of the SHA-256 Hash of the payload.
*
* As of 0.9.14, for non-DSA_SHA1 Destinations, the signature is of the payload itself.
*
* @param payload non-null Bytes to be contained in the I2P datagram.
* @return null on error
* @throws IllegalArgumentException if payload is too big
* @throws IllegalStateException if Destination signature type unsupported
*/
public byte[] makeI2PDatagram(byte[] payload) {
sxDGram.reset();
try {
sxDGram.write(sxDestBytes);
SigType type = sxPrivKey.getType();
if (type == null)
throw new IllegalStateException("Unsupported sig type");
Signature sig;
if (type == SigType.DSA_SHA1) {
byte[] hash = SimpleByteCache.acquire(Hash.HASH_LENGTH);
// non-caching
hashGen.calculateHash(payload, 0, payload.length, hash, 0);
sig = dsaEng.sign(hash, sxPrivKey);
SimpleByteCache.release(hash);
} else {
sig = dsaEng.sign(payload, sxPrivKey);
}
sig.writeBytes(sxDGram);
sxDGram.write(payload);
if (sxDGram.size() > DGRAM_BUFSIZE)
throw new IllegalArgumentException("Too big");
return sxDGram.toByteArray();
} catch (IOException e) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(I2PDatagramMaker.class);
log.error("Caught IOException", e);
return null;
} catch (DataFormatException e) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(I2PDatagramMaker.class);
log.error("Caught DataFormatException", e);
return null;
}
}
Aggregations