From 26d305d8666a0617050fa17efae1b906d7b1e87b Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Sat, 9 Jan 2016 17:26:17 -0500
Subject: [PATCH] fixed misalignment of certificate length

---
 Identity.cpp | 18 +++++++++---------
 Identity.h   |  9 ++-------
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/Identity.cpp b/Identity.cpp
index 4b518b5b..ff3946b8 100644
--- a/Identity.cpp
+++ b/Identity.cpp
@@ -16,7 +16,7 @@ namespace data
 	{
 		// copy public and signing keys together
 		memcpy (publicKey, keys.publicKey, sizeof (publicKey) + sizeof (signingKey));
-		memset (&certificate, 0, sizeof (certificate));		
+		memset (certificate, 0, sizeof (certificate));		
 		return *this;
 	}
 
@@ -105,8 +105,8 @@ namespace data
 			}	
 			m_ExtendedLen = 4 + excessLen; // 4 bytes extra + excess length
 			// fill certificate
-			m_StandardIdentity.certificate.type = CERTIFICATE_TYPE_KEY;
-			m_StandardIdentity.certificate.length = htobe16 (m_ExtendedLen); 
+			m_StandardIdentity.certificate[0] = CERTIFICATE_TYPE_KEY;
+			htobe16buf (m_StandardIdentity.certificate + 1, m_ExtendedLen); 
 			// fill extended buffer
 			m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
 			htobe16buf (m_ExtendedBuffer, type);
@@ -125,7 +125,7 @@ namespace data
 		else // DSA-SHA1
 		{
 			memcpy (m_StandardIdentity.signingKey, signingKey, sizeof (m_StandardIdentity.signingKey));
-			memset (&m_StandardIdentity.certificate, 0, sizeof (m_StandardIdentity.certificate));
+			memset (m_StandardIdentity.certificate, 0, sizeof (m_StandardIdentity.certificate));
 			m_IdentHash = m_StandardIdentity.Hash ();
 			m_ExtendedLen = 0;
 			m_ExtendedBuffer = nullptr;
@@ -200,9 +200,9 @@ namespace data
 		memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE);
 
 		delete[] m_ExtendedBuffer;
-		if (m_StandardIdentity.certificate.length)
+		m_ExtendedLen = bufbe16toh (m_StandardIdentity.certificate + 1);
+		if (m_ExtendedLen)
 		{
-			m_ExtendedLen = be16toh (m_StandardIdentity.certificate.length);
 			if (m_ExtendedLen + DEFAULT_IDENTITY_SIZE <= len)
 			{	
 				m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
@@ -272,7 +272,7 @@ namespace data
 		if (!m_Verifier) CreateVerifier ();	
 		if (m_Verifier)
 			return m_Verifier->GetSignatureLen ();
-		return 40;
+		return i2p::crypto::DSA_SIGNATURE_LENGTH;
 	}	
 	bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const 
 	{
@@ -284,14 +284,14 @@ namespace data
 
 	SigningKeyType IdentityEx::GetSigningKeyType () const
 	{
-		if (m_StandardIdentity.certificate.type == CERTIFICATE_TYPE_KEY && m_ExtendedBuffer)				
+		if (m_StandardIdentity.certificate[0] == CERTIFICATE_TYPE_KEY && m_ExtendedBuffer)				
 			return bufbe16toh (m_ExtendedBuffer); // signing key
 		return SIGNING_KEY_TYPE_DSA_SHA1;
 	}	
 
 	CryptoKeyType IdentityEx::GetCryptoKeyType () const
 	{
-		if (m_StandardIdentity.certificate.type == CERTIFICATE_TYPE_KEY && m_ExtendedBuffer)				
+		if (m_StandardIdentity.certificate[0] == CERTIFICATE_TYPE_KEY && m_ExtendedBuffer)				
 			return bufbe16toh (m_ExtendedBuffer + 2); // crypto key
 		return CRYPTO_KEY_TYPE_ELGAMAL;
 	}	
diff --git a/Identity.h b/Identity.h
index 1e7316af..27da190d 100644
--- a/Identity.h
+++ b/Identity.h
@@ -18,7 +18,6 @@ namespace data
 		return ident.ToBase64 ().substr (0, 4); 
 	}
 
-#pragma pack(1)
 	struct Keys
 	{
 		uint8_t privateKey[256];
@@ -38,11 +37,7 @@ namespace data
 	{
 		uint8_t publicKey[256];
 		uint8_t signingKey[128];
-		struct
-		{
-			uint8_t type;
-			uint16_t length;
-		} certificate;	
+		uint8_t certificate[3];	// byte 1 - type, bytes 2-3 - length
 
 		Identity () = default;
 		Identity (const Keys& keys) { *this = keys; };
@@ -50,7 +45,7 @@ namespace data
 		size_t FromBuffer (const uint8_t * buf, size_t len);
 		IdentHash Hash () const;
 	};
-#pragma pack()
+
 	Keys CreateRandomKeys ();
 	
 	const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes