diff --git a/Identity.cpp b/Identity.cpp
index e63cdb35..dc26d649 100644
--- a/Identity.cpp
+++ b/Identity.cpp
@@ -33,6 +33,123 @@ namespace data
 		return DEFAULT_IDENTITY_SIZE;
 	}
 
+	IdentityEx::IdentityEx ():
+		m_Verifier (nullptr), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
+	{
+	}
+	
+	IdentityEx::IdentityEx (const uint8_t * buf, size_t len):
+		m_Verifier (nullptr), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
+	{
+		FromBuffer (buf, len);
+	}
+
+	IdentityEx::IdentityEx (const IdentityEx& other):
+		m_Verifier (nullptr), m_ExtendedBuffer (nullptr)
+	{
+		*this = other;
+	}	
+		
+	IdentityEx::~IdentityEx ()
+	{
+		delete m_Verifier;
+		delete[] m_ExtendedBuffer;
+	}	
+
+	IdentityEx& IdentityEx::operator=(const IdentityEx& other)
+	{
+		memcpy (&m_StandardIdentity, &other.m_StandardIdentity, DEFAULT_IDENTITY_SIZE);
+		m_IdentHash = other.m_IdentHash;
+		
+		delete m_Verifier;
+		m_Verifier = nullptr;
+		
+		delete[] m_ExtendedBuffer;
+		m_ExtendedLen = other.m_ExtendedLen;
+		if (m_ExtendedLen > 0)
+		{	
+			m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
+			memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen);
+		}	        
+		else
+			m_ExtendedBuffer = nullptr;
+
+		return *this;
+	}	
+
+	size_t IdentityEx::FromBuffer (const uint8_t * buf, size_t len)
+	{
+		delete m_Verifier;
+		m_Verifier = nullptr;
+		delete[] m_ExtendedBuffer;
+		
+		memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE);
+		if (m_StandardIdentity.certificate.length)
+		{
+			m_ExtendedLen = be16toh (m_StandardIdentity.certificate.length);
+			m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
+			memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen);
+		}		
+		else
+		{
+			m_ExtendedLen = 0;
+			m_ExtendedBuffer = nullptr;
+		}	
+		CryptoPP::SHA256().CalculateDigest(m_IdentHash, buf, GetFullLen ());
+		return GetFullLen ();
+	}	
+
+	size_t IdentityEx::GetSigningPublicKeyLen () 
+	{
+		if (!m_Verifier) 
+			CreateVerifier ();
+		if (m_Verifier)
+			return m_Verifier->GetPublicKeyLen ();
+		return 128;
+	}	
+		
+	bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature)
+	{
+		if (!m_Verifier) 
+			CreateVerifier ();
+		if (m_Verifier)
+			return m_Verifier->Verify (buf, len, signature);
+		return false;
+	}	
+		
+	void IdentityEx::CreateVerifier ()
+	{
+		switch (m_StandardIdentity.certificate.type)
+		{	
+			case CERTIFICATE_TYPE_NULL:
+				m_Verifier = new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey);
+			break;
+			case CERTIFICATE_TYPE_KEY:
+			{	
+				if (m_ExtendedBuffer)
+				{
+					uint16_t keyType = be16toh (*(uint16_t *)m_ExtendedBuffer); // sigining key
+					switch (keyType)
+					{
+						case PUBLIC_KEY_TYPE_DSA_SHA1:
+							m_Verifier = new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey);
+						break;
+						case PUBLIC_KEY_TYPE_ECDSA_SHA256_P256:
+							m_Verifier = new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey);
+						break;	
+						default:
+							LogPrint ("Signing key type ", keyType, " is not supported");
+					}	
+				}
+				else
+					LogPrint ("Missing certificate payload");
+				break;
+			}	
+			default:
+				LogPrint ("Certificate type ", m_StandardIdentity.certificate.type, " is not supported");
+		}	
+	}	
+		
 	IdentHash Identity::Hash() const 
 	{
 		IdentHash hash;
diff --git a/Identity.h b/Identity.h
index d82e225e..631aea71 100644
--- a/Identity.h
+++ b/Identity.h
@@ -80,7 +80,9 @@ namespace data
 	const uint8_t CERTIFICATE_TYPE_MULTIPLE = 4;	
 	const uint8_t CERTIFICATE_TYPE_KEY = 5;
 
-	const size_t DEFAULT_IDENTITY_SIZE = 387;
+	const uint16_t PUBLIC_KEY_TYPE_DSA_SHA1 = 0;
+	const uint16_t PUBLIC_KEY_TYPE_ECDSA_SHA256_P256 = 1;
+	
 	struct Identity
 	{
 		uint8_t publicKey[256];
@@ -96,6 +98,37 @@ namespace data
 		size_t FromBuffer (const uint8_t * buf, size_t len);
 		IdentHash Hash() const;
 	};	
+	const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes
+
+	class IdentityEx
+	{
+		public:
+
+			IdentityEx ();
+			IdentityEx (const uint8_t * buf, size_t len);
+			IdentityEx (const IdentityEx& other);
+			~IdentityEx ();
+			IdentityEx& operator=(const IdentityEx& other);
+
+			size_t FromBuffer (const uint8_t * buf, size_t len);
+			const Identity& GetStandardIdentity () const { return m_StandardIdentity; };
+			const IdentHash& GetIdentHash () const { return m_IdentHash; };
+			size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; };
+			size_t GetSigningPublicKeyLen ();
+			bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature);
+			
+		private:
+
+			void CreateVerifier ();
+			
+		private:
+
+			Identity m_StandardIdentity;
+			IdentHash m_IdentHash;
+			i2p::crypto::Verifier * m_Verifier;
+			size_t m_ExtendedLen;
+			uint8_t * m_ExtendedBuffer;
+	};	
 	
 	struct PrivateKeys // for eepsites
 	{
diff --git a/LeaseSet.cpp b/LeaseSet.cpp
index 0b79a0ab..43b6ef58 100644
--- a/LeaseSet.cpp
+++ b/LeaseSet.cpp
@@ -62,15 +62,17 @@ namespace data
 	
 	void LeaseSet::ReadFromBuffer ()	
 	{	
-		const LeaseSetHeader * header = (const LeaseSetHeader *)m_Buffer;
-		m_Identity = header->destination;
-		m_IdentHash = m_Identity.Hash();
-		memcpy (m_EncryptionKey, header->encryptionKey, 256);
-		LogPrint ("LeaseSet num=", (int)header->num);
+		size_t size = m_Identity.FromBuffer (m_Buffer, m_BufferLen);
+		memcpy (m_EncryptionKey, m_Buffer + size, 256);
+		size += 256; // encryption key
+		size += m_Identity.GetSigningPublicKeyLen (); // unused signing key
+		uint8_t num = m_Buffer[size];
+		size++; // num
+		LogPrint ("LeaseSet num=", (int)num);
 
 		// process leases
-		const uint8_t * leases = m_Buffer + sizeof (LeaseSetHeader);
-		for (int i = 0; i < header->num; i++)
+		const uint8_t * leases = m_Buffer + size;
+		for (int i = 0; i < num; i++)
 		{
 			Lease lease = *(Lease *)leases;
 			lease.tunnelID = be32toh (lease.tunnelID);
@@ -88,11 +90,7 @@ namespace data
 		}	
 		
 		// verify
-		CryptoPP::DSA::PublicKey pubKey;
-		pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, 
-			CryptoPP::Integer (m_Identity.signingKey, 128));
-		CryptoPP::DSA::Verifier verifier (pubKey);
-		if (!verifier.VerifyMessage (m_Buffer, leases - m_Buffer, leases, 40))
+		if (!m_Identity.Verify (m_Buffer, leases - m_Buffer, leases))
 			LogPrint ("LeaseSet verification failed");
 	}				
 	
diff --git a/LeaseSet.h b/LeaseSet.h
index a8e70d43..c02bbfad 100644
--- a/LeaseSet.h
+++ b/LeaseSet.h
@@ -62,8 +62,8 @@ namespace data
 			void SetUnsolicited (bool unsolicited) { m_IsUnsolicited = unsolicited; };
 
 			// implements RoutingDestination
-			const Identity& GetIdentity () const { return m_Identity; };
-			const IdentHash& GetIdentHash () const { return m_IdentHash; };
+			const Identity& GetIdentity () const { return m_Identity.GetStandardIdentity (); };
+			const IdentHash& GetIdentHash () const { return m_Identity.GetIdentHash (); };
 			const std::vector<Lease>& GetLeases () const { return m_Leases; };
 			const std::vector<Lease> GetNonExpiredLeases () const;
 			bool HasExpiredLeases () const;
@@ -78,8 +78,7 @@ namespace data
 		private:
 
 			std::vector<Lease> m_Leases;
-			Identity m_Identity;
-			IdentHash m_IdentHash;
+			IdentityEx m_Identity;
 			uint8_t m_EncryptionKey[256];
 			uint8_t m_Buffer[MAX_LS_BUFFER_SIZE];
 			size_t m_BufferLen;
diff --git a/Signature.h b/Signature.h
index 79bbcb65..594c12ed 100644
--- a/Signature.h
+++ b/Signature.h
@@ -18,6 +18,8 @@ namespace crypto
 			
 			virtual ~Verifier () {};
 			virtual bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) = 0;
+			virtual size_t GetPublicKeyLen () const = 0;
+			virtual size_t GetSignatureLen () const = 0;
 	};
 
 	class DSAVerifier: public Verifier
@@ -35,6 +37,9 @@ namespace crypto
 				return verifier.VerifyMessage (buf, len, signature, 40);
 			}	
 
+			size_t GetPublicKeyLen () const { return 128; };
+			size_t GetSignatureLen () const { return 40; };
+			
 		private:
 
 			CryptoPP::DSA::PublicKey m_PublicKey;
@@ -57,6 +62,9 @@ namespace crypto
 				return verifier.VerifyMessage (buf, len, signature, 64);
 			}	
 
+			size_t GetPublicKeyLen () const { return 64; };
+			size_t GetSignatureLen () const { return 64; };
+			
 		private:
 
 			CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey m_PublicKey;