mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	common code for offline signatures
This commit is contained in:
		
							parent
							
								
									f5f4190803
								
							
						
					
					
						commit
						2cac9b03ff
					
				
					 4 changed files with 57 additions and 62 deletions
				
			
		| 
						 | 
				
			
			@ -285,27 +285,15 @@ namespace data
 | 
			
		|||
		uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
 | 
			
		||||
		SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
 | 
			
		||||
		uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags
 | 
			
		||||
		std::unique_ptr<i2p::crypto::Verifier> transientVerifier;
 | 
			
		||||
		if (flags & 0x0001)
 | 
			
		||||
		{
 | 
			
		||||
			// transient key
 | 
			
		||||
			if (offset + 6 >= len) return;
 | 
			
		||||
			const uint8_t * signedData = buf + offset;
 | 
			
		||||
			uint32_t expiresTimestamp = bufbe32toh (buf + offset); offset += 4; // expires timestamp
 | 
			
		||||
			if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ())
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogWarning, "LeaseSet2: transient key expired");
 | 
			
		||||
			m_TransientVerifier = ProcessOfflineSignature (identity, buf, len, offset);
 | 
			
		||||
			if (!m_TransientVerifier)
 | 
			
		||||
			{ 
 | 
			
		||||
				LogPrint (eLogError, "LeaseSet2: offline signature failed");
 | 
			
		||||
				return;
 | 
			
		||||
			}	
 | 
			
		||||
			uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
 | 
			
		||||
			transientVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
 | 
			
		||||
			if (!transientVerifier) return;
 | 
			
		||||
			auto keyLen = transientVerifier->GetPublicKeyLen ();
 | 
			
		||||
			if (offset + keyLen >= len) return;
 | 
			
		||||
			transientVerifier->SetPublicKey (buf + offset); offset += keyLen;
 | 
			
		||||
			if (offset + identity->GetSignatureLen () >= len) return;
 | 
			
		||||
			if (!identity->Verify (signedData, keyLen + 6, buf + offset)) return;
 | 
			
		||||
			offset += identity->GetSignatureLen ();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// type specific part
 | 
			
		||||
		size_t s = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -322,10 +310,10 @@ namespace data
 | 
			
		|||
		}
 | 
			
		||||
		if (!s) return;
 | 
			
		||||
		offset += s;
 | 
			
		||||
		if (verifySignature || transientVerifier)
 | 
			
		||||
		if (verifySignature || m_TransientVerifier)
 | 
			
		||||
		{	
 | 
			
		||||
			// verify signature
 | 
			
		||||
			bool verified = transientVerifier ? VerifySignature (transientVerifier, buf, len, offset) :
 | 
			
		||||
			bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) :
 | 
			
		||||
				VerifySignature (identity, buf, len, offset);	
 | 
			
		||||
			SetIsValid (verified);	
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -443,33 +431,21 @@ namespace data
 | 
			
		|||
		uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
 | 
			
		||||
		SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
 | 
			
		||||
		uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags
 | 
			
		||||
		std::unique_ptr<i2p::crypto::Verifier> transientVerifier;
 | 
			
		||||
		if (flags & 0x0001)
 | 
			
		||||
		{
 | 
			
		||||
			// transient key
 | 
			
		||||
			if (offset + 6 >= len) return;
 | 
			
		||||
			const uint8_t * signedData = buf + offset;
 | 
			
		||||
			uint32_t expiresTimestamp = bufbe32toh (buf + offset); offset += 4; // expires timestamp
 | 
			
		||||
			if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ())
 | 
			
		||||
			m_TransientVerifier = ProcessOfflineSignature (blindedVerifier, buf, len, offset);
 | 
			
		||||
			if (!m_TransientVerifier) 
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogWarning, "LeaseSet2: transient key expired");
 | 
			
		||||
				LogPrint (eLogError, "LeaseSet2: offline signature failed");
 | 
			
		||||
				return;
 | 
			
		||||
			}	
 | 
			
		||||
			uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
 | 
			
		||||
			transientVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
 | 
			
		||||
			if (!transientVerifier) return;
 | 
			
		||||
			auto keyLen = transientVerifier->GetPublicKeyLen ();
 | 
			
		||||
			if (offset + keyLen >= len) return;
 | 
			
		||||
			transientVerifier->SetPublicKey (buf + offset); offset += keyLen;
 | 
			
		||||
			if (offset + blindedVerifier->GetSignatureLen () >= len) return;
 | 
			
		||||
			if (!blindedVerifier->Verify (signedData, keyLen + 6, buf + offset)) return;
 | 
			
		||||
			offset += blindedVerifier->GetSignatureLen ();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// outer ciphertext
 | 
			
		||||
		if (offset + 2 > len) return;
 | 
			
		||||
		uint16_t lenOuterCiphertext = bufbe16toh (buf + offset); offset += 2 + lenOuterCiphertext;		
 | 
			
		||||
		// verify signature
 | 
			
		||||
		bool verified = transientVerifier ? VerifySignature (transientVerifier, buf, len, offset) :
 | 
			
		||||
		bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) :
 | 
			
		||||
			VerifySignature (blindedVerifier, buf, len, offset);	
 | 
			
		||||
		SetIsValid (verified);	
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#include <memory>
 | 
			
		||||
#include "Identity.h"
 | 
			
		||||
#include "Timestamp.h"
 | 
			
		||||
#include "I2PEndian.h"
 | 
			
		||||
 | 
			
		||||
namespace i2p
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +78,8 @@ namespace data
 | 
			
		|||
			bool operator== (const LeaseSet& other) const
 | 
			
		||||
			{ return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); };
 | 
			
		||||
			virtual uint8_t GetStoreType () const { return NETDB_STORE_TYPE_LEASESET; };
 | 
			
		||||
		  
 | 
			
		||||
			virtual std::shared_ptr<const i2p::crypto::Verifier> GetTransientVerifier () const { return nullptr; };		  
 | 
			
		||||
 | 
			
		||||
			// implements RoutingDestination
 | 
			
		||||
			std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; };
 | 
			
		||||
			void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
 | 
			
		||||
| 
						 | 
				
			
			@ -128,8 +130,9 @@ namespace data
 | 
			
		|||
 | 
			
		||||
			LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len,  bool storeLeases = true);
 | 
			
		||||
			uint8_t GetStoreType () const { return m_StoreType; };
 | 
			
		||||
			std::shared_ptr<const i2p::crypto::Verifier> GetTransientVerifier () const { return m_TransientVerifier; };
 | 
			
		||||
			void Update (const uint8_t * buf, size_t len, bool verifySignature);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			// implements RoutingDestination
 | 
			
		||||
			void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,9 +151,31 @@ namespace data
 | 
			
		|||
		private:
 | 
			
		||||
 | 
			
		||||
			uint8_t m_StoreType;
 | 
			
		||||
			std::shared_ptr<i2p::crypto::Verifier> m_TransientVerifier;
 | 
			
		||||
			std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> m_Encryptor; // for standardLS2
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// also called from Streaming.cpp 	
 | 
			
		||||
	template<typename Verifier>
 | 
			
		||||
	std::shared_ptr<i2p::crypto::Verifier> ProcessOfflineSignature (const Verifier& verifier, const uint8_t * buf, size_t len, size_t& offset)
 | 
			
		||||
	{
 | 
			
		||||
		if (offset + 6 >= len) return nullptr;
 | 
			
		||||
		const uint8_t * signedData = buf + offset;
 | 
			
		||||
		uint32_t expiresTimestamp = bufbe32toh (buf + offset); offset += 4; // expires timestamp
 | 
			
		||||
		if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ()) return nullptr;
 | 
			
		||||
		uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
 | 
			
		||||
		std::shared_ptr<i2p::crypto::Verifier> transientVerifier (i2p::data::IdentityEx::CreateVerifier (keyType));
 | 
			
		||||
		if (!transientVerifier) return nullptr;
 | 
			
		||||
		auto keyLen = transientVerifier->GetPublicKeyLen ();
 | 
			
		||||
		if (offset + keyLen >= len) return nullptr;
 | 
			
		||||
		transientVerifier->SetPublicKey (buf + offset); offset += keyLen;
 | 
			
		||||
		if (offset + verifier->GetSignatureLen () >= len) return nullptr;
 | 
			
		||||
		if (!verifier->Verify (signedData, keyLen + 6, buf + offset)) return nullptr;
 | 
			
		||||
		offset += verifier->GetSignatureLen ();	
 | 
			
		||||
		return transientVerifier;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------------
 | 
			
		||||
	class LocalLeaseSet
 | 
			
		||||
	{
 | 
			
		||||
		public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -288,33 +288,27 @@ namespace stream
 | 
			
		|||
				LogPrint (eLogInfo, "Streaming: offline signature without identity");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			const uint8_t * signedData = optionData;
 | 
			
		||||
			uint32_t expiresTimestamp = bufbe32toh (optionData); optionData += 4; // expires timestamp
 | 
			
		||||
			if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ())
 | 
			
		||||
			// if we have it in LeaseSet already we don't neet parse it again
 | 
			
		||||
			if (m_RemoteLeaseSet) m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier ();
 | 
			
		||||
			if (m_TransientVerifier)
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogInfo, "Streaming: offline signature transient key expired");
 | 
			
		||||
				return false;
 | 
			
		||||
				// skip option data
 | 
			
		||||
				optionData += 6; // timestamp and key type
 | 
			
		||||
				optionData += m_TransientVerifier->GetPublicKeyLen (); // public key
 | 
			
		||||
				optionData += m_RemoteIdentity->GetSignatureLen (); // signature
 | 
			
		||||
			}
 | 
			
		||||
			uint16_t keyType = bufbe16toh (optionData); optionData += 2; // key type
 | 
			
		||||
			m_TransientVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType)); 
 | 
			
		||||
			if (!m_TransientVerifier)
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogInfo, "Streaming: Unknown transient key type ", (int)keyType);
 | 
			
		||||
				return false;
 | 
			
		||||
				// transient key
 | 
			
		||||
				size_t offset = 0;
 | 
			
		||||
				m_TransientVerifier = i2p::data::ProcessOfflineSignature (m_RemoteIdentity, optionData, optionSize - (optionData - packet->GetOptionData ()), offset);
 | 
			
		||||
				optionData += offset;
 | 
			
		||||
				if (!m_TransientVerifier) 
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "Streaming: offline signature failed");
 | 
			
		||||
					return false;
 | 
			
		||||
				}				
 | 
			
		||||
			}
 | 
			
		||||
			auto keyLen = m_TransientVerifier->GetPublicKeyLen ();
 | 
			
		||||
			if ((optionData - packet->GetOptionData ()) + keyLen + m_RemoteIdentity->GetSignatureLen () > optionSize)			
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogInfo, "Streaming: Option data is too short ", (int)optionSize);
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			m_TransientVerifier->SetPublicKey (optionData); optionData += keyLen; // key
 | 
			
		||||
			if (!m_RemoteIdentity->Verify (signedData, keyLen + 6, optionData))
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogError, "Streaming: Transient key signature verification failed");
 | 
			
		||||
				return false;
 | 
			
		||||
			}	
 | 
			
		||||
			optionData += m_RemoteIdentity->GetSignatureLen (); // signature
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -218,7 +218,7 @@ namespace stream
 | 
			
		|||
			bool m_IsAckSendScheduled;
 | 
			
		||||
			StreamingDestination& m_LocalDestination;
 | 
			
		||||
			std::shared_ptr<const i2p::data::IdentityEx> m_RemoteIdentity;
 | 
			
		||||
			std::unique_ptr<i2p::crypto::Verifier> m_TransientVerifier; // in case of offline key
 | 
			
		||||
			std::shared_ptr<const i2p::crypto::Verifier> m_TransientVerifier; // in case of offline key
 | 
			
		||||
			std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
 | 
			
		||||
			std::shared_ptr<i2p::garlic::GarlicRoutingSession> m_RoutingSession;
 | 
			
		||||
			std::shared_ptr<const i2p::data::Lease> m_CurrentRemoteLease;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue