From 52bb2aea94f91877b7d19281cfc4826e8b2b6214 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 7 Jun 2022 14:08:53 -0400 Subject: [PATCH] SSU2: Peer test fixes per spec, Alice hash not included in msg 1/2 sig Add sig checks of msgs 1/3 at Bob Fix checking of 'B' cap in peer selection --- history.txt | 9 ++++ .../src/net/i2p/router/RouterVersion.java | 2 +- .../router/transport/udp/PeerTestManager.java | 45 ++++++++++++++----- .../router/transport/udp/UDPTransport.java | 14 +++++- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/history.txt b/history.txt index 10bd4393d..4520bc9d6 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,12 @@ +2022-06-07 zzz + * SSU2: Peer test fixes + +2022-06-06 zzz + * Console: Add deadlock detector + * SSU: Don't allow Android introducers + * SSU2: Continue work on relay + * SSU2: Peer test fixes + 2022-06-03 zzz * SSU: Possible fix for rare HMAC NPE * Transports: Periodically send RI to connected peers diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 2d30a2c12..35ab2b80b 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 = "Git"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 3; + public final static long BUILD = 4; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 37be6c0cd..7d1c96eb0 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -992,16 +992,6 @@ class PeerTestManager { _log.warn("Msg 1 status " + status); return; } - PeerState charlie = _transport.pickTestPeer(CHARLIE, fromPeer.getVersion(), isIPv6, from); - if (charlie == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Unable to pick a charlie (no peer), IPv6? " + isIPv6); - // send reject - UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_NO_CHARLIE, - Hash.FAKE_HASH, data, fromPeer); - _transport.send(packet); - return; - } Hash alice = fromPeer.getRemotePeer(); RouterInfo aliceRI = _context.netDb().lookupRouterInfoLocally(alice); if (aliceRI == null) { @@ -1013,6 +1003,29 @@ class PeerTestManager { _transport.send(packet); return; } + // validate signed data + // not strictly necessary but needed for debugging + SigningPublicKey spk = aliceRI.getIdentity().getSigningPublicKey(); + if (!SSU2Util.validateSig(_context, SSU2Util.PEER_TEST_PROLOGUE, + _context.routerHash(), null, data, spk)) { + if (_log.shouldWarn()) + _log.warn("Signature failed msg 1\n" + aliceRI); + // send reject + UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_SIGFAIL, + Hash.FAKE_HASH, data, fromPeer); + _transport.send(packet); + return; + } + PeerState charlie = _transport.pickTestPeer(CHARLIE, fromPeer.getVersion(), isIPv6, from); + if (charlie == null) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Unable to pick a charlie (no peer), IPv6? " + isIPv6); + // send reject + UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_NO_CHARLIE, + Hash.FAKE_HASH, data, fromPeer); + _transport.send(packet); + return; + } InetAddress aliceIP = fromPeer.getRemoteIPAddress(); int alicePort = fromPeer.getRemotePort(); state = new PeerTestState(BOB, null, isIPv6, nonce, now); @@ -1073,7 +1086,7 @@ class PeerTestManager { // validate signed data SigningPublicKey spk = aliceRI.getIdentity().getSigningPublicKey(); if (SSU2Util.validateSig(_context, SSU2Util.PEER_TEST_PROLOGUE, - fromPeer.getRemotePeer(), h, data, spk)) { + fromPeer.getRemotePeer(), null, data, spk)) { aliceIntroKey = getIntroKey(getAddress(aliceRI, isIPv6)); if (aliceIntroKey != null) rcode = SSU2Util.TEST_ACCEPT; @@ -1144,6 +1157,16 @@ class PeerTestManager { dbsm.setEntry(charlieRI); dbsm.setMessageExpiration(now + 10*1000); _transport.send(dbsm, alice); + if (true) { + // Debug - validate signed data + // we forward it to alice even on failure + SigningPublicKey spk = charlieRI.getIdentity().getSigningPublicKey(); + if (!SSU2Util.validateSig(_context, SSU2Util.PEER_TEST_PROLOGUE, + _context.routerHash(), alice.getRemotePeer(), data, spk)) { + if (_log.shouldWarn()) + _log.warn("Signature failed msg 3\n" + charlieRI); + } + } } else { // oh well, maybe alice has it if (_log.shouldLog(Log.WARN)) diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index f2466e64b..44a197c0a 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -3819,7 +3819,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority PeerState peer = iter.next(); if (peerRole == BOB) { // Skip SSU2 until we have support for peer test - if (peer.getVersion() != 1) { + version = peer.getVersion(); + if (version != 1) { if (!SSU2Util.ENABLE_PEER_TEST) continue; // we must know our IP/port @@ -3857,6 +3858,17 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority ip = null; List addrs = getTargetAddresses(peerInfo); for (RouterAddress addr : addrs) { + if (_enableSSU2) { + // get the right address + String style = addr.getTransportStyle(); + if (version == 1) { + if (style.equals("SSU2")) + continue; + } else { + if (style.equals("SSU") && !"2".equals(addr.getOption("v"))) + continue; + } + } byte[] rip = addr.getIP(); if (rip != null) { if (isIPv6) {