From 1c162f9fd5b0507feb12f2d9cf0f8cada522597b Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Wed, 16 Apr 2025 21:59:10 -0400
Subject: [PATCH] get preferred crypto key type from ratchets session

---
 libi2pd/Destination.cpp                   | 18 ++++++++++++------
 libi2pd/Destination.h                     |  5 +++--
 libi2pd/ECIESX25519AEADRatchetSession.cpp |  4 ++--
 libi2pd/ECIESX25519AEADRatchetSession.h   |  1 +
 libi2pd/Garlic.cpp                        |  5 +++--
 libi2pd/Garlic.h                          |  5 +++--
 6 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp
index 3d910e54..f89fc0f0 100644
--- a/libi2pd/Destination.cpp
+++ b/libi2pd/Destination.cpp
@@ -13,6 +13,7 @@
 #include <vector>
 #include <boost/algorithm/string.hpp>
 #include "Crypto.h"
+#include "ECIESX25519AEADRatchetSession.h"
 #include "Log.h"
 #include "FS.h"
 #include "Timestamp.h"
@@ -377,10 +378,12 @@ namespace client
 	{
 		I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]);
 		uint32_t msgID = bufbe32toh (buf + I2NP_HEADER_MSGID_OFFSET);
-		LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID);
+		LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, 
+			GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID, nullptr);
 	}
 
-	bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID)
+	bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload,
+		size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from)
 	{
 		switch (typeID)
 		{
@@ -395,7 +398,7 @@ namespace client
 					m_Pool->ProcessTunnelTest (bufbe32toh (payload + TUNNEL_TEST_MSGID_OFFSET), bufbe64toh (payload + TUNNEL_TEST_TIMESTAMP_OFFSET));
 			break;
 			case eI2NPDatabaseStore:
-				HandleDatabaseStoreMessage (payload, len);
+				HandleDatabaseStoreMessage (payload, len, from);
 			break;
 			case eI2NPDatabaseSearchReply:
 				HandleDatabaseSearchReplyMessage (payload, len);
@@ -410,7 +413,8 @@ namespace client
 		return true;
 	}
 
-	void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len)
+	void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len,
+		i2p::garlic::ECIESX25519AEADRatchetSession * from)
 	{
 		if (len < DATABASE_STORE_HEADER_SIZE)
 		{
@@ -465,7 +469,8 @@ namespace client
 					if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET)
 						leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset); // LeaseSet
 					else
-						leaseSet = std::make_shared<i2p::data::LeaseSet2> (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetPreferredCryptoType () ); // LeaseSet2
+						leaseSet = std::make_shared<i2p::data::LeaseSet2> (buf[DATABASE_STORE_TYPE_OFFSET], 
+							buf + offset, len - offset, true, from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType () ); // LeaseSet2
 					if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ())
 					{
 						if (leaseSet->GetIdentHash () != GetIdentHash ())
@@ -494,7 +499,8 @@ namespace client
 					if (request->requestedBlindedKey)
 					{
 						auto ls2 = std::make_shared<i2p::data::LeaseSet2> (buf + offset, len - offset,
-							request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ());
+							request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr, 
+						    from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType ());
 						if (ls2->IsValid () && !ls2->IsExpired ())
 						{
 							leaseSet = ls2;
diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h
index 33e8bf08..abb63af2 100644
--- a/libi2pd/Destination.h
+++ b/libi2pd/Destination.h
@@ -164,7 +164,8 @@ namespace client
 
 			// implements GarlicDestination
 			void HandleI2NPMessage (const uint8_t * buf, size_t len) override;
-			bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) override;
+			bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, 
+				size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from) override;
 
 			void SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet);
 			int GetLeaseSetType () const { return m_LeaseSetType; };
@@ -184,7 +185,7 @@ namespace client
 			void HandlePublishConfirmationTimer (const boost::system::error_code& ecode);
 			void HandlePublishVerificationTimer (const boost::system::error_code& ecode);
 			void HandlePublishDelayTimer (const boost::system::error_code& ecode);
-			void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len);
+			void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from);
 			void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len);
 			void HandleDeliveryStatusMessage (uint32_t msgID);
 
diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp
index d38abd13..266caeaa 100644
--- a/libi2pd/ECIESX25519AEADRatchetSession.cpp
+++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp
@@ -163,7 +163,7 @@ namespace garlic
 			return false;
 		}
 		if (m_Destination)
-			m_Destination->HandleECIESx25519GarlicClove (buf + offset, size);
+			m_Destination->HandleECIESx25519GarlicClove (buf + offset, size, nullptr);
 		return true;
 	}
 
@@ -390,7 +390,7 @@ namespace garlic
 			{
 				case eECIESx25519BlkGalicClove:
 					if (GetOwner ())
-						GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size);
+						GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size, this);
 				break;
 				case eECIESx25519BlkNextKey:
 					LogPrint (eLogDebug, "Garlic: Next key");
diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h
index b7704534..1b810cd0 100644
--- a/libi2pd/ECIESX25519AEADRatchetSession.h
+++ b/libi2pd/ECIESX25519AEADRatchetSession.h
@@ -170,6 +170,7 @@ namespace garlic
 			std::shared_ptr<I2NPMessage> WrapOneTimeMessage (std::shared_ptr<const I2NPMessage> msg);
 
 			const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
+			i2p::data::CryptoKeyType GetRemoteStaticKeyType () const { return m_RemoteStaticKeyType; }
 			void SetRemoteStaticKey (i2p::data::CryptoKeyType keyType, const uint8_t * key) 
 			{ 
 				m_RemoteStaticKeyType = keyType;
diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp
index 5a3e4cae..3675b0b0 100644
--- a/libi2pd/Garlic.cpp
+++ b/libi2pd/Garlic.cpp
@@ -1003,7 +1003,8 @@ namespace garlic
 				i2p::fs::Remove (it);
 	}
 
-	void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
+	void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len,
+		ECIESX25519AEADRatchetSession * from)
 	{
 		const uint8_t * buf1 = buf;
 		uint8_t flag = buf[0]; buf++; // flag
@@ -1023,7 +1024,7 @@ namespace garlic
 				buf += 4; // expiration
 				ptrdiff_t offset = buf - buf1;
 				if (offset <= (int)len)
-					HandleCloveI2NPMessage (typeID, buf, len - offset, msgID);
+					HandleCloveI2NPMessage (typeID, buf, len - offset, msgID, from);
 				else
 					LogPrint (eLogError, "Garlic: Clove is too long");
 				break;
diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h
index 0eef4871..dc6b9bba 100644
--- a/libi2pd/Garlic.h
+++ b/libi2pd/Garlic.h
@@ -257,7 +257,7 @@ namespace garlic
 			uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset);
 			void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
 			void RemoveECIESx25519Session (const uint8_t * staticKey);
-			void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len);
+			void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len, ECIESX25519AEADRatchetSession * from);
 			uint8_t * GetPayloadBuffer ();
 
 			virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
@@ -272,7 +272,8 @@ namespace garlic
 			void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag
 			bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found
 			virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only
-			virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) = 0;
+			virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, 
+				size_t len, uint32_t msgID, ECIESX25519AEADRatchetSession * from) = 0;
 			void HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg);
 			void HandleDeliveryStatusMessage (uint32_t msgID);