diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java index a501a8d22..ff3a09514 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java @@ -161,6 +161,9 @@ public class I2PSocketManagerFull implements I2PSocketManager { */ public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException { if (privateKeyStream == null) { + // We don't actually need the same pubkey in the dest, just in the LS. + // The dest one is unused. But this is how we find the LS keys + // to reuse in RequestLeaseSetMessageHandler. ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024); try { SigType type = getSigType(opts); diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java index 032f8117a..9722748a8 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java @@ -806,7 +806,7 @@ class Packet { if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED)) buf.append(" MS ").append(_optionMaxSize); if (isFlagSet(FLAG_PROFILE_INTERACTIVE)) buf.append(" INTERACTIVE"); if (isFlagSet(FLAG_RESET)) buf.append(" RESET"); - if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) buf.append(" SIG"); + if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) buf.append(" SIG ").append(_optionSignature.length()); if (isFlagSet(FLAG_SIGNATURE_REQUESTED)) buf.append(" SIGREQ"); if (isFlagSet(FLAG_SYNCHRONIZE)) buf.append(" SYN"); } diff --git a/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java b/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java index e6e9965a8..e6729a2e4 100644 --- a/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java +++ b/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java @@ -88,9 +88,8 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { String sspk = session.getOptions().getProperty("i2cp.leaseSetSigningPrivateKey"); PrivateKey privKey = null; SigningPrivateKey signingPrivKey = null; - boolean useOldKeys; if (spk != null && sspk != null) { - useOldKeys = true; + boolean useOldKeys = true; int colon = sspk.indexOf(':'); SigType type = dest.getSigType(); if (colon > 0) { @@ -111,6 +110,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { signingPrivKey.fromBase64(sspk); } catch (DataFormatException iae) { useOldKeys = false; + signingPrivKey = null; } } if (useOldKeys) { @@ -118,20 +118,36 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { privKey = new PrivateKey(); privKey.fromBase64(spk); } catch (DataFormatException iae) { - useOldKeys = false; + privKey = null; } } - } else { - useOldKeys = false; } - if (useOldKeys) - li = new LeaseInfo(privKey, signingPrivKey); - else + if (privKey == null && !_existingLeaseSets.isEmpty()) { + // look for keypair from another dest using same pubkey + PublicKey pk = dest.getPublicKey(); + for (Map.Entry e : _existingLeaseSets.entrySet()) { + if (pk.equals(e.getKey().getPublicKey())) { + privKey = e.getValue().getPrivateKey(); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey()); + break; + } + } + } + if (privKey != null) { + if (signingPrivKey != null) { + li = new LeaseInfo(privKey, signingPrivKey); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys"); + } else { + li = new LeaseInfo(privKey, dest); + } + } else { li = new LeaseInfo(dest); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys"); + } _existingLeaseSets.put(dest, li); - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Creating new leaseInfo keys for " - + dest + " using configured private keys? " + useOldKeys); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Caching the old leaseInfo keys for " @@ -178,6 +194,9 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { private final SigningPublicKey _signingPubKey; private final SigningPrivateKey _signingPrivKey; + /** + * New keys + */ public LeaseInfo(Destination dest) { SimpleDataStructure encKeys[] = KeyGenerator.getInstance().generatePKIKeys(); // must be same type as the Destination's signing key @@ -194,6 +213,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { } /** + * Existing keys * @since 0.9.18 */ public LeaseInfo(PrivateKey privKey, SigningPrivateKey signingPrivKey) { @@ -203,6 +223,23 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { _signingPrivKey = signingPrivKey; } + /** + * Existing crypto key, new signing key + * @since 0.9.20 + */ + public LeaseInfo(PrivateKey privKey, Destination dest) { + SimpleDataStructure signKeys[]; + try { + signKeys = KeyGenerator.getInstance().generateSigningKeys(dest.getSigningPublicKey().getType()); + } catch (GeneralSecurityException gse) { + throw new IllegalStateException(gse); + } + _pubKey = KeyGenerator.getPublicKey(privKey); + _privKey = privKey; + _signingPubKey = (SigningPublicKey) signKeys[0]; + _signingPrivKey = (SigningPrivateKey) signKeys[1]; + } + public PublicKey getPublicKey() { return _pubKey; } diff --git a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java index 5b77ffc4c..3ef99808d 100644 --- a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java +++ b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java @@ -285,6 +285,12 @@ public class MessageStatusMessage extends I2CPMessageImpl { return "GUARANTEED SUCCESS "; case STATUS_SEND_SUCCESS_LOCAL: return "LOCAL SUCCESS "; + case STATUS_SEND_BEST_EFFORT_FAILURE: + return "PROBABLE FAILURE "; + case STATUS_SEND_FAILURE_NO_TUNNELS: + return "NO LOCAL TUNNELS "; + case STATUS_SEND_FAILURE_NO_LEASESET: + return "LEASESET NOT FOUND "; default: return "SEND FAILURE CODE: " + status; }