diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 064290c5..19e3a124 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -307,7 +307,11 @@ namespace transport else { LogPrint ("Phase 3 sent: ", bytes_transferred); - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase4, sizeof (NTCPPhase4)), boost::asio::transfer_all (), + // wait for phase4 + m_Establisher->phase4Len = m_RemoteIdentity.GetSignatureLen (); + size_t paddingSize = m_Establisher->phase4Len & 0x0F; // %16 + if (paddingSize > 0) m_Establisher->phase4Len += (16 - paddingSize); + boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->phase4, m_Establisher->phase4Len), boost::asio::transfer_all (), boost::bind(&NTCPSession::HandlePhase4Received, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, tsA)); } @@ -352,10 +356,20 @@ namespace transport 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); + auto keys = i2p::context.GetPrivateKeys (); + m_Establisher->phase4Len = keys.GetPublic ().GetSignatureLen (); + if (m_Establisher->phase4Len > 64) + { + LogPrint (eLogError, "Signature length ", m_Establisher->phase4Len, " exceeds 64"); + Terminate (); + } + s.Sign (keys, m_Establisher->phase4); + size_t paddingSize = m_Establisher->phase4Len & 0x0F; // %16 + if (paddingSize > 0) m_Establisher->phase4Len += (16 - paddingSize); + + m_Encryption.Encrypt (m_Establisher->phase4, m_Establisher->phase4Len, m_Establisher->phase4); - boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase4, sizeof (NTCPPhase4)), boost::asio::transfer_all (), + boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->phase4, m_Establisher->phase4Len), boost::asio::transfer_all (), boost::bind(&NTCPSession::HandlePhase4Sent, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } @@ -392,7 +406,7 @@ namespace transport else { LogPrint ("Phase 4 received: ", bytes_transferred); - m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase4, sizeof(NTCPPhase4), (uint8_t *)&m_Establisher->phase4); + m_Decryption.Decrypt(m_Establisher->phase4, m_Establisher->phase4Len, m_Establisher->phase4); // verify signature SignedData s; @@ -402,7 +416,7 @@ namespace transport s.Insert (tsA); // tsA s.Insert (m_Establisher->phase2.encrypted.timestamp); // tsB - if (!s.Verify (m_RemoteIdentity, m_Establisher->phase4.signature)) + if (!s.Verify (m_RemoteIdentity, m_Establisher->phase4)) { LogPrint ("signature verification failed"); Terminate (); diff --git a/NTCPSession.h b/NTCPSession.h index 5417b380..f585fed9 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -44,13 +44,6 @@ namespace transport uint8_t padding[15]; uint8_t signature[40]; }; - - - struct NTCPPhase4 - { - uint8_t signature[40]; - uint8_t padding[8]; - }; #pragma pack() @@ -129,7 +122,8 @@ namespace transport NTCPPhase1 phase1; NTCPPhase2 phase2; NTCPPhase3 phase3; - NTCPPhase4 phase4; + i2p::crypto::AESAlignedBuffer<64> phase4; // 64 bytes max signature len + size_t phase4Len; } * m_Establisher; uint8_t m_ReceiveBuffer[NTCP_BUFFER_SIZE + 16], m_TimeSyncBuffer[16];