use of net.i2p.data.Signature in project i2p.i2p by i2p.
the class RouterInfo method readBytes.
/**
* If verifySig is true,
* this validates the signature while reading in,
* and throws a DataFormatException if the sig is invalid.
* This is faster than reserializing to validate later.
*
* @throws IllegalStateException if RouterInfo was already read in
* @since 0.9
*/
public void readBytes(InputStream in, boolean verifySig) throws DataFormatException, IOException {
if (_signature != null)
throw new IllegalStateException();
_identity = new RouterIdentity();
_identity.readBytes(in);
// can't set the digest until we know the sig type
InputStream din;
MessageDigest digest;
if (verifySig) {
SigType type = _identity.getSigningPublicKey().getType();
if (type != SigType.EdDSA_SHA512_Ed25519) {
// This won't work for EdDSA
digest = _identity.getSigningPublicKey().getType().getDigestInstance();
// TODO any better way?
digest.update(_identity.toByteArray());
din = new DigestInputStream(in, digest);
} else {
digest = null;
din = in;
}
} else {
digest = null;
din = in;
}
// avoid thrashing objects
// Date when = DataHelper.readDate(in);
// if (when == null)
// _published = 0;
// else
// _published = when.getTime();
_published = DataHelper.readLong(din, 8);
int numAddresses = (int) DataHelper.readLong(din, 1);
for (int i = 0; i < numAddresses; i++) {
RouterAddress address = new RouterAddress();
address.readBytes(din);
_addresses.add(address);
}
int numPeers = (int) DataHelper.readLong(din, 1);
if (numPeers == 0) {
_peers = null;
} else {
_peers = new HashSet<Hash>(numPeers);
for (int i = 0; i < numPeers; i++) {
Hash peerIdentityHash = new Hash();
peerIdentityHash.readBytes(din);
_peers.add(peerIdentityHash);
}
}
DataHelper.readProperties(din, _options);
_signature = new Signature(_identity.getSigningPublicKey().getType());
_signature.readBytes(in);
if (verifySig) {
SigType type = _identity.getSigningPublicKey().getType();
if (type != SigType.EdDSA_SHA512_Ed25519) {
// This won't work for EdDSA
SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance();
hash.setData(digest.digest());
_isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
_validated = true;
} else {
doValidate();
}
if (!_isValid) {
throw new DataFormatException("Bad sig");
}
}
// _log.debug("Read routerInfo: " + toString());
}
use of net.i2p.data.Signature in project i2p.i2p by i2p.
the class SessionConfig method readBytes.
public void readBytes(InputStream rawConfig) throws DataFormatException, IOException {
_destination = Destination.create(rawConfig);
_options = DataHelper.readProperties(rawConfig);
_creationDate = DataHelper.readDate(rawConfig);
_signature = new Signature(_destination.getSigningPublicKey().getType());
_signature.readBytes(rawConfig);
}
use of net.i2p.data.Signature in project i2p.i2p by i2p.
the class EstablishState method verifyInbound.
/**
* We are Bob. Verify message #3 from Alice, then send message #4 to Alice.
*
* _aliceIdentSize and _aliceIdent must be set.
* _sz_aliceIdent_tsA_padding_aliceSig must contain at least
* (2 + _aliceIdentSize + 4 + padding + sig) bytes.
*
* Sets _aliceIdent so that we
*
* readAliceRouterIdentity() must have been called previously
*
* Make sure the signatures are correct, and if they are, update the
* NIOConnection with the session key / peer ident / clock skew / iv.
* The NIOConnection itself is responsible for registering with the
* transport
*
* State must be IB_GOT_RI.
* Caller must synch.
*/
private void verifyInbound() {
byte[] b = _sz_aliceIdent_tsA_padding_aliceSig.toByteArray();
try {
int sz = _aliceIdentSize;
// her timestamp from message #3
long tsA = DataHelper.fromLong(b, 2 + sz, 4);
// _tsB is when we sent message #2
// Adjust backward by RTT/2
long now = _context.clock().now();
// rtt from sending #2 to receiving #3
long rtt = now - _con.getCreated();
_peerSkew = (now - (tsA * 1000) - (rtt / 2) + 500) / 1000;
ByteArrayOutputStream baos = new ByteArrayOutputStream(768);
baos.write(_X);
baos.write(_Y);
baos.write(_context.routerHash().getData());
baos.write(DataHelper.toLong(4, tsA));
baos.write(DataHelper.toLong(4, _tsB));
// baos.write(b, 2+sz+4, b.length-2-sz-4-Signature.SIGNATURE_BYTES);
byte[] toVerify = baos.toByteArray();
// if (_log.shouldLog(Log.DEBUG)) {
// _log.debug(prefix()+"checking " + Base64.encode(toVerify, 0, AES_SIZE));
// //_log.debug(prefix()+"check pad " + Base64.encode(b, 2+sz+4, 12));
// }
// handle variable signature size
SigType type = _aliceIdent.getSigningPublicKey().getType();
if (type == null) {
fail("unsupported sig type");
return;
}
byte[] s = new byte[type.getSigLen()];
System.arraycopy(b, b.length - s.length, s, 0, s.length);
Signature sig = new Signature(type, s);
boolean ok = _context.dsa().verifySignature(sig, toVerify, _aliceIdent.getSigningPublicKey());
if (ok) {
// get inet-addr
InetAddress addr = this._con.getChannel().socket().getInetAddress();
byte[] ip = (addr == null) ? null : addr.getAddress();
if (_context.banlist().isBanlistedForever(_aliceIdent.calculateHash())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Dropping inbound connection from permanently banlisted peer: " + _aliceIdent.calculateHash());
// rather than doing the whole handshake
if (ip != null)
_context.blocklist().add(ip);
fail("Peer is banlisted forever: " + _aliceIdent.calculateHash());
return;
}
if (ip != null)
_transport.setIP(_aliceIdent.calculateHash(), ip);
if (_log.shouldLog(Log.DEBUG))
_log.debug(prefix() + "verification successful for " + _con);
long diff = 1000 * Math.abs(_peerSkew);
if (!_context.clock().getUpdatedSuccessfully()) {
// Adjust the clock one time in desperation
// This isn't very likely, outbound will do it first
// We are Bob, she is Alice, adjust to match Alice
_context.clock().setOffset(1000 * (0 - _peerSkew), true);
_peerSkew = 0;
if (diff != 0)
_log.logAlways(Log.WARN, "NTP failure, NTCP adjusting clock by " + DataHelper.formatDuration(diff));
} else if (diff >= Router.CLOCK_FUDGE_FACTOR) {
_context.statManager().addRateData("ntcp.invalidInboundSkew", diff);
_transport.markReachable(_aliceIdent.calculateHash(), true);
// Only banlist if we know what time it is
_context.banlist().banlistRouter(DataHelper.formatDuration(diff), _aliceIdent.calculateHash(), _x("Excessive clock skew: {0}"));
_transport.setLastBadSkew(_peerSkew);
fail("Clocks too skewed (" + diff + " ms)", null, true);
return;
} else if (_log.shouldLog(Log.DEBUG)) {
_log.debug(prefix() + "Clock skew: " + diff + " ms");
}
_con.setRemotePeer(_aliceIdent);
sendInboundConfirm(_aliceIdent, tsA);
if (_log.shouldLog(Log.DEBUG))
_log.debug(prefix() + "e_bobSig is " + _e_bobSig.length + " bytes long");
// reuse buf
byte[] iv = _curEncrypted;
System.arraycopy(_e_bobSig, _e_bobSig.length - AES_SIZE, iv, 0, AES_SIZE);
// this does not copy the IV, do not release to cache
// We are Bob, she is Alice, clock skew is Alice-Bob
// skew in seconds
_con.finishInboundEstablishment(_dh.getSessionKey(), _peerSkew, iv, _prevEncrypted);
releaseBufs(true);
if (_log.shouldLog(Log.INFO))
_log.info(prefix() + "Verified remote peer as " + _aliceIdent.calculateHash());
changeState(State.VERIFIED);
} else {
_context.statManager().addRateData("ntcp.invalidInboundSignature", 1);
fail("Peer verification failed - spoof of " + _aliceIdent.calculateHash() + "?");
}
} catch (IOException ioe) {
_context.statManager().addRateData("ntcp.invalidInboundIOE", 1);
fail("Error verifying peer", ioe);
}
}
use of net.i2p.data.Signature in project i2p.i2p by i2p.
the class DSABench method main.
public static void main(String[] args) {
int times = 100;
long keygentime = 0;
long signtime = 0;
long verifytime = 0;
long maxKey = 0;
long minKey = 0;
long maxS = 0;
long minS = 0;
long maxV = 0;
long minV = 0;
Object[] keys = KeyGenerator.getInstance().generateSigningKeypair();
byte[] message = new byte[32 + 32];
for (int i = 0; i < message.length; i++) message[i] = (byte) ((i % 26) + 'a');
for (int x = 0; x < times; x++) {
long startkeys = System.currentTimeMillis();
keys = KeyGenerator.getInstance().generateSigningKeypair();
SigningPublicKey pubkey = (SigningPublicKey) keys[0];
SigningPrivateKey privkey = (SigningPrivateKey) keys[1];
long endkeys = System.currentTimeMillis();
long startsign = System.currentTimeMillis();
Signature s = DSAEngine.getInstance().sign(message, privkey);
Signature s1 = DSAEngine.getInstance().sign(new ByteArrayInputStream(message), privkey);
long endsignstartverify = System.currentTimeMillis();
boolean v = DSAEngine.getInstance().verifySignature(s, message, pubkey);
boolean v1 = DSAEngine.getInstance().verifySignature(s1, new ByteArrayInputStream(message), pubkey);
boolean v2 = DSAEngine.getInstance().verifySignature(s1, message, pubkey);
boolean v3 = DSAEngine.getInstance().verifySignature(s, new ByteArrayInputStream(message), pubkey);
long endverify = System.currentTimeMillis();
System.out.print(".");
keygentime += endkeys - startkeys;
signtime += endsignstartverify - startsign;
verifytime += endverify - endsignstartverify;
if (!v) {
throw new RuntimeException("Holy crap, did not verify");
}
if (!(v1 && v2 && v3))
throw new RuntimeException("Stream did not verify");
if ((minKey == 0) && (minS == 0) && (minV == 0)) {
minKey = endkeys - startkeys;
maxKey = endkeys - startkeys;
minS = endsignstartverify - startsign;
maxS = endsignstartverify - startsign;
minV = endverify - endsignstartverify;
maxV = endverify - endsignstartverify;
} else {
if (minKey > endkeys - startkeys)
minKey = endkeys - startkeys;
if (maxKey < endkeys - startkeys)
maxKey = endkeys - startkeys;
if (minS > endsignstartverify - startsign)
minS = endsignstartverify - startsign;
if (maxS < endsignstartverify - startsign)
maxS = endsignstartverify - startsign;
if (minV > endverify - endsignstartverify)
minV = endverify - endsignstartverify;
if (maxV < endverify - endsignstartverify)
maxV = endverify - endsignstartverify;
}
}
System.out.println();
System.out.println("Key Generation Time Average: " + (keygentime / times) + "\ttotal: " + keygentime + "\tmin: " + minKey + "\tmax: " + maxKey + "\tKeygen/second: " + (keygentime == 0 ? "NaN" : "" + (times * 1000) / keygentime));
System.out.println("Signing Time Average : " + (signtime / times) + "\ttotal: " + signtime + "\tmin: " + minS + "\tmax: " + maxS + "\tSigning Bps: " + (times * message.length * 1000) / signtime);
System.out.println("Verification Time Average : " + (verifytime / times) + "\ttotal: " + verifytime + "\tmin: " + minV + "\tmax: " + maxV + "\tDecryption Bps: " + (times * message.length * 1000) / verifytime);
}
use of net.i2p.data.Signature in project i2p.i2p by i2p.
the class KeyGeneratorTest method testKeyGen.
public void testKeyGen() {
RandomSource.getInstance().nextBoolean();
byte[] src = new byte[200];
RandomSource.getInstance().nextBytes(src);
I2PAppContext ctx = I2PAppContext.getGlobalContext();
for (int i = 0; i < 10; i++) {
Object[] keys = KeyGenerator.getInstance().generatePKIKeypair();
byte[] ctext = ctx.elGamalEngine().encrypt(src, (PublicKey) keys[0]);
byte[] ptext = ctx.elGamalEngine().decrypt(ctext, (PrivateKey) keys[1]);
assertTrue(DataHelper.eq(ptext, src));
}
Object[] obj = KeyGenerator.getInstance().generateSigningKeypair();
SigningPublicKey fake = (SigningPublicKey) obj[0];
for (int i = 0; i < 10; i++) {
Object[] keys = KeyGenerator.getInstance().generateSigningKeypair();
Signature sig = DSAEngine.getInstance().sign(src, (SigningPrivateKey) keys[1]);
assertTrue(DSAEngine.getInstance().verifySignature(sig, src, (SigningPublicKey) keys[0]));
assertFalse(DSAEngine.getInstance().verifySignature(sig, src, fake));
}
for (int i = 0; i < 1000; i++) {
KeyGenerator.getInstance().generateSessionKey();
}
}
Aggregations