support of multiple incoming garlic sessions

pull/11/head
orignal 11 years ago
parent 991a80428d
commit ebc6811e71

@ -232,14 +232,17 @@ namespace garlic
uint32_t length = be32toh (*(uint32_t *)buf); uint32_t length = be32toh (*(uint32_t *)buf);
buf += 4; buf += 4;
std::string sessionTag((const char *)buf, 32); std::string sessionTag((const char *)buf, 32);
if (m_SessionTags.count (sessionTag) > 0) auto it = m_SessionTags.find (sessionTag);
if (it != m_SessionTags.end ())
{ {
// existing session // existing session
std::string sessionKey (it->second);
m_SessionTags.erase (it); // tag might be used only once
uint8_t iv[32]; // IV is first 16 bytes uint8_t iv[32]; // IV is first 16 bytes
CryptoPP::SHA256().CalculateDigest(iv, buf, 32); CryptoPP::SHA256().CalculateDigest(iv, buf, 32);
m_Decryption.SetKeyWithIV (m_SessionKey, 32, iv); m_Decryption.SetKeyWithIV ((uint8_t *)sessionKey.c_str (), 32, iv); // tag is mapped to 32 bytes key
m_Decryption.ProcessData(buf + 32, buf + 32, length - 32); m_Decryption.ProcessData(buf + 32, buf + 32, length - 32);
HandleAESBlock (buf + 32, length - 32); HandleAESBlock (buf + 32, length - 32, (uint8_t *)sessionKey.c_str ());
} }
else else
{ {
@ -248,22 +251,21 @@ namespace garlic
i2p::crypto::ElGamalDecrypt ( i2p::crypto::ElGamalDecrypt (
isFromTunnel ? i2p::context.GetLeaseSetPrivateKey () : i2p::context.GetPrivateKey (), isFromTunnel ? i2p::context.GetLeaseSetPrivateKey () : i2p::context.GetPrivateKey (),
buf, (uint8_t *)&elGamal, true); buf, (uint8_t *)&elGamal, true);
memcpy (m_SessionKey, elGamal.sessionKey, 32);
uint8_t iv[32]; // IV is first 16 bytes uint8_t iv[32]; // IV is first 16 bytes
CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32); CryptoPP::SHA256().CalculateDigest(iv, elGamal.preIV, 32);
m_Decryption.SetKeyWithIV (m_SessionKey, 32, iv); m_Decryption.SetKeyWithIV (elGamal.sessionKey, 32, iv);
m_Decryption.ProcessData(buf + 514, buf + 514, length - 514); m_Decryption.ProcessData(buf + 514, buf + 514, length - 514);
HandleAESBlock (buf + 514, length - 514); HandleAESBlock (buf + 514, length - 514, elGamal.sessionKey);
} }
} }
void GarlicRouting::HandleAESBlock (uint8_t * buf, size_t len) void GarlicRouting::HandleAESBlock (uint8_t * buf, size_t len, uint8_t * sessionKey)
{ {
uint16_t tagCount = be16toh (*(uint16_t *)buf); uint16_t tagCount = be16toh (*(uint16_t *)buf);
buf += 2; buf += 2;
for (int i = 0; i < tagCount; i++) for (int i = 0; i < tagCount; i++)
m_SessionTags.insert (std::string ((const char *)(buf + i*32), 32)); m_SessionTags[std::string ((const char *)(buf + i*32), 32)] = std::string ((const char *)sessionKey, 32);
buf += tagCount*32; buf += tagCount*32;
uint32_t payloadSize = be32toh (*(uint32_t *)buf); uint32_t payloadSize = be32toh (*(uint32_t *)buf);
buf += 4; buf += 4;

@ -3,7 +3,6 @@
#include <inttypes.h> #include <inttypes.h>
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include <cryptopp/modes.h> #include <cryptopp/modes.h>
#include <cryptopp/aes.h> #include <cryptopp/aes.h>
@ -75,7 +74,7 @@ namespace garlic
private: private:
void HandleAESBlock (uint8_t * buf, size_t len); void HandleAESBlock (uint8_t * buf, size_t len, uint8_t * sessionKey);
void HandleGarlicPayload (uint8_t * buf, size_t len); void HandleGarlicPayload (uint8_t * buf, size_t len);
private: private:
@ -83,8 +82,7 @@ namespace garlic
// outgoing sessions // outgoing sessions
std::map<i2p::data::IdentHash, GarlicRoutingSession *> m_Sessions; std::map<i2p::data::IdentHash, GarlicRoutingSession *> m_Sessions;
// incoming session // incoming session
uint8_t m_SessionKey[32]; std::map<std::string, std::string> m_SessionTags; // tag -> key
std::set<std::string> m_SessionTags;
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption m_Decryption; CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption m_Decryption;
}; };

Loading…
Cancel
Save