Browse Source

pass secret to encrypted LeaseSet2

pull/1362/head
orignal 6 years ago
parent
commit
347a5f7346
  1. 40
      libi2pd/LeaseSet.cpp
  2. 4
      libi2pd/LeaseSet.h

40
libi2pd/LeaseSet.cpp

@ -1,5 +1,4 @@
#include <string.h> #include <string.h>
#include <unordered_map>
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Crypto.h" #include "Crypto.h"
#include "Log.h" #include "Log.h"
@ -257,15 +256,15 @@ namespace data
{ {
SetBuffer (buf, len); SetBuffer (buf, len);
if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
ReadFromBufferEncrypted (buf, len, nullptr); ReadFromBufferEncrypted (buf, len, nullptr, nullptr);
else else
ReadFromBuffer (buf, len); ReadFromBuffer (buf, len);
} }
LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key): LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key, const uint8_t * secret):
LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_OrigStoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_OrigStoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
{ {
ReadFromBufferEncrypted (buf, len, key); ReadFromBufferEncrypted (buf, len, key, secret);
} }
void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature) void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature)
@ -422,7 +421,7 @@ namespace data
return offset; return offset;
} }
void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key) void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key, const uint8_t * secret)
{ {
size_t offset = 0; size_t offset = 0;
// blinded key // blinded key
@ -503,7 +502,7 @@ namespace data
// innerSalt = innerCiphertext[0:32] // innerSalt = innerCiphertext[0:32]
// keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44) // keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44)
uint8_t innerInput[68]; uint8_t innerInput[68];
size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, nullptr /*TODO*/, subcredential, innerInput); size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, secret, subcredential, innerInput);
if (authDataLen > 0) if (authDataLen > 0)
{ {
memcpy (innerInput + 32, subcredential, 36); memcpy (innerInput + 32, subcredential, 36);
@ -538,17 +537,11 @@ namespace data
uint8_t flag = buf[offset]; offset++; // flag uint8_t flag = buf[offset]; offset++; // flag
if (flag & 0x01) // client auth if (flag & 0x01) // client auth
{ {
if (flag & 0x0E) // PSK, bits 3-1 are set to 1 if ((flag & 0x0E) == 0x0E) // PSK, bits 3-1 are set to 1
{ {
const uint8_t * authSalt = buf + offset; authSalt += 32; // authSalt const uint8_t * authSalt = buf + offset; authSalt += 32; // authSalt
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
std::unordered_map<uint64_t, i2p::data::Tag<32> > authClients; const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
for (int i = 0; i < numClients; i++)
{
uint64_t clientID = buf64toh (buf + offset); offset += 8; // clientID_i, don't care about endianess
authClients.emplace (clientID, buf + offset);
offset += 32; // clientCookie_i
}
// calculate authCookie // calculate authCookie
if (secret) if (secret)
{ {
@ -557,14 +550,21 @@ namespace data
memcpy (authInput, subcredential, 36); memcpy (authInput, subcredential, 36);
uint8_t okm[64]; // 52 actual data uint8_t okm[64]; // 52 actual data
i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm);
uint64_t clientID = buf64toh (okm + 44); // clientID_i = okm[44:51] // try to find clientCookie_i for clientID_i = okm[44:51]
auto it = authClients.find (clientID); bool found = false;
if (it != authClients.end ()) for (int i = 0; i < numClients; i++)
{
if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i
{
// clientKey_i = okm[0:31] // clientKey_i = okm[0:31]
// clientIV_i = okm[32:43] // clientIV_i = okm[32:43]
i2p::crypto::ChaCha20 (it->second, 32, okm, okm + 32, authCookie); i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i
else found = true;
LogPrint (eLogError, "LeaseSet2: Client cookie for clientID_i ", clientID, " not found"); break;
}
}
if (!found)
LogPrint (eLogError, "LeaseSet2: Client cookie not found");
} }
else else
LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided");

4
libi2pd/LeaseSet.h

@ -135,7 +135,7 @@ namespace data
public: public:
LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true); LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true);
LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key); // store type 5, called from local netdb only LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key, const uint8_t * secret = nullptr); // store type 5, called from local netdb only
uint8_t GetStoreType () const { return m_StoreType; }; uint8_t GetStoreType () const { return m_StoreType; };
uint8_t GetOrigStoreType () const { return m_OrigStoreType; }; uint8_t GetOrigStoreType () const { return m_OrigStoreType; };
uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; };
@ -148,7 +148,7 @@ namespace data
private: private:
void ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity = true, bool verifySignature = true); void ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity = true, bool verifySignature = true);
void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key); void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr<const BlindedPublicKey> key, const uint8_t * secret);
size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len); size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len);
size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len); size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len);

Loading…
Cancel
Save