diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5dd78747..c57553d4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -38,6 +38,7 @@ namespace garlic { i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; + if (m_NextIndex >= 65535) m_NextIndex = 0; // TODO: dirty hack, should create new tagset return m_KeyData.GetTag (); } @@ -178,7 +179,7 @@ namespace garlic return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, int index) { size_t offset = 0; while (offset < len) @@ -207,6 +208,12 @@ namespace garlic case eECIESx25519BlkPadding: LogPrint (eLogDebug, "Garlic: padding"); break; + case eECIESx25519BlkAckRequest: + { + LogPrint (eLogDebug, "Garlic: ack request"); + m_AckRequests.push_back ( {bufbe16toh (buf + offset), index}); + break; + } default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } @@ -401,7 +408,7 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - HandlePayload (payload.data (), len - 16); + HandlePayload (payload.data (), len - 16, index); if (m_ReceiveTagset.GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); return true; @@ -478,6 +485,8 @@ namespace garlic SetLeaseSetSubmissionTime (ts); GetOwner ()->DeliveryStatusSent (shared_from_this (), leaseSet->GetMsgID ()); } + if (m_AckRequests.size () > 0) + payloadLen += m_AckRequests.size ()*4 + 3; uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -497,6 +506,18 @@ namespace garlic // msg if (msg && m_Destination) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + // ack + if (m_AckRequests.size () > 0) + { + v[offset] = eECIESx25519BlkAck; offset++; + htobe16buf (v.data () + offset, m_AckRequests.size ()*4); offset += 2; + for (auto& it: m_AckRequests) + { + htobe16buf (v.data () + offset, it.first); offset += 2; + htobe16buf (v.data () + offset, it.second); offset += 2; + } + m_AckRequests.clear (); + } // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 95875013..56fb48cf 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "Identity.h" #include "Crypto.h" #include "Garlic.h" @@ -51,6 +52,8 @@ namespace garlic eECIESx25519BlkTermination = 4, eECIESx25519BlkOptions = 5, eECIESx25519BlkNextSessionKey = 7, + eECIESx25519BlkAck = 8, + eECIESx25519BlkAckRequest = 9, eECIESx25519BlkGalicClove = 11, eECIESx25519BlkPadding = 254 }; @@ -99,7 +102,7 @@ namespace garlic bool HandleNewIncomingSession (const uint8_t * buf, size_t len); bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len); bool HandleExistingSessionMessage (const uint8_t * buf, size_t len, int index); - void HandlePayload (const uint8_t * buf, size_t len); + void HandlePayload (const uint8_t * buf, size_t len, int index = 0); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); @@ -120,6 +123,7 @@ namespace garlic uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; std::unique_ptr m_Destination;// TODO: might not need it + std::list > m_AckRequests; // (key_id, indeX) }; } }