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