From d25206abcefff1c914ee16adad8229197f14ca3b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Feb 2024 19:46:29 -0500 Subject: [PATCH] encrypted tunnel test messages --- libi2pd/Destination.cpp | 5 ++-- libi2pd/ECIESX25519AEADRatchetSession.cpp | 8 +++++- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/RouterContext.cpp | 7 +++++ libi2pd/TunnelPool.cpp | 33 ++++++++++++++++------- libi2pd/TunnelPool.h | 1 + 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ef0d5db3..64e5d085 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -367,8 +367,9 @@ namespace client HandleDataMessage (payload, len); break; case eI2NPDeliveryStatus: - // we assume tunnel tests non-encrypted - HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET)); + // try tunnel test first + if (!m_Pool || !m_Pool->ProcessDeliveryStatus (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET), bufbe64toh (payload + DELIVERY_STATUS_TIMESTAMP_OFFSET))) + HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET)); break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (payload, len); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 3513b7ac..b4730d0e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1154,7 +1154,7 @@ namespace garlic return len; } - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -1174,6 +1174,12 @@ namespace garlic htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); + if (msg->onDrop) + { + // move onDrop to the wrapping I2NP messages + m->onDrop = msg->onDrop; + msg->onDrop = nullptr; + } return m; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 030e2c45..e6deb2bc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -247,7 +247,7 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_CurrentNoiseState; }; - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey); } } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 864d2c61..2c1dc979 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1152,6 +1152,13 @@ namespace i2p bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { + if (typeID == eI2NPDeliveryStatus) + { + // try tunnel test + auto pool = GetTunnelPool (); + if (pool && pool->ProcessDeliveryStatus (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET), bufbe64toh (payload + DELIVERY_STATUS_TIMESTAMP_OFFSET))) + return true; + } auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index c342d546..898a05bc 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -13,6 +13,7 @@ #include "NetDb.hpp" #include "Timestamp.h" #include "Garlic.h" +#include "ECIESX25519AEADRatchetSession.h" #include "Transports.h" #include "Log.h" #include "Tunnel.h" @@ -383,6 +384,7 @@ namespace tunnel newTests.push_back(std::make_pair (*it1, *it2)); ++it1; ++it2; } + bool encrypt = m_LocalDestination ? m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) : false; for (auto& it: newTests) { uint32_t msgID; @@ -407,6 +409,14 @@ namespace tunnel s->m_OutboundTunnels.erase (outbound); } }; + if (encrypt) + { + // encrypt + uint8_t key[32]; RAND_bytes (key, 32); + uint64_t tag; RAND_bytes ((uint8_t *)&tag, 8); + m_LocalDestination->SubmitECIESx25519Key (key, tag); + msg = i2p::garlic::WrapECIESX25519Message (msg, key, tag); + } outbound->SendTunnelDataMsgTo (it.second->GetNextIdentHash (), it.second->GetNextTunnelID (), msg); } } @@ -436,6 +446,17 @@ namespace tunnel buf += 4; uint64_t timestamp = bufbe64toh (buf); + if (!ProcessDeliveryStatus (msgID, timestamp)) + { + if (m_LocalDestination) + m_LocalDestination->ProcessDeliveryStatusMessage (msg); + else + LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); + } + } + + bool TunnelPool::ProcessDeliveryStatus (uint32_t msgID, uint64_t timestamp) + { decltype(m_Tests)::mapped_type test; bool found = false; { @@ -477,15 +498,9 @@ namespace tunnel test.second->AddLatencySample(latency); } } - else - { - if (m_LocalDestination) - m_LocalDestination->ProcessDeliveryStatusMessage (msg); - else - LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); - } - } - + return found; + } + bool TunnelPool::IsExploratory () const { return i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this (); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index d9f5966d..3e845c0e 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -85,6 +85,7 @@ namespace tunnel void ManageTunnels (uint64_t ts); void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatus (std::shared_ptr msg); + bool ProcessDeliveryStatus (uint32_t msgID, uint64_t timestamp); bool IsExploratory () const; bool IsActive () const { return m_IsActive; };