diff --git a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java index facf890f9e27781f77250bbec17cf9f5ae4776d4..4697e15f6d83a7a4ac9074c191c8591bd6f33caf 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java @@ -640,9 +640,8 @@ class EstablishState { prepareExtra(src); byte nextWriteIV[] = _curEncrypted; // reuse buf System.arraycopy(_prevEncrypted, _prevEncrypted.length-AES_SIZE, nextWriteIV, 0, AES_SIZE); - byte nextReadIV[] = _curDecrypted; // reuse buf - System.arraycopy(_e_bobSig, _e_bobSig.length-AES_SIZE, nextReadIV, 0, nextReadIV.length); - _con.finishOutboundEstablishment(_dh.getSessionKey(), (_tsA-_tsB), nextWriteIV, nextReadIV); // skew in seconds + // this does not copy the nextWriteIV, do not release to cache + _con.finishOutboundEstablishment(_dh.getSessionKey(), (_tsA-_tsB), nextWriteIV, _e_bobSig); // skew in seconds releaseBufs(); // if socket gets closed this will be null - prevent NPE InetAddress ia = _con.getChannel().socket().getInetAddress(); @@ -821,8 +820,9 @@ class EstablishState { _con.setRemotePeer(_aliceIdent); if (_log.shouldLog(Log.DEBUG)) _log.debug(prefix()+"e_bobSig is " + _e_bobSig.length + " bytes long"); - byte iv[] = _curDecrypted; // reuse buf + byte iv[] = _curEncrypted; // reuse buf System.arraycopy(_e_bobSig, _e_bobSig.length-AES_SIZE, iv, 0, AES_SIZE); + // this does not copy the IV, do not release to cache _con.finishInboundEstablishment(_dh.getSessionKey(), (tsA-_tsB), iv, _prevEncrypted); // skew in seconds releaseBufs(); if (_log.shouldLog(Log.INFO)) @@ -936,7 +936,10 @@ class EstablishState { // null or longer for OB if (_prevEncrypted != null && _prevEncrypted.length == AES_SIZE) SimpleByteCache.release(_prevEncrypted); - SimpleByteCache.release(_curEncrypted); + // Do not release _curEncrypted if verified, it is passed to + // NTCPConnection to use as the IV + if (_state != State.VERIFIED) + SimpleByteCache.release(_curEncrypted); SimpleByteCache.release(_curDecrypted); SimpleByteCache.release(_hX_xor_bobIdentHash); if (_dh.getPeerPublicValue() == null) diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java index 0e6ad832349a04d244e456aaf9a434c968d139e4..a9752a286250a2ec406c749c25aed8f71257b184 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -266,6 +266,8 @@ class NTCPConnection { /** * @param clockSkew alice's clock minus bob's clock in seconds (may be negative, obviously, but |val| should * be under 1 minute) + * @param prevWriteEnd exactly 16 bytes, not copied, do not corrupt + * @param prevReadEnd 16 or more bytes, last 16 bytes copied */ public void finishInboundEstablishment(SessionKey key, long clockSkew, byte prevWriteEnd[], byte prevReadEnd[]) { NTCPConnection toClose = locked_finishInboundEstablishment(key, clockSkew, prevWriteEnd, prevReadEnd); @@ -278,6 +280,12 @@ class NTCPConnection { enqueueInfoMessage(); } + /** + * @param clockSkew alice's clock minus bob's clock in seconds (may be negative, obviously, but |val| should + * be under 1 minute) + * @param prevWriteEnd exactly 16 bytes, not copied, do not corrupt + * @param prevReadEnd 16 or more bytes, last 16 bytes copied + */ private synchronized NTCPConnection locked_finishInboundEstablishment( SessionKey key, long clockSkew, byte prevWriteEnd[], byte prevReadEnd[]) { _sessionKey = key; @@ -582,6 +590,8 @@ class NTCPConnection { /** * @param clockSkew alice's clock minus bob's clock in seconds (may be negative, obviously, but |val| should * be under 1 minute) + * @param prevWriteEnd exactly 16 bytes, not copied, do not corrupt + * @param prevReadEnd 16 or more bytes, last 16 bytes copied */ public synchronized void finishOutboundEstablishment(SessionKey key, long clockSkew, byte prevWriteEnd[], byte prevReadEnd[]) { if (_log.shouldLog(Log.DEBUG))