mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	extract ret code per hop
This commit is contained in:
		
							parent
							
								
									ed0c2e68a5
								
							
						
					
					
						commit
						d73b42b726
					
				
					 3 changed files with 24 additions and 21 deletions
				
			
		| 
						 | 
					@ -103,26 +103,22 @@ namespace tunnel
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records.");
 | 
							LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		i2p::crypto::CBCDecryption decryption;
 | 
					 | 
				
			||||||
		TunnelHopConfig * hop = m_Config->GetLastHop ();
 | 
							TunnelHopConfig * hop = m_Config->GetLastHop ();
 | 
				
			||||||
		while (hop)
 | 
							while (hop)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// decrypt current hop
 | 
								// decrypt current hop
 | 
				
			||||||
			auto idx = hop->recordIndex;
 | 
								if (hop->recordIndex >= 0 && hop->recordIndex < msg[0])
 | 
				
			||||||
			if (idx >= 0 && idx < msg[0])
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE;
 | 
									if (!hop->DecryptBuildResponseRecord (msg + 1))
 | 
				
			||||||
				if (!hop->DecryptBuildResponseRecord (record, record))
 | 
					 | 
				
			||||||
					return false;
 | 
										return false;
 | 
				
			||||||
			}	
 | 
								}	
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range");
 | 
									LogPrint (eLogWarning, "Tunnel: hop index ", hop->recordIndex, " is out of range");
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			}	
 | 
								}	
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// decrypt records before current hop 
 | 
								// decrypt records before current hop 
 | 
				
			||||||
			decryption.SetKey (hop->replyKey);
 | 
					 | 
				
			||||||
			TunnelHopConfig * hop1 = hop->prev;
 | 
								TunnelHopConfig * hop1 = hop->prev;
 | 
				
			||||||
			while (hop1)
 | 
								while (hop1)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -140,8 +136,7 @@ namespace tunnel
 | 
				
			||||||
		hop = m_Config->GetFirstHop ();
 | 
							hop = m_Config->GetFirstHop ();
 | 
				
			||||||
		while (hop)
 | 
							while (hop)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE;
 | 
								uint8_t ret = hop->GetRetCode (msg + 1);
 | 
				
			||||||
			uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET];
 | 
					 | 
				
			||||||
			LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret);
 | 
								LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret);
 | 
				
			||||||
			auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ());
 | 
								auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ());
 | 
				
			||||||
			if (profile)
 | 
								if (profile)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,12 +113,13 @@ namespace tunnel
 | 
				
			||||||
		memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
 | 
							memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
 | 
				
			||||||
	}	
 | 
						}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const
 | 
						bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE;
 | 
				
			||||||
		i2p::crypto::CBCDecryption decryption;
 | 
							i2p::crypto::CBCDecryption decryption;
 | 
				
			||||||
		decryption.SetKey (replyKey);
 | 
							decryption.SetKey (replyKey);
 | 
				
			||||||
		decryption.SetIV (replyIV);
 | 
							decryption.SetIV (replyIV);
 | 
				
			||||||
		decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText);
 | 
							decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record);
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}	
 | 
						}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,11 +177,12 @@ namespace tunnel
 | 
				
			||||||
		memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
 | 
							memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const
 | 
						bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE;
 | 
				
			||||||
		uint8_t nonce[12];
 | 
							uint8_t nonce[12];
 | 
				
			||||||
		memset (nonce, 0, 12);
 | 
							memset (nonce, 0, 12);
 | 
				
			||||||
		if (!DecryptECIES (m_CK, nonce, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText))
 | 
							if (!DecryptECIES (m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE, record))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
 | 
								LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
| 
						 | 
					@ -223,12 +225,13 @@ namespace tunnel
 | 
				
			||||||
		memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
 | 
							memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const
 | 
						bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE;
 | 
				
			||||||
		uint8_t nonce[12];
 | 
							uint8_t nonce[12];
 | 
				
			||||||
		memset (nonce, 0, 12);
 | 
							memset (nonce, 0, 12);
 | 
				
			||||||
		nonce[4] = recordIndex; // nonce is record index
 | 
							nonce[4] = recordIndex; // nonce is record index
 | 
				
			||||||
		if (!DecryptECIES (replyKey, nonce, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText))
 | 
							if (!DecryptECIES (replyKey, nonce, record, SHORT_TUNNEL_BUILD_RECORD_SIZE, record))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
 | 
								LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed");
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,9 +40,9 @@ namespace tunnel
 | 
				
			||||||
		void SetNext (TunnelHopConfig * n);
 | 
							void SetNext (TunnelHopConfig * n);
 | 
				
			||||||
		void SetPrev (TunnelHopConfig * p);		
 | 
							void SetPrev (TunnelHopConfig * p);		
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual bool IsECIES () const { return false; };
 | 
							virtual uint8_t GetRetCode (const uint8_t * records) const = 0;
 | 
				
			||||||
		virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0;
 | 
							virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0;
 | 
				
			||||||
		virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const = 0;
 | 
							virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0;
 | 
				
			||||||
		virtual void DecryptRecord (uint8_t * records, int index) const; // AES
 | 
							virtual void DecryptRecord (uint8_t * records, int index) const; // AES
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,15 +50,16 @@ namespace tunnel
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ElGamalTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
							ElGamalTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
				
			||||||
			TunnelHopConfig (r) {};
 | 
								TunnelHopConfig (r) {};
 | 
				
			||||||
 | 
							uint8_t GetRetCode (const uint8_t * records) const 
 | 
				
			||||||
 | 
							{ return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; };	
 | 
				
			||||||
		void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);	
 | 
							void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);	
 | 
				
			||||||
		bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const;	
 | 
							bool DecryptBuildResponseRecord (uint8_t * records) const;	
 | 
				
			||||||
	};	
 | 
						};	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState
 | 
						struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
							ECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
				
			||||||
			TunnelHopConfig (r) {};
 | 
								TunnelHopConfig (r) {};
 | 
				
			||||||
		bool IsECIES () const { return true; };	
 | 
					 | 
				
			||||||
		void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted);	
 | 
							void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted);	
 | 
				
			||||||
		bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const;
 | 
							bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
| 
						 | 
					@ -67,16 +68,20 @@ namespace tunnel
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		LongECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
							LongECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
				
			||||||
			ECIESTunnelHopConfig (r) {};
 | 
								ECIESTunnelHopConfig (r) {};
 | 
				
			||||||
 | 
							uint8_t GetRetCode (const uint8_t * records) const 
 | 
				
			||||||
 | 
							{ return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; };		
 | 
				
			||||||
		void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);
 | 
							void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);
 | 
				
			||||||
		bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const;		
 | 
							bool DecryptBuildResponseRecord (uint8_t * records) const;		
 | 
				
			||||||
	};	
 | 
						};	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig
 | 
						struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ShortECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
							ShortECIESTunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> r):
 | 
				
			||||||
			ECIESTunnelHopConfig (r) {};
 | 
								ECIESTunnelHopConfig (r) {};
 | 
				
			||||||
 | 
							uint8_t GetRetCode (const uint8_t * records) const 
 | 
				
			||||||
 | 
							{ return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO			
 | 
				
			||||||
		void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);
 | 
							void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx);
 | 
				
			||||||
		bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const;	
 | 
							bool DecryptBuildResponseRecord (uint8_t * records) const;	
 | 
				
			||||||
		void DecryptRecord (uint8_t * records, int index) const override; // Chacha20
 | 
							void DecryptRecord (uint8_t * records, int index) const override; // Chacha20
 | 
				
			||||||
	};	
 | 
						};	
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue