Search in sources :

Example 6 with GarlicMessage

use of net.i2p.data.i2np.GarlicMessage in project i2p.i2p by i2p.

the class MessageWrapper method wrap.

/**
 *  Garlic wrap a message from nobody, destined for a router,
 *  to hide the contents from the OBEP.
 *  Forces ElGamal.
 *
 *  @return null on encrypt failure
 *  @since 0.9.5
 */
static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, RouterInfo to) {
    PayloadGarlicConfig payload = new PayloadGarlicConfig();
    payload.setCertificate(Certificate.NULL_CERT);
    payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    payload.setPayload(m);
    payload.setRecipient(to);
    payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
    payload.setExpiration(m.getMessageExpiration());
    SessionKey sentKey = ctx.keyGenerator().generateSessionKey();
    PublicKey key = to.getIdentity().getPublicKey();
    GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, null, key, sentKey, null);
    return msg;
}
Also used : PayloadGarlicConfig(net.i2p.router.message.PayloadGarlicConfig) SessionKey(net.i2p.data.SessionKey) PublicKey(net.i2p.data.PublicKey) GarlicMessage(net.i2p.data.i2np.GarlicMessage)

Example 7 with GarlicMessage

use of net.i2p.data.i2np.GarlicMessage in project i2p.i2p by i2p.

the class MessageWrapper method wrap.

/**
 *  Garlic wrap a message from nobody, destined for an unknown router,
 *  to hide the contents from the IBGW.
 *  Uses a supplied session key and session tag for AES encryption,
 *  avoiding ElGamal.
 *
 *  @param encryptKey non-null
 *  @param encryptTag non-null
 *  @return null on encrypt failure
 *  @since 0.9.7
 */
public static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, SessionKey encryptKey, SessionTag encryptTag) {
    PayloadGarlicConfig payload = new PayloadGarlicConfig();
    payload.setCertificate(Certificate.NULL_CERT);
    payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    payload.setPayload(m);
    payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
    payload.setExpiration(m.getMessageExpiration());
    GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, null, null, encryptKey, encryptTag);
    return msg;
}
Also used : PayloadGarlicConfig(net.i2p.router.message.PayloadGarlicConfig) GarlicMessage(net.i2p.data.i2np.GarlicMessage)

Example 8 with GarlicMessage

use of net.i2p.data.i2np.GarlicMessage in project i2p.i2p by i2p.

the class OutboundClientMessageOneShotJob method send.

/**
 * Send the message to the specified tunnel by creating a new garlic message containing
 * the (already created) payload clove as well as a new delivery status message.  This garlic
 * message is sent out one of our tunnels, destined for the lease (tunnel+router) specified, and the delivery
 * status message is targetting one of our free inbound tunnels as well.  We use a new
 * reply selector to keep an eye out for that delivery status message's token
 */
private void send() {
    synchronized (this) {
        if (_finished != Result.NONE) {
            if (_log.shouldLog(Log.WARN))
                _log.warn(OutboundClientMessageOneShotJob.this.getJobId() + ": SEND-AFTER-" + _finished);
            return;
        }
    }
    long now = getContext().clock().now();
    if (now >= _overallExpiration) {
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_EXPIRED);
        return;
    }
    _outTunnel = selectOutboundTunnel(_to);
    if (_outTunnel == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn(getJobId() + ": Could not find any outbound tunnels to send the payload through... this might take a while");
        getContext().statManager().addRateData("client.dispatchNoTunnels", now - _start);
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_TUNNELS);
        return;
    }
    // boolean wantACK = _wantACK || existingTags <= 30 || getContext().random().nextInt(100) < 5;
    // what's the point of 5% random? possible improvements or replacements:
    // DONE (getNextLease() is called before this): wantACK if we changed their inbound lease (getNextLease() sets _wantACK)
    // DONE (selectOutboundTunnel() moved above here): wantACK if we changed our outbound tunnel (selectOutboundTunnel() sets _wantACK)
    // DONE (added new cache): wantACK if we haven't in last 1m (requires a new static cache probably)
    Long lastReplyRequestSent = _cache.lastReplyRequestCache.get(_hashPair);
    boolean shouldRequestReply = lastReplyRequestSent == null || lastReplyRequestSent.longValue() < now - REPLY_REQUEST_INTERVAL;
    int sendFlags = _clientMessage.getFlags();
    // Per-message flag > 0 overrides per-session option
    int tagsRequired = SendMessageOptions.getTagThreshold(sendFlags);
    boolean wantACK = _wantACK || shouldRequestReply || GarlicMessageBuilder.needsTags(getContext(), _leaseSet.getEncryptionKey(), _from.calculateHash(), tagsRequired);
    LeaseSet replyLeaseSet;
    // Per-message flag == false overrides session option which is default true
    String allow = _clientMessage.getSenderConfig().getOptions().getProperty(BUNDLE_REPLY_LEASESET);
    boolean allowLeaseBundle = SendMessageOptions.getSendLeaseSet(sendFlags) && (allow == null || Boolean.parseBoolean(allow));
    if (allowLeaseBundle) {
        // If we want an ack, bundle a leaseSet...
        // replyLeaseSet = getReplyLeaseSet(wantACK);
        // Only when necessary. We don't need to force.
        // ACKs find their own way back, they don't need a leaseset.
        replyLeaseSet = getReplyLeaseSet(false);
        // ... and vice versa  (so we know he got it)
        if (replyLeaseSet != null)
            wantACK = true;
    } else {
        replyLeaseSet = null;
    }
    long token;
    if (wantACK) {
        _cache.lastReplyRequestCache.put(_hashPair, Long.valueOf(now));
        token = getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
        _inTunnel = selectInboundTunnel();
    } else {
        token = -1;
    }
    PayloadGarlicConfig clove = buildClove();
    if (clove == null) {
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_UNSUPPORTED_ENCRYPTION);
        return;
    }
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug(getJobId() + ": Clove built to " + _toString);
    PublicKey key = _leaseSet.getEncryptionKey();
    SessionKey sessKey = new SessionKey();
    Set<SessionTag> tags = new HashSet<SessionTag>();
    // Per-message flag > 0 overrides per-session option
    int tagsToSend = SendMessageOptions.getTagsToSend(sendFlags);
    GarlicMessage msg = OutboundClientMessageJobHelper.createGarlicMessage(getContext(), token, _overallExpiration, key, clove, _from.calculateHash(), _to, _inTunnel, tagsToSend, tagsRequired, sessKey, tags, wantACK, replyLeaseSet);
    if (msg == null) {
        // we dont receive the reply? hmm...)
        if (_log.shouldLog(Log.WARN))
            _log.warn(getJobId() + ": Unable to create the garlic message (no tunnels left or too lagged) to " + _toString);
        getContext().statManager().addRateData("client.dispatchNoTunnels", now - _start);
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_TUNNELS);
        return;
    }
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug(getJobId() + ": send() - token expected " + token + " to " + _toString);
    SendSuccessJob onReply = null;
    SendTimeoutJob onFail = null;
    ReplySelector selector = null;
    if (wantACK) {
        TagSetHandle tsh = null;
        if (!tags.isEmpty()) {
            SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_from.calculateHash());
            if (skm != null)
                tsh = skm.tagsDelivered(_leaseSet.getEncryptionKey(), sessKey, tags);
        }
        onReply = new SendSuccessJob(getContext(), sessKey, tsh);
        onFail = new SendTimeoutJob(getContext(), sessKey, tsh);
        long expiration = Math.max(_overallExpiration, _start + REPLY_TIMEOUT_MS_MIN);
        selector = new ReplySelector(token, expiration);
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(getJobId() + ": Sending msg out " + _outTunnel.getSendTunnelId(0) + " to " + _toString + " at " + _lease.getTunnelId() + " on " + _lease.getGateway());
    DispatchJob dispatchJob = new DispatchJob(getContext(), msg, selector, onReply, onFail);
    // if (false) // dispatch may take 100+ms, so toss it in its own job
    // getContext().jobQueue().addJob(dispatchJob);
    // else
    dispatchJob.runJob();
    getContext().statManager().addRateData("client.dispatchPrepareTime", now - _start);
    if (!wantACK)
        getContext().statManager().addRateData("client.dispatchNoACK", 1);
}
Also used : PublicKey(net.i2p.data.PublicKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) TagSetHandle(net.i2p.crypto.TagSetHandle) LeaseSet(net.i2p.data.LeaseSet) SessionKey(net.i2p.data.SessionKey) GarlicMessage(net.i2p.data.i2np.GarlicMessage) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet)

Example 9 with GarlicMessage

use of net.i2p.data.i2np.GarlicMessage in project i2p.i2p by i2p.

the class MessageWrapper method wrap.

/**
 *  Garlic wrap a message from a client or this router, destined for a router,
 *  to hide the contents from the OBEP.
 *  Caller must call acked() or fail() on the returned object.
 *
 *  @param from must be a local client with a session key manager,
 *              or null to use the router's session key manager
 *  @return null on encrypt failure
 */
static WrappedMessage wrap(RouterContext ctx, I2NPMessage m, Hash from, RouterInfo to) {
    PayloadGarlicConfig payload = new PayloadGarlicConfig();
    payload.setCertificate(Certificate.NULL_CERT);
    payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    payload.setPayload(m);
    payload.setRecipient(to);
    payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
    payload.setExpiration(m.getMessageExpiration());
    SessionKeyManager skm;
    if (from != null)
        skm = ctx.clientManager().getClientSessionKeyManager(from);
    else
        skm = ctx.sessionKeyManager();
    if (skm == null)
        return null;
    SessionKey sentKey = new SessionKey();
    Set<SessionTag> sentTags = new HashSet<SessionTag>();
    GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, sentKey, sentTags, NETDB_TAGS_TO_DELIVER, NETDB_LOW_THRESHOLD, skm);
    if (msg == null)
        return null;
    TagSetHandle tsh = null;
    PublicKey sentTo = to.getIdentity().getPublicKey();
    if (!sentTags.isEmpty())
        tsh = skm.tagsDelivered(sentTo, sentKey, sentTags);
    // _log.debug("Sent to: " + to.getIdentity().getHash() + " with key: " + sentKey + " and tags: " + sentTags.size());
    return new WrappedMessage(msg, skm, sentTo, sentKey, tsh);
}
Also used : PayloadGarlicConfig(net.i2p.router.message.PayloadGarlicConfig) SessionKey(net.i2p.data.SessionKey) PublicKey(net.i2p.data.PublicKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) GarlicMessage(net.i2p.data.i2np.GarlicMessage) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet) TagSetHandle(net.i2p.crypto.TagSetHandle)

Example 10 with GarlicMessage

use of net.i2p.data.i2np.GarlicMessage in project i2p.i2p by i2p.

the class OutboundClientMessageJobHelper method wrapDSM.

/**
 *  As of 0.9.12, encrypt to hide it from the target and the return path OBEP and IBGW.
 *  Wrap a DSM in a GarlicMessage, add the fake session to the SKM.
 *
 *  @param skm encrypt dsm with this skm non-null
 *  @return null on error
 *  @since 0.9.12
 */
private static GarlicMessage wrapDSM(RouterContext ctx, SessionKeyManager skm, DeliveryStatusMessage dsm) {
    // garlic route that DeliveryStatusMessage to ourselves so the endpoints and gateways
    // can't tell its a test.  to simplify this, we encrypt it with a random key and tag,
    // remembering that key+tag so that we can decrypt it later.  this means we can do the
    // garlic encryption without any ElGamal (yay)
    MessageWrapper.OneTimeSession sess = MessageWrapper.generateSession(ctx, skm);
    GarlicMessage msg = MessageWrapper.wrap(ctx, dsm, sess);
    return msg;
}
Also used : MessageWrapper(net.i2p.router.networkdb.kademlia.MessageWrapper) GarlicMessage(net.i2p.data.i2np.GarlicMessage)

Aggregations

GarlicMessage (net.i2p.data.i2np.GarlicMessage)10 SessionKeyManager (net.i2p.crypto.SessionKeyManager)4 SessionKey (net.i2p.data.SessionKey)4 PayloadGarlicConfig (net.i2p.router.message.PayloadGarlicConfig)4 PublicKey (net.i2p.data.PublicKey)3 SessionTag (net.i2p.data.SessionTag)3 HashSet (java.util.HashSet)2 TagSetHandle (net.i2p.crypto.TagSetHandle)2 DataFormatException (net.i2p.data.DataFormatException)2 Log (net.i2p.util.Log)2 IOException (java.io.IOException)1 Hash (net.i2p.data.Hash)1 LeaseSet (net.i2p.data.LeaseSet)1 TunnelId (net.i2p.data.TunnelId)1 DeliveryInstructions (net.i2p.data.i2np.DeliveryInstructions)1 DeliveryStatusMessage (net.i2p.data.i2np.DeliveryStatusMessage)1 GarlicClove (net.i2p.data.i2np.GarlicClove)1 MessageWrapper (net.i2p.router.networkdb.kademlia.MessageWrapper)1 RemovableSingletonSet (net.i2p.router.util.RemovableSingletonSet)1