From 9d9310a72678b1876c0740cc9c126eb5a1068056 Mon Sep 17 00:00:00 2001 From: zzz <zzz@i2pmail.org> Date: Wed, 2 Mar 2022 08:32:22 -0500 Subject: [PATCH] SSU2: Data phase fixes Fix receiver CipherState key Override clearWantedACKSendSince() to avoid NPE Add/tweak debug logging --- .../transport/udp/InboundEstablishState2.java | 4 ++-- .../udp/OutboundEstablishState2.java | 8 ++++---- .../router/transport/udp/PacketBuilder2.java | 5 +++++ .../i2p/router/transport/udp/PeerState2.java | 20 ++++++++++++++++++- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java index 5f83fe5497..d6f7f04a50 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java @@ -462,9 +462,9 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa ChaChaPolyCipherState sender = new ChaChaPolyCipherState(); sender.initializeKey(d_ba, 0); ChaChaPolyCipherState rcvr = new ChaChaPolyCipherState(); - sender.initializeKey(d_ab, 0); + rcvr.initializeKey(d_ab, 0); if (_log.shouldDebug()) - _log.debug("Generated Chain key: " + Base64.encode(ckd) + + _log.debug("split()\nGenerated Chain key: " + Base64.encode(ckd) + "\nGenerated split key for A->B: " + Base64.encode(k_ab) + "\nGenerated split key for B->A: " + Base64.encode(k_ba) + "\nGenerated encrypt key for A->B: " + Base64.encode(d_ab) + diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java index b1c761c588..eaba331681 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java @@ -418,15 +418,15 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl ChaChaPolyCipherState sender = new ChaChaPolyCipherState(); sender.initializeKey(d_ab, 0); ChaChaPolyCipherState rcvr = new ChaChaPolyCipherState(); - sender.initializeKey(d_ba, 0); + rcvr.initializeKey(d_ba, 0); if (_log.shouldDebug()) - _log.debug("Generated Chain key: " + Base64.encode(ckd) + + _log.debug("split()\nGenerated Chain key: " + Base64.encode(ckd) + "\nGenerated split key for A->B: " + Base64.encode(k_ab) + "\nGenerated split key for B->A: " + Base64.encode(k_ba) + "\nGenerated encrypt key for A->B: " + Base64.encode(d_ab) + "\nGenerated encrypt key for B->A: " + Base64.encode(d_ba) + - "\nIntro key for Alice: " + Base64.encode(_sendHeaderEncryptKey1) + - "\nIntro key for Bob: " + Base64.encode(_rcvHeaderEncryptKey1) + + "\nIntro key for Alice: " + Base64.encode(_transport.getSSU2StaticIntroKey()) + + "\nIntro key for Bob: " + Base64.encode(_sendHeaderEncryptKey1) + "\nGenerated header key 2 for A->B: " + Base64.encode(h_ab) + "\nGenerated header key 2 for B->A: " + Base64.encode(h_ba)); _handshakeState.destroy(); diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder2.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder2.java index 302d44fa67..6be94e5a49 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder2.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder2.java @@ -29,6 +29,7 @@ import net.i2p.router.transport.udp.PacketBuilder.Fragment; import net.i2p.router.transport.udp.SSU2Payload.Block; import static net.i2p.router.transport.udp.SSU2Util.*; import net.i2p.util.Addresses; +import net.i2p.util.HexDump; import net.i2p.util.Log; /** @@ -215,9 +216,13 @@ class PacketBuilder2 { } SSU2Payload.writePayload(data, SHORT_HEADER_SIZE, blocks); pkt.setLength(off); + if (_log.shouldDebug()) + _log.debug("Packet " + pktNum + " before encryption:\n" + HexDump.dump(data, 0, off)); encryptDataPacket(packet, peer.getSendCipher(), pktNum, peer.getSendHeaderEncryptKey1(), peer.getSendHeaderEncryptKey2()); setTo(packet, peer.getRemoteIPAddress(), peer.getRemotePort()); + if (_log.shouldDebug()) + _log.debug("Packet " + pktNum + " after encryption:\n" + HexDump.dump(data, 0, pkt.getLength())); // FIXME ticket #2675 // the packet could have been built before the current mtu got lowered, so diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState2.java b/router/java/src/net/i2p/router/transport/udp/PeerState2.java index 693e8cb7f3..af30b443f9 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState2.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState2.java @@ -119,6 +119,16 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback DATA_FOLLOWON_EXTRA_SIZE; // Followon fragment block overhead (5) } + /** + * All acks have been sent. + */ + @Override + void clearWantedACKSendSince() { + // TODO + //if ( ) + // _wantACKSendSince = 0; + } + // SSU 1 unsupported things @Override @@ -160,6 +170,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback byte[] data = dpacket.getData(); int off = dpacket.getOffset(); int len = dpacket.getLength(); + if (_log.shouldDebug()) + _log.debug("Packet before header decryption:\n" + HexDump.dump(data, off, len)); try { if (len < MIN_DATA_LEN) { if (_log.shouldWarn()) @@ -192,10 +204,14 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback } long n = header.getPacketNumber(); SSU2Header.acceptTrialDecrypt(packet, header); + if (_log.shouldDebug()) + _log.debug("Packet " + n + " after header decryption:\n" + HexDump.dump(data, off, len)); synchronized (_rcvCha) { _rcvCha.setNonce(n); // decrypt in-place _rcvCha.decryptWithAd(header.data, data, off + SHORT_HEADER_SIZE, data, off + SHORT_HEADER_SIZE, len - SHORT_HEADER_SIZE); + if (_log.shouldDebug()) + _log.debug("Packet " + n + " after full decryption:\n" + HexDump.dump(data, off, len - MAC_LEN)); if (_receivedMessages.set(n)) { if (_log.shouldWarn()) _log.warn("dup pkt rcvd " + n + " on " + this); @@ -203,6 +219,8 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback } } int payloadLen = len - (SHORT_HEADER_SIZE + MAC_LEN); + if (_log.shouldInfo()) + _log.info("New pkt rcvd " + n + " on " + this); processPayload(data, off + SHORT_HEADER_SIZE, payloadLen); packetReceived(payloadLen); } catch (GeneralSecurityException gse) { @@ -220,7 +238,7 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback try { int blocks = SSU2Payload.processPayload(_context, this, payload, offset, length, false); } catch (Exception e) { - throw new GeneralSecurityException("Session Created payload error", e); + throw new GeneralSecurityException("Data payload error", e); } } -- GitLab