From 2b0d1a2190743135f3a412c0d106b2e520e304d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Sep 2020 19:39:18 -0400 Subject: [PATCH] implement DatabaseLookupTagSet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 50 +++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 21 +++++++++- libi2pd/Garlic.cpp | 3 +- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 885dc1fc..aef273ed 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -99,6 +99,56 @@ namespace garlic m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; } + bool RatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + { + auto session = GetSession (); + if (!session) return false; + return session->HandleNextMessage (buf, len, shared_from_this (), index); + } + + DatabaseLookupTagSet::DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key): + RatchetTagSet (nullptr), m_Destination (destination) + { + memcpy (m_Key, key, 32); + Expire (); + } + + bool DatabaseLookupTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + { + if (len < 24) return false; + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + size_t offset = 8; // first 8 bytes is reply tag used as AD + len -= 16; // poly1305 + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len - offset, buf, 8, m_Key, nonce, buf + offset, len - offset, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Lookup reply AEAD decryption failed"); + return false; + } + // we assume 1 I2NP block with delivery type local + if (offset + 3 > len) + { + LogPrint (eLogWarning, "Garlic: Lookup reply is too short ", len); + return false; + } + if (buf[offset] != eECIESx25519BlkGalicClove) + { + LogPrint (eLogWarning, "Garlic: Lookup reply unexpected block ", (int)buf[offset]); + return false; + } + offset++; + auto size = bufbe16toh (buf + offset); + offset += 2; + if (offset + size > len) + { + LogPrint (eLogWarning, "Garlic: Lookup reply block is too long ", size); + return false; + } + if (m_Destination) + m_Destination->HandleECIESx25519GarlicClove (buf + offset, size); + return true; + } + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index c7451b98..af0b5de5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -40,7 +40,7 @@ namespace garlic // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ class ECIESX25519AEADRatchetSession; - class RatchetTagSet + class RatchetTagSet: public std::enable_shared_from_this { public: @@ -61,7 +61,9 @@ namespace garlic void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + virtual bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + + virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); private: @@ -94,6 +96,21 @@ namespace garlic std::shared_ptr m_DummySession; // we need a strong pointer for NS }; + + class DatabaseLookupTagSet: public RatchetTagSet + { + public: + + DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key); + + bool IsIndexExpired (int index) const { return false; }; + bool HandleNextMessage (uint8_t * buf, size_t len, int index); + + private: + + GarlicDestination * m_Destination; + uint8_t m_Key[32]; + }; enum ECIESx25519BlockType { diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 6bdbb630..05d7fd3e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -507,8 +507,7 @@ namespace garlic if (it1 != m_ECIESx25519Tags.end ()) { found = true; - auto session = it1->second.tagset->GetSession (); - if (!session || !session->HandleNextMessage (buf, length, it1->second.tagset, it1->second.index)) + if (!it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it1); }