diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 154bec98..b8ddf577 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -370,8 +370,8 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { size_t payloadLen = 7; // datatime - if (msg) - payloadLen += msg->GetPayloadLength () + 13; + if (msg && m_Destination) + payloadLen += msg->GetPayloadLength () + 13 + 32; auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); if (leaseSet) payloadLen += leaseSet->GetPayloadLength () + 13; @@ -389,8 +389,8 @@ namespace garlic if (leaseSet) offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); // msg - if (msg) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); + if (msg && m_Destination) + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; @@ -398,18 +398,27 @@ namespace garlic return v; } - size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) { if (!msg) return 0; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + if (isDestination) cloveSize += 32; if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (buf + 1, cloveSize); // size - buf[3] = 0; // flag and delivery instructions - buf[4] = msg->GetTypeID (); // I2NP msg type - htobe32buf (buf + 5, msg->GetMsgID ()); // msgID - htobe32buf (buf + 9, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (buf + 13, msg->GetPayload (), msg->GetPayloadLength ()); + htobe16buf (buf + 1, cloveSize); // size + buf += 3; + if (isDestination) + { + *buf = (eGarlicDeliveryTypeDestination << 5); + memcpy (buf + 1, *m_Destination, 32); buf += 32; + } + else + *buf = 0; + buf++; // flag and delivery instructions + *buf = msg->GetTypeID (); // I2NP msg type + htobe32buf (buf + 1, msg->GetMsgID ()); // msgID + htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); return cloveSize + 3; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index f5cef114..ebe8cf13 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -70,6 +70,11 @@ namespace garlic const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } + void SetDestination (const i2p::data::IdentHash& dest) // TODO: + { + if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); + } + private: void ResetKeys (); @@ -84,7 +89,7 @@ namespace garlic 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); std::vector CreatePayload (std::shared_ptr msg); - size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); + size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); private: @@ -93,6 +98,7 @@ namespace garlic i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; RatchetTagSet m_TagsetAB, m_TagsetBA; + std::unique_ptr m_Destination;// TODO: might not need it }; } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 69ca0335..1b34f99c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -669,6 +669,7 @@ namespace garlic session = std::make_shared (this); session->SetRemoteStaticKey (staticKey); } + session->SetDestination (destination->GetIdentHash ()); // TODO: remove return session; } else @@ -860,8 +861,6 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - auto handleClove = std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, - this, std::placeholders::_1, std::placeholders::_2); uint64_t tag; memcpy (&tag, buf, 8); ECIESX25519AEADRatchetSessionPtr session; @@ -874,7 +873,8 @@ namespace garlic else session = std::make_shared (this); // incoming - if (!session->HandleNextMessage (buf, len, handleClove)) + if (!session->HandleNextMessage (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2))) LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); }