Browse Source

extract ret code per hop

pull/1677/head
orignal 3 years ago
parent
commit
d73b42b726
  1. 13
      libi2pd/Tunnel.cpp
  2. 15
      libi2pd/TunnelConfig.cpp
  3. 17
      libi2pd/TunnelConfig.h

13
libi2pd/Tunnel.cpp

@ -103,26 +103,22 @@ namespace tunnel
{ {
LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records."); LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records.");
i2p::crypto::CBCDecryption decryption;
TunnelHopConfig * hop = m_Config->GetLastHop (); TunnelHopConfig * hop = m_Config->GetLastHop ();
while (hop) while (hop)
{ {
// decrypt current hop // decrypt current hop
auto idx = hop->recordIndex; if (hop->recordIndex >= 0 && hop->recordIndex < msg[0])
if (idx >= 0 && idx < msg[0])
{ {
uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; if (!hop->DecryptBuildResponseRecord (msg + 1))
if (!hop->DecryptBuildResponseRecord (record, record))
return false; return false;
} }
else else
{ {
LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); LogPrint (eLogWarning, "Tunnel: hop index ", hop->recordIndex, " is out of range");
return false; return false;
} }
// decrypt records before current hop // decrypt records before current hop
decryption.SetKey (hop->replyKey);
TunnelHopConfig * hop1 = hop->prev; TunnelHopConfig * hop1 = hop->prev;
while (hop1) while (hop1)
{ {
@ -140,8 +136,7 @@ namespace tunnel
hop = m_Config->GetFirstHop (); hop = m_Config->GetFirstHop ();
while (hop) while (hop)
{ {
const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE; uint8_t ret = hop->GetRetCode (msg + 1);
uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET];
LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret); LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret);
auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ()); auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ());
if (profile) if (profile)

15
libi2pd/TunnelConfig.cpp

@ -113,12 +113,13 @@ namespace tunnel
memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); 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; i2p::crypto::CBCDecryption decryption;
decryption.SetKey (replyKey); decryption.SetKey (replyKey);
decryption.SetIV (replyIV); decryption.SetIV (replyIV);
decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record);
return true; return true;
} }
@ -176,11 +177,12 @@ namespace tunnel
memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); 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]; uint8_t nonce[12];
memset (nonce, 0, 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"); LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
return false; return false;
@ -223,12 +225,13 @@ namespace tunnel
memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); 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]; uint8_t nonce[12];
memset (nonce, 0, 12); memset (nonce, 0, 12);
nonce[4] = recordIndex; // nonce is record index 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"); LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
return false; return false;

17
libi2pd/TunnelConfig.h

@ -40,9 +40,9 @@ namespace tunnel
void SetNext (TunnelHopConfig * n); void SetNext (TunnelHopConfig * n);
void SetPrev (TunnelHopConfig * p); 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 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 virtual void DecryptRecord (uint8_t * records, int index) const; // AES
}; };
@ -50,15 +50,16 @@ namespace tunnel
{ {
ElGamalTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r): ElGamalTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
TunnelHopConfig (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); 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 struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState
{ {
ECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r): ECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
TunnelHopConfig (r) {}; TunnelHopConfig (r) {};
bool IsECIES () const { return true; };
void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); 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; 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<const i2p::data::IdentityEx> r): LongECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
ECIESTunnelHopConfig (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); 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 struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig
{ {
ShortECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r): ShortECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
ECIESTunnelHopConfig (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); 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 void DecryptRecord (uint8_t * records, int index) const override; // Chacha20
}; };

Loading…
Cancel
Save