From 659edf2590428e7802b5eb224d24abf6103d2e7a Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Tue, 28 Oct 2014 11:34:50 -0400
Subject: [PATCH] common code  for signing and verifing exchanged data

---
 NTCPSession.cpp    | 48 ++++++++++++++++++++++------------------------
 NTCPSession.h      |  9 ---------
 TransportSession.h | 32 +++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 34 deletions(-)

diff --git a/NTCPSession.cpp b/NTCPSession.cpp
index c75755b3..39b1ad07 100644
--- a/NTCPSession.cpp
+++ b/NTCPSession.cpp
@@ -282,12 +282,11 @@ namespace transport
 		m_Establisher->phase3.timestamp = tsA;
 		
 		SignedData s;
-		memcpy (s.x, m_Establisher->phase1.pubKey, 256);
-		memcpy (s.y, m_Establisher->phase2.pubKey, 256);
-		memcpy (s.ident, m_RemoteIdentity.GetIdentHash (), 32);
-		s.tsA = tsA;
-		s.tsB = m_Establisher->phase2.encrypted.timestamp;
-		i2p::context.Sign ((uint8_t *)&s, sizeof (s), m_Establisher->phase3.signature);
+		s.Insert (m_Establisher->phase1.pubKey, 256); // x
+		s.Insert (m_Establisher->phase2.pubKey, 256); // y
+		s.Insert (tsA);	// tsA
+		s.Insert (m_Establisher->phase2.encrypted.timestamp); // tsB
+		s.Sign (i2p::context.GetPrivateKeys (), m_Establisher->phase3.signature);	
 
 		m_Encryption.Encrypt((uint8_t *)&m_Establisher->phase3, sizeof(NTCPPhase3), (uint8_t *)&m_Establisher->phase3);
 		        
@@ -327,13 +326,12 @@ namespace transport
 			m_RemoteIdentity = m_Establisher->phase3.ident;
 
 			SignedData s;
-			memcpy (s.x, m_Establisher->phase1.pubKey, 256);
-			memcpy (s.y, m_Establisher->phase2.pubKey, 256);
-			memcpy (s.ident, i2p::context.GetRouterInfo ().GetIdentHash (), 32);
-			s.tsA = m_Establisher->phase3.timestamp;
-			s.tsB = tsB;
-			
-			if (!m_RemoteIdentity.Verify ((uint8_t *)&s, sizeof(s), m_Establisher->phase3.signature))
+			s.Insert (m_Establisher->phase1.pubKey, 256); // x
+			s.Insert (m_Establisher->phase2.pubKey, 256); // y
+			s.Insert (i2p::context.GetRouterInfo ().GetIdentHash (), 32); // ident
+			s.Insert (m_Establisher->phase3.timestamp); // tsA
+			s.Insert (tsB); // tsB			
+			if (!s.Verify (m_RemoteIdentity, m_Establisher->phase3.signature))
 			{	
 				LogPrint ("signature verification failed");
 				Terminate ();
@@ -347,12 +345,12 @@ namespace transport
 	void NTCPSession::SendPhase4 (uint32_t tsB)
 	{
 		SignedData s;
-		memcpy (s.x, m_Establisher->phase1.pubKey, 256);
-		memcpy (s.y, m_Establisher->phase2.pubKey, 256);
-		memcpy (s.ident, m_RemoteIdentity.GetIdentHash (), 32);
-		s.tsA = m_Establisher->phase3.timestamp;
-		s.tsB = tsB;
-		i2p::context.Sign ((uint8_t *)&s, sizeof (s), m_Establisher->phase4.signature);
+		s.Insert (m_Establisher->phase1.pubKey, 256); // x
+		s.Insert (m_Establisher->phase2.pubKey, 256); // y
+		s.Insert (m_RemoteIdentity.GetIdentHash (), 32); // ident
+		s.Insert (m_Establisher->phase3.timestamp); // tsA
+		s.Insert (tsB); // tsB
+		s.Sign (i2p::context.GetPrivateKeys (), m_Establisher->phase4.signature);
 		m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase4, sizeof(NTCPPhase4), (uint8_t *)&m_Establisher->phase4);
 
 		boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase4, sizeof (NTCPPhase4)), boost::asio::transfer_all (),
@@ -396,13 +394,13 @@ namespace transport
 
 			// verify signature
 			SignedData s;
-			memcpy (s.x, m_Establisher->phase1.pubKey, 256);
-			memcpy (s.y, m_Establisher->phase2.pubKey, 256);
-			memcpy (s.ident, i2p::context.GetRouterInfo ().GetIdentHash (), 32);
-			s.tsA = tsA;
-			s.tsB = m_Establisher->phase2.encrypted.timestamp;
+			s.Insert (m_Establisher->phase1.pubKey, 256); // x
+			s.Insert (m_Establisher->phase2.pubKey, 256); // y
+			s.Insert (i2p::context.GetRouterInfo ().GetIdentHash (), 32); // ident
+			s.Insert (tsA); // tsA
+			s.Insert (m_Establisher->phase2.encrypted.timestamp); // tsB
 
-			if (!m_RemoteIdentity.Verify ((uint8_t *)&s, sizeof(s), m_Establisher->phase4.signature))
+			if (!s.Verify (m_RemoteIdentity, m_Establisher->phase4.signature))
 			{	
 				LogPrint ("signature verification failed");
 				Terminate ();
diff --git a/NTCPSession.h b/NTCPSession.h
index 61113772..25ffa2be 100644
--- a/NTCPSession.h
+++ b/NTCPSession.h
@@ -51,15 +51,6 @@ namespace transport
 		uint8_t signature[40];
 		uint8_t padding[8];
 	};
-
-	struct SignedData // used for signature in Phase3 and Phase4
-	{
-		uint8_t x[256];
-		uint8_t y[256];
-		uint8_t ident[32];
-		uint32_t tsA;
-		uint32_t tsB;
-	};	
 	
 #pragma pack()	
 
diff --git a/TransportSession.h b/TransportSession.h
index 0e993508..0293686c 100644
--- a/TransportSession.h
+++ b/TransportSession.h
@@ -2,6 +2,7 @@
 #define TRANSPORT_SESSION_H__
 
 #include <inttypes.h>
+#include <iostream>
 #include "Identity.h"
 #include "RouterInfo.h"
 
@@ -15,6 +16,37 @@ namespace transport
 		uint8_t privateKey[256];
 	};	
 
+	class SignedData
+	{
+		public:
+
+			SignedData () {};
+			void Insert (const uint8_t * buf, size_t len) 
+			{ 
+				m_Stream.write ((char *)buf, len); 
+			}			
+
+			template<typename T>
+			void Insert (T t)
+			{
+				m_Stream.write ((char *)&t, sizeof (T)); 
+			}
+
+			bool Verify (const i2p::data::IdentityEx& ident, const uint8_t * signature) const
+			{
+				return ident.Verify ((const uint8_t *)m_Stream.str ().c_str (), m_Stream.str ().size (), signature); 
+			}
+
+			void Sign (const i2p::data::PrivateKeys& keys, uint8_t * signature) const
+			{
+				keys.Sign ((const uint8_t *)m_Stream.str ().c_str (), m_Stream.str ().size (), signature); 
+			}	
+
+		private:
+		
+			std::stringstream m_Stream;
+	};		
+
 	class TransportSession
 	{
 		public: