mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	read offline info
This commit is contained in:
		
							parent
							
								
									b6bfd66a49
								
							
						
					
					
						commit
						1fa3ba8b42
					
				
					 2 changed files with 63 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -455,11 +455,49 @@ namespace data
 | 
			
		|||
		memcpy (m_PrivateKey, buf + ret, 256); // private key always 256
 | 
			
		||||
		ret += 256;
 | 
			
		||||
		size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen ();
 | 
			
		||||
		if(signingPrivateKeySize + ret > len) return 0; // overflow
 | 
			
		||||
		if(signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0; // overflow
 | 
			
		||||
		memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize);
 | 
			
		||||
		ret += signingPrivateKeySize;
 | 
			
		||||
		m_Signer = nullptr;
 | 
			
		||||
		CreateSigner ();
 | 
			
		||||
		// check if signing private key is all zeros
 | 
			
		||||
		bool allzeros = true;
 | 
			
		||||
		for (size_t i = 0; i < signingPrivateKeySize; i++)
 | 
			
		||||
			if (m_SigningPrivateKey[i]) 
 | 
			
		||||
			{
 | 
			
		||||
				allzeros = false;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		if (allzeros)
 | 
			
		||||
		{
 | 
			
		||||
			// offline information
 | 
			
		||||
			const uint8_t * offlineInfo = buf + ret;
 | 
			
		||||
			ret += 4; // expires timestamp
 | 
			
		||||
			SigningKeyType keyType = bufbe16toh (buf + ret); ret += 2; // key type
 | 
			
		||||
			std::unique_ptr<i2p::crypto::Verifier> transientVerifier (IdentityEx::CreateVerifier (keyType));
 | 
			
		||||
			if (!transientVerifier) return 0;
 | 
			
		||||
			auto keyLen = transientVerifier->GetPublicKeyLen ();
 | 
			
		||||
			if (keyLen + ret > len) return 0;
 | 
			
		||||
			transientVerifier->SetPublicKey (buf + ret); ret += keyLen;
 | 
			
		||||
			if (m_Public->GetSignatureLen () + ret > len) return 0;
 | 
			
		||||
			if (!m_Public->Verify (offlineInfo, keyLen + 6, buf + ret)) 
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogError, "Identity: offline signature verification failed");
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
			ret += m_Public->GetSignatureLen ();
 | 
			
		||||
			// copy offline signature
 | 
			
		||||
			size_t offlineInfoLen = buf + ret - offlineInfo;
 | 
			
		||||
			m_OfflineSignature.resize (offlineInfoLen);
 | 
			
		||||
			memcpy (m_OfflineSignature.data (), offlineInfo, offlineInfoLen);
 | 
			
		||||
			// override signing private key 
 | 
			
		||||
			signingPrivateKeySize = transientVerifier->GetPrivateKeyLen ();
 | 
			
		||||
			if (signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0;
 | 
			
		||||
			memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize);
 | 
			
		||||
			ret += signingPrivateKeySize;
 | 
			
		||||
			CreateSigner (keyType);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			CreateSigner (m_Public->GetSigningKeyType ());
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -472,6 +510,7 @@ namespace data
 | 
			
		|||
		if(ret + signingPrivateKeySize > len) return 0; // overflow
 | 
			
		||||
		memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize);
 | 
			
		||||
		ret += signingPrivateKeySize;
 | 
			
		||||
		// TODO: implement offline info
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -505,9 +544,17 @@ namespace data
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	void PrivateKeys::CreateSigner () const
 | 
			
		||||
	{
 | 
			
		||||
		if (IsOfflineSignature ())
 | 
			
		||||
			CreateSigner (bufbe16toh (m_OfflineSignature.data () + 4)); // key type
 | 
			
		||||
		else
 | 
			
		||||
			CreateSigner (m_Public->GetSigningKeyType ());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void PrivateKeys::CreateSigner (SigningKeyType keyType) const
 | 
			
		||||
	{
 | 
			
		||||
		if (m_Signer) return;
 | 
			
		||||
		switch (m_Public->GetSigningKeyType ())
 | 
			
		||||
		switch (keyType)
 | 
			
		||||
		{
 | 
			
		||||
			case SIGNING_KEY_TYPE_DSA_SHA1:
 | 
			
		||||
				m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey));
 | 
			
		||||
| 
						 | 
				
			
			@ -540,6 +587,11 @@ namespace data
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t PrivateKeys::GetSignatureLen () const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Public->GetSignatureLen ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint8_t * PrivateKeys::GetPadding()
 | 
			
		||||
	{
 | 
			
		||||
		if(m_Public->GetSigningKeyType () == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
#include <string>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "Base.h"
 | 
			
		||||
#include "Signature.h"
 | 
			
		||||
#include "CryptoKey.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -142,8 +143,10 @@ namespace data
 | 
			
		|||
			std::shared_ptr<const IdentityEx> GetPublic () const { return m_Public; };
 | 
			
		||||
			const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
 | 
			
		||||
			const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
 | 
			
		||||
    uint8_t * GetPadding();
 | 
			
		||||
		void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
 | 
			
		||||
			size_t GetSignatureLen () const; // might not match identity
 | 
			
		||||
			bool IsOfflineSignature () const { return m_OfflineSignature.size () > 0; };
 | 
			
		||||
    		uint8_t * GetPadding();
 | 
			
		||||
			void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
 | 
			
		||||
			void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
 | 
			
		||||
 | 
			
		||||
			size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };
 | 
			
		||||
| 
						 | 
				
			
			@ -162,13 +165,15 @@ namespace data
 | 
			
		|||
		private:
 | 
			
		||||
 | 
			
		||||
			void CreateSigner () const;
 | 
			
		||||
			void CreateSigner (SigningKeyType keyType) const;
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			std::shared_ptr<IdentityEx> m_Public;
 | 
			
		||||
			uint8_t m_PrivateKey[256];
 | 
			
		||||
			uint8_t m_SigningPrivateKey[1024]; // assume private key doesn't exceed 1024 bytes
 | 
			
		||||
			uint8_t m_SigningPrivateKey[128]; // assume private key doesn't exceed 128 bytes
 | 
			
		||||
			mutable std::unique_ptr<i2p::crypto::Signer> m_Signer;
 | 
			
		||||
			std::vector<uint8_t> m_OfflineSignature; // non zero length, if applicable
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// kademlia
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue