encrypted tunnel test messages

This commit is contained in:
orignal 2024-02-21 19:46:29 -05:00
parent 5d7c6fb0b3
commit d25206abce
6 changed files with 43 additions and 13 deletions

View File

@ -367,8 +367,9 @@ namespace client
HandleDataMessage (payload, len); HandleDataMessage (payload, len);
break; break;
case eI2NPDeliveryStatus: case eI2NPDeliveryStatus:
// we assume tunnel tests non-encrypted // try tunnel test first
HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET)); 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; break;
case eI2NPDatabaseStore: case eI2NPDatabaseStore:
HandleDatabaseStoreMessage (payload, len); HandleDatabaseStoreMessage (payload, len);

View File

@ -1154,7 +1154,7 @@ namespace garlic
return len; return len;
} }
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag) std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<I2NPMessage> msg, const uint8_t * key, uint64_t tag)
{ {
auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128); auto m = NewI2NPMessage ((msg ? msg->GetPayloadLength () : 0) + 128);
m->Align (12); // in order to get buf aligned to 16 (12 + 4) m->Align (12); // in order to get buf aligned to 16 (12 + 4)
@ -1174,6 +1174,12 @@ namespace garlic
htobe32buf (m->GetPayload (), offset); htobe32buf (m->GetPayload (), offset);
m->len += offset + 4; m->len += offset + 4;
m->FillI2NPMessageHeader (eI2NPGarlic); m->FillI2NPMessageHeader (eI2NPGarlic);
if (msg->onDrop)
{
// move onDrop to the wrapping I2NP messages
m->onDrop = msg->onDrop;
msg->onDrop = nullptr;
}
return m; return m;
} }

View File

@ -247,7 +247,7 @@ namespace garlic
i2p::crypto::NoiseSymmetricState m_CurrentNoiseState; i2p::crypto::NoiseSymmetricState m_CurrentNoiseState;
}; };
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag); std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<I2NPMessage> msg, const uint8_t * key, uint64_t tag);
std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<I2NPMessage> msg, const uint8_t * routerPublicKey); std::shared_ptr<I2NPMessage> WrapECIESX25519MessageForRouter (std::shared_ptr<I2NPMessage> msg, const uint8_t * routerPublicKey);
} }
} }

View File

@ -1152,6 +1152,13 @@ namespace i2p
bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) 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); auto msg = CreateI2NPMessage (typeID, payload, len, msgID);
if (!msg) return false; if (!msg) return false;
i2p::HandleI2NPMessage (msg); i2p::HandleI2NPMessage (msg);

View File

@ -13,6 +13,7 @@
#include "NetDb.hpp" #include "NetDb.hpp"
#include "Timestamp.h" #include "Timestamp.h"
#include "Garlic.h" #include "Garlic.h"
#include "ECIESX25519AEADRatchetSession.h"
#include "Transports.h" #include "Transports.h"
#include "Log.h" #include "Log.h"
#include "Tunnel.h" #include "Tunnel.h"
@ -383,6 +384,7 @@ namespace tunnel
newTests.push_back(std::make_pair (*it1, *it2)); newTests.push_back(std::make_pair (*it1, *it2));
++it1; ++it2; ++it1; ++it2;
} }
bool encrypt = m_LocalDestination ? m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) : false;
for (auto& it: newTests) for (auto& it: newTests)
{ {
uint32_t msgID; uint32_t msgID;
@ -407,6 +409,14 @@ namespace tunnel
s->m_OutboundTunnels.erase (outbound); 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); outbound->SendTunnelDataMsgTo (it.second->GetNextIdentHash (), it.second->GetNextTunnelID (), msg);
} }
} }
@ -436,6 +446,17 @@ namespace tunnel
buf += 4; buf += 4;
uint64_t timestamp = bufbe64toh (buf); 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; decltype(m_Tests)::mapped_type test;
bool found = false; bool found = false;
{ {
@ -477,15 +498,9 @@ namespace tunnel
test.second->AddLatencySample(latency); test.second->AddLatencySample(latency);
} }
} }
else return found;
{ }
if (m_LocalDestination)
m_LocalDestination->ProcessDeliveryStatusMessage (msg);
else
LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped");
}
}
bool TunnelPool::IsExploratory () const bool TunnelPool::IsExploratory () const
{ {
return i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this (); return i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this ();

View File

@ -85,6 +85,7 @@ namespace tunnel
void ManageTunnels (uint64_t ts); void ManageTunnels (uint64_t ts);
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg); void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessDeliveryStatus (std::shared_ptr<I2NPMessage> msg); void ProcessDeliveryStatus (std::shared_ptr<I2NPMessage> msg);
bool ProcessDeliveryStatus (uint32_t msgID, uint64_t timestamp);
bool IsExploratory () const; bool IsExploratory () const;
bool IsActive () const { return m_IsActive; }; bool IsActive () const { return m_IsActive; };