OCMOSJ: Select target key in LS based on local client's support

Hook new SKMs and ending into Garlic Message encryption/decryption
Remove unused wrappedKey param from buildMessage()
Log tweaks and javadoc fixes
WIP
This commit is contained in:
zzz
2019-10-25 12:21:33 +00:00
parent 43c93bceed
commit 0c256d30c7
6 changed files with 218 additions and 59 deletions

View File

@ -14,17 +14,22 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.data.i2np.GarlicClove;
import net.i2p.data.i2np.GarlicMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.router.LeaseSetKeys;
import net.i2p.router.RouterContext;
import net.i2p.router.crypto.ratchet.MuxedSKM;
import net.i2p.router.crypto.ratchet.RatchetSKM;
import net.i2p.util.Log;
/**
@ -34,10 +39,14 @@ import net.i2p.util.Log;
public class GarlicMessageBuilder {
/**
* ELGAMAL_2048 only.
*
* @param local non-null; do not use this method for the router's SessionKeyManager
* @param minTagOverride 0 for no override, > 0 to override SKM's settings
*/
static boolean needsTags(RouterContext ctx, PublicKey key, Hash local, int minTagOverride) {
if (key.getType() == EncType.ECIES_X25519)
return false;
SessionKeyManager skm = ctx.clientManager().getClientSessionKeyManager(local);
if (skm == null)
return true;
@ -51,6 +60,7 @@ public class GarlicMessageBuilder {
/**
* Unused and probably a bad idea.
* ELGAMAL_2048 only.
*
* Used below only on a recursive call if the garlic message contains a garlic message.
* We don't need the SessionKey or SesssionTags returned
@ -60,6 +70,7 @@ public class GarlicMessageBuilder {
*
* @param ctx scope
* @param config how/what to wrap
* @return null if expired
* @throws IllegalArgumentException on error
*/
private static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config) {
@ -70,14 +81,17 @@ public class GarlicMessageBuilder {
/**
* Now unused, since we have to generate a reply token first in OCMOSJ but we don't know if tags are required yet.
* ELGAMAL_2048 only.
*
* @param ctx scope
* @param config how/what to wrap
* @param wrappedKey output parameter that will be filled with the sessionKey used
* @param wrappedKey non-null with null data,
* output parameter that will be filled with the SessionKey used
* @param wrappedTags Output parameter that will be filled with the sessionTags used.
If non-empty on return you must call skm.tagsDelivered() when sent
and then call skm.tagsAcked() or skm.failTags() later.
* @param skm non-null
* @return null if expired
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
@ -94,11 +108,13 @@ public class GarlicMessageBuilder {
***/
/**
* called by OCMJH
* ELGAMAL_2048 only.
* Called by OCMJH.
*
* @param ctx scope
* @param config how/what to wrap
* @param wrappedKey output parameter that will be filled with the sessionKey used
* @param wrappedKey non-null with null data,
* output parameter that will be filled with the SessionKey used
* @param wrappedTags Output parameter that will be filled with the sessionTags used.
If non-empty on return you must call skm.tagsDelivered() when sent
and then call skm.tagsAcked() or skm.failTags() later.
@ -106,6 +122,7 @@ public class GarlicMessageBuilder {
Set to zero to disable tag delivery. You must set to zero if you are not
equipped to confirm delivery and call skm.tagsAcked() or skm.failTags() later.
* @param skm non-null
* @return null if expired
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
@ -114,11 +131,13 @@ public class GarlicMessageBuilder {
}
/**
* called by netdb and above
* ELGAMAL_2048 only.
* Called by netdb and above.
*
* @param ctx scope
* @param config how/what to wrap
* @param wrappedKey output parameter that will be filled with the sessionKey used
* @param wrappedKey non-null with null data,
* output parameter that will be filled with the SessionKey used
* @param wrappedTags Output parameter that will be filled with the sessionTags used.
If non-empty on return you must call skm.tagsDelivered() when sent
and then call skm.tagsAcked() or skm.failTags() later.
@ -128,6 +147,7 @@ public class GarlicMessageBuilder {
If this is always 0, it forces ElGamal every time.
* @param lowTagsThreshold the threshold
* @param skm non-null
* @return null if expired
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
@ -144,14 +164,14 @@ public class GarlicMessageBuilder {
} else
key = config.getRecipient().getIdentity().getPublicKey();
}
if (key.getType() != EncType.ELGAMAL_2048)
throw new IllegalArgumentException();
if (log.shouldLog(Log.INFO))
log.info("Encrypted with public key to expire on " + new Date(config.getExpiration()));
SessionKey curKey = skm.getCurrentOrNewKey(key);
SessionTag curTag = null;
curTag = skm.consumeNextAvailableTag(key, curKey);
SessionTag curTag = skm.consumeNextAvailableTag(key, curKey);
if (log.shouldLog(Log.DEBUG)) {
int availTags = skm.getAvailableTags(key, curKey);
@ -167,25 +187,26 @@ public class GarlicMessageBuilder {
wrappedKey.setData(curKey.getData());
return buildMessage(ctx, config, wrappedKey, wrappedTags, key, curKey, curTag);
return buildMessage(ctx, config, wrappedTags, key, curKey, curTag);
}
/**
* used by TestJob and directly above
* and for encrypting DatabaseLookupMessages
* ELGAMAL_2048 only.
* Used by TestJob, and directly above,
* and by MessageWrapper 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
* @return null if expired
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, Set<SessionTag> wrappedTags,
PublicKey target, SessionKey encryptKey, SessionTag encryptTag) {
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
if (config == null)
@ -199,6 +220,11 @@ public class GarlicMessageBuilder {
// TODO - 128 is the minimum padded size - should it be more? less? random?
byte encData[] = ctx.elGamalAESEngine().encrypt(cloveSet, target, encryptKey, wrappedTags, encryptTag, 128);
if (encData == null) {
if (log.shouldWarn())
log.warn("ElG encrypt fail");
return null;
}
msg.setData(encData);
msg.setMessageExpiration(config.getExpiration());
@ -216,6 +242,69 @@ public class GarlicMessageBuilder {
return msg;
}
/**
* ECIES_X25519 only.
* Called by GarlicMessageBuilder only.
*
* @param ctx scope
* @param config how/what to wrap
* @param target public key of the location being garlic routed to (may be null if we
* know the encryptKey and encryptTag)
* @return null if expired or on other errors
* @throws IllegalArgumentException on error
* @since 0.9.44
*/
static GarlicMessage buildECIESMessage(RouterContext ctx, GarlicConfig config,
PublicKey target, Hash from, SessionKeyManager skm) {
PublicKey key = config.getRecipientPublicKey();
if (key.getType() != EncType.ECIES_X25519)
throw new IllegalArgumentException();
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
GarlicMessage msg = new GarlicMessage(ctx);
byte cloveSet[] = buildCloveSet(ctx, config);
LeaseSetKeys lsk = ctx.keyManager().getKeys(from);
if (lsk == null) {
if (log.shouldWarn())
log.warn("No LSK for " + from.toBase32());
return null;
}
PrivateKey priv = lsk.getDecryptionKey(EncType.ECIES_X25519);
if (priv == null) {
if (log.shouldWarn())
log.warn("No key for " + from.toBase32());
return null;
}
RatchetSKM rskm;
if (skm instanceof RatchetSKM) {
rskm = (RatchetSKM) skm;
} else if (skm instanceof MuxedSKM) {
rskm = ((MuxedSKM) skm).getECSKM();
} else {
if (log.shouldWarn())
log.warn("No SKM for " + from.toBase32());
return null;
}
byte encData[] = ctx.eciesEngine().encrypt(cloveSet, target, priv, rskm, config.getExpiration());
if (encData == null) {
if (log.shouldWarn())
log.warn("Encrypt fail for " + from.toBase32());
return null;
}
msg.setData(encData);
msg.setMessageExpiration(config.getExpiration());
long timeFromNow = config.getExpiration() - ctx.clock().now();
if (timeFromNow < 1*1000) {
if (log.shouldDebug())
log.debug("Building a message expiring in " + timeFromNow + "ms: " + config, new Exception("created by"));
return null;
}
if (log.shouldDebug())
log.debug("CloveSet (" + config.getCloveCount() + " cloves) for message " + msg.getUniqueId() + " is " + cloveSet.length
+ " bytes and encrypted message data is " + encData.length + " bytes");
return msg;
}
/****
private static void noteWrap(RouterContext ctx, GarlicMessage wrapper, GarlicConfig contained) {
for (int i = 0; i < contained.getCloveCount(); i++) {
@ -237,8 +326,7 @@ public class GarlicMessageBuilder {
* @throws IllegalArgumentException on error
*/
private static byte[] buildCloveSet(RouterContext ctx, GarlicConfig config) {
ByteArrayOutputStream baos = null;
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
ByteArrayOutputStream baos;
try {
if (config instanceof PayloadGarlicConfig) {
byte clove[] = buildClove(ctx, (PayloadGarlicConfig)config);
@ -253,7 +341,7 @@ public class GarlicMessageBuilder {
//log.debug("Subclove IS a payload garlic clove");
cloves[i] = buildClove(ctx, (PayloadGarlicConfig)c);
} else {
log.debug("Subclove IS NOT a payload garlic clove");
//log.debug("Subclove IS NOT a payload garlic clove");
// See notes below
cloves[i] = buildClove(ctx, c);
}
@ -271,10 +359,8 @@ public class GarlicMessageBuilder {
DataHelper.writeLong(baos, 4, config.getId());
DataHelper.writeLong(baos, DataHelper.DATE_LENGTH, config.getExpiration());
} catch (IOException ioe) {
log.error("Error building the clove set", ioe);
throw new IllegalArgumentException("Error building the clove set", ioe);
} catch (DataFormatException dfe) {
log.error("Error building the clove set", dfe);
throw new IllegalArgumentException("Error building the clove set", dfe);
}
return baos.toByteArray();

View File

@ -10,6 +10,7 @@ package net.i2p.router.message;
import java.util.Date;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Certificate;
import net.i2p.data.DataFormatException;
@ -18,6 +19,8 @@ import net.i2p.data.PrivateKey;
import net.i2p.data.i2np.GarlicClove;
import net.i2p.data.i2np.GarlicMessage;
import net.i2p.router.RouterContext;
import net.i2p.router.crypto.ratchet.MuxedSKM;
import net.i2p.router.crypto.ratchet.RatchetSKM;
import net.i2p.util.Log;
/**
@ -41,16 +44,45 @@ public class GarlicMessageParser {
}
/**
* Supports both ELGAMAL_2048 and ECIES_X25519.
*
* @param encryptionKey either type TODO need both for muxed
* @param skm use tags from this session key manager
* @return null on error
*/
public CloveSet getGarlicCloves(GarlicMessage message, PrivateKey encryptionKey, SessionKeyManager skm) {
CloveSet getGarlicCloves(GarlicMessage message, PrivateKey encryptionKey, SessionKeyManager skm) {
byte encData[] = message.getData();
byte decrData[];
try {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Decrypting with private key " + encryptionKey);
decrData = _context.elGamalAESEngine().decrypt(encData, encryptionKey, skm);
EncType type = encryptionKey.getType();
if (type == EncType.ELGAMAL_2048) {
decrData = _context.elGamalAESEngine().decrypt(encData, encryptionKey, skm);
} else if (type == EncType.ECIES_X25519) {
RatchetSKM rskm;
if (skm instanceof RatchetSKM) {
rskm = (RatchetSKM) skm;
} else if (skm instanceof MuxedSKM) {
rskm = ((MuxedSKM) skm).getECSKM();
} else {
if (_log.shouldWarn())
_log.warn("No SKM to decrypt ECIES");
return null;
}
decrData = _context.eciesEngine().decrypt(encData, encryptionKey, rskm);
if (decrData != null) {
if (_log.shouldWarn())
_log.warn("ECIES decrypt success, length: " + decrData.length);
} else {
if (_log.shouldWarn())
_log.warn("ECIES decrypt fail");
}
} else {
if (_log.shouldWarn())
_log.warn("Can't decrypt with key type " + type);
return null;
}
} catch (DataFormatException dfe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error decrypting", dfe);
@ -63,7 +95,10 @@ public class GarlicMessageParser {
return null;
} else {
try {
return readCloveSet(decrData);
CloveSet rv = readCloveSet(decrData, 0);
if (_log.shouldDebug())
_log.debug("Got cloves: " + rv.getCloveCount());
return rv;
} catch (DataFormatException dfe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to read cloveSet", dfe);
@ -72,13 +107,15 @@ public class GarlicMessageParser {
}
}
private CloveSet readCloveSet(byte data[]) throws DataFormatException {
int offset = 0;
/**
* @param offset where in data to start
* @return non-null, throws on all errors
*/
private CloveSet readCloveSet(byte data[], int offset) throws DataFormatException {
int numCloves = data[offset] & 0xff;
offset++;
if (_log.shouldLog(Log.DEBUG))
_log.debug("# cloves to read: " + numCloves);
//if (_log.shouldLog(Log.DEBUG))
// _log.debug("# cloves to read: " + numCloves);
if (numCloves <= 0 || numCloves > MAX_CLOVES)
throw new DataFormatException("bad clove count " + numCloves);
GarlicClove[] cloves = new GarlicClove[numCloves];

View File

@ -8,6 +8,7 @@ package net.i2p.router.message;
*
*/
import net.i2p.crypto.EncType;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
@ -21,7 +22,7 @@ import net.i2p.router.RouterContext;
import net.i2p.util.Log;
/**
* Unencrypt a garlic message and pass off any valid cloves to the configured
* Decrypt a garlic message and pass off any valid cloves to the configured
* receiver to dispatch as they choose.
*
*/
@ -61,7 +62,16 @@ public class GarlicMessageReceiver {
LeaseSetKeys keys = _context.keyManager().getKeys(_clientDestination);
skm = _context.clientManager().getClientSessionKeyManager(_clientDestination);
if (keys != null && skm != null) {
// TODO need to pass both keys if available for muxed decrypt
decryptionKey = keys.getDecryptionKey();
if (decryptionKey == null) {
decryptionKey = keys.getDecryptionKey(EncType.ECIES_X25519);
if (decryptionKey == null) {
if (_log.shouldWarn())
_log.warn("No key to decrypt for " + _clientDestination.toBase32());
return;
}
}
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Not trying to decrypt a garlic routed message to a disconnected client");
@ -72,6 +82,7 @@ public class GarlicMessageReceiver {
skm = _context.sessionKeyManager();
}
// TODO need to pass both keys if available for muxed decrypt
CloveSet set = _context.garlicMessageParser().getGarlicCloves(message, decryptionKey, skm);
if (set != null) {
for (int i = 0; i < set.getCloveCount(); i++) {
@ -79,9 +90,13 @@ public class GarlicMessageReceiver {
handleClove(clove);
}
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("CloveMessageParser failed to decrypt the message [" + message.getUniqueId()
+ "]", new Exception("Decrypt garlic failed"));
if (_log.shouldLog(Log.WARN)) {
String d = (_clientDestination != null) ? _clientDestination.toBase32() : "the router";
_log.warn("CloveMessageParser failed to decrypt the " + message.getData().length +
" byte message [" + message.getUniqueId()
+ "] for " + d + " with key " + decryptionKey.getType(),
new Exception("Decrypt garlic failed"));
}
_context.statManager().addRateData("crypto.garlic.decryptFail", 1);
_context.messageHistory().messageProcessingError(message.getUniqueId(),
message.getClass().getName(),
@ -110,10 +125,10 @@ public class GarlicMessageReceiver {
boolean rv = invalidReason == null;
if (!rv) {
String howLongAgo = DataHelper.formatDuration(_context.clock().now()-clove.getExpiration().getTime());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Clove is NOT valid: id=" + clove.getCloveId()
if (_log.shouldInfo())
_log.info("Clove is NOT valid: id=" + clove.getCloveId()
+ " expiration " + howLongAgo + " ago", new Exception("Invalid within..."));
else if (_log.shouldLog(Log.WARN))
else if (_log.shouldWarn())
_log.warn("Clove is NOT valid: id=" + clove.getCloveId()
+ " expiration " + howLongAgo + " ago: " + invalidReason + ": " + clove);
_context.messageHistory().messageProcessingError(clove.getCloveId(),

View File

@ -10,6 +10,7 @@ package net.i2p.router.message;
import java.util.Set;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Certificate;
import net.i2p.data.Destination;
@ -72,9 +73,8 @@ class OutboundClientMessageJobHelper {
*
* For now, its just a tunneled DeliveryStatusMessage
*
* Unused?
*
* @param wrappedKey output parameter that will be filled with the sessionKey used
* @param wrappedKey non-null with null data,
* 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)
@ -101,7 +101,8 @@ class OutboundClientMessageJobHelper {
*
* @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 wrappedKey non-null with null data,
* 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
@ -120,11 +121,16 @@ class OutboundClientMessageJobHelper {
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);
GarlicMessage msg;
if (recipientPK.getType() == EncType.ECIES_X25519) {
msg = GarlicMessageBuilder.buildECIESMessage(ctx, config, recipientPK, from, skm);
} else {
// 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();
msg = GarlicMessageBuilder.buildMessage(ctx, config, wrappedKey, wrappedTags,
tagsToSend, lowThreshold, skm);
}
return msg;
}
@ -150,7 +156,8 @@ class OutboundClientMessageJobHelper {
ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE),
expiration, DeliveryInstructions.LOCAL);
if (requireAck) {
// for now, skip this for ratchet
if (requireAck && recipientPK.getType() == EncType.ELGAMAL_2048) {
// extend the expiration of the return message
PayloadGarlicConfig ackClove = buildAckClove(ctx, from, replyTunnel, replyToken,
expiration + ACK_EXTRA_EXPIRATION, skm);

View File

@ -32,6 +32,7 @@ import net.i2p.data.i2np.GarlicMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.router.ClientMessage;
import net.i2p.router.JobImpl;
import net.i2p.router.LeaseSetKeys;
import net.i2p.router.MessageSelector;
import net.i2p.router.ReplyJob;
import net.i2p.router.Router;
@ -116,6 +117,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
private LeaseSet _leaseSet;
/** Actual lease the message is being routed through */
private Lease _lease;
/** Actual target encryption key from the LS being used */
private PublicKey _encryptionKey;
private final long _start;
/** note we can succeed after failure, but not vice versa */
private enum Result {NONE, FAIL, SUCCESS}
@ -373,8 +376,13 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
}
/**
* Choose a lease from his leaseset to send the message to. Sets _lease.
* Choose a lease from his leaseset to send the message to.
*
* Side effects:
* Sets _lease.
* Sets _wantACK if it's new or changed.
* Sets _encryptionKey.
*
* Does several checks to see if we can actually send to this leaseset,
* and returns nonzero failure code if unable to.
*
@ -399,12 +407,21 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
lsType != DatabaseEntry.KEY_TYPE_LS2) {
return MessageStatusMessage.STATUS_SEND_FAILURE_BAD_LEASESET;
}
PublicKey pk = _leaseSet.getEncryptionKey();
if (pk == null)
// select an encryption key from the leaseset
Set<EncType> supported;
LeaseSetKeys ourKeys = getContext().keyManager().getKeys(_from);
if (ourKeys != null)
supported = ourKeys.getSupportedEncryption();
else
supported = LeaseSetKeys.SET_ELG;
_encryptionKey = _leaseSet.getEncryptionKey(supported);
if (_encryptionKey == null) {
if (_leaseSet.getEncryptionKey() != null)
return MessageStatusMessage.STATUS_SEND_FAILURE_UNSUPPORTED_ENCRYPTION;
// no keys at all?
return MessageStatusMessage.STATUS_SEND_FAILURE_BAD_LEASESET;
EncType encType = pk.getType();
if (encType == null || !encType.isAvailable())
return MessageStatusMessage.STATUS_SEND_FAILURE_UNSUPPORTED_ENCRYPTION;
}
// Use the same lease if it's still good
// Even if _leaseSet changed, _leaseSet.getEncryptionKey() didn't...
@ -590,7 +607,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
int tagsRequired = SendMessageOptions.getTagThreshold(sendFlags);
boolean wantACK = _wantACK ||
shouldRequestReply ||
GarlicMessageBuilder.needsTags(getContext(), _leaseSet.getEncryptionKey(),
GarlicMessageBuilder.needsTags(getContext(), _encryptionKey,
_from.calculateHash(), tagsRequired);
LeaseSet replyLeaseSet;
@ -627,17 +644,14 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
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,
_overallExpiration, _encryptionKey,
clove, _from.calculateHash(),
_to, _inTunnel, tagsToSend,
tagsRequired, sessKey, tags,
@ -664,7 +678,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
if (!tags.isEmpty()) {
SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_from.calculateHash());
if (skm != null)
tsh = skm.tagsDelivered(_leaseSet.getEncryptionKey(), sessKey, tags);
tsh = skm.tagsDelivered(_encryptionKey, sessKey, tags);
}
onReply = new SendSuccessJob(getContext(), sessKey, tsh);
onFail = new SendTimeoutJob(getContext(), sessKey, tsh);
@ -1019,7 +1033,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
if (_key != null && _tags != null && _leaseSet != null) {
SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_from.calculateHash());
if (skm != null)
skm.tagsAcked(_leaseSet.getEncryptionKey(), _key, _tags);
skm.tagsAcked(_encryptionKey, _key, _tags);
}
}
@ -1110,7 +1124,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
if (_key != null && _tags != null && _leaseSet != null) {
SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_from.calculateHash());
if (skm != null)
skm.failTags(_leaseSet.getEncryptionKey(), _key, _tags);
skm.failTags(_encryptionKey, _key, _tags);
}
}
if (old == Result.NONE)

View File

@ -139,7 +139,7 @@ public class MessageWrapper {
payload.setRecipient(to);
SessionKey sentKey = ctx.keyGenerator().generateSessionKey();
GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, null,
GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null,
key, sentKey, null);
return msg;
}
@ -234,7 +234,7 @@ public class MessageWrapper {
m.getMessageExpiration(),
DeliveryInstructions.LOCAL, m);
GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, null,
GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null,
null, encryptKey, encryptTag);
return msg;
}