From 57c97208f9da13e7a6fba2e7c3da8110ff466959 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 8 Jan 2014 22:47:22 -0500 Subject: [PATCH] include DeliveryStatus to Garlic --- Garlic.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++------ Garlic.h | 1 + I2NPProtocol.cpp | 4 ++-- I2NPProtocol.h | 2 +- LeaseSet.cpp | 16 +++++++++++++- Streaming.cpp | 19 +++++++++++++++-- Streaming.h | 11 ++++++++-- 7 files changed, 93 insertions(+), 14 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index 202949bb..ec52550c 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -4,6 +4,8 @@ #include #include "ElGamal.h" #include "RouterContext.h" +#include "I2NPProtocol.h" +#include "Tunnel.h" #include "Timestamp.h" #include "Streaming.h" #include "Garlic.h" @@ -65,8 +67,6 @@ namespace garlic FillI2NPMessageHeader (m, eI2NPGarlic); if (msg) DeleteI2NPMessage (msg); - if (leaseSet) - DeleteI2NPMessage (leaseSet); return m; } @@ -97,17 +97,23 @@ namespace garlic size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec + uint32_t msgID = m_Rnd.GenerateWord32 (); size_t size = 0; uint8_t * numCloves = payload + size; *numCloves = 0; size++; + + if (leaseSet) + { + // clove is DeliveryStatus is LeaseSet is presented + size += CreateDeliveryStatusClove (payload + size, msgID); + (*numCloves)++; - if (leaseSet) // first clove is our leaseSet if presented - { + // clove is our leaseSet if presented size += CreateGarlicClove (payload + size, leaseSet, false); (*numCloves)++; } - if (msg) // next clove message ifself if presented + if (msg) // clove message ifself if presented { size += CreateGarlicClove (payload + size, msg, m_Destination->IsDestination ()); (*numCloves)++; @@ -115,7 +121,7 @@ namespace garlic memset (payload + size, 0, 3); // certificate of message size += 3; - *(uint32_t *)(payload + size) = htobe32 (m_Rnd.GenerateWord32 ()); // MessageID + *(uint32_t *)(payload + size) = htobe32 (msgID); // MessageID size += 4; *(uint64_t *)(payload + size) = htobe64 (ts); // Expiration of message size += 8; @@ -149,6 +155,42 @@ namespace garlic size += 3; return size; } + + size_t GarlicRoutingSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID) + { + size_t size = 0; + auto tunnel = i2p::tunnel::tunnels.GetNextInboundTunnel (); + if (tunnel) + { + buf[size] = eGarlicDeliveryTypeTunnel << 5; // delivery instructions flag tunnel + size++; + *(uint32_t *)(buf + size) = htobe32 (tunnel->GetNextTunnelID ()); // tunnelID + size += 4; + memcpy (buf + size, tunnel->GetNextIdentHash (), 32); // To Hash + size += 32; + } + else + { + LogPrint ("No reply tunnels for garlic DeliveryStatus found"); + buf[size] = 0;// delivery instructions flag local + size++; + } + + + I2NPMessage * msg = CreateDeliveryStatusMsg (msgID); + memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); + size += msg->GetLength (); + DeleteI2NPMessage (msg); + uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec + *(uint32_t *)(buf + size) = htobe32 (m_Rnd.GenerateWord32 ()); // CloveID + size += 4; + *(uint64_t *)(buf + size) = htobe64 (ts); // Expiration of clove + size += 8; + memset (buf + size, 0, 3); // certificate of clove + size += 3; + + return size; + } GarlicRouting routing; GarlicRouting::GarlicRouting () diff --git a/Garlic.h b/Garlic.h index 536ed173..81675fa9 100644 --- a/Garlic.h +++ b/Garlic.h @@ -48,6 +48,7 @@ namespace garlic size_t CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet); size_t CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet); size_t CreateGarlicClove (uint8_t * buf, I2NPMessage * msg, bool isDestination); + size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID); private: diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 11ccd757..44862dc0 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -67,7 +67,7 @@ namespace i2p return msg; } - I2NPMessage * CreateDeliveryStatusMsg () + I2NPMessage * CreateDeliveryStatusMsg (uint32_t msgID) { #pragma pack(1) struct @@ -77,7 +77,7 @@ namespace i2p } msg; #pragma pack () - msg.msgID = 0; + msg.msgID = htobe32 (msgID); msg.timestamp = htobe64 (i2p::util::GetMillisecondsSinceEpoch ()); return CreateI2NPMessage (eI2NPDeliveryStatus, (uint8_t *)&msg, sizeof (msg)); } diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 71b93525..ebba0c5e 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -103,7 +103,7 @@ namespace i2p I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len); - I2NPMessage * CreateDeliveryStatusMsg (); + I2NPMessage * CreateDeliveryStatusMsg (uint32_t msgID); I2NPMessage * CreateDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory = false, std::set * excludedPeers = nullptr); diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 9a646e98..d7939d2d 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -1,3 +1,5 @@ +#include +#include "CryptoConst.h" #include "Log.h" #include "LeaseSet.h" @@ -24,10 +26,22 @@ namespace data memcpy (m_EncryptionKey, header->encryptionKey, 256); LogPrint ("LeaseSet num=", (int)header->num); + const uint8_t * leases = buf + sizeof (H); for (int i = 0; i < header->num; i++) { - m_Leases.push_back (*(Lease *)(buf + sizeof (H))); + Lease lease = *(Lease *)leases; + lease.tunnelID = be32toh (lease.tunnelID); + m_Leases.push_back (lease); + leases += sizeof (Lease); } + + // verify + CryptoPP::DSA::PublicKey pubKey; + pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, + CryptoPP::Integer (m_Identity.signingKey, 128)); + CryptoPP::DSA::Verifier verifier (pubKey); + if (!verifier.VerifyMessage (buf, leases - buf, leases, 40)) + LogPrint ("LeaseSet verification failed"); } } } diff --git a/Streaming.cpp b/Streaming.cpp index 05d9933c..73f2ff8a 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -91,7 +91,7 @@ namespace stream size += len; // payload m_LocalDestination->Sign (packet, size, signature); I2NPMessage * msg = i2p::garlic::routing.WrapSingleMessage (m_RemoteLeaseSet, - CreateDataMessage (this, packet, size), m_LocalDestination->CreateLeaseSet ()); + CreateDataMessage (this, packet, size), m_LocalDestination->GetLeaseSet ()); auto outbound = i2p::tunnel::tunnels.GetNextOutboundTunnel (); if (outbound) @@ -106,7 +106,7 @@ namespace stream StreamingDestination * sharedLocalDestination = nullptr; - StreamingDestination::StreamingDestination () + StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr) { // TODO: read from file later m_Keys = i2p::data::CreateRandomKeys (); @@ -115,6 +115,12 @@ namespace stream m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); } + + StreamingDestination::~StreamingDestination () + { + if (m_LeaseSet) + DeleteI2NPMessage (m_LeaseSet); + } void StreamingDestination::HandleNextPacket (const uint8_t * buf, size_t len) { @@ -141,6 +147,15 @@ namespace stream delete stream; } } + + I2NPMessage * StreamingDestination::GetLeaseSet () + { + if (!m_LeaseSet) + m_LeaseSet = CreateLeaseSet (); + else + FillI2NPMessageHeader (m_LeaseSet, eI2NPDatabaseStore); // refresh msgID + return m_LeaseSet; + } I2NPMessage * StreamingDestination::CreateLeaseSet () const { diff --git a/Streaming.h b/Streaming.h index c3c97bd8..86aeac31 100644 --- a/Streaming.h +++ b/Streaming.h @@ -52,15 +52,20 @@ namespace stream public: StreamingDestination (); - + ~StreamingDestination (); + const i2p::data::Keys& GetKeys () const { return m_Keys; }; const i2p::data::Identity& GetIdentity () const { return m_Identity; }; - I2NPMessage * CreateLeaseSet () const; + I2NPMessage * GetLeaseSet (); void Sign (uint8_t * buf, int len, uint8_t * signature) const; Stream * CreateNewStream (const i2p::data::LeaseSet * remote); void DeleteStream (Stream * stream); void HandleNextPacket (const uint8_t * buf, size_t len); + + private: + + I2NPMessage * CreateLeaseSet () const; private: @@ -69,6 +74,8 @@ namespace stream i2p::data::Identity m_Identity; i2p::data::IdentHash m_IdentHash; + I2NPMessage * m_LeaseSet; + CryptoPP::DSA::PrivateKey m_SigningPrivateKey; };