Browse Source

handle follow-on NSR messages

pull/1610/head
orignal 4 years ago
parent
commit
7ce92118e4
  1. 36
      libi2pd/ECIESX25519AEADRatchetSession.cpp
  2. 3
      libi2pd/ECIESX25519AEADRatchetSession.h
  3. 14
      libi2pd/util.h

36
libi2pd/ECIESX25519AEADRatchetSession.cpp

@ -9,6 +9,7 @@
#include <string.h> #include <string.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include "Log.h" #include "Log.h"
#include "util.h"
#include "Crypto.h" #include "Crypto.h"
#include "Elligator.h" #include "Elligator.h"
#include "Tag.h" #include "Tag.h"
@ -619,18 +620,15 @@ namespace garlic
} }
buf += 32; len -= 32; buf += 32; len -= 32;
// KDF for Reply Key Section // KDF for Reply Key Section
uint8_t h[32]; memcpy (h, m_H, 32); // save m_H i2p::util::SaveStateHelper<i2p::crypto::NoiseSymmetricState> s(*this); // restore noise state on exit
MixHash (tag, 8); // h = SHA256(h || tag) MixHash (tag, 8); // h = SHA256(h || tag)
MixHash (bepk, 32); // h = SHA256(h || bepk) MixHash (bepk, 32); // h = SHA256(h || bepk)
uint8_t sharedSecret[32]; uint8_t sharedSecret[32];
if (m_State == eSessionStateNewSessionSent) m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk)
{ MixKey (sharedSecret);
// only fist time, we assume ephemeral keys the same GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) MixKey (sharedSecret);
MixKey (sharedSecret);
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
MixKey (sharedSecret);
}
uint8_t nonce[12]; uint8_t nonce[12];
CreateNonce (0, nonce); CreateNonce (0, nonce);
// calculate hash for zero length // calculate hash for zero length
@ -646,6 +644,7 @@ namespace garlic
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
if (m_State == eSessionStateNewSessionSent) if (m_State == eSessionStateNewSessionSent)
{ {
// only first time, then we keep using existing tagsets
// k_ab = keydata[0:31], k_ba = keydata[32:63] // k_ab = keydata[0:31], k_ba = keydata[32:63]
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ()); m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
@ -667,11 +666,10 @@ namespace garlic
if (m_State == eSessionStateNewSessionSent) if (m_State == eSessionStateNewSessionSent)
{ {
m_State = eSessionStateEstablished; m_State = eSessionStateEstablished;
m_EphemeralKeys = nullptr; //m_EphemeralKeys = nullptr; // TODO: delete after a while
m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch ();
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
} }
memcpy (m_H, h, 32); // restore m_H
HandlePayload (buf, len - 16, nullptr, 0); HandlePayload (buf, len - 16, nullptr, 0);
// we have received reply to NS with LeaseSet in it // we have received reply to NS with LeaseSet in it
@ -762,12 +760,16 @@ namespace garlic
[[fallthrough]]; [[fallthrough]];
#endif #endif
case eSessionStateEstablished: case eSessionStateEstablished:
if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; if (receiveTagset->IsNS ())
// check NSR just in case {
LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); // our of sequence NSR
if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2) LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index);
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS); if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2)
return HandleNewOutgoingSessionReply (buf, len); GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS);
return HandleNewOutgoingSessionReply (buf, len);
}
else
return HandleExistingSessionMessage (buf, len, receiveTagset, index);
case eSessionStateNew: case eSessionStateNew:
return HandleNewIncomingSession (buf, len); return HandleNewIncomingSession (buf, len);
case eSessionStateNewSessionSent: case eSessionStateNewSessionSent:

3
libi2pd/ECIESX25519AEADRatchetSession.h

@ -45,6 +45,7 @@ namespace garlic
public: public:
RatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session): m_Session (session) {}; RatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session): m_Session (session) {};
virtual bool IsNS () const { return false; };
void DHInitialize (const uint8_t * rootKey, const uint8_t * k); void DHInitialize (const uint8_t * rootKey, const uint8_t * k);
void NextSessionTagRatchet (); void NextSessionTagRatchet ();
@ -92,6 +93,8 @@ namespace garlic
NSRatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session): NSRatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session):
RatchetTagSet (session), m_DummySession (session) {}; RatchetTagSet (session), m_DummySession (session) {};
bool IsNS () const { return true; };
private: private:
std::shared_ptr<ECIESX25519AEADRatchetSession> m_DummySession; // we need a strong pointer for NS std::shared_ptr<ECIESX25519AEADRatchetSession> m_DummySession; // we need a strong pointer for NS

14
libi2pd/util.h

@ -170,6 +170,20 @@ namespace util
void SetThreadName (const char *name); void SetThreadName (const char *name);
template<typename T>
class SaveStateHelper
{
public:
SaveStateHelper (T& orig): m_Original (orig), m_Copy (orig) {};
~SaveStateHelper () { m_Original = m_Copy; };
private:
T& m_Original;
T m_Copy;
};
namespace net namespace net
{ {
int GetMTU (const boost::asio::ip::address& localAddress); int GetMTU (const boost::asio::ip::address& localAddress);

Loading…
Cancel
Save