Search in sources :

Example 21 with SessionKey

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

the class SessionEncryptionTest method testSessions.

/**
 *  Run     tagsIncluded    useTag  rekey
 *  1       yes (2)         no      no
 *  2       no              yes     no
 *  3       yes (2)         yes     no
 *  4       no              yes     no
 *  5       no              yes     no
 */
public void testSessions() 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);
    SessionTag tag1 = new SessionTag(true);
    SessionTag tag2 = new SessionTag(true);
    SessionTag tag3 = new SessionTag(true);
    SessionTag tag4 = new SessionTag(true);
    HashSet<SessionTag> firstTags = new HashSet<SessionTag>();
    firstTags.add(tag1);
    firstTags.add(tag2);
    HashSet<SessionTag> secondTags = new HashSet<SessionTag>();
    secondTags.add(tag3);
    secondTags.add(tag4);
    byte[] msg1 = DataHelper.getASCII("msg 1");
    byte[] msg2 = DataHelper.getASCII("msg 2");
    byte[] msg3 = DataHelper.getASCII("msg 3");
    byte[] msg4 = DataHelper.getASCII("msg 4");
    byte[] msg5 = DataHelper.getASCII("msg 5");
    byte[] emsg1 = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, firstTags, null, 64);
    byte[] dmsg1 = _context.elGamalAESEngine().decrypt(emsg1, privKey, skm);
    assertTrue(DataHelper.eq(dmsg1, msg1));
    TagSetHandle tsh = skm.tagsDelivered(pubKey, curKey, firstTags);
    skm.tagsAcked(pubKey, curKey, tsh);
    curKey = skm.getCurrentKey(pubKey);
    SessionTag curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    byte[] emsg2 = _context.elGamalAESEngine().encrypt(msg2, pubKey, curKey, null, curTag, 64);
    byte[] dmsg2 = _context.elGamalAESEngine().decrypt(emsg2, privKey, skm);
    assertTrue(DataHelper.eq(dmsg2, msg2));
    curKey = skm.getCurrentKey(pubKey);
    curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    assertNotNull(curKey);
    byte[] emsg3 = _context.elGamalAESEngine().encrypt(msg3, pubKey, curKey, secondTags, curTag, 64);
    byte[] dmsg3 = _context.elGamalAESEngine().decrypt(emsg3, privKey, skm);
    assertTrue(DataHelper.eq(dmsg3, msg3));
    tsh = skm.tagsDelivered(pubKey, curKey, secondTags);
    skm.tagsAcked(pubKey, curKey, tsh);
    curKey = skm.getCurrentKey(pubKey);
    curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    assertNotNull(curKey);
    byte[] emsg4 = _context.elGamalAESEngine().encrypt(msg4, pubKey, curKey, null, curTag, 64);
    byte[] dmsg4 = _context.elGamalAESEngine().decrypt(emsg4, privKey, skm);
    assertTrue(DataHelper.eq(dmsg4, msg4));
    curKey = skm.getCurrentKey(pubKey);
    curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    assertNotNull(curKey);
    byte[] emsg5 = _context.elGamalAESEngine().encrypt(msg5, pubKey, curKey, null, curTag, 64);
    byte[] dmsg5 = _context.elGamalAESEngine().decrypt(emsg5, privKey, skm);
    assertTrue(DataHelper.eq(dmsg5, msg5));
}
Also used : PrivateKey(net.i2p.data.PrivateKey) PublicKey(net.i2p.data.PublicKey) SessionKey(net.i2p.data.SessionKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet) TagSetHandle(net.i2p.crypto.TagSetHandle)

Example 22 with SessionKey

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

the class DHSessionKeyBuilderTest method testDHSessionKeyBuilder.

public void testDHSessionKeyBuilder() {
    I2PAppContext ctx = new I2PAppContext();
    for (int i = 0; i < 5; i++) {
        DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder();
        DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder();
        BigInteger pub1 = builder1.getMyPublicValue();
        BigInteger pub2 = builder2.getMyPublicValue();
        try {
            builder2.setPeerPublicValue(pub1);
            builder1.setPeerPublicValue(pub2);
        } catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) {
            assertTrue(ippe.getMessage(), true);
        }
        SessionKey key1 = builder1.getSessionKey();
        SessionKey key2 = builder2.getSessionKey();
        assertEquals(key1, key2);
        byte[] iv = new byte[16];
        RandomSource.getInstance().nextBytes(iv);
        // 16 bytes max using AESEngine
        String origVal = "1234567890123456";
        byte[] enc = new byte[16];
        byte[] dec = new byte[16];
        ctx.aes().encrypt(DataHelper.getASCII(origVal), 0, enc, 0, key1, iv, 16);
        ctx.aes().decrypt(enc, 0, dec, 0, key2, iv, 16);
        String tranVal = new String(dec);
        assertEquals(origVal, tranVal);
    }
}
Also used : I2PAppContext(net.i2p.I2PAppContext) SessionKey(net.i2p.data.SessionKey) BigInteger(java.math.BigInteger)

Example 23 with SessionKey

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

the class TransientSessionKeyManager method aggressiveExpire.

/**
 * Aggressively expire inbound tag sets and outbound sessions
 *
 * @return number of tag sets expired (bogus as it overcounts inbound)
 */
private int aggressiveExpire() {
    int removed = 0;
    int remaining = 0;
    long now = _context.clock().now();
    synchronized (_inboundTagSets) {
        for (Iterator<TagSet> iter = _inboundTagSets.values().iterator(); iter.hasNext(); ) {
            TagSet ts = iter.next();
            // for inbound tagsets, getDate() is the expire time
            if (ts.getDate() <= now) {
                iter.remove();
                // bug, this counts inbound tags, not tag sets
                removed++;
            }
        }
        remaining = _inboundTagSets.size();
        if (remaining > 500) {
            // find SessionKeys with a large number of TagSets and trim them
            Map<SessionKey, Set<TagSet>> inboundSets = getInboundTagSetsBySessionKey();
            for (Map.Entry<SessionKey, Set<TagSet>> e : inboundSets.entrySet()) {
                SessionKey skey = e.getKey();
                Set<TagSet> sets = e.getValue();
                int count = sets.size();
                if (count >= 10) {
                    if (_log.shouldInfo())
                        _log.info("Session key " + skey.toBase64() + " has " + count + " tag sets");
                    // for any session key with at least 10 tagsets,
                    // remove all tagsets larger than 8 tags that haven't been used and
                    // are old. The more the tagsets, the more aggressively we expire.
                    // From 9 minutes at 10 down to one minute at 50
                    long age = Math.min(5 * 60 * 1000, Math.max(60 * 1000, 9 * 60 * 1000 - ((count - 10) * 8 * 60 * 1000 / 40)));
                    for (TagSet ts : sets) {
                        Set<SessionTag> tags = ts.getTags();
                        int curSize = tags.size();
                        int origSize = ts.getOriginalSize();
                        long expires = ts.getDate();
                        if (curSize == origSize && curSize > 8 && expires < now + SESSION_LIFETIME_MAX_MS - age) {
                            if (_log.shouldInfo())
                                _log.info("Removed unused tag set " + ts);
                            for (SessionTag tag : tags) {
                                _inboundTagSets.remove(tag);
                            }
                            removed += curSize;
                        }
                    }
                }
            }
            remaining = _inboundTagSets.size();
        }
    }
    _context.statManager().addRateData("crypto.sessionTagsRemaining", remaining, 0);
    if (removed > 0 && _log.shouldInfo())
        _log.info("Expired inbound: " + removed);
    int oremoved = 0;
    synchronized (_outboundSessions) {
        for (Iterator<OutboundSession> iter = _outboundSessions.values().iterator(); iter.hasNext(); ) {
            OutboundSession sess = iter.next();
            oremoved += sess.expireTags();
            // don't kill a new session or one that's temporarily out of tags
            if (sess.getLastUsedDate() < now - (SESSION_LIFETIME_MAX_MS / 2) && sess.availableTags() <= 0) {
                iter.remove();
                // just to have a non-zero return value?
                oremoved++;
            }
        }
    }
    if (oremoved > 0 && _log.shouldInfo())
        _log.info("Expired outbound: " + oremoved);
    return removed + oremoved;
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) SessionKey(net.i2p.data.SessionKey) SessionTag(net.i2p.data.SessionTag) HashMap(java.util.HashMap) Map(java.util.Map)

Example 24 with SessionKey

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

the class TransientSessionKeyManager method consumeTag.

/**
 * Determine if we have received a session key associated with the given session tag,
 * and if so, discard it (but keep track for frequent dups) and return the decryption
 * key it was received with (via tagsReceived(...)).  returns null if no session key
 * matches
 */
@Override
public SessionKey consumeTag(SessionTag tag) {
    TagSet tagSet;
    synchronized (_inboundTagSets) {
        tagSet = _inboundTagSets.remove(tag);
        if (tagSet == null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Cannot consume IB " + tag + " as it is not known");
            return null;
        }
        tagSet.consume(tag);
    }
    SessionKey key = tagSet.getAssociatedKey();
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("IB Tag consumed: " + tag + " from: " + tagSet);
    return key;
}
Also used : SessionKey(net.i2p.data.SessionKey)

Example 25 with SessionKey

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

the class TransientSessionKeyManager method getCurrentOrNewKey.

/**
 * Retrieve the session key currently associated with encryption to the target.
 * Generates a new session and session key if not previously exising.
 *
 * @return non-null
 * @since 0.9
 */
@Override
public SessionKey getCurrentOrNewKey(PublicKey target) {
    synchronized (_outboundSessions) {
        OutboundSession sess = _outboundSessions.get(target);
        if (sess != null) {
            long now = _context.clock().now();
            if (sess.getLastUsedDate() < now - SESSION_LIFETIME_MAX_MS)
                sess = null;
        }
        if (sess == null) {
            SessionKey key = _context.keyGenerator().generateSessionKey();
            createAndReturnSession(target, key);
            return key;
        }
        return sess.getCurrentKey();
    }
}
Also used : SessionKey(net.i2p.data.SessionKey)

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