Browse Source

handle ECIESFlag in DatabaseLookup at floodfill

pull/1502/head
orignal 5 years ago
parent
commit
4e1319d874
  1. 35
      libi2pd/ECIESX25519AEADRatchetSession.cpp
  2. 2
      libi2pd/ECIESX25519AEADRatchetSession.h
  3. 1
      libi2pd/I2NPProtocol.h
  4. 15
      libi2pd/NetDb.cpp

35
libi2pd/ECIESX25519AEADRatchetSession.cpp

@ -623,6 +623,41 @@ namespace garlic
CleanupUnconfirmedLeaseSet (ts); CleanupUnconfirmedLeaseSet (ts);
return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT;
} }
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
{
auto m = NewI2NPMessage ();
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
uint8_t nonce[12];
memset (nonce, 0, 12); // n = 0
size_t offset = 0;
memcpy (buf + offset, &tag, 8); offset += 8;
auto payload = buf + offset;
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
size_t len = cloveSize + 3;
payload[0] = eECIESx25519BlkGalicClove; // clove type
htobe16buf (payload + 1, cloveSize); // size
payload += 3;
*payload = 0; payload++; // flag and delivery instructions
*payload = msg->GetTypeID (); // I2NP msg type
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
htobe32buf (payload + 5, msg->GetExpiration ()/1000); // expiration in seconds
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt
{
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
return nullptr;
}
offset += len + 16;
htobe32buf (m->GetPayload (), offset);
m->len += offset + 4;
m->FillI2NPMessageHeader (eI2NPGarlic);
return m;
}
} }
} }

2
libi2pd/ECIESX25519AEADRatchetSession.h

@ -128,6 +128,8 @@ namespace garlic
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
std::list<std::pair<uint16_t, int> > m_AckRequests; // (tagsetid, index) std::list<std::pair<uint16_t, int> > m_AckRequests; // (tagsetid, index)
}; };
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);
} }
} }

1
libi2pd/I2NPProtocol.h

@ -95,6 +95,7 @@ namespace i2p
// DatabaseLookup flags // DatabaseLookup flags
const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01; const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01;
const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02; const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02;
const uint8_t DATABASE_LOOKUP_ECIES_FLAG = 0x10;
const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C; const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C;
const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0; const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0;
const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04; // 0100 const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04; // 0100

15
libi2pd/NetDb.cpp

@ -15,8 +15,9 @@
#include "NTCP2.h" #include "NTCP2.h"
#include "RouterContext.h" #include "RouterContext.h"
#include "Garlic.h" #include "Garlic.h"
#include "NetDb.hpp" #include "ECIESX25519AEADRatchetSession.h"
#include "Config.h" #include "Config.h"
#include "NetDb.hpp"
using namespace i2p::transport; using namespace i2p::transport;
@ -948,11 +949,21 @@ namespace data
const uint8_t * sessionKey = excluded; const uint8_t * sessionKey = excluded;
const uint8_t numTags = excluded[32]; const uint8_t numTags = excluded[32];
if (numTags) if (numTags)
{
if (flag & DATABASE_LOOKUP_ECIES_FLAG)
{
uint64_t tag;
memcpy (&tag, excluded + 33, 8);
replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag);
}
else
{ {
const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag
i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag);
replyMsg = garlic.WrapSingleMessage (replyMsg); replyMsg = garlic.WrapSingleMessage (replyMsg);
if(replyMsg == nullptr) LogPrint(eLogError, "NetDb: failed to wrap message"); }
if (!replyMsg)
LogPrint (eLogError, "NetDb: failed to wrap message");
} }
else else
LogPrint(eLogWarning, "NetDb: encrypted reply requested but no tags provided"); LogPrint(eLogWarning, "NetDb: encrypted reply requested but no tags provided");

Loading…
Cancel
Save