From bc9b355d5de504bd1a23ca07c4301585db14db29 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2014 08:08:28 -0500 Subject: [PATCH] check garlic message payload hash --- Garlic.cpp | 31 ++++++++++++++++++++++--------- Streaming.cpp | 4 ++-- TunnelEndpoint.cpp | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index 1db02493..d66e4eb3 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -17,13 +17,7 @@ namespace garlic GarlicRoutingSession::GarlicRoutingSession (const i2p::data::RoutingDestination * destination, int numTags): m_Destination (destination), m_NumTags (numTags), m_NextTag (-1), m_SessionTags (0) { - m_Rnd.GenerateBlock (m_SessionKey, 32); - if (m_NumTags > 0) - { - m_SessionTags = new uint8_t[m_NumTags*32]; - for (int i = 0; i < m_NumTags; i++) - m_Rnd.GenerateBlock (m_SessionTags + i*32, 32); - } + m_SessionTags = new uint8_t[m_NumTags*32]; } GarlicRoutingSession::~GarlicRoutingSession () @@ -36,8 +30,13 @@ namespace garlic I2NPMessage * m = NewI2NPMessage (); size_t len = 0; uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - if (m_NextTag < 0) // new session + if (m_NextTag < 0 || m_NextTag >= m_NumTags) // new session { + // create new session tags and session key + m_Rnd.GenerateBlock (m_SessionKey, 32); + for (int i = 0; i < m_NumTags; i++) + m_Rnd.GenerateBlock (m_SessionTags + i*32, 32); + // create ElGamal block ElGamalBlock elGamal; memcpy (elGamal.sessionKey, m_SessionKey, 32); @@ -268,12 +267,26 @@ namespace garlic m_SessionTags[std::string ((const char *)(buf + i*32), 32)] = std::string ((const char *)sessionKey, 32); buf += tagCount*32; uint32_t payloadSize = be32toh (*(uint32_t *)buf); + if (payloadSize > len) + { + LogPrint ("Unxpected payload size ", payloadSize); + return; + } buf += 4; - buf += 32;// payload hash. TODO: verify it + uint8_t * payloadHash = buf; + buf += 32;// payload hash. if (*buf) // session key? buf += 32; // new session key buf++; // flag + // payload + uint8_t hash[32]; + CryptoPP::SHA256().CalculateDigest(hash, buf, payloadSize); + if (memcmp (hash, payloadHash, 32)) // payload hash doesn't match + { + LogPrint ("Wrong payload hash"); + return; + } HandleGarlicPayload (buf, payloadSize); } diff --git a/Streaming.cpp b/Streaming.cpp index 1acbad79..c910a190 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -163,7 +163,7 @@ namespace stream size++; // resend delay *(uint16_t *)(packet + size) = 0; // nof flags set size += 2; // flags - *(uint16_t *)(packet + size) = 0; // nof flags set + *(uint16_t *)(packet + size) = 0; // no options size += 2; // options size I2NPMessage * msg = i2p::garlic::routing.WrapSingleMessage (m_RemoteLeaseSet, @@ -207,7 +207,7 @@ namespace stream size++; // resend delay *(uint16_t *)(packet + size) = PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED; size += 2; // flags - *(uint16_t *)(packet + size) = 40; // 40 bytes signature + *(uint16_t *)(packet + size) = htobe16 (40); // 40 bytes signature size += 2; // options size uint8_t * signature = packet + size; memset (packet + size, 0, 40); diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index c5ec73b4..45aa4373 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -143,7 +143,7 @@ namespace tunnel void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg) { - LogPrint ("TunnelMessage: handle fragment of ", msg.data->GetLength ()," bytes"); + LogPrint ("TunnelMessage: handle fragment of ", msg.data->GetLength ()," bytes. Msg type ", (int)msg.data->GetHeader()->typeID); switch (msg.deliveryType) { case eDeliveryTypeLocal: