diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 84df9b56..fe219214 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -103,26 +103,22 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records."); - i2p::crypto::CBCDecryption decryption; TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { // decrypt current hop - auto idx = hop->recordIndex; - if (idx >= 0 && idx < msg[0]) + if (hop->recordIndex >= 0 && hop->recordIndex < msg[0]) { - uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - if (!hop->DecryptBuildResponseRecord (record, record)) + if (!hop->DecryptBuildResponseRecord (msg + 1)) return false; } else { - LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); + LogPrint (eLogWarning, "Tunnel: hop index ", hop->recordIndex, " is out of range"); return false; } // decrypt records before current hop - decryption.SetKey (hop->replyKey); TunnelHopConfig * hop1 = hop->prev; while (hop1) { @@ -140,8 +136,7 @@ namespace tunnel hop = m_Config->GetFirstHop (); while (hop) { - const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE; - uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET]; + uint8_t ret = hop->GetRetCode (msg + 1); LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret); auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ()); if (profile) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 1680a0b1..b461a3d5 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -113,12 +113,13 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; i2p::crypto::CBCDecryption decryption; decryption.SetKey (replyKey); decryption.SetIV (replyIV); - decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record); return true; } @@ -176,11 +177,12 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; uint8_t nonce[12]; memset (nonce, 0, 12); - if (!DecryptECIES (m_CK, nonce, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE, record)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -223,12 +225,13 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; uint8_t nonce[12]; memset (nonce, 0, 12); nonce[4] = recordIndex; // nonce is record index - if (!DecryptECIES (replyKey, nonce, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (replyKey, nonce, record, SHORT_TUNNEL_BUILD_RECORD_SIZE, record)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index e356a9f0..b2bf26b7 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -40,9 +40,9 @@ namespace tunnel void SetNext (TunnelHopConfig * n); void SetPrev (TunnelHopConfig * p); - virtual bool IsECIES () const { return false; }; + virtual uint8_t GetRetCode (const uint8_t * records) const = 0; virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; - virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const = 0; + virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; @@ -50,15 +50,16 @@ namespace tunnel { ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; @@ -67,16 +68,20 @@ namespace tunnel { LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig { ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 };