Search in sources :

Example 26 with Signature

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());
}
Also used : DigestInputStream(java.security.DigestInputStream) DigestInputStream(java.security.DigestInputStream) InputStream(java.io.InputStream) Hash(net.i2p.data.Hash) SHA1Hash(net.i2p.crypto.SHA1Hash) SigType(net.i2p.crypto.SigType) DataFormatException(net.i2p.data.DataFormatException) Signature(net.i2p.data.Signature) MessageDigest(java.security.MessageDigest) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 27 with Signature

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);
}
Also used : Signature(net.i2p.data.Signature)

Example 28 with Signature

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);
    }
}
Also used : Signature(net.i2p.data.Signature) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) InetAddress(java.net.InetAddress) SigType(net.i2p.crypto.SigType)

Example 29 with Signature

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);
}
Also used : SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) ByteArrayInputStream(java.io.ByteArrayInputStream) Signature(net.i2p.data.Signature)

Example 30 with Signature

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();
    }
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) I2PAppContext(net.i2p.I2PAppContext) Signature(net.i2p.data.Signature)

Aggregations

Signature (net.i2p.data.Signature)36 IOException (java.io.IOException)16 SigType (net.i2p.crypto.SigType)14 DataFormatException (net.i2p.data.DataFormatException)11 SigningPublicKey (net.i2p.data.SigningPublicKey)11 ByteArrayInputStream (java.io.ByteArrayInputStream)7 GeneralSecurityException (java.security.GeneralSecurityException)6 FileInputStream (java.io.FileInputStream)5 StringWriter (java.io.StringWriter)5 SigningPrivateKey (net.i2p.data.SigningPrivateKey)5 InetAddress (java.net.InetAddress)4 MessageDigest (java.security.MessageDigest)4 Destination (net.i2p.data.Destination)4 SimpleDataStructure (net.i2p.data.SimpleDataStructure)4 FileOutputStream (java.io.FileOutputStream)3 InputStream (java.io.InputStream)3 DigestInputStream (java.security.DigestInputStream)3 Hash (net.i2p.data.Hash)3 Log (net.i2p.util.Log)3 SecureFileOutputStream (net.i2p.util.SecureFileOutputStream)3