diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java index cce957c0e9..5fc087c190 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java @@ -467,27 +467,29 @@ class NetDbRenderer { buf.append(in.getDestinationNickname()); else buf.append(dest.toBase64().substring(0, 6)); - buf.append("\n is appended with an "Add to addressbook" link, so this - // should not span 2 columns. - String host = null; - if (!unpublished) { - host = _context.namingService().reverseLookup(dest); - } - if (unpublished || host != null || !linkSusi) { - buf.append(" colspan=\"2\""); - } - buf.append(">"); - String b32 = key.toBase32(); - buf.append("").append(b32).append(""); - if (linkSusi && !unpublished) { - if (host == null) { + buf.append("\n"); + // we don't show a b32 or addressbook links if encrypted + if (type != DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) { + buf.append(" is appended with an "Add to addressbook" link, so this + // should not span 2 columns. + String host = null; + if (!unpublished) { + host = _context.namingService().reverseLookup(dest); + } + if (unpublished || host != null || !linkSusi) { + buf.append(" colspan=\"2\""); + } + buf.append(">"); + String b32 = key.toBase32(); + buf.append("").append(b32).append(""); + if (linkSusi && !unpublished && host == null) { buf.append("").append("").append(_t("Add to local addressbook")).append(""); - } - } // else probably a client + } // else probably a client + } } else { buf.append("").append(_t("Destination")).append(": "); String host = (dest != null) ? _context.namingService().reverseLookup(dest) : null; diff --git a/core/java/src/net/i2p/crypto/Blinding.java b/core/java/src/net/i2p/crypto/Blinding.java index 6ef788d324..3cc7af0479 100644 --- a/core/java/src/net/i2p/crypto/Blinding.java +++ b/core/java/src/net/i2p/crypto/Blinding.java @@ -27,6 +27,7 @@ public final class Blinding { private static final SigType TYPE = SigType.EdDSA_SHA512_Ed25519; private static final SigType TYPER = SigType.RedDSA_SHA512_Ed25519; private static final String INFO = "i2pblinding1"; + private static final byte[] INFO_ALPHA = DataHelper.getASCII("I2PGenerateAlpha"); // following copied from RouterKeyGenerator private static final String FORMAT = "yyyyMMdd"; @@ -112,16 +113,16 @@ public final class Blinding { * Generate alpha for current time. * Only for SigType EdDSA_SHA512_Ed25519. * - * @param dest spk must be SigType EdDSA_SHA512_Ed25519 + * @param destspk must be SigType EdDSA_SHA512_Ed25519 * @param secret may be null or zero-length * @return SigType RedDSA_SHA512_Ed25519 * @throws UnsupportedOperationException unless supported SigTypes * @throws IllegalArgumentException on bad inputs * @since 0.9.39 */ - public static SigningPrivateKey generateAlpha(I2PAppContext ctx, Destination dest, String secret) { + public static SigningPrivateKey generateAlpha(I2PAppContext ctx, SigningPublicKey destspk, String secret) { long now = ctx.clock().now(); - return generateAlpha(ctx, dest, secret, now); + return generateAlpha(ctx, destspk, secret, now); } /** @@ -136,7 +137,7 @@ public final class Blinding { * @throws IllegalArgumentException on bad inputs * @since 0.9.39 */ - public static SigningPrivateKey generateAlpha(I2PAppContext ctx, Destination dest, + public static SigningPrivateKey generateAlpha(I2PAppContext ctx, SigningPublicKey destspk, String secret, long now) { String modVal; synchronized(_fmt) { @@ -155,7 +156,15 @@ public final class Blinding { } HKDF hkdf = new HKDF(ctx); byte[] out = new byte[64]; - hkdf.calculate(dest.getHash().getData(), data, INFO, out, out, 32); + int stoff = INFO_ALPHA.length + destspk.length(); + byte[] in = new byte[stoff + 4]; + // SHA256("I2PGenerateAlpha" || spk || sigtypein || sigtypeout) + System.arraycopy(INFO_ALPHA, 0, in, 0, INFO_ALPHA.length); + System.arraycopy(destspk.getData(), 0, in, INFO_ALPHA.length, destspk.length()); + DataHelper.toLong(in, stoff, 2, destspk.getType().getCode()); + DataHelper.toLong(in, stoff + 2, 2, TYPER.getCode()); + Hash salt = ctx.sha().calculateHash(in); + hkdf.calculate(salt.getData(), data, INFO, out, out, 32); byte[] b = EdDSABlinding.reduce(out); return new SigningPrivateKey(TYPER, b); } diff --git a/core/java/src/net/i2p/data/EncryptedLeaseSet.java b/core/java/src/net/i2p/data/EncryptedLeaseSet.java index 55f454af35..e590d17cd5 100644 --- a/core/java/src/net/i2p/data/EncryptedLeaseSet.java +++ b/core/java/src/net/i2p/data/EncryptedLeaseSet.java @@ -129,9 +129,9 @@ public class EncryptedLeaseSet extends LeaseSet2 { SigningPublicKey spk = _destination.getSigningPublicKey(); I2PAppContext ctx = I2PAppContext.getGlobalContext(); if (_published <= 0) - _alpha = Blinding.generateAlpha(ctx, _destination, null); + _alpha = Blinding.generateAlpha(ctx, _destination.getSigningPublicKey(), null); else - _alpha = Blinding.generateAlpha(ctx, _destination, null, _published); + _alpha = Blinding.generateAlpha(ctx, _destination.getSigningPublicKey(), null, _published); SigningPublicKey rv = Blinding.blind(spk, _alpha); if (_log.shouldDebug()) _log.debug("Blind:" + @@ -464,7 +464,14 @@ public class EncryptedLeaseSet extends LeaseSet2 { private byte[] getSubcredential(I2PAppContext ctx) { if (_destination == null) throw new IllegalStateException("no known destination to decrypt with"); - byte[] credential = hash(ctx, CREDENTIAL, _destination.toByteArray()); + SigningPublicKey destspk = _destination.getSigningPublicKey(); + int spklen = destspk.length(); + byte[] in = new byte[spklen + 4]; + // SHA256("credential" || spk || sigtypein || sigtypeout) + System.arraycopy(destspk.getData(), 0, in, 0, spklen); + DataHelper.toLong(in, spklen, 2, destspk.getType().getCode()); + DataHelper.toLong(in, spklen + 2, 2, SigType.RedDSA_SHA512_Ed25519.getCode()); + byte[] credential = hash(ctx, CREDENTIAL, in); byte[] spk = _signingKey.getData(); byte[] tmp = new byte[credential.length + spk.length]; System.arraycopy(credential, 0, tmp, 0, credential.length); diff --git a/history.txt b/history.txt index 3163990373..86521e8097 100644 --- a/history.txt +++ b/history.txt @@ -1,10 +1,22 @@ +2019-03-05 zzz + * Data: Update Encrypted LS2 blinding and encryption + +2019-03-04 zzz + * Console: Fix NPEs displaying encrypted LS2 + * Data: Fix NPE in debug logging + * I2CP, NetDB: More fixes for encrypted LS2 (proposal 123) + * NetDB: Call fail callback when lookup is negative cached (thx zab) + +2019-03-02 zzz + * I2CP, NetDB: Fixes for encrypted LS2 (proposal 123) + 2019-03-01 zzz - * Streaming: Fix sending messages with expired times (ticket #2451) + * Streaming: Fix sending messages with expired times (ticket #2451) 2019-02-28 zzz - * Console: - - Fix router logs not shown if first msg is a dup - - Change fallback client names to use b32 + * Console: + - Fix router logs not shown if first msg is a dup + - Change fallback client names to use b32 2019-02-26 zzz * SSU: diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index e36cd3b143..7f4edb9752 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 = 12; + public final static long BUILD = 13; /** for example "-test" */ public final static String EXTRA = "";