diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index bdc31dec..2c2ff3d0 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -258,18 +258,23 @@ namespace garlic uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) { - i2p::crypto::X25519Keys k; - k.GenerateKeys (); + m_IsReverseKeyRequested = true; + if (!m_NextReceiveKey) + m_NextReceiveKey.reset (new i2p::crypto::X25519Keys ()); + else + { + if (keyID == m_ReceiveKeyID) return; + else m_ReceiveKeyID++; // TODO + } + m_NextReceiveKey->GenerateKeys (); uint8_t sharedSecret[32], tagsetKey[32]; - k.Agree (buf, sharedSecret); + m_NextReceiveKey->Agree (buf, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared(shared_from_this ()); newTagset->SetTagSetID (1 + keyID + m_ReceiveKeyID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, GetOwner ()->GetNumTags ()); - m_ReverseKeys.push_back ({m_ReceiveKeyID, k.GetPublicKey ()}); - m_ReceiveKeyID++; + GenerateMoreReceiveTags (newTagset, GetOwner ()->GetNumTags ()); LogPrint (eLogDebug, "Garlic: next receive tagset ", newTagset->GetTagSetID (), " created"); } else @@ -580,8 +585,8 @@ namespace garlic } if (m_AckRequests.size () > 0) payloadLen += m_AckRequests.size ()*4 + 3; - if (m_ReverseKeys.size () > 0) - payloadLen += m_ReverseKeys.size ()*(3 + 35); + if (m_IsReverseKeyRequested) + payloadLen += 3 + 35; uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -623,16 +628,14 @@ namespace garlic m_AckRequests.clear (); } // next keys - if (m_ReverseKeys.size () > 0) + if (m_IsReverseKeyRequested) { - for (auto& it: m_ReverseKeys) - { - v[offset] = eECIESx25519BlkNextKey; offset++; - htobe16buf (v.data () + offset, 35); offset += 2; - v[offset] = ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG | ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; offset++; // flag - htobe16buf (v.data () + offset, it.first); offset += 2; // keyid - memcpy (v.data () + offset, it.second, 32); offset += 32; // public key - } + v[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (v.data () + offset, 35); offset += 2; + v[offset] = ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG | ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; offset++; // flag + htobe16buf (v.data () + offset, m_ReceiveKeyID); offset += 2; // keyid + memcpy (v.data () + offset, m_NextReceiveKey->GetPublicKey (), 32); offset += 32; // public key + m_IsReverseKeyRequested = false; } // padding v[offset] = eECIESx25519BlkPadding; offset++; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 354b8d74..794571f6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -138,10 +138,11 @@ namespace garlic SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming std::shared_ptr m_SendTagset; - int m_SendKeyID = 0, m_ReceiveKeyID = 0; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) - std::list > > m_ReverseKeys; // (keyid, public key) + int m_SendKeyID = 0, m_ReceiveKeyID = 0; + bool m_IsReverseKeyRequested = false; + std::unique_ptr m_NextReceiveKey; }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag);