mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	handle encrypted LS2
This commit is contained in:
		
							parent
							
								
									fdcea5537c
								
							
						
					
					
						commit
						b5596c4596
					
				
					 2 changed files with 67 additions and 9 deletions
				
			
		| 
						 | 
					@ -237,7 +237,10 @@ namespace data
 | 
				
			||||||
		m_StoreType (storeType)
 | 
							m_StoreType (storeType)
 | 
				
			||||||
	{	
 | 
						{	
 | 
				
			||||||
		SetBuffer (buf, len);
 | 
							SetBuffer (buf, len);
 | 
				
			||||||
		ReadFromBuffer (buf, len);
 | 
							if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
 | 
				
			||||||
 | 
								ReadFromBufferEncrypted (buf, len);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ReadFromBuffer (buf, len);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len)
 | 
						void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len)
 | 
				
			||||||
| 
						 | 
					@ -246,7 +249,7 @@ namespace data
 | 
				
			||||||
		auto identity = std::make_shared<IdentityEx>(buf, len);
 | 
							auto identity = std::make_shared<IdentityEx>(buf, len);
 | 
				
			||||||
		SetIdentity (identity);
 | 
							SetIdentity (identity);
 | 
				
			||||||
		size_t offset = identity->GetFullLen ();
 | 
							size_t offset = identity->GetFullLen ();
 | 
				
			||||||
		if (offset + 10 >= len) return;
 | 
							if (offset + 8 >= len) return;
 | 
				
			||||||
		uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; // published timestamp (seconds)
 | 
							uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; // published timestamp (seconds)
 | 
				
			||||||
		uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
 | 
							uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
 | 
				
			||||||
		SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
 | 
							SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
 | 
				
			||||||
| 
						 | 
					@ -264,9 +267,9 @@ namespace data
 | 
				
			||||||
			auto keyLen = offlineVerifier->GetPublicKeyLen ();
 | 
								auto keyLen = offlineVerifier->GetPublicKeyLen ();
 | 
				
			||||||
			if (offset + keyLen >= len) return;
 | 
								if (offset + keyLen >= len) return;
 | 
				
			||||||
			offlineVerifier->SetPublicKey (buf + offset); offset += keyLen;
 | 
								offlineVerifier->SetPublicKey (buf + offset); offset += keyLen;
 | 
				
			||||||
			if (offset + offlineVerifier->GetSignatureLen () >= len) return;
 | 
								if (offset + identity->GetSignatureLen () >= len) return;
 | 
				
			||||||
			if (!identity->Verify (signedData, keyLen + 6, buf + offset)) return;
 | 
								if (!identity->Verify (signedData, keyLen + 6, buf + offset)) return;
 | 
				
			||||||
			offset += offlineVerifier->GetSignatureLen ();
 | 
								offset += identity->GetSignatureLen ();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// type specific part
 | 
							// type specific part
 | 
				
			||||||
		size_t s = 0;
 | 
							size_t s = 0;
 | 
				
			||||||
| 
						 | 
					@ -284,15 +287,23 @@ namespace data
 | 
				
			||||||
		if (!s) return;
 | 
							if (!s) return;
 | 
				
			||||||
		offset += s;
 | 
							offset += s;
 | 
				
			||||||
		// verify signature
 | 
							// verify signature
 | 
				
			||||||
		if (offset + identity->GetSignatureLen () > len) return;
 | 
							bool verified = offlineVerifier ? VerifySignature (offlineVerifier, buf, len, offset) :
 | 
				
			||||||
		uint8_t * buf1 = new uint8_t[offset + 1];
 | 
								VerifySignature (identity, buf, len, offset);	
 | 
				
			||||||
 | 
							SetIsValid (verified);	
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template<typename Verifier>
 | 
				
			||||||
 | 
						bool LeaseSet2::VerifySignature (Verifier& verifier, const uint8_t * buf, size_t len, size_t signatureOffset)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (signatureOffset + verifier->GetSignatureLen () > len) return false;
 | 
				
			||||||
 | 
							uint8_t * buf1 = new uint8_t[signatureOffset + 1];
 | 
				
			||||||
		buf1[0] = m_StoreType;
 | 
							buf1[0] = m_StoreType;
 | 
				
			||||||
		memcpy (buf1 + 1, buf, offset); // TODO: implement it better
 | 
							memcpy (buf1 + 1, buf, signatureOffset); // TODO: implement it better
 | 
				
			||||||
		bool verified = offlineVerifier ? offlineVerifier->Verify (buf1, offset + 1, buf + offset) : identity->Verify (buf1, offset + 1, buf + offset); 
 | 
							bool verified = verifier->Verify (buf1, signatureOffset + 1, buf + signatureOffset); 
 | 
				
			||||||
		delete[] buf1;
 | 
							delete[] buf1;
 | 
				
			||||||
		if (!verified)
 | 
							if (!verified)
 | 
				
			||||||
			LogPrint (eLogWarning, "LeaseSet2: verification failed");
 | 
								LogPrint (eLogWarning, "LeaseSet2: verification failed");
 | 
				
			||||||
		SetIsValid (verified);	
 | 
							return verified;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size_t LeaseSet2::ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len)
 | 
						size_t LeaseSet2::ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len)
 | 
				
			||||||
| 
						 | 
					@ -357,6 +368,48 @@ namespace data
 | 
				
			||||||
		return offset;
 | 
							return offset;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size_t offset = 0;
 | 
				
			||||||
 | 
							// blinded key
 | 
				
			||||||
 | 
							uint16_t blindedKeyType = bufbe16toh (buf + offset); offset += 2;
 | 
				
			||||||
 | 
							std::unique_ptr<i2p::crypto::Verifier> blindedVerifier (i2p::data::IdentityEx::CreateVerifier (blindedKeyType));
 | 
				
			||||||
 | 
							if (!blindedVerifier) return;
 | 
				
			||||||
 | 
							auto blindedKeyLen = blindedVerifier->GetPublicKeyLen ();			
 | 
				
			||||||
 | 
							if (offset + blindedKeyLen >= len) return;
 | 
				
			||||||
 | 
							blindedVerifier->SetPublicKey (buf + offset); offset += blindedKeyLen;
 | 
				
			||||||
 | 
							// expiration
 | 
				
			||||||
 | 
							if (offset + 8 >= len) return;
 | 
				
			||||||
 | 
							uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; // published timestamp (seconds)
 | 
				
			||||||
 | 
							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> offlineVerifier;
 | 
				
			||||||
 | 
							if (flags & 0x0001)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// offline key
 | 
				
			||||||
 | 
								if (offset + 6 >= len) return;
 | 
				
			||||||
 | 
								const uint8_t * signedData = buf + offset;
 | 
				
			||||||
 | 
								offset += 4; // expires timestamp
 | 
				
			||||||
 | 
								uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
 | 
				
			||||||
 | 
								offlineVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
 | 
				
			||||||
 | 
								if (!offlineVerifier) return;
 | 
				
			||||||
 | 
								auto keyLen = offlineVerifier->GetPublicKeyLen ();
 | 
				
			||||||
 | 
								if (offset + keyLen >= len) return;
 | 
				
			||||||
 | 
								offlineVerifier->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 = offlineVerifier ? VerifySignature (offlineVerifier, buf, len, offset) :
 | 
				
			||||||
 | 
								VerifySignature (blindedVerifier, buf, len, offset);	
 | 
				
			||||||
 | 
							SetIsValid (verified);	
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels):
 | 
						LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels):
 | 
				
			||||||
		m_ExpirationTime (0), m_Identity (identity)
 | 
							m_ExpirationTime (0), m_Identity (identity)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,6 +116,7 @@ namespace data
 | 
				
			||||||
	bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
 | 
						bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const uint8_t NETDB_STORE_TYPE_STANDARD_LEASESET2 = 3;
 | 
						const uint8_t NETDB_STORE_TYPE_STANDARD_LEASESET2 = 3;
 | 
				
			||||||
 | 
						const uint8_t NETDB_STORE_TYPE_ENCRYPTED_LEASESET2 = 5;
 | 
				
			||||||
	const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7;
 | 
						const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7;
 | 
				
			||||||
	class LeaseSet2: public LeaseSet
 | 
						class LeaseSet2: public LeaseSet
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -127,9 +128,13 @@ namespace data
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			void ReadFromBuffer (const uint8_t * buf, size_t len);
 | 
								void ReadFromBuffer (const uint8_t * buf, size_t len);
 | 
				
			||||||
 | 
								void ReadFromBufferEncrypted (const uint8_t * buf, size_t len);
 | 
				
			||||||
			size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len);
 | 
								size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len);
 | 
				
			||||||
			size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len);
 | 
								size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								template<typename Verifier>
 | 
				
			||||||
 | 
								bool VerifySignature (Verifier& verifier, const uint8_t * buf, size_t len, size_t signatureOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			uint8_t m_StoreType;
 | 
								uint8_t m_StoreType;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue