Search in sources :

Example 11 with SessionTag

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

the class BuildTestMessageJob method runJob.

public void runJob() {
    if (alreadyKnownReachable()) {
        getContext().jobQueue().addJob(_onSend);
        return;
    }
    // first goes to the peer then back to us.
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Building garlic message to test " + _target.getIdentity().getHash().toBase64());
    GarlicConfig config = buildGarlicCloveConfig();
    // TODO: make the last params on this specify the correct sessionKey and tags used
    ReplyJob replyJob = new JobReplyJob(getContext(), _onSend, config.getRecipient().getIdentity().getPublicKey(), config.getId(), null, new HashSet<SessionTag>());
    MessageSelector sel = buildMessageSelector();
    SendGarlicJob job = new SendGarlicJob(getContext(), config, null, _onSendFailed, replyJob, _onSendFailed, _timeoutMs, _priority, sel);
    getContext().jobQueue().addJob(job);
}
Also used : SessionTag(net.i2p.data.SessionTag) MessageSelector(net.i2p.router.MessageSelector) ReplyJob(net.i2p.router.ReplyJob)

Example 12 with SessionTag

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

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

the class ElGamalAESEngine method encryptAESBlock.

/**
 * @param tagsForDelivery session tags to be associated with the key or null;
 *                        200 max enforced at receiver
 */
private final byte[] encryptAESBlock(byte[] data, SessionKey key, byte[] iv, Set<SessionTag> tagsForDelivery, SessionKey newKey, long paddedSize, int prefixBytes) {
    // _log.debug("Encrypting AES");
    if (tagsForDelivery == null)
        tagsForDelivery = Collections.emptySet();
    int size = // sizeof(tags)
    2 + SessionTag.BYTE_LENGTH * tagsForDelivery.size() + // payload length
    4 + Hash.HASH_LENGTH + (newKey == null ? 1 : 1 + SessionKey.KEYSIZE_BYTES) + data.length;
    int totalSize = size + getPaddingSize(size, paddedSize);
    byte[] aesData = new byte[totalSize + prefixBytes];
    int cur = prefixBytes;
    DataHelper.toLong(aesData, cur, 2, tagsForDelivery.size());
    cur += 2;
    for (SessionTag tag : tagsForDelivery) {
        System.arraycopy(tag.getData(), 0, aesData, cur, SessionTag.BYTE_LENGTH);
        cur += SessionTag.BYTE_LENGTH;
    }
    // _log.debug("# tags created, registered, and written: " + tagsForDelivery.size());
    DataHelper.toLong(aesData, cur, 4, data.length);
    cur += 4;
    // _log.debug("data length: " + data.length);
    // use alternate calculateHash() method to avoid object churn and caching
    // Hash hash = _context.sha().calculateHash(data);
    // System.arraycopy(hash.getData(), 0, aesData, cur, Hash.HASH_LENGTH);
    _context.sha().calculateHash(data, 0, data.length, aesData, cur);
    cur += Hash.HASH_LENGTH;
    // _log.debug("hash of data: " + DataHelper.toString(hash.getData(), 32));
    if (newKey == null) {
        // don't rekey
        aesData[cur++] = 0x00;
    // _log.debug("flag written");
    } else {
        // rekey
        aesData[cur++] = 0x01;
        System.arraycopy(newKey.getData(), 0, aesData, cur, SessionKey.KEYSIZE_BYTES);
        cur += SessionKey.KEYSIZE_BYTES;
    }
    System.arraycopy(data, 0, aesData, cur, data.length);
    cur += data.length;
    // _log.debug("raw data written: " + len);
    byte[] padding = getPadding(_context, size, paddedSize);
    // _log.debug("padding length: " + padding.length);
    System.arraycopy(padding, 0, aesData, cur, padding.length);
    cur += padding.length;
    // Hash h = _context.sha().calculateHash(data);
    // _log.debug("Hash of entire aes block before encryption: (len=" + data.length + ")\n" + DataHelper.toString(h.getData(), 32));
    _context.aes().encrypt(aesData, prefixBytes, aesData, prefixBytes, key, iv, aesData.length - prefixBytes);
    // return aesEncr;
    return aesData;
}
Also used : SessionTag(net.i2p.data.SessionTag)

Example 14 with SessionTag

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

the class TransientSessionKeyManager method tagsReceived.

/**
 * Accept the given tags and associate them with the given key for decryption
 *
 * @param sessionTags modifiable; NOT copied. Non-null, non-empty.
 * @param expire time from now
 * @since 0.9.7
 */
@Override
public void tagsReceived(SessionKey key, Set<SessionTag> sessionTags, long expire) {
    TagSet tagSet = new TagSet(sessionTags, key, _context.clock().now() + expire, _rcvTagSetID.incrementAndGet());
    if (_log.shouldLog(Log.DEBUG)) {
        _log.debug("Received " + tagSet);
    // _log.debug("Tags: " + DataHelper.toString(sessionTags));
    }
    TagSet old = null;
    SessionTag dupTag = null;
    synchronized (_inboundTagSets) {
        for (SessionTag tag : sessionTags) {
            old = _inboundTagSets.put(tag, tagSet);
            if (old != null) {
                if (!old.getAssociatedKey().equals(tagSet.getAssociatedKey())) {
                    _inboundTagSets.remove(tag);
                    dupTag = tag;
                    break;
                } else {
                    // ignore the dup
                    old = null;
                }
            }
        }
    }
    if (old != null) {
        // drop both old and tagSet tags
        synchronized (_inboundTagSets) {
            for (SessionTag tag : old.getTags()) {
                _inboundTagSets.remove(tag);
            }
            for (SessionTag tag : sessionTags) {
                _inboundTagSets.remove(tag);
            }
        }
        if (_log.shouldLog(Log.WARN)) {
            _log.warn("Multiple tags matching!  tagSet: " + tagSet + " and old tagSet: " + old + " tag: " + dupTag + "/" + dupTag);
            _log.warn("Earlier tag set creation: " + old + ": key=" + old.getAssociatedKey());
            _log.warn("Current tag set creation: " + tagSet + ": key=" + tagSet.getAssociatedKey());
        }
    }
}
Also used : SessionTag(net.i2p.data.SessionTag)

Example 15 with SessionTag

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

the class TransientSessionKeyManager method clearExcess.

/**
 * remove a bunch of arbitrarily selected tags, then drop all of
 * the associated tag sets.  this is very time consuming - iterating
 * across the entire _inboundTagSets map, but it should be very rare,
 * and the stats we can gather can hopefully reduce the frequency of
 * using too many session tags in the future
 */
private void clearExcess(int overage) {
    long now = _context.clock().now();
    int old = 0;
    int large = 0;
    int absurd = 0;
    int recent = 0;
    int tags = 0;
    int toRemove = overage * 2;
    _log.logAlways(Log.WARN, "TOO MANY SESSION TAGS! Starting cleanup, overage = " + overage);
    List<TagSet> removed = new ArrayList<TagSet>(toRemove);
    synchronized (_inboundTagSets) {
        for (TagSet set : _inboundTagSets.values()) {
            int size = set.getTags().size();
            if (size > 1000)
                absurd++;
            if (size > 100)
                large++;
            if (set.getDate() - now < 3 * 60 * 1000) {
                // expiration is 12 minutes, so these are older than 9 minutes
                old++;
                removed.add(set);
                continue;
            } else if (set.getDate() - now > 8 * 60 * 1000) {
                // expiration is 12 minutes, so these were created in last 4 minutes
                recent++;
                continue;
            }
            if (removed.size() < toRemove)
                removed.add(set);
        }
        for (int i = 0; i < removed.size(); i++) {
            TagSet cur = removed.get(i);
            for (SessionTag tag : cur.getTags()) {
                _inboundTagSets.remove(tag);
                tags++;
            }
        }
    }
    _log.logAlways(Log.WARN, "TOO MANY SESSION TAGS!  removed " + removed.size() + " tag sets arbitrarily, with " + tags + " tags," + "where there are " + old + " long lasting sessions, " + recent + " ones created in the last few minutes, and " + large + " sessions with more than 100 tags (and " + absurd + " with more than 1000!), leaving a total of " + _inboundTagSets.size() + " tags behind");
}
Also used : ArrayList(java.util.ArrayList) SessionTag(net.i2p.data.SessionTag)

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