Search in sources :

Example 1 with GarlicMessage

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

the class TestJob method sendTest.

private void sendTest(I2NPMessage m) {
    // 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)
    PayloadGarlicConfig payload = new PayloadGarlicConfig();
    payload.setCertificate(Certificate.NULL_CERT);
    payload.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
    payload.setPayload(m);
    payload.setRecipient(getContext().router().getRouterInfo());
    payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
    payload.setExpiration(m.getMessageExpiration());
    SessionKey encryptKey = getContext().keyGenerator().generateSessionKey();
    SessionTag encryptTag = new SessionTag(true);
    _encryptTag = encryptTag;
    SessionKey sentKey = new SessionKey();
    Set<SessionTag> sentTags = null;
    GarlicMessage msg = GarlicMessageBuilder.buildMessage(getContext(), payload, sentKey, sentTags, getContext().keyManager().getPublicKey(), encryptKey, encryptTag);
    if (msg == null) {
        // overloaded / unknown peers / etc
        scheduleRetest();
        return;
    }
    Set<SessionTag> encryptTags = new RemovableSingletonSet<SessionTag>(encryptTag);
    // Register the single tag with the appropriate SKM
    if (_cfg.isInbound() && !_pool.getSettings().isExploratory()) {
        SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_pool.getSettings().getDestination());
        if (skm != null)
            skm.tagsReceived(encryptKey, encryptTags);
    } else {
        getContext().sessionKeyManager().tagsReceived(encryptKey, encryptTags);
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Sending garlic test of " + _outTunnel + " / " + _replyTunnel);
    getContext().tunnelDispatcher().dispatchOutbound(msg, _outTunnel.getSendTunnelId(0), _replyTunnel.getReceiveTunnelId(0), _replyTunnel.getPeer(0));
}
Also used : PayloadGarlicConfig(net.i2p.router.message.PayloadGarlicConfig) SessionKey(net.i2p.data.SessionKey) RemovableSingletonSet(net.i2p.router.util.RemovableSingletonSet) GarlicMessage(net.i2p.data.i2np.GarlicMessage) SessionKeyManager(net.i2p.crypto.SessionKeyManager) SessionTag(net.i2p.data.SessionTag)

Example 2 with GarlicMessage

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

the class GarlicMessageBuilder method buildClove.

/**
 *  UNUSED
 *
 *  The Garlic Message we are building contains another garlic message,
 *  as specified by a GarlicConfig (NOT a PayloadGarlicConfig).
 *
 *  So this calls back to the top, to buildMessage(ctx, config),
 *  which uses the router's SKM, i.e. the wrong one.
 *  Unfortunately we've lost the reference to the SessionKeyManager way down here,
 *  so we can't call buildMessage(ctx, config, key, tags, skm).
 *
 *  If we do ever end up constructing a garlic message that contains a garlic message,
 *  we'll have to fix this by passing the skm through the last buildMessage,
 *  through buildCloveSet, to here.
 */
private static byte[] buildClove(RouterContext ctx, GarlicConfig config) throws DataFormatException, IOException {
    GarlicClove clove = new GarlicClove(ctx);
    GarlicMessage msg = buildMessage(ctx, config);
    if (msg == null)
        throw new DataFormatException("Unable to build message from clove config");
    clove.setData(msg);
    return buildCommonClove(clove, config);
}
Also used : DataFormatException(net.i2p.data.DataFormatException) GarlicMessage(net.i2p.data.i2np.GarlicMessage) GarlicClove(net.i2p.data.i2np.GarlicClove)

Example 3 with GarlicMessage

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

the class GarlicMessageBuilder method buildMessage.

/**
 *  used by TestJob and directly above
 *  and for encrypting DatabaseLookupMessages
 *
 * @param ctx scope
 * @param config how/what to wrap
 * @param wrappedKey unused - why??
 * @param wrappedTags New tags to be sent along with the message.
 *                    200 max enforced at receiver; null OK
 * @param target public key of the location being garlic routed to (may be null if we
 *               know the encryptKey and encryptTag)
 * @param encryptKey sessionKey used to encrypt the current message, non-null
 * @param encryptTag sessionTag used to encrypt the current message, null to force ElG
 * @throws IllegalArgumentException on error
 */
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, PublicKey target, SessionKey encryptKey, SessionTag encryptTag) {
    Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
    if (config == null)
        throw new IllegalArgumentException("Null config specified");
    GarlicMessage msg = new GarlicMessage(ctx);
    // noteWrap(ctx, msg, config);
    byte[] cloveSet = buildCloveSet(ctx, config);
    // TODO - 128 is the minimum padded size - should it be more? less? random?
    byte[] encData = ctx.elGamalAESEngine().encrypt(cloveSet, target, encryptKey, wrappedTags, encryptTag, 128);
    msg.setData(encData);
    msg.setMessageExpiration(config.getExpiration());
    long timeFromNow = config.getExpiration() - ctx.clock().now();
    if (timeFromNow < 1 * 1000) {
        if (log.shouldLog(Log.DEBUG))
            log.debug("Building a message expiring in " + timeFromNow + "ms: " + config, new Exception("created by"));
        return null;
    }
    if (log.shouldLog(Log.DEBUG))
        log.debug("CloveSet (" + config.getCloveCount() + " cloves) for message " + msg.getUniqueId() + " is " + cloveSet.length + " bytes and encrypted message data is " + encData.length + " bytes");
    return msg;
}
Also used : Log(net.i2p.util.Log) GarlicMessage(net.i2p.data.i2np.GarlicMessage) DataFormatException(net.i2p.data.DataFormatException) IOException(java.io.IOException)

Example 4 with GarlicMessage

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

the class OutboundClientMessageJobHelper method buildAckClove.

/**
 *  Build a clove that sends a DeliveryStatusMessage to us.
 *  As of 0.9.12, the DSM is wrapped in a GarlicMessage.
 *  @param skm encrypt dsm with this skm non-null
 *  @return null on error
 */
private static PayloadGarlicConfig buildAckClove(RouterContext ctx, Hash from, TunnelInfo replyToTunnel, long replyToken, long expiration, SessionKeyManager skm) {
    Log log = ctx.logManager().getLog(OutboundClientMessageJobHelper.class);
    if (replyToTunnel == null) {
        if (log.shouldLog(Log.WARN))
            log.warn("Unable to send client message from " + from.toBase64() + ", as there are no inbound tunnels available");
        return null;
    }
    // tunnel id on that gateway
    TunnelId replyToTunnelId = replyToTunnel.getReceiveTunnelId(0);
    // inbound tunnel gateway
    Hash replyToTunnelRouter = replyToTunnel.getPeer(0);
    if (log.shouldLog(Log.DEBUG))
        log.debug("Ack for the data message will come back along tunnel " + replyToTunnelId + ": " + replyToTunnel);
    DeliveryInstructions ackInstructions = new DeliveryInstructions();
    ackInstructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_TUNNEL);
    ackInstructions.setRouter(replyToTunnelRouter);
    ackInstructions.setTunnelId(replyToTunnelId);
    // defaults
    // ackInstructions.setDelayRequested(false);
    // ackInstructions.setDelaySeconds(0);
    // ackInstructions.setEncrypted(false);
    PayloadGarlicConfig ackClove = new PayloadGarlicConfig();
    ackClove.setCertificate(Certificate.NULL_CERT);
    ackClove.setDeliveryInstructions(ackInstructions);
    ackClove.setExpiration(expiration);
    ackClove.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    DeliveryStatusMessage dsm = buildDSM(ctx, replyToken);
    GarlicMessage msg = wrapDSM(ctx, skm, dsm);
    if (msg == null) {
        if (log.shouldLog(Log.WARN))
            log.warn("Failed to wrap ack clove");
        return null;
    }
    ackClove.setPayload(msg);
    return ackClove;
}
Also used : DeliveryInstructions(net.i2p.data.i2np.DeliveryInstructions) Log(net.i2p.util.Log) GarlicMessage(net.i2p.data.i2np.GarlicMessage) Hash(net.i2p.data.Hash) TunnelId(net.i2p.data.TunnelId) DeliveryStatusMessage(net.i2p.data.i2np.DeliveryStatusMessage)

Example 5 with GarlicMessage

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

the class OutboundClientMessageJobHelper method createGarlicMessage.

/**
 * Build a garlic message that will be delivered to the router on which the target is located.
 * Inside the message are two cloves: one containing the payload with instructions for
 * delivery to the (now local) destination, and the other containing a DeliveryStatusMessage with
 * instructions for delivery to an inbound tunnel of this router.
 *
 * How the DeliveryStatusMessage is wrapped can vary - it can be simply sent to a tunnel (as above),
 * wrapped in a GarlicMessage and source routed a few hops before being tunneled, source routed the
 * entire way back, or not wrapped at all - in which case the payload clove contains a SourceRouteBlock
 * and a request for a reply.
 *
 * For now, its just a tunneled DeliveryStatusMessage
 *
 * Unused?
 *
 * @param wrappedKey output parameter that will be filled with the sessionKey used
 * @param wrappedTags output parameter that will be filled with the sessionTags used
 * @param bundledReplyLeaseSet if specified, the given LeaseSet will be packaged with the message (allowing
 *                             much faster replies, since their netDb search will return almost instantly)
 * @param replyTunnel non-null if requireAck is true or bundledReplyLeaseSet is non-null
 * @param requireAck if true, bundle replyToken in an ack clove
 * @return garlic, or null if no tunnels were found (or other errors)
 */
/**
 **
 *    static GarlicMessage createGarlicMessage(RouterContext ctx, long replyToken, long expiration, PublicKey recipientPK,
 *                                             Payload data, Hash from, Destination dest, TunnelInfo replyTunnel,
 *                                             SessionKey wrappedKey, Set<SessionTag> wrappedTags,
 *                                             boolean requireAck, LeaseSet bundledReplyLeaseSet) {
 *        PayloadGarlicConfig dataClove = buildDataClove(ctx, data, dest, expiration);
 *        return createGarlicMessage(ctx, replyToken, expiration, recipientPK, dataClove, from, dest, replyTunnel,
 *                                   0, 0, wrappedKey, wrappedTags, requireAck, bundledReplyLeaseSet);
 *    }
 ***
 */
/**
 * Allow the app to specify the data clove directly, which enables OutboundClientMessage to resend the
 * same payload (including expiration and unique id) in different garlics (down different tunnels)
 *
 * This is called from OCMOSJ
 *
 * @param tagsToSendOverride if &gt; 0, use this instead of skm's default
 * @param lowTagsOverride if &gt; 0, use this instead of skm's default
 * @param wrappedKey output parameter that will be filled with the sessionKey used
 * @param wrappedTags output parameter that will be filled with the sessionTags used
 * @param replyTunnel non-null if requireAck is true or bundledReplyLeaseSet is non-null
 * @param requireAck if true, bundle replyToken in an ack clove
 * @param bundledReplyLeaseSet may be null; if non-null, put it in a clove
 * @return garlic, or null if no tunnels were found (or other errors)
 */
static GarlicMessage createGarlicMessage(RouterContext ctx, long replyToken, long expiration, PublicKey recipientPK, PayloadGarlicConfig dataClove, Hash from, Destination dest, TunnelInfo replyTunnel, int tagsToSendOverride, int lowTagsOverride, SessionKey wrappedKey, Set<SessionTag> wrappedTags, boolean requireAck, LeaseSet bundledReplyLeaseSet) {
    SessionKeyManager skm = ctx.clientManager().getClientSessionKeyManager(from);
    if (skm == null)
        return null;
    GarlicConfig config = createGarlicConfig(ctx, replyToken, expiration, recipientPK, dataClove, from, dest, replyTunnel, requireAck, bundledReplyLeaseSet, skm);
    if (config == null)
        return null;
    // no use sending tags unless we have a reply token set up already
    int tagsToSend = replyToken >= 0 ? (tagsToSendOverride > 0 ? tagsToSendOverride : skm.getTagsToSend()) : 0;
    int lowThreshold = lowTagsOverride > 0 ? lowTagsOverride : skm.getLowThreshold();
    GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, config, wrappedKey, wrappedTags, tagsToSend, lowThreshold, skm);
    return msg;
}
Also used : SessionKeyManager(net.i2p.crypto.SessionKeyManager) 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