I2CP: Set client SKM based on configured encryption

This commit is contained in:
zzz
2019-10-25 11:36:46 +00:00
parent f021abcae0
commit 43c93bceed

View File

@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import net.i2p.client.I2PClient; import net.i2p.client.I2PClient;
import net.i2p.crypto.SessionKeyManager; import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DatabaseEntry; import net.i2p.data.DatabaseEntry;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination; import net.i2p.data.Destination;
import net.i2p.data.EncryptedLeaseSet; import net.i2p.data.EncryptedLeaseSet;
import net.i2p.data.Hash; import net.i2p.data.Hash;
@ -47,6 +48,8 @@ import net.i2p.router.Job;
import net.i2p.router.JobImpl; import net.i2p.router.JobImpl;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.crypto.TransientSessionKeyManager; import net.i2p.router.crypto.TransientSessionKeyManager;
import net.i2p.router.crypto.ratchet.RatchetSKM;
import net.i2p.router.crypto.ratchet.MuxedSKM;
import net.i2p.util.ConcurrentHashSet; import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.I2PThread; import net.i2p.util.I2PThread;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -287,7 +290,10 @@ class ClientConnectionRunner {
return _clientVersion; return _clientVersion;
} }
/** current client's sessionkeymanager */ /**
* The current client's SessionKeyManager.
* As of 0.9.44, returned implementation varies based on supported encryption types.
*/
public SessionKeyManager getSessionKeyManager() { return _sessionKeyManager; } public SessionKeyManager getSessionKeyManager() { return _sessionKeyManager; }
/** /**
@ -544,10 +550,12 @@ class ClientConnectionRunner {
if (!isPrimary) { if (!isPrimary) {
// all encryption keys must be the same // all encryption keys must be the same
for (SessionParams sp : _sessions.values()) { for (SessionParams sp : _sessions.values()) {
if (!dest.getPublicKey().equals(sp.dest.getPublicKey())) if (!dest.getPublicKey().equals(sp.dest.getPublicKey())) {
_log.error("LS pubkey mismatch");
return SessionStatusMessage.STATUS_INVALID; return SessionStatusMessage.STATUS_INVALID;
} }
} }
}
SessionParams sp = new SessionParams(dest, isPrimary); SessionParams sp = new SessionParams(dest, isPrimary);
sp.config = config; sp.config = config;
SessionParams old = _sessions.putIfAbsent(destHash, sp); SessionParams old = _sessions.putIfAbsent(destHash, sp);
@ -560,10 +568,15 @@ class ClientConnectionRunner {
_dontSendMSM = "none".equals(opts.getProperty(I2PClient.PROP_RELIABILITY, "").toLowerCase(Locale.US)); _dontSendMSM = "none".equals(opts.getProperty(I2PClient.PROP_RELIABILITY, "").toLowerCase(Locale.US));
_dontSendMSMOnReceive = Boolean.parseBoolean(opts.getProperty(I2PClient.PROP_FAST_RECEIVE)); _dontSendMSMOnReceive = Boolean.parseBoolean(opts.getProperty(I2PClient.PROP_FAST_RECEIVE));
} }
// Set up the
// per-destination session key manager to prevent rather easy correlation // per-destination session key manager to prevent rather easy correlation
// based on the specified encryption types in the config
if (isPrimary && _sessionKeyManager == null) { if (isPrimary && _sessionKeyManager == null) {
int tags = TransientSessionKeyManager.DEFAULT_TAGS; int tags = TransientSessionKeyManager.DEFAULT_TAGS;
int thresh = TransientSessionKeyManager.LOW_THRESHOLD; int thresh = TransientSessionKeyManager.LOW_THRESHOLD;
boolean hasElg = false;
boolean hasEC = false;
if (opts != null) { if (opts != null) {
String ptags = opts.getProperty(PROP_TAGS); String ptags = opts.getProperty(PROP_TAGS);
if (ptags != null) { if (ptags != null) {
@ -573,9 +586,38 @@ class ClientConnectionRunner {
if (pthresh != null) { if (pthresh != null) {
try { thresh = Integer.parseInt(pthresh); } catch (NumberFormatException nfe) {} try { thresh = Integer.parseInt(pthresh); } catch (NumberFormatException nfe) {}
} }
String senc = opts.getProperty("i2cp.leaseSetEncType");
if (senc != null) {
String[] senca = DataHelper.split(senc, ",");
for (String sencaa : senca) {
if (sencaa.equals("0"))
hasElg = true;
else if (sencaa.equals("4"))
hasEC = true;
} }
} else {
hasElg = true;
}
} else {
hasElg = true;
}
if (hasElg) {
if (hasEC) {
TransientSessionKeyManager tskm = new TransientSessionKeyManager(_context, tags, thresh);
RatchetSKM rskm = new RatchetSKM(_context);
_sessionKeyManager = new MuxedSKM(tskm, rskm);
} else {
_sessionKeyManager = new TransientSessionKeyManager(_context, tags, thresh); _sessionKeyManager = new TransientSessionKeyManager(_context, tags, thresh);
} }
} else {
if (hasEC) {
_sessionKeyManager = new RatchetSKM(_context);
} else {
_log.error("No supported encryption types in i2cp.leaseSetEncType for " + dest.toBase32());
return SessionStatusMessage.STATUS_INVALID;
}
}
}
return _manager.destinationEstablished(this, dest); return _manager.destinationEstablished(this, dest);
} }
@ -877,8 +919,8 @@ class ClientConnectionRunner {
if (! current.getLease(i).getGateway().equals(set.getLease(i).getGateway())) if (! current.getLease(i).getGateway().equals(set.getLease(i).getGateway()))
break; break;
if (i == leases - 1) { if (i == leases - 1) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldDebug())
_log.info("Requested leaseSet hasn't changed"); _log.debug("Requested leaseSet hasn't changed");
if (onCreateJob != null) if (onCreateJob != null)
_context.jobQueue().addJob(onCreateJob); _context.jobQueue().addJob(onCreateJob);
return; // no change return; // no change