diff --git a/apps/i2ptunnel/jsp/editServer.jsi b/apps/i2ptunnel/jsp/editServer.jsi index a8370f18e..aa2cc6c4f 100644 --- a/apps/i2ptunnel/jsp/editServer.jsi +++ b/apps/i2ptunnel/jsp/editServer.jsi @@ -523,7 +523,7 @@ java.util.List clientAuths = editBean.getClientAuths(curTunnel, dhClient); if (!clientAuths.isEmpty()) { %> - <%=intl._t("Revoke?")%>    <%=intl._t("Client Name")%><%=intl._t("Client Key")%> + <%=intl._t("Revoke")%>    <%=intl._t("Client Name")%><%=intl._t("Client Key")%> <% int i = 0; for (String clientAuth : clientAuths) { @@ -552,7 +552,7 @@ } // for } // isEmpty %> - <%=intl._t("Add?")%>    <%=intl._t("Client Name")%> + <%=intl._t("Add")%>    <%=intl._t("Client Name")%> <% if (dhClient) { %> diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java index 69155dcbb..aa73fb1c8 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/ConfigKeyringHandler.java @@ -153,8 +153,8 @@ public class ConfigKeyringHandler extends FormHandler { bdout = new BlindData(_context, spk, blindType, _secret, atype, pk); } if (bdold != null) { - // debug - addFormNotice("already cached: " + bdold); + if (_log.shouldDebug()) + _log.debug("already cached: " + bdold); } try { _context.netDb().setBlindData(bdout); diff --git a/core/java/src/net/i2p/client/impl/RequestLeaseSetMessageHandler.java b/core/java/src/net/i2p/client/impl/RequestLeaseSetMessageHandler.java index c07ba8355..5621551b8 100644 --- a/core/java/src/net/i2p/client/impl/RequestLeaseSetMessageHandler.java +++ b/core/java/src/net/i2p/client/impl/RequestLeaseSetMessageHandler.java @@ -130,13 +130,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { if (_ls2Type == DatabaseEntry.KEY_TYPE_LS2) { leaseSet = new LeaseSet2(); } else if (_ls2Type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) { - EncryptedLeaseSet encls2 = new EncryptedLeaseSet(); - String secret = session.getOptions().getProperty(PROP_SECRET); - if (secret != null) { - secret = DataHelper.getUTF8(Base64.decode(secret)); - encls2.setSecret(secret); - } - leaseSet = encls2; + leaseSet = new EncryptedLeaseSet(); } else if (_ls2Type == DatabaseEntry.KEY_TYPE_META_LS2) { leaseSet = new MetaLeaseSet(); } else { @@ -174,6 +168,15 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { * @since 0.9.7 */ protected synchronized void signLeaseSet(LeaseSet leaseSet, boolean isLS2, I2PSessionImpl session) { + // must be before setDestination() + if (isLS2 && _ls2Type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) { + String secret = session.getOptions().getProperty(PROP_SECRET); + if (secret != null) { + EncryptedLeaseSet encls2 = (EncryptedLeaseSet) leaseSet; + secret = DataHelper.getUTF8(Base64.decode(secret)); + encls2.setSecret(secret); + } + } Destination dest = session.getMyDestination(); // also, if this session is connected to multiple routers, include other leases here leaseSet.setDestination(dest); diff --git a/core/java/src/net/i2p/client/impl/RequestVariableLeaseSetMessageHandler.java b/core/java/src/net/i2p/client/impl/RequestVariableLeaseSetMessageHandler.java index 7290570f6..4f47d51c1 100644 --- a/core/java/src/net/i2p/client/impl/RequestVariableLeaseSetMessageHandler.java +++ b/core/java/src/net/i2p/client/impl/RequestVariableLeaseSetMessageHandler.java @@ -58,7 +58,7 @@ class RequestVariableLeaseSetMessageHandler extends RequestLeaseSetMessageHandle } else { leaseSet = new LeaseSet(); } - // Full Meta and Encrypted support TODO + // Full Meta support TODO for (int i = 0; i < msg.getEndpoints(); i++) { Lease lease; if (isLS2) { diff --git a/core/java/src/net/i2p/crypto/Blinding.java b/core/java/src/net/i2p/crypto/Blinding.java index 4fe04b280..8ea3101ab 100644 --- a/core/java/src/net/i2p/crypto/Blinding.java +++ b/core/java/src/net/i2p/crypto/Blinding.java @@ -327,7 +327,7 @@ public final class Blinding { SigningPrivateKey priv = (SigningPrivateKey) keys[1]; I2PAppContext ctx = I2PAppContext.getGlobalContext(); //String b32 = encode(pub, null); - String b32 = encode(pub, "foobarbaz"); + String b32 = encode(pub, true, false); System.out.println("pub b32 is " + b32); BlindData bd = decode(ctx, b32); if (bd.getBlindedPubKey().equals(pub)) diff --git a/core/java/src/net/i2p/data/EncryptedLeaseSet.java b/core/java/src/net/i2p/data/EncryptedLeaseSet.java index e7f0b2e20..f83f6c046 100644 --- a/core/java/src/net/i2p/data/EncryptedLeaseSet.java +++ b/core/java/src/net/i2p/data/EncryptedLeaseSet.java @@ -42,6 +42,8 @@ public class EncryptedLeaseSet extends LeaseSet2 { private String _secret; private PrivateKey _clientPrivateKey; private final Log _log; + // debug + private int _authType, _numKeys; private static final int MIN_ENCRYPTED_SIZE = 8 + 16; private static final int MAX_ENCRYPTED_SIZE = 4096; @@ -74,11 +76,17 @@ public class EncryptedLeaseSet extends LeaseSet2 { /** * Must be set before sign or verify. + * Must be called before setDestination() or setSigningKey(), or alpha will be wrong. * * @param secret null or "" for none (default) * @since 0.9.39 */ public void setSecret(String secret) { + if (_signingKey != null && !DataHelper.eq(secret, _secret)) { + if (_log.shouldWarn()) + _log.warn("setSecret() after setSigningKey()" + + " was: " + _secret + " now: " + secret); + } _secret = secret; } @@ -128,7 +136,8 @@ public class EncryptedLeaseSet extends LeaseSet2 { } /** - * Overridden to set the blinded key + * Overridden to set the blinded key. + * setSecret() MUST be called before this for non-null secret, or alpha will be wrong. * * @param dest non-null, must be EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519 * @throws IllegalStateException if already signed @@ -147,7 +156,8 @@ public class EncryptedLeaseSet extends LeaseSet2 { } /** - * Overridden to set the blinded key + * Overridden to set the blinded key. + * setSecret() MUST be called before this for non-null secret, or alpha will be wrong. * * @param spk unblinded key non-null, must be EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519 * @throws IllegalStateException if already signed @@ -156,7 +166,6 @@ public class EncryptedLeaseSet extends LeaseSet2 { */ @Override public void setSigningKey(SigningPublicKey spk) { - // TODO already-set checks SigType type = spk.getType(); if (type != SigType.EdDSA_SHA512_Ed25519 && type != SigType.RedDSA_SHA512_Ed25519) @@ -192,6 +201,7 @@ public class EncryptedLeaseSet extends LeaseSet2 { if (_log.shouldDebug()) _log.debug("Blind:" + "\norig: " + spk + + "\nsecret: " + _secret + "\nalpha: " + _alpha + "\nblinded: " + rv); return rv; @@ -415,12 +425,14 @@ public class EncryptedLeaseSet extends LeaseSet2 { // use first 12 bytes only byte[] iv = new byte[32]; int authLen; + _authType = authType; // debug if (authType == BlindData.AUTH_NONE) { authLen = 1; } else if (authType == BlindData.AUTH_DH || authType == BlindData.AUTH_PSK) { if (clientKeys == null || clientKeys.isEmpty()) throw new IllegalArgumentException("No client keys provided"); + _numKeys = clientKeys.size(); // debug authLen = 1 + SALT_LEN + 2 + (clientKeys.size() * CLIENT_LEN); } else { throw new IllegalArgumentException("Bad auth type " + authType); @@ -609,6 +621,7 @@ public class EncryptedLeaseSet extends LeaseSet2 { } int authType = plaintext[0] & 0x0f; + _authType = authType; // debug int authLen; if (authType == BlindData.AUTH_NONE) { authLen = 1; @@ -622,6 +635,7 @@ public class EncryptedLeaseSet extends LeaseSet2 { byte[] seed = new byte[32]; System.arraycopy(plaintext, 1, seed, 0, 32); int count = (int) DataHelper.fromLong(plaintext, 33, 2); + _numKeys = count; // debug if (count == 0) throw new DataFormatException("No client entries"); authLen = 1 + SALT_LEN + 2 + (count * CLIENT_LEN); @@ -948,7 +962,13 @@ public class EncryptedLeaseSet extends LeaseSet2 { buf.append("\n\tSignature: ").append(_signature); buf.append("\n\tPublished: ").append(new java.util.Date(_published)); buf.append("\n\tExpires: ").append(new java.util.Date(_expires)); + buf.append("\n\tAuth Type: ").append(_authType); + buf.append("\n\tClient Keys: ").append(_numKeys); if (_decryptedLS2 != null) { + if (_secret != null) + buf.append("\n\tSecret: ").append(_secret); + if (_clientPrivateKey != null) + buf.append("\n\tClient Private Key: ").append(_clientPrivateKey.toBase64()); buf.append("\n\tDecrypted LS:\n").append(_decryptedLS2); } else if (_destination != null) { buf.append("\n\tDestination: ").append(_destination); diff --git a/history.txt b/history.txt index fd9d80117..ce80f6af9 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,16 @@ +2019-05-29 zzz + * I2CP: Fix bugs with lookup password + * Util: Store save time in config files + +2019-05-28 zzz + * Console: Form handling on /configkeyring for LS2 + +2019-05-27 zzz + * Console: Start rework of /configkeyring for LS2 + +2019-05-26 zzz + * I2CP: Add per-client auth to generated leaseset + 2019-05-24 zzz * i2ptunnel: - Per-client auth config diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index c10128fe6..fecba78d6 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 6; + public final static long BUILD = 7; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/client/ClientMessageEventListener.java b/router/java/src/net/i2p/router/client/ClientMessageEventListener.java index dbaafb4a9..7d3cf5e93 100644 --- a/router/java/src/net/i2p/router/client/ClientMessageEventListener.java +++ b/router/java/src/net/i2p/router/client/ClientMessageEventListener.java @@ -551,6 +551,13 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi Destination dest = cfg.getDestination(); if (type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) { // so we can decrypt it + // secret must be set before destination + String secret = cfg.getOptions().getProperty("i2cp.leaseSetSecret"); + if (secret != null) { + EncryptedLeaseSet encls = (EncryptedLeaseSet) ls; + secret = DataHelper.getUTF8(Base64.decode(secret)); + encls.setSecret(secret); + } try { ls.setDestination(dest); } catch (RuntimeException re) { @@ -652,12 +659,6 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi _runner.disconnectClient("Duplicate hash of encrypted LS2"); return; } - String secret = cfg.getOptions().getProperty("i2cp.leaseSetSecret"); - if (secret != null) { - EncryptedLeaseSet encls = (EncryptedLeaseSet) ls; - secret = DataHelper.getUTF8(Base64.decode(secret)); - encls.setSecret(secret); - } } if (_log.shouldDebug()) _log.debug("Publishing: " + ls); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java index 80c963a6a..4062815bf 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -946,16 +946,16 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad if (_log.shouldWarn()) _log.warn("Found blind data for encls: " + bd); encls = (EncryptedLeaseSet) leaseSet; + // secret must be set before destination + String secret = bd.getSecret(); + if (secret != null) + encls.setSecret(secret); Destination dest = bd.getDestination(); if (dest != null) { encls.setDestination(dest); } else { encls.setSigningKey(bd.getUnblindedPubKey()); } - // secret - String secret = bd.getSecret(); - if (secret != null) - encls.setSecret(secret); // per-client auth if (bd.getAuthType() != BlindData.AUTH_NONE) encls.setClientPrivateKey(bd.getAuthPrivKey());