Search in sources :

Example 31 with SigningPrivateKey

use of net.i2p.data.SigningPrivateKey in project i2p.i2p by i2p.

the class RequestLeaseSetMessageHandler method signLeaseSet.

/**
 *  Finish creating and signing the new LeaseSet
 *  @since 0.9.7
 */
protected synchronized void signLeaseSet(LeaseSet leaseSet, I2PSessionImpl session) {
    Destination dest = session.getMyDestination();
    // also, if this session is connected to multiple routers, include other leases here
    leaseSet.setDestination(dest);
    // reuse the old keys for the client
    LeaseInfo li = _existingLeaseSets.get(dest);
    if (li == null) {
        // [enctype:]b64 of private key
        String spk = session.getOptions().getProperty("i2cp.leaseSetPrivateKey");
        // [sigtype:]b64 of private key
        String sspk = session.getOptions().getProperty("i2cp.leaseSetSigningPrivateKey");
        PrivateKey privKey = null;
        SigningPrivateKey signingPrivKey = null;
        if (spk != null && sspk != null) {
            boolean useOldKeys = true;
            int colon = sspk.indexOf(':');
            SigType type = dest.getSigType();
            if (colon > 0) {
                String stype = sspk.substring(0, colon);
                SigType t = SigType.parseSigType(stype);
                if (t == type)
                    sspk = sspk.substring(colon + 1);
                else
                    useOldKeys = false;
            }
            colon = spk.indexOf(':');
            // just ignore for now, no other types supported
            if (colon >= 0)
                spk = spk.substring(colon + 1);
            if (useOldKeys) {
                try {
                    signingPrivKey = new SigningPrivateKey(type);
                    signingPrivKey.fromBase64(sspk);
                } catch (DataFormatException iae) {
                    useOldKeys = false;
                    signingPrivKey = null;
                }
            }
            if (useOldKeys) {
                try {
                    privKey = new PrivateKey();
                    privKey.fromBase64(spk);
                } catch (DataFormatException iae) {
                    privKey = null;
                }
            }
        }
        if (privKey == null && !_existingLeaseSets.isEmpty()) {
            // look for keypair from another dest using same pubkey
            PublicKey pk = dest.getPublicKey();
            for (Map.Entry<Destination, LeaseInfo> e : _existingLeaseSets.entrySet()) {
                if (pk.equals(e.getKey().getPublicKey())) {
                    privKey = e.getValue().getPrivateKey();
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey());
                    break;
                }
            }
        }
        if (privKey != null) {
            if (signingPrivKey != null) {
                li = new LeaseInfo(privKey, signingPrivKey);
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys");
            } else {
                li = new LeaseInfo(privKey, dest);
            }
        } else {
            li = new LeaseInfo(dest);
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys");
        }
        _existingLeaseSets.put(dest, li);
    } else {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Caching the old leaseInfo keys for " + dest);
    }
    leaseSet.setEncryptionKey(li.getPublicKey());
    leaseSet.setSigningKey(li.getSigningPublicKey());
    // SubSession options aren't updated via the gui, so use the primary options
    Properties opts;
    if (session instanceof SubSession)
        opts = ((SubSession) session).getPrimaryOptions();
    else
        opts = session.getOptions();
    boolean encrypt = Boolean.parseBoolean(opts.getProperty("i2cp.encryptLeaseSet"));
    String sk = opts.getProperty("i2cp.leaseSetKey");
    Hash h = dest.calculateHash();
    if (encrypt && sk != null) {
        SessionKey key = new SessionKey();
        try {
            key.fromBase64(sk);
            leaseSet.encrypt(key);
            _context.keyRing().put(h, key);
        } catch (DataFormatException dfe) {
            _log.error("Bad leaseset key: " + sk);
            _context.keyRing().remove(h);
        }
    } else {
        _context.keyRing().remove(h);
    }
    try {
        leaseSet.sign(session.getPrivateKey());
        // Workaround for unparsable serialized signing private key for revocation
        // Send him a dummy DSA_SHA1 private key since it's unused anyway
        // See CreateLeaseSetMessage.doReadMessage()
        SigningPrivateKey spk = li.getSigningPrivateKey();
        if (!_context.isRouterContext() && spk.getType() != SigType.DSA_SHA1) {
            byte[] dummy = new byte[SigningPrivateKey.KEYSIZE_BYTES];
            _context.random().nextBytes(dummy);
            spk = new SigningPrivateKey(dummy);
        }
        session.getProducer().createLeaseSet(session, leaseSet, spk, li.getPrivateKey());
        session.setLeaseSet(leaseSet);
    } catch (DataFormatException dfe) {
        session.propogateError("Error signing the leaseSet", dfe);
    } catch (I2PSessionException ise) {
        if (session.isClosed()) {
            // race, closed while signing leaseset
            // EOFExceptions are logged at WARN level (see I2PSessionImpl.propogateError())
            // so the user won't see this
            EOFException eof = new EOFException("Session closed while signing leaseset");
            eof.initCause(ise);
            session.propogateError("Session closed while signing leaseset", eof);
        } else {
            session.propogateError("Error sending the signed leaseSet", ise);
        }
    }
}
Also used : Destination(net.i2p.data.Destination) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) Properties(java.util.Properties) Hash(net.i2p.data.Hash) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) DataFormatException(net.i2p.data.DataFormatException) SessionKey(net.i2p.data.SessionKey) EOFException(java.io.EOFException) I2PSessionException(net.i2p.client.I2PSessionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map)

Aggregations

SigningPrivateKey (net.i2p.data.SigningPrivateKey)31 SigningPublicKey (net.i2p.data.SigningPublicKey)14 DataFormatException (net.i2p.data.DataFormatException)11 IOException (java.io.IOException)10 PrivateKey (net.i2p.data.PrivateKey)10 GeneralSecurityException (java.security.GeneralSecurityException)8 PublicKey (net.i2p.data.PublicKey)7 File (java.io.File)6 PrivateKey (java.security.PrivateKey)6 SigType (net.i2p.crypto.SigType)6 SimpleDataStructure (net.i2p.data.SimpleDataStructure)6 FileInputStream (java.io.FileInputStream)5 Properties (java.util.Properties)5 Destination (net.i2p.data.Destination)5 Signature (net.i2p.data.Signature)5 ByteArrayInputStream (java.io.ByteArrayInputStream)4 BigInteger (java.math.BigInteger)4 RouterInfo (net.i2p.data.router.RouterInfo)4 BufferedInputStream (java.io.BufferedInputStream)3 InputStream (java.io.InputStream)3