From ba79b94e0680c71f47200fc0b0b227a780730705 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 8 Dec 2020 15:16:40 -0500 Subject: [PATCH] try to generate missing ECIESx25519 tag in last tagset --- libi2pd/Garlic.cpp | 35 +++++++++++++++++++++++++++++------ libi2pd/Garlic.h | 3 ++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 9c008bc0..2d08f339 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -487,17 +487,19 @@ namespace garlic buf += 4; // length bool found = false; + uint64_t tag; if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) { - // try ECIESx25519 tag - uint64_t tag; + // try ECIESx25519 tag memcpy (&tag, buf, 8); auto it1 = m_ECIESx25519Tags.find (tag); if (it1 != m_ECIESx25519Tags.end ()) { found = true; - if (!it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + if (it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) + m_LastTagset = it1->second.tagset; + else + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it1); } } @@ -542,7 +544,25 @@ namespace garlic // otherwise ECIESx25519 auto session = std::make_shared (this, false); // incoming if (!session->HandleNextMessage (buf, length, nullptr, 0)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + { + // try to gererate more tags for last tagset + if (m_LastTagset) + { + for (int i = 0; i < ECIESX25519_MAX_NUM_GENERATED_TAGS; i++) + { + LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); + if (AddECIESx25519SessionNextTag (m_LastTagset) == tag) + { + if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[tag].index)) + found = true; + break; + } + } + if (!found) m_LastTagset = nullptr; + } + if (!found) + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + } } else LogPrint (eLogError, "Garlic: Failed to decrypt message"); @@ -845,6 +865,8 @@ namespace garlic } if (numExpiredTags > 0) LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ()); + if (m_LastTagset && m_LastTagset->IsExpired (ts)) + m_LastTagset = nullptr; } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) @@ -1030,11 +1052,12 @@ namespace garlic } } - void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) + uint64_t GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset}); + return tag; } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 8df830c7..379477e8 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -245,7 +245,7 @@ namespace garlic void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); - void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); + uint64_t AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); @@ -285,6 +285,7 @@ namespace garlic int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session + RatchetTagSetPtr m_LastTagset; // tagset last message came for // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session