Search in sources :

Example 6 with SessionTag

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

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

the class DatabaseLookupMessage method readMessage.

public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException {
    if (type != MESSAGE_TYPE)
        throw new I2NPMessageException("Message type is incorrect for this message");
    int curIndex = offset;
    // byte keyData[] = new byte[Hash.HASH_LENGTH];
    // System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
    _key = Hash.create(data, curIndex);
    curIndex += Hash.HASH_LENGTH;
    // _key = new Hash(keyData);
    // byte fromData[] = new byte[Hash.HASH_LENGTH];
    // System.arraycopy(data, curIndex, fromData, 0, Hash.HASH_LENGTH);
    _fromHash = Hash.create(data, curIndex);
    curIndex += Hash.HASH_LENGTH;
    // _fromHash = new Hash(fromData);
    // as of 0.9.6, ignore other 7 bits of the flag byte
    // TODO store the whole flag byte
    boolean tunnelSpecified = (data[curIndex] & FLAG_TUNNEL) != 0;
    boolean replyKeySpecified = (data[curIndex] & FLAG_ENCRYPT) != 0;
    switch(data[curIndex] & FLAG_TYPE_MASK) {
        case FLAG_TYPE_LS:
            _type = Type.LS;
            break;
        case FLAG_TYPE_RI:
            _type = Type.RI;
            break;
        case FLAG_TYPE_EXPL:
            _type = Type.EXPL;
            break;
        case FLAG_TYPE_ANY:
        default:
            _type = Type.ANY;
            break;
    }
    curIndex++;
    if (tunnelSpecified) {
        _replyTunnel = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
        curIndex += 4;
    }
    int numPeers = (int) DataHelper.fromLong(data, curIndex, 2);
    curIndex += 2;
    if ((numPeers < 0) || (numPeers > MAX_NUM_PEERS))
        throw new I2NPMessageException("Invalid number of peers - " + numPeers);
    List<Hash> peers = numPeers > 0 ? new ArrayList<Hash>(numPeers) : null;
    for (int i = 0; i < numPeers; i++) {
        // byte peer[] = new byte[Hash.HASH_LENGTH];
        // System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
        Hash p = Hash.create(data, curIndex);
        curIndex += Hash.HASH_LENGTH;
        peers.add(p);
    }
    _dontIncludePeers = peers;
    if (replyKeySpecified) {
        byte[] rk = new byte[SessionKey.KEYSIZE_BYTES];
        System.arraycopy(data, curIndex, rk, 0, SessionKey.KEYSIZE_BYTES);
        _replyKey = new SessionKey(rk);
        curIndex += SessionKey.KEYSIZE_BYTES;
        // number of tags, assume always 1 for now
        curIndex++;
        byte[] rt = new byte[SessionTag.BYTE_LENGTH];
        System.arraycopy(data, curIndex, rt, 0, SessionTag.BYTE_LENGTH);
        _replyTag = new SessionTag(rt);
    }
}
Also used : SessionKey(net.i2p.data.SessionKey) SessionTag(net.i2p.data.SessionTag) Hash(net.i2p.data.Hash) TunnelId(net.i2p.data.TunnelId)

Example 8 with SessionTag

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

the class ElGamalTest method testAES.

public void testAES() {
    SessionKey sessionKey = KeyGenerator.getInstance().generateSessionKey();
    Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData());
    byte[] iv = new byte[16];
    System.arraycopy(h.getData(), 0, iv, 0, 16);
    String msg = "Hello world";
    byte[] encrypted = _context.elGamalAESEngine().encryptAESBlock(DataHelper.getASCII(msg), sessionKey, iv, null, null, 64);
    Set<SessionTag> foundTags = new HashSet<SessionTag>();
    SessionKey foundKey = new SessionKey();
    byte[] decrypted = null;
    try {
        decrypted = _context.elGamalAESEngine().decryptAESBlock(encrypted, 0, encrypted.length, sessionKey, iv, null, foundTags, foundKey);
    } catch (DataFormatException dfe) {
        dfe.printStackTrace();
        fail();
    }
    assertNotNull(decrypted);
    String read = new String(decrypted);
    assertEquals(msg, read);
}
Also used : DataFormatException(net.i2p.data.DataFormatException) SessionKey(net.i2p.data.SessionKey) SessionTag(net.i2p.data.SessionTag) Hash(net.i2p.data.Hash) HashSet(java.util.HashSet)

Example 9 with SessionTag

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

the class SessionEncryptionTest method testRekeying.

/**
 *  Run tagsIncluded    useTag  rekey
 *  1   yes (2)         no      no
 *  2   no              yes     no
 *  3   yes (2)         yes     yes
 *  4   no              yes     no
 *  5   no              yes     no
 */
public void testRekeying() 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);
    SessionKey nextKey = KeyGenerator.getInstance().generateSessionKey();
    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, nextKey, 64);
    byte[] dmsg3 = _context.elGamalAESEngine().decrypt(emsg3, privKey, skm);
    assertTrue(DataHelper.eq(dmsg3, msg3));
    // note nextKey not curKey
    tsh = skm.tagsDelivered(pubKey, nextKey, secondTags);
    skm.tagsAcked(pubKey, nextKey, 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 10 with SessionTag

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

the class SessionEncryptionTest method testLongSession.

/**
 *  20 tags every 10 messages, rekey every 50
 */
public void testLongSession() 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);
    for (int i = 0; i < 1000; i++) {
        Set<SessionTag> tags = null;
        SessionKey nextKey = null;
        curKey = skm.getCurrentKey(pubKey);
        SessionTag curTag = skm.consumeNextAvailableTag(pubKey, curKey);
        int availTags = skm.getAvailableTags(pubKey, curKey);
        if ((availTags < 1)) {
            tags = generateNewTags(50);
        }
        if (i % 50 == 0)
            nextKey = KeyGenerator.getInstance().generateSessionKey();
        byte[] msg = DataHelper.getASCII("msg " + i);
        byte[] emsg = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, tags, curTag, nextKey, 64);
        byte[] dmsg = _context.elGamalAESEngine().decrypt(emsg, privKey, skm);
        assertTrue(DataHelper.eq(dmsg, msg));
        if ((tags != null) && (tags.size() > 0)) {
            if (nextKey == null) {
                TagSetHandle tsh = skm.tagsDelivered(pubKey, curKey, tags);
                skm.tagsAcked(pubKey, curKey, tsh);
            } else {
                TagSetHandle tsh = skm.tagsDelivered(pubKey, nextKey, tags);
                skm.tagsAcked(pubKey, nextKey, tsh);
            }
        }
    }
}
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) TagSetHandle(net.i2p.crypto.TagSetHandle)

Aggregations

SessionTag (net.i2p.data.SessionTag)19 SessionKey (net.i2p.data.SessionKey)15 HashSet (java.util.HashSet)8 PublicKey (net.i2p.data.PublicKey)7 SessionKeyManager (net.i2p.crypto.SessionKeyManager)6 TagSetHandle (net.i2p.crypto.TagSetHandle)5 PrivateKey (net.i2p.data.PrivateKey)4 GarlicMessage (net.i2p.data.i2np.GarlicMessage)3 ArrayList (java.util.ArrayList)2 DataFormatException (net.i2p.data.DataFormatException)2 Hash (net.i2p.data.Hash)2 PayloadGarlicConfig (net.i2p.router.message.PayloadGarlicConfig)2 RemovableSingletonSet (net.i2p.router.util.RemovableSingletonSet)2 Log (net.i2p.util.Log)2 IOException (java.io.IOException)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1