From 4dd5e7737b968d3597c97b7ae41b8cb6524f637d Mon Sep 17 00:00:00 2001
From: zzz <zzz@i2pmail.org>
Date: Fri, 3 Jun 2022 08:07:29 -0400
Subject: [PATCH] SSU: Make cipher/MAC keys final

Possible fix for HMAC NPE
---
 .../transport/udp/EstablishmentManager.java   | 10 ++++----
 .../i2p/router/transport/udp/PeerState.java   | 23 +++++++------------
 .../i2p/router/transport/udp/PeerState2.java  |  4 ----
 3 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
index 8ee70c1db1..91ec8b3363 100644
--- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
@@ -947,9 +947,8 @@ class EstablishmentManager {
         int version = state.getVersion();
         if (version == 1) {
             peer = new PeerState(_context, _transport,
-                                 state.getSentIP(), state.getSentPort(), remote.calculateHash(), true, state.getRTT());
-            peer.setCurrentCipherKey(state.getCipherKey());
-            peer.setCurrentMACKey(state.getMACKey());
+                                 state.getSentIP(), state.getSentPort(), remote.calculateHash(), true, state.getRTT(),
+                                 state.getCipherKey(), state.getMACKey());
             peer.setWeRelayToThemAs(state.getSentRelayTag());
         } else {
             InboundEstablishState2 state2 = (InboundEstablishState2) state;
@@ -1083,9 +1082,8 @@ class EstablishmentManager {
         PeerState peer;
         if (version == 1) {
             peer = new PeerState(_context, _transport,
-                                 state.getSentIP(), state.getSentPort(), remote.calculateHash(), false, state.getRTT());
-            peer.setCurrentCipherKey(state.getCipherKey());
-            peer.setCurrentMACKey(state.getMACKey());
+                                 state.getSentIP(), state.getSentPort(), remote.calculateHash(), false, state.getRTT(),
+                                 state.getCipherKey(), state.getMACKey());
             int mtu = state.getRemoteAddress().getMTU();
             if (mtu > 0)
                 peer.setHisMTU(mtu);
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java
index 8149fab8c9..01e43175d4 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java
@@ -51,12 +51,12 @@ public class PeerState {
      * The AES key used to verify packets, set only after the connection is
      * established.
      */
-    private SessionKey _currentMACKey;
+    private final SessionKey _currentMACKey;
     /**
      * The AES key used to encrypt/decrypt packets, set only after the
      * connection is established.
      */
-    private SessionKey _currentCipherKey;
+    private final SessionKey _currentCipherKey;
     /**
      * The pending AES key for verifying packets if we are rekeying the
      * connection, or null if we are not in the process of rekeying.
@@ -329,7 +329,8 @@ public class PeerState {
      *  @param rtt from the EstablishState, or 0 if not available
      */
     public PeerState(RouterContext ctx, UDPTransport transport,
-                     byte[] remoteIP, int remotePort, Hash remotePeer, boolean isInbound, int rtt) {
+                     byte[] remoteIP, int remotePort, Hash remotePeer, boolean isInbound, int rtt,
+                     SessionKey cipherKey, SessionKey macKey) {
         _context = ctx;
         _log = ctx.logManager().getLog(PeerState.class);
         _transport = transport;
@@ -376,6 +377,8 @@ public class PeerState {
         _isInbound = isInbound;
         _remoteHostId = new RemoteHostId(remoteIP, remotePort);
         _bwEstimator = new SimpleBandwidthEstimator(ctx, this);
+        _currentCipherKey = cipherKey;
+        _currentMACKey = macKey;
     }
 
     /**
@@ -425,6 +428,8 @@ public class PeerState {
         _currentACKs = null;
         _currentACKsResend = null;
         _ackedMessages = null;
+        _currentCipherKey = null;
+        _currentMACKey = null;
     }
     
     /**
@@ -568,18 +573,6 @@ public class PeerState {
      */
     public int getReceiveMTU() { return _mtuReceive; }
 
-    /**
-     * The AES key used to verify packets, set only after the connection is
-     * established.
-     */
-    void setCurrentMACKey(SessionKey key) { _currentMACKey = key; }
-
-    /**
-     * The AES key used to encrypt/decrypt packets, set only after the
-     * connection is established.
-     */
-    void setCurrentCipherKey(SessionKey key) { _currentCipherKey = key; }
-
     /**
      *  Update the moving-average clock skew based on the current difference.
      *  The raw skew will be adjusted for RTT/2 here.
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 1b35bb2824..526cfe0697 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState2.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState2.java
@@ -243,10 +243,6 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
 
     // SSU 1 unsupported things
 
-    @Override
-    void setCurrentMACKey(SessionKey key) { throw new UnsupportedOperationException(); }
-    @Override
-    void setCurrentCipherKey(SessionKey key) { throw new UnsupportedOperationException(); }
     @Override
     List<Long> getCurrentFullACKs() { throw new UnsupportedOperationException(); }
     @Override
-- 
GitLab