SSU2: Peer Test fixes part 1

Store our IP/port in PeerState2
Send our IP/port in message 1
Fix signature validation of message 4
Check for 0 status in messages 1 and 2
Fail on nonzero status in message 4
Log tweaks
This commit is contained in:
zzz
2022-04-23 12:13:03 -04:00
parent 4c10b414c4
commit ce2b5639b5
5 changed files with 55 additions and 9 deletions

View File

@@ -685,6 +685,11 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
// PS2.super adds CLOCK_SKEW_FUDGE that doesn't apply here
_pstate.adjustClockSkew(_skew - (_rtt / 2) - PeerState.CLOCK_SKEW_FUDGE);
_pstate.setHisMTU(_mtu);
// set our address. _bobIP and _bobPort in super are not set for SSU2
boolean isIPv6 = _aliceIP.length == 16;
RouterAddress ra = _transport.getCurrentExternalAddress(isIPv6);
if (ra != null)
_pstate.setOurAddress(ra.getIP(), ra.getPort());
}
/**

View File

@@ -111,7 +111,6 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
}
}
_mtu = mtu;
// TODO if RI too big, give up now
if (addr.getIntroducerCount() > 0) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("new outbound establish to " + remotePeer.calculateHash() + ", with address: " + addr);
@@ -520,6 +519,7 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
// PS2.super adds CLOCK_SKEW_FUDGE that doesn't apply here
_pstate.adjustClockSkew(_skew - (_rtt / 2) - PeerState.CLOCK_SKEW_FUDGE);
_pstate.setHisMTU(_mtu);
_pstate.setOurAddress(_aliceIP, _alicePort);
}
confirmedPacketsSent();
return _pstate;

View File

@@ -59,6 +59,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
private final SSU2Bitfield _ackedMessages;
private final ConcurrentHashMap<Long, List<PacketBuilder.Fragment>> _sentMessages;
private long _sentMessagesLastExpired;
private byte[] _ourIP;
private int _ourPort;
// Session Confirmed retransmit
private byte[][] _sessConfForReTX;
@@ -269,6 +271,12 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
byte[] getSendHeaderEncryptKey2() { return _sendHeaderEncryptKey2; }
byte[] getRcvHeaderEncryptKey2() { return _rcvHeaderEncryptKey2; }
void setOurAddress(byte[] ip, int port) {
_ourIP = ip; _ourPort = port;
}
byte[] getOurIP() { return _ourIP; }
int getOurPort() { return _ourPort; }
SSU2Bitfield getReceivedMessages() {
// logged in PacketBuilder2
//if (_log.shouldDebug())
@@ -379,6 +387,7 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
}
public void gotAddress(byte[] ip, int port) {
_ourIP = ip; _ourPort = port;
}
public void gotRelayTagRequest() {
@@ -594,8 +603,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
if (_log.shouldWarn())
_log.warn("Dup send of pkt " + pktNum + " on " + this);
} else {
if (_log.shouldWarn())
_log.warn("New data pkt " + pktNum + " sent with " + fragments.size() + " fragments on " + this);
if (_log.shouldDebug())
_log.debug("New data pkt " + pktNum + " sent with " + fragments.size() + " fragments on " + this);
}
}

View File

@@ -293,7 +293,7 @@ class PeerTestManager {
PeerState2 bob = (PeerState2) test.getBob();
// TODO only create this once
byte[] data = SSU2Util.createPeerTestData(_context, bob.getRemotePeer(), _context.routerHash(),
ALICE, test.getNonce(), null, 0, spk);
ALICE, test.getNonce(), bob.getOurIP(), bob.getOurPort(), spk);
if (data == null) {
if (_log.shouldWarn())
_log.warn("sig fail");
@@ -786,7 +786,7 @@ class PeerTestManager {
state = _activeTests.get(lNonce);
if (_log.shouldDebug())
_log.debug("Got peer test from " + from + ' ' + fromPeer +
_log.debug("Got peer test" +
" msg: " + msg +
" status: " + status +
" hash: " + h +
@@ -794,6 +794,7 @@ class PeerTestManager {
" nonce: " + nonce +
" time: " + DataHelper.formatTime(time) +
" ip/port: " + Addresses.toString(testIP, testPort) +
" from " + fromPeer +
" state: " + state);
byte[] fromIP = from.getIP();
@@ -877,6 +878,11 @@ class PeerTestManager {
switch (msg) {
// alice to bob, in-session
case 1: {
if (status != 0) {
if (_log.shouldWarn())
_log.warn("Msg 1 status " + status);
return;
}
PeerState charlie = _transport.pickTestPeer(CHARLIE, fromPeer.getVersion(), isIPv6, from);
if (charlie == null) {
if (_log.shouldLog(Log.WARN))
@@ -921,6 +927,11 @@ class PeerTestManager {
// bob to charlie, in-session
case 2: {
if (status != 0) {
if (_log.shouldWarn())
_log.warn("Msg 2 status " + status);
return;
}
InetAddress aliceIP;
try {
aliceIP = InetAddress.getByAddress(testIP);
@@ -952,9 +963,13 @@ class PeerTestManager {
else
rcode = SSU2Util.TEST_REJECT_CHARLIE_ADDRESS;
} else {
if (_log.shouldWarn())
_log.warn("Signature failed msg 2\n" + aliceRI);
rcode = SSU2Util.TEST_REJECT_CHARLIE_SIGFAIL;
}
} else {
if (_log.shouldWarn())
_log.warn("Alice RI not found " + h);
rcode = SSU2Util.TEST_REJECT_CHARLIE_UNKNOWN_ALICE;
}
}
@@ -1037,7 +1052,10 @@ class PeerTestManager {
boolean fail = false;
RouterInfo charlieRI = null;
SessionKey charlieIntroKey = null;
if (_context.banlist().isBanlisted(h) ||
if (status != 0) {
if (_log.shouldWarn())
_log.warn("Msg 4 status " + status);
} else if (_context.banlist().isBanlisted(h) ||
!TransportUtil.isValidPort(testPort) ||
!_transport.isValid(testIP) ||
_transport.isTooClose(testIP) ||
@@ -1052,9 +1070,17 @@ class PeerTestManager {
// validate signed data
SigningPublicKey spk = charlieRI.getIdentity().getSigningPublicKey();
if (SSU2Util.validateSig(_context, SSU2Util.PEER_TEST_PROLOGUE,
fromPeer.getRemotePeer(), h, data, spk)) {
fromPeer.getRemotePeer(), _context.routerHash(), data, spk)) {
charlieIntroKey = getIntroKey(charlieRI, isIPv6);
if (charlieIntroKey == null && _log.shouldWarn())
_log.warn("Charlie intro key not found: " + test + '\n' + charlieRI);
} else {
if (_log.shouldWarn())
_log.warn("Signature failed msg 4 " + test + '\n' + charlieRI);
}
} else {
if (_log.shouldWarn())
_log.warn("Charlie RI not found" + test + ' ' + h);
}
}
if (charlieIntroKey == null) {

View File

@@ -3808,8 +3808,14 @@ 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 && !SSU2Util.ENABLE_PEER_TEST)
continue;
if (peer.getVersion() != 1) {
if (!SSU2Util.ENABLE_PEER_TEST)
continue;
// we must know our IP/port
PeerState2 bob = (PeerState2) peer;
if (bob.getOurIP() == null || bob.getOurPort() <= 0)
continue;
}
} else {
// charlie must be same version
if (peer.getVersion() != version)