mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-06-21 21:38:20 +02:00
don't verify signature in incoming SYN packet if came from ECIESx25519 session. Compare static key instead
Some checks are pending
Build Debian packages / bookworm (push) Waiting to run
Build Debian packages / bullseye (push) Waiting to run
Build Debian packages / buster (push) Waiting to run
Build on FreeBSD / with UPnP (push) Waiting to run
Build on OSX / With USE_UPNP=no (push) Waiting to run
Build on OSX / With USE_UPNP=yes (push) Waiting to run
Build on Windows / clang-x86_64 (push) Waiting to run
Build on Windows / i686 (push) Waiting to run
Build on Windows / ucrt-x86_64 (push) Waiting to run
Build on Windows / x86_64 (push) Waiting to run
Build on Windows / CMake clang-x86_64 (push) Waiting to run
Build on Windows / CMake i686 (push) Waiting to run
Build on Windows / CMake ucrt-x86_64 (push) Waiting to run
Build on Windows / CMake x86_64 (push) Waiting to run
Build on Windows / XP (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=no (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=yes (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Waiting to run
Build containers / Building container for linux/386 (push) Waiting to run
Build containers / Building container for linux/amd64 (push) Waiting to run
Build containers / Building container for linux/arm64 (push) Waiting to run
Build containers / Building container for linux/arm/v7 (push) Waiting to run
Build containers / Pushing merged manifest (push) Blocked by required conditions
Some checks are pending
Build Debian packages / bookworm (push) Waiting to run
Build Debian packages / bullseye (push) Waiting to run
Build Debian packages / buster (push) Waiting to run
Build on FreeBSD / with UPnP (push) Waiting to run
Build on OSX / With USE_UPNP=no (push) Waiting to run
Build on OSX / With USE_UPNP=yes (push) Waiting to run
Build on Windows / clang-x86_64 (push) Waiting to run
Build on Windows / i686 (push) Waiting to run
Build on Windows / ucrt-x86_64 (push) Waiting to run
Build on Windows / x86_64 (push) Waiting to run
Build on Windows / CMake clang-x86_64 (push) Waiting to run
Build on Windows / CMake i686 (push) Waiting to run
Build on Windows / CMake ucrt-x86_64 (push) Waiting to run
Build on Windows / CMake x86_64 (push) Waiting to run
Build on Windows / XP (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=no (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=yes (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Waiting to run
Build containers / Building container for linux/386 (push) Waiting to run
Build containers / Building container for linux/amd64 (push) Waiting to run
Build containers / Building container for linux/arm64 (push) Waiting to run
Build containers / Building container for linux/arm/v7 (push) Waiting to run
Build containers / Pushing merged manifest (push) Blocked by required conditions
This commit is contained in:
parent
5f0262ea2f
commit
78357c23d2
6 changed files with 70 additions and 35 deletions
|
@ -388,7 +388,7 @@ namespace client
|
||||||
switch (typeID)
|
switch (typeID)
|
||||||
{
|
{
|
||||||
case eI2NPData:
|
case eI2NPData:
|
||||||
HandleDataMessage (payload, len);
|
HandleDataMessage (payload, len, from);
|
||||||
break;
|
break;
|
||||||
case eI2NPDeliveryStatus:
|
case eI2NPDeliveryStatus:
|
||||||
HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET));
|
HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET));
|
||||||
|
@ -1158,7 +1158,8 @@ namespace client
|
||||||
LogPrint(eLogDebug, "Destination: -> Stopping done");
|
LogPrint(eLogDebug, "Destination: -> Stopping done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len)
|
void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len,
|
||||||
|
i2p::garlic::ECIESX25519AEADRatchetSession * from)
|
||||||
{
|
{
|
||||||
uint32_t length = bufbe32toh (buf);
|
uint32_t length = bufbe32toh (buf);
|
||||||
if(length > len - 4)
|
if(length > len - 4)
|
||||||
|
@ -1183,7 +1184,7 @@ namespace client
|
||||||
m_LastPort = toPort;
|
m_LastPort = toPort;
|
||||||
}
|
}
|
||||||
if (m_LastStreamingDestination)
|
if (m_LastStreamingDestination)
|
||||||
m_LastStreamingDestination->HandleDataMessagePayload (buf, length);
|
m_LastStreamingDestination->HandleDataMessagePayload (buf, length, from);
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Destination: Missing streaming destination");
|
LogPrint (eLogError, "Destination: Missing streaming destination");
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,7 @@ namespace client
|
||||||
virtual void CleanupDestination () {}; // additional clean up in derived classes
|
virtual void CleanupDestination () {}; // additional clean up in derived classes
|
||||||
virtual i2p::data::CryptoKeyType GetPreferredCryptoType () const = 0;
|
virtual i2p::data::CryptoKeyType GetPreferredCryptoType () const = 0;
|
||||||
// I2CP
|
// I2CP
|
||||||
virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0;
|
virtual void HandleDataMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from) = 0;
|
||||||
virtual void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) = 0;
|
virtual void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -288,7 +288,7 @@ namespace client
|
||||||
void CleanupDestination () override;
|
void CleanupDestination () override;
|
||||||
i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; }
|
i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; }
|
||||||
// I2CP
|
// I2CP
|
||||||
void HandleDataMessage (const uint8_t * buf, size_t len) override;
|
void HandleDataMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from) override;
|
||||||
void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) override;
|
void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -397,6 +397,7 @@ namespace stream
|
||||||
optionData += 2;
|
optionData += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sessionVerified = false;
|
||||||
if (flags & PACKET_FLAG_FROM_INCLUDED)
|
if (flags & PACKET_FLAG_FROM_INCLUDED)
|
||||||
{
|
{
|
||||||
if (m_RemoteLeaseSet) m_RemoteIdentity = m_RemoteLeaseSet->GetIdentity ();
|
if (m_RemoteLeaseSet) m_RemoteIdentity = m_RemoteLeaseSet->GetIdentity ();
|
||||||
|
@ -409,7 +410,29 @@ namespace stream
|
||||||
}
|
}
|
||||||
optionData += m_RemoteIdentity->GetFullLen ();
|
optionData += m_RemoteIdentity->GetFullLen ();
|
||||||
if (!m_RemoteLeaseSet)
|
if (!m_RemoteLeaseSet)
|
||||||
LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
{
|
||||||
|
LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase32 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
||||||
|
if (packet->from)
|
||||||
|
{
|
||||||
|
// stream came from ratchets session and static key must match one from LeaseSet
|
||||||
|
m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());
|
||||||
|
if (!m_RemoteLeaseSet)
|
||||||
|
{
|
||||||
|
LogPrint (eLogInfo, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase32 (),
|
||||||
|
" without LeaseSet. sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint8_t staticKey[32];
|
||||||
|
m_RemoteLeaseSet->Encrypt (nullptr, staticKey);
|
||||||
|
if (memcmp (packet->from->GetRemoteStaticKey (), staticKey, 32))
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Streaming: Remote LeaseSet static key mismatch for incoming stream from ",
|
||||||
|
m_RemoteIdentity->GetIdentHash ().ToBase32 ());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sessionVerified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED)
|
if (flags & PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED)
|
||||||
|
@ -451,13 +474,16 @@ namespace stream
|
||||||
|
|
||||||
if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
|
if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
|
||||||
{
|
{
|
||||||
bool verified = false;
|
|
||||||
auto signatureLen = m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : m_RemoteIdentity->GetSignatureLen ();
|
auto signatureLen = m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : m_RemoteIdentity->GetSignatureLen ();
|
||||||
if (signatureLen > packet->GetLength ())
|
if (signatureLen > packet->GetLength ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Streaming: Signature too big, ", signatureLen, " bytes");
|
LogPrint (eLogError, "Streaming: Signature too big, ", signatureLen, " bytes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool verified = sessionVerified;
|
||||||
|
if (!verified) // packet was not verified through session
|
||||||
|
{
|
||||||
|
// verify actual signature
|
||||||
if (signatureLen <= 256)
|
if (signatureLen <= 256)
|
||||||
{
|
{
|
||||||
// standard
|
// standard
|
||||||
|
@ -480,6 +506,7 @@ namespace stream
|
||||||
m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ()) :
|
m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ()) :
|
||||||
m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ());
|
m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (verified)
|
if (verified)
|
||||||
optionData += signatureLen;
|
optionData += signatureLen;
|
||||||
else
|
else
|
||||||
|
@ -812,7 +839,7 @@ namespace stream
|
||||||
{
|
{
|
||||||
// initial packet
|
// initial packet
|
||||||
m_Status = eStreamStatusOpen;
|
m_Status = eStreamStatusOpen;
|
||||||
if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());;
|
if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());
|
||||||
if (m_RemoteLeaseSet)
|
if (m_RemoteLeaseSet)
|
||||||
{
|
{
|
||||||
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true, !m_IsIncoming);
|
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true, !m_IsIncoming);
|
||||||
|
@ -2054,14 +2081,18 @@ namespace stream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamingDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len)
|
void StreamingDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len,
|
||||||
|
i2p::garlic::ECIESX25519AEADRatchetSession * from)
|
||||||
{
|
{
|
||||||
// unzip it
|
// unzip it
|
||||||
Packet * uncompressed = NewPacket ();
|
Packet * uncompressed = NewPacket ();
|
||||||
uncompressed->offset = 0;
|
uncompressed->offset = 0;
|
||||||
uncompressed->len = m_Inflator.Inflate (buf, len, uncompressed->buf, MAX_PACKET_SIZE);
|
uncompressed->len = m_Inflator.Inflate (buf, len, uncompressed->buf, MAX_PACKET_SIZE);
|
||||||
if (uncompressed->len)
|
if (uncompressed->len)
|
||||||
|
{
|
||||||
|
uncompressed->from = from;
|
||||||
HandleNextPacket (uncompressed);
|
HandleNextPacket (uncompressed);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
DeletePacket (uncompressed);
|
DeletePacket (uncompressed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "Garlic.h"
|
#include "Garlic.h"
|
||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
#include "util.h" // MemoryPool
|
#include "util.h" // MemoryPool
|
||||||
|
#include "ECIESX25519AEADRatchetSession.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -88,8 +89,9 @@ namespace stream
|
||||||
uint8_t buf[MAX_PACKET_SIZE];
|
uint8_t buf[MAX_PACKET_SIZE];
|
||||||
uint64_t sendTime;
|
uint64_t sendTime;
|
||||||
bool resent;
|
bool resent;
|
||||||
|
i2p::garlic::ECIESX25519AEADRatchetSession * from;
|
||||||
|
|
||||||
Packet (): len (0), offset (0), sendTime (0), resent (false) {};
|
Packet (): len (0), offset (0), sendTime (0), resent (false), from (nullptr) {};
|
||||||
uint8_t * GetBuffer () { return buf + offset; };
|
uint8_t * GetBuffer () { return buf + offset; };
|
||||||
size_t GetLength () const { return len > offset ? len - offset : 0; };
|
size_t GetLength () const { return len > offset ? len - offset : 0; };
|
||||||
|
|
||||||
|
@ -340,7 +342,7 @@ namespace stream
|
||||||
void SetOwner (std::shared_ptr<i2p::client::ClientDestination> owner) { m_Owner = owner; };
|
void SetOwner (std::shared_ptr<i2p::client::ClientDestination> owner) { m_Owner = owner; };
|
||||||
uint16_t GetLocalPort () const { return m_LocalPort; };
|
uint16_t GetLocalPort () const { return m_LocalPort; };
|
||||||
|
|
||||||
void HandleDataMessagePayload (const uint8_t * buf, size_t len);
|
void HandleDataMessagePayload (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from);
|
||||||
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort, bool checksum = true, bool gzip = false);
|
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort, bool checksum = true, bool gzip = false);
|
||||||
|
|
||||||
Packet * NewPacket () { return m_PacketsPool.Acquire(); }
|
Packet * NewPacket () { return m_PacketsPool.Acquire(); }
|
||||||
|
|
|
@ -86,7 +86,8 @@ namespace client
|
||||||
return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len)
|
void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len,
|
||||||
|
i2p::garlic::ECIESX25519AEADRatchetSession * from)
|
||||||
{
|
{
|
||||||
uint32_t length = bufbe32toh (buf);
|
uint32_t length = bufbe32toh (buf);
|
||||||
if (length > len - 4) length = len - 4;
|
if (length > len - 4) length = len - 4;
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace client
|
||||||
void CleanupDestination () override;
|
void CleanupDestination () override;
|
||||||
i2p::data::CryptoKeyType GetPreferredCryptoType () const override;
|
i2p::data::CryptoKeyType GetPreferredCryptoType () const override;
|
||||||
// I2CP
|
// I2CP
|
||||||
void HandleDataMessage (const uint8_t * buf, size_t len) override;
|
void HandleDataMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from) override;
|
||||||
void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) override;
|
void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue