From c2f47119ceb4eadc11d3f91959ab4f25c27dbd6c Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Mon, 23 Sep 2019 13:42:15 -0400
Subject: [PATCH] fixed #1424. Check if .b32.i2p address string is valid

---
 libi2pd/Blinding.cpp           |  3 ++-
 libi2pd/Blinding.h             |  1 +
 libi2pd_client/AddressBook.cpp | 15 ++++++++++-----
 libi2pd_client/AddressBook.h   |  3 ++-
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp
index 6bf11c9e..8d3f4b40 100644
--- a/libi2pd/Blinding.cpp
+++ b/libi2pd/Blinding.cpp
@@ -141,7 +141,8 @@ namespace data
 		m_BlindedSigType = m_SigType;	
 	}
 
-	BlindedPublicKey::BlindedPublicKey (const std::string& b33)
+	BlindedPublicKey::BlindedPublicKey (const std::string& b33):
+		m_SigType (0) // 0 means invalid, we can't blind DSA, set it later
 	{
 		uint8_t addr[40]; // TODO: define length from b33
 		size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40);
diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h
index 9d274fd0..65b8c0f8 100644
--- a/libi2pd/Blinding.h
+++ b/libi2pd/Blinding.h
@@ -22,6 +22,7 @@ namespace data
 			size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
 			SigningKeyType GetSigType () const  { return m_SigType; };
 			SigningKeyType GetBlindedSigType () const  { return m_BlindedSigType; };
+			bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
 
 			void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
 			size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length  
diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp
index 14ed89a7..0e40c76e 100644
--- a/libi2pd_client/AddressBook.cpp
+++ b/libi2pd_client/AddressBook.cpp
@@ -237,17 +237,19 @@ namespace client
 
 //---------------------------------------------------------------------
 
-	Address::Address (const std::string& b32)
+	Address::Address (const std::string& b32):
+		addressType (eAddressInvalid)
 	{
 		if (b32.length () <= B33_ADDRESS_THRESHOLD)
 		{
-			addressType = eAddressIndentHash;
-			identHash.FromBase32 (b32);
+			if (identHash.FromBase32 (b32) > 0)
+				addressType = eAddressIndentHash;
 		}
 		else
 		{
-			addressType = eAddressBlindedPublicKey;
 			blindedPublicKey = std::make_shared<i2p::data::BlindedPublicKey>(b32);
+			if (blindedPublicKey->IsValid ())
+				addressType = eAddressBlindedPublicKey;
 		}
 	}	
 
@@ -320,7 +322,10 @@ namespace client
 	{
 		auto pos = address.find(".b32.i2p");
 		if (pos != std::string::npos)
-			return std::make_shared<const Address>(address.substr (0, pos));
+		{			
+			auto addr = std::make_shared<const Address>(address.substr (0, pos));
+			return addr->IsValid () ? addr : nullptr;
+		}
 		else
 		{
 			pos = address.find (".i2p");
diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h
index 47ad9993..82ba167b 100644
--- a/libi2pd_client/AddressBook.h
+++ b/libi2pd_client/AddressBook.h
@@ -33,13 +33,14 @@ namespace client
 
 	struct Address
 	{
-		enum { eAddressIndentHash, eAddressBlindedPublicKey } addressType;
+		enum { eAddressIndentHash, eAddressBlindedPublicKey, eAddressInvalid } addressType;
 		i2p::data::IdentHash identHash;
 		std::shared_ptr<i2p::data::BlindedPublicKey> blindedPublicKey;
 
 		Address (const std::string& b32);	
 		Address (const i2p::data::IdentHash& hash);	
 		bool IsIdentHash () const { return addressType == eAddressIndentHash; };
+		bool IsValid () const { return addressType != eAddressInvalid; };
 	};
 
 	inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); }