forked from I2P_Developers/i2p.i2p
I2CP: Basic router-side handling of meta LS2
Improve error handling of LS2 params client-side Methods to remember blinded key in LS2
This commit is contained in:
@@ -103,6 +103,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
return true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
session.propogateError("Bad LS2 type", nfe);
|
||||
session.destroySession();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -124,6 +125,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
leaseSet = new MetaLeaseSet();
|
||||
} else {
|
||||
session.propogateError("Unsupported LS2 type", new Exception());
|
||||
session.destroySession();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -284,7 +286,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
session.getOfflineSignature());
|
||||
if (!ok) {
|
||||
session.propogateError("Bad offline signature", new Exception());
|
||||
// TODO just let the router handle it for now
|
||||
session.destroySession();
|
||||
}
|
||||
}
|
||||
try {
|
||||
@@ -306,6 +308,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
_log.debug("Created and signed LeaseSet: " + leaseSet);
|
||||
} catch (DataFormatException dfe) {
|
||||
session.propogateError("Error signing the leaseSet", dfe);
|
||||
session.destroySession();
|
||||
} catch (I2PSessionException ise) {
|
||||
if (session.isClosed()) {
|
||||
// race, closed while signing leaseset
|
||||
|
@@ -50,6 +50,7 @@ class RequestVariableLeaseSetMessageHandler extends RequestLeaseSetMessageHandle
|
||||
leaseSet = new MetaLeaseSet();
|
||||
} else {
|
||||
session.propogateError("Unsupported LS2 type", new Exception());
|
||||
session.destroySession();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@@ -39,6 +39,8 @@ public class LeaseSet2 extends LeaseSet {
|
||||
protected Properties _options;
|
||||
// only used if more than one key, otherwise null
|
||||
private List<PublicKey> _encryptionKeys;
|
||||
// If this leaseset was formerly blinded, the blinded hash, so we can find it again
|
||||
private Hash _blindedHash;
|
||||
|
||||
private static final int FLAG_OFFLINE_KEYS = 1;
|
||||
private static final int FLAG_UNPUBLISHED = 2;
|
||||
@@ -182,6 +184,21 @@ public class LeaseSet2 extends LeaseSet {
|
||||
return ctx.dsa().verifySignature(_offlineSignature, data, 0, data.length, getSigningPublicKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this on creation if known
|
||||
*/
|
||||
public void setBlindedHash(Hash bh) {
|
||||
_blindedHash = bh;
|
||||
}
|
||||
|
||||
/**
|
||||
* The orignal blinded hash, where this came from.
|
||||
* @return null if unknown or not previously blinded
|
||||
*/
|
||||
public Hash getBlindedHash() {
|
||||
return _blindedHash;
|
||||
}
|
||||
|
||||
|
||||
///// overrides below here
|
||||
|
||||
|
@@ -13,9 +13,11 @@ import java.util.Properties;
|
||||
|
||||
import net.i2p.CoreVersion;
|
||||
import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.DatabaseEntry;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.Payload;
|
||||
import net.i2p.data.PublicKey;
|
||||
import net.i2p.data.i2cp.BandwidthLimitsMessage;
|
||||
@@ -266,6 +268,14 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
||||
}
|
||||
}
|
||||
props.putAll(inProps);
|
||||
if ("7".equals(props.getProperty("i2cp.leaseSetType"))) {
|
||||
// Prevent tunnel builds for Meta LS
|
||||
// more TODO
|
||||
props.setProperty("inbound.length", "0");
|
||||
props.setProperty("outbound.length", "0");
|
||||
props.setProperty("inbound.lengthVariance", "0");
|
||||
props.setProperty("outbound.lengthVariance", "0");
|
||||
}
|
||||
cfg.setOptions(props);
|
||||
// this sets the session id
|
||||
int status = _runner.sessionEstablished(cfg);
|
||||
@@ -469,10 +479,19 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
||||
|
||||
/** override for testing */
|
||||
protected void handleCreateLeaseSet(CreateLeaseSetMessage message) {
|
||||
if ( (message.getLeaseSet() == null) || (message.getPrivateKey() == null) || (message.getSigningPrivateKey() == null) ) {
|
||||
LeaseSet ls = message.getLeaseSet();
|
||||
if (ls == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Null lease set granted: " + message);
|
||||
_runner.disconnectClient("Invalid CreateLeaseSetMessage");
|
||||
_runner.disconnectClient("Invalid CreateLeaseSetMessage - null LS");
|
||||
return;
|
||||
}
|
||||
int type = ls.getType();
|
||||
if (type != DatabaseEntry.KEY_TYPE_META_LS2 &&
|
||||
(message.getPrivateKey() == null || message.getSigningPrivateKey() == null)) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Null private keys: " + message);
|
||||
_runner.disconnectClient("Invalid CreateLeaseSetMessage - null private keys");
|
||||
return;
|
||||
}
|
||||
SessionId id = message.getSessionId();
|
||||
@@ -486,42 +505,44 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
||||
return;
|
||||
}
|
||||
Destination dest = cfg.getDestination();
|
||||
Destination ndest = message.getLeaseSet().getDestination();
|
||||
Destination ndest = ls.getDestination();
|
||||
if (!dest.equals(ndest)) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Different destination in LS");
|
||||
_runner.disconnectClient("Different destination in LS");
|
||||
return;
|
||||
}
|
||||
LeaseSetKeys keys = _context.keyManager().getKeys(dest);
|
||||
if (keys == null ||
|
||||
!message.getPrivateKey().equals(keys.getDecryptionKey())) {
|
||||
// Verify and register crypto keys if new or if changed
|
||||
// Private crypto key should never change, and if it does,
|
||||
// one of the checks below will fail
|
||||
PublicKey pk;
|
||||
try {
|
||||
pk = message.getPrivateKey().toPublic();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Bad private key in LS");
|
||||
_runner.disconnectClient("Bad private key in LS");
|
||||
return;
|
||||
if (type != DatabaseEntry.KEY_TYPE_META_LS2) {
|
||||
LeaseSetKeys keys = _context.keyManager().getKeys(dest);
|
||||
if (keys == null ||
|
||||
!message.getPrivateKey().equals(keys.getDecryptionKey())) {
|
||||
// Verify and register crypto keys if new or if changed
|
||||
// Private crypto key should never change, and if it does,
|
||||
// one of the checks below will fail
|
||||
PublicKey pk;
|
||||
try {
|
||||
pk = message.getPrivateKey().toPublic();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Bad private key in LS");
|
||||
_runner.disconnectClient("Bad private key in LS");
|
||||
return;
|
||||
}
|
||||
if (!pk.equals(ls.getEncryptionKey())) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Private/public crypto key mismatch in LS");
|
||||
_runner.disconnectClient("Private/public crypto key mismatch in LS");
|
||||
return;
|
||||
}
|
||||
// just register new SPK, don't verify, unused
|
||||
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
|
||||
} else if (!message.getSigningPrivateKey().equals(keys.getRevocationKey())) {
|
||||
// just register new SPK, don't verify, unused
|
||||
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
|
||||
}
|
||||
if (!pk.equals(message.getLeaseSet().getEncryptionKey())) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Private/public crypto key mismatch in LS");
|
||||
_runner.disconnectClient("Private/public crypto key mismatch in LS");
|
||||
return;
|
||||
}
|
||||
// just register new SPK, don't verify, unused
|
||||
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
|
||||
} else if (!message.getSigningPrivateKey().equals(keys.getRevocationKey())) {
|
||||
// just register new SPK, don't verify, unused
|
||||
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
|
||||
}
|
||||
try {
|
||||
_context.netDb().publish(message.getLeaseSet());
|
||||
_context.netDb().publish(ls);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Invalid leaseset from client", iae);
|
||||
@@ -532,7 +553,7 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
||||
_log.info("New lease set granted for destination " + dest);
|
||||
|
||||
// leaseSetCreated takes care of all the LeaseRequestState stuff (including firing any jobs)
|
||||
_runner.leaseSetCreated(message.getLeaseSet());
|
||||
_runner.leaseSetCreated(ls);
|
||||
}
|
||||
|
||||
/** override for testing */
|
||||
|
Reference in New Issue
Block a user