Search in sources :

Example 56 with SessionKey

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

the class SessionEncryptionTest method testNoSessions2.

public void testNoSessions2() throws Exception {
    Object[] keys = KeyGenerator.getInstance().generatePKIKeypair();
    PublicKey pubKey = (PublicKey) keys[0];
    PrivateKey privKey = (PrivateKey) keys[1];
    SessionKeyManager skm = new TransientSessionKeyManager(_context);
    SessionKey curKey = skm.createSession(pubKey);
    byte[] msg = DataHelper.getASCII("msg 2");
    byte[] emsg = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, null, null, 64);
    byte[] dmsg = _context.elGamalAESEngine().decrypt(emsg, privKey, skm);
    assertTrue(DataHelper.eq(dmsg, msg));
}
Also used : PrivateKey(net.i2p.data.PrivateKey) PublicKey(net.i2p.data.PublicKey) SessionKey(net.i2p.data.SessionKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager)

Example 57 with SessionKey

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

the class ElGamalAESEngine method decrypt.

/**
 * Decrypt the message using the given private key
 * and using tags from the specified key manager.
 * This works according to the
 * ElGamal+AES algorithm in the data structure spec.
 *
 * Warning - use the correct SessionKeyManager. Clients should instantiate their own.
 * Clients using I2PAppContext.sessionKeyManager() may be correlated with the router,
 * unless you are careful to use different keys.
 *
 * @return decrypted data or null on failure
 */
public byte[] decrypt(byte[] data, PrivateKey targetPrivateKey, SessionKeyManager keyManager) throws DataFormatException {
    if (data == null) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Null data being decrypted?");
        return null;
    } else if (data.length < MIN_ENCRYPTED_SIZE) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Data is less than the minimum size (" + data.length + " < " + MIN_ENCRYPTED_SIZE + ")");
        return null;
    }
    byte[] tag = new byte[32];
    System.arraycopy(data, 0, tag, 0, 32);
    SessionTag st = new SessionTag(tag);
    SessionKey key = keyManager.consumeTag(st);
    SessionKey foundKey = new SessionKey();
    SessionKey usedKey = new SessionKey();
    Set<SessionTag> foundTags = new HashSet<SessionTag>();
    byte[] decrypted = null;
    boolean wasExisting = false;
    if (key != null) {
        // if (_log.shouldLog(Log.DEBUG)) _log.debug("Key is known for tag " + st);
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Decrypting existing session encrypted with tag: " + st.toString() + ": key: " + key.toBase64() + ": " + data.length + " bytes ");
        decrypted = decryptExistingSession(data, key, targetPrivateKey, foundTags, usedKey, foundKey);
        if (decrypted != null) {
            _context.statManager().updateFrequency("crypto.elGamalAES.decryptExistingSession");
            if ((!foundTags.isEmpty()) && (_log.shouldLog(Log.DEBUG)))
                _log.debug("ElG/AES decrypt success with " + st + ": found tags: " + foundTags);
            wasExisting = true;
        } else {
            _context.statManager().updateFrequency("crypto.elGamalAES.decryptFailed");
            if (_log.shouldLog(Log.WARN)) {
                _log.warn("ElG decrypt fail: known tag [" + st + "], failed decrypt");
            }
        }
    } else {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Key is NOT known for tag " + st);
        decrypted = decryptNewSession(data, targetPrivateKey, foundTags, usedKey, foundKey);
        if (decrypted != null) {
            _context.statManager().updateFrequency("crypto.elGamalAES.decryptNewSession");
            if ((!foundTags.isEmpty()) && (_log.shouldLog(Log.DEBUG)))
                _log.debug("ElG decrypt success: found tags: " + foundTags);
        } else {
            _context.statManager().updateFrequency("crypto.elGamalAES.decryptFailed");
            if (_log.shouldLog(Log.WARN))
                _log.warn("ElG decrypt fail: unknown tag: " + st);
        }
    }
    if ((key == null) && (decrypted == null)) {
    // _log.debug("Unable to decrypt the data starting with tag [" + st + "] - did the tag expire recently?", new Exception("Decrypt failure"));
    }
    if (!foundTags.isEmpty()) {
        if (foundKey.getData() != null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Found key: " + foundKey.toBase64() + " tags: " + foundTags + " wasExisting? " + wasExisting);
            keyManager.tagsReceived(foundKey, foundTags);
        } else if (usedKey.getData() != null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Used key: " + usedKey.toBase64() + " tags: " + foundTags + " wasExisting? " + wasExisting);
            keyManager.tagsReceived(usedKey, foundTags);
        }
    }
    return decrypted;
}
Also used : SessionKey(net.i2p.data.SessionKey) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet)

Example 58 with SessionKey

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

the class HMAC256Generator method calculate.

/**
 *  Calculate the HMAC of the data with the given key.
 *  Outputs 32 bytes to target starting at targetOffset.
 *
 *  @throws UnsupportedOperationException if the JVM does not support it
 *  @throws IllegalArgumentException for bad key or target too small
 *  @since 0.9.12 overrides HMACGenerator
 */
@Override
public void calculate(SessionKey key, byte[] data, int offset, int length, byte[] target, int targetOffset) {
    try {
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA256");
        Key keyObj = new SecretKeySpec(key.getData(), "HmacSHA256");
        mac.init(keyObj);
        mac.update(data, offset, length);
        mac.doFinal(target, targetOffset);
    } catch (NoSuchAlgorithmException e) {
        throw new UnsupportedOperationException("HmacSHA256", e);
    } catch (GeneralSecurityException e) {
        throw new IllegalArgumentException("HmacSHA256", e);
    }
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) GeneralSecurityException(java.security.GeneralSecurityException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Key(java.security.Key) SessionKey(net.i2p.data.SessionKey)

Example 59 with SessionKey

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

the class KeyGenerator method generateSessionKey.

/**
 * Generate a private 256 bit session key
 * @return session key
 */
public SessionKey generateSessionKey() {
    // 256bit random # as a session key
    SessionKey key = new SessionKey();
    byte[] data = new byte[SessionKey.KEYSIZE_BYTES];
    _context.random().nextBytes(data);
    key.setData(data);
    return key;
}
Also used : SessionKey(net.i2p.data.SessionKey)

Example 60 with SessionKey

use of net.i2p.data.SessionKey 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

SessionKey (net.i2p.data.SessionKey)69 SessionTag (net.i2p.data.SessionTag)15 PublicKey (net.i2p.data.PublicKey)14 I2PAppContext (net.i2p.I2PAppContext)13 HashSet (java.util.HashSet)11 Hash (net.i2p.data.Hash)11 SessionKeyManager (net.i2p.crypto.SessionKeyManager)10 PrivateKey (net.i2p.data.PrivateKey)10 InetAddress (java.net.InetAddress)9 DataFormatException (net.i2p.data.DataFormatException)9 UnknownHostException (java.net.UnknownHostException)7 TagSetHandle (net.i2p.crypto.TagSetHandle)5 Map (java.util.Map)4 GarlicMessage (net.i2p.data.i2np.GarlicMessage)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Set (java.util.Set)3 EncryptedBuildRecord (net.i2p.data.i2np.EncryptedBuildRecord)3 BigInteger (java.math.BigInteger)2