Browse Source

Merge pull request #772 from majestrate/ssu-revert

don't use heap allocated buffers in ssu and fill uninitialized memory
pull/777/head
orignal 8 years ago committed by GitHub
parent
commit
70b30f7849
  1. 9
      SSUData.cpp
  2. 41
      SSUSession.cpp

9
SSUData.cpp

@ -154,8 +154,7 @@ namespace transport
{ {
uint32_t msgID = bufbe32toh (buf); // message ID uint32_t msgID = bufbe32toh (buf); // message ID
buf += 4; buf += 4;
uint8_t frag[4]; uint8_t frag[4] = {0};
frag[0] = 0;
memcpy (frag + 1, buf, 3); memcpy (frag + 1, buf, 3);
buf += 3; buf += 3;
uint32_t fragmentInfo = bufbe32toh (frag); // fragment info uint32_t fragmentInfo = bufbe32toh (frag); // fragment info
@ -371,7 +370,7 @@ namespace transport
void SSUData::SendMsgAck (uint32_t msgID) void SSUData::SendMsgAck (uint32_t msgID)
{ {
uint8_t * buf = new uint8_t[48 + 18]; // actual length is 44 = 37 + 7 but pad it to multiple of 16 uint8_t buf[48 + 18] = {0}; // actual length is 44 = 37 + 7 but pad it to multiple of 16
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = DATA_FLAG_EXPLICIT_ACKS_INCLUDED; // flag *payload = DATA_FLAG_EXPLICIT_ACKS_INCLUDED; // flag
payload++; payload++;
@ -384,7 +383,6 @@ namespace transport
// encrypt message with session key // encrypt message with session key
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48); m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48);
m_Session.Send (buf, 48); m_Session.Send (buf, 48);
delete [] buf;
} }
void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum) void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum)
@ -394,7 +392,7 @@ namespace transport
LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64"); LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64");
return; return;
} }
uint8_t * buf = new uint8_t[64 + 18]; uint8_t buf[64 + 18] = {0};
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag *payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag
payload++; payload++;
@ -414,7 +412,6 @@ namespace transport
// encrypt message with session key // encrypt message with session key
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len); m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len);
m_Session.Send (buf, len); m_Session.Send (buf, len);
delete [] buf;
} }
void SSUData::ScheduleResend() void SSUData::ScheduleResend()

41
SSUSession.cpp

@ -350,7 +350,7 @@ namespace transport
void SSUSession::SendSessionRequest () void SSUSession::SendSessionRequest ()
{ {
uint8_t * buf = new uint8_t[320 + 18]; // 304 bytes for ipv4, 320 for ipv6 uint8_t buf[320 + 18] = {0}; // 304 bytes for ipv4, 320 for ipv6
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
uint8_t flag = 0; uint8_t flag = 0;
// fill extended options, 3 bytes extended options don't change message size // fill extended options, 3 bytes extended options don't change message size
@ -381,7 +381,6 @@ namespace transport
RAND_bytes (iv, 16); // random iv RAND_bytes (iv, 16); // random iv
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, isV4 ? 304 : 320, m_IntroKey, iv, m_IntroKey, flag); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, isV4 ? 304 : 320, m_IntroKey, iv, m_IntroKey, flag);
m_Server.Send (buf, isV4 ? 304 : 320, m_RemoteEndpoint); m_Server.Send (buf, isV4 ? 304 : 320, m_RemoteEndpoint);
delete [] buf;
} }
void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce) void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce)
@ -393,7 +392,7 @@ namespace transport
return; return;
} }
uint8_t * buf = new uint8_t[96 + 18]; uint8_t buf[96 + 18] = {0};
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
htobe32buf (payload, introducer.iTag); htobe32buf (payload, introducer.iTag);
payload += 4; payload += 4;
@ -414,7 +413,6 @@ namespace transport
else else
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, introducer.iKey, iv, introducer.iKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, introducer.iKey, iv, introducer.iKey);
m_Server.Send (buf, 96, m_RemoteEndpoint); m_Server.Send (buf, 96, m_RemoteEndpoint);
delete [] buf;
} }
void SSUSession::SendSessionCreated (const uint8_t * x, bool sendRelayTag) void SSUSession::SendSessionCreated (const uint8_t * x, bool sendRelayTag)
@ -429,7 +427,7 @@ namespace transport
SignedData s; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time SignedData s; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time
s.Insert (x, 256); // x s.Insert (x, 256); // x
uint8_t * buf = new uint8_t[384 + 18]; uint8_t buf[384 + 18] = {0};
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
memcpy (payload, m_DHKeysPair->GetPublicKey (), 256); memcpy (payload, m_DHKeysPair->GetPublicKey (), 256);
s.Insert (payload, 256); // y s.Insert (payload, 256); // y
@ -475,14 +473,18 @@ namespace transport
m_SignedData = std::unique_ptr<SignedData>(new SignedData (s)); m_SignedData = std::unique_ptr<SignedData>(new SignedData (s));
s.Insert (payload - 4, 4); // BOB's signed on time s.Insert (payload - 4, 4); // BOB's signed on time
s.Sign (i2p::context.GetPrivateKeys (), payload); // DSA signature s.Sign (i2p::context.GetPrivateKeys (), payload); // DSA signature
// TODO: fill padding with random data
uint8_t iv[16]; uint8_t iv[16];
RAND_bytes (iv, 16); // random iv RAND_bytes (iv, 16); // random iv
// encrypt signature and padding with newly created session key // encrypt signature and padding with newly created session key
size_t signatureLen = i2p::context.GetIdentity ()->GetSignatureLen (); size_t signatureLen = i2p::context.GetIdentity ()->GetSignatureLen ();
size_t paddingSize = signatureLen & 0x0F; // %16 size_t paddingSize = signatureLen & 0x0F; // %16
if (paddingSize > 0) signatureLen += (16 - paddingSize); if (paddingSize > 0)
{
// fill random padding
RAND_bytes(payload + signatureLen, (16 - paddingSize));
signatureLen += (16 - paddingSize);
}
m_SessionKeyEncryption.SetIV (iv); m_SessionKeyEncryption.SetIV (iv);
m_SessionKeyEncryption.Encrypt (payload, signatureLen, payload); m_SessionKeyEncryption.Encrypt (payload, signatureLen, payload);
payload += signatureLen; payload += signatureLen;
@ -491,12 +493,11 @@ namespace transport
// encrypt message with intro key // encrypt message with intro key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, msgLen, m_IntroKey, iv, m_IntroKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, msgLen, m_IntroKey, iv, m_IntroKey);
Send (buf, msgLen); Send (buf, msgLen);
delete [] buf;
} }
void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen) void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen)
{ {
uint8_t * buf = new uint8_t[512 + 18]; uint8_t buf[512 + 18] = {0};
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 1; // 1 fragment *payload = 1; // 1 fragment
payload++; // info payload++; // info
@ -511,9 +512,8 @@ namespace transport
auto signatureLen = i2p::context.GetIdentity ()->GetSignatureLen (); auto signatureLen = i2p::context.GetIdentity ()->GetSignatureLen ();
size_t paddingSize = ((payload - buf) + signatureLen)%16; size_t paddingSize = ((payload - buf) + signatureLen)%16;
if (paddingSize > 0) paddingSize = 16 - paddingSize; if (paddingSize > 0) paddingSize = 16 - paddingSize;
// TODO: fill padding RAND_bytes(payload, paddingSize); // fill padding with random
payload += paddingSize; // padding size payload += paddingSize; // padding size
// signature // signature
SignedData s; // x,y, our IP, our port, remote IP, remote port, relayTag, our signed on time SignedData s; // x,y, our IP, our port, remote IP, remote port, relayTag, our signed on time
s.Insert (m_DHKeysPair->GetPublicKey (), 256); // x s.Insert (m_DHKeysPair->GetPublicKey (), 256); // x
@ -535,7 +535,6 @@ namespace transport
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CONFIRMED, buf, msgLen, m_SessionKey, iv, m_MacKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CONFIRMED, buf, msgLen, m_SessionKey, iv, m_MacKey);
Send (buf, msgLen); Send (buf, msgLen);
delete [] buf;
} }
void SSUSession::ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from) void SSUSession::ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from)
@ -569,7 +568,7 @@ namespace transport
LogPrint (eLogWarning, "SSU: Charlie's IP must be v4"); LogPrint (eLogWarning, "SSU: Charlie's IP must be v4");
return; return;
} }
uint8_t * buf = new uint8_t[80 + 18]; // 64 Alice's ipv4 and 80 Alice's ipv6 uint8_t buf[80 + 18] = {0}; // 64 Alice's ipv4 and 80 Alice's ipv6
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 4; *payload = 4;
payload++; // size payload++; // size
@ -612,7 +611,6 @@ namespace transport
m_Server.Send (buf, isV4 ? 64 : 80, from); m_Server.Send (buf, isV4 ? 64 : 80, from);
} }
LogPrint (eLogDebug, "SSU: relay response sent"); LogPrint (eLogDebug, "SSU: relay response sent");
delete [] buf;
} }
void SSUSession::SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from) void SSUSession::SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from)
@ -624,7 +622,7 @@ namespace transport
LogPrint (eLogWarning, "SSU: Alice's IP must be v4"); LogPrint (eLogWarning, "SSU: Alice's IP must be v4");
return; return;
} }
uint8_t * buf = new uint8_t[48 + 18]; uint8_t buf[48 + 18] = {0};
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 4; *payload = 4;
payload++; // size payload++; // size
@ -638,7 +636,6 @@ namespace transport
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, 48, session->m_SessionKey, iv, session->m_MacKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, 48, session->m_SessionKey, iv, session->m_MacKey);
m_Server.Send (buf, 48, session->m_RemoteEndpoint); m_Server.Send (buf, 48, session->m_RemoteEndpoint);
LogPrint (eLogDebug, "SSU: relay intro sent"); LogPrint (eLogDebug, "SSU: relay intro sent");
delete [] buf;
} }
void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len) void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len)
@ -1046,7 +1043,7 @@ namespace transport
// toAddress is true for Alice<->Chalie communications only // toAddress is true for Alice<->Chalie communications only
// sendAddress is false if message comes from Alice // sendAddress is false if message comes from Alice
{ {
uint8_t * buf = new uint8_t[80 + 18]; uint8_t buf[80 + 18] = {0};
uint8_t iv[16]; uint8_t iv[16];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
htobe32buf (payload, nonce); htobe32buf (payload, nonce);
@ -1103,7 +1100,6 @@ namespace transport
FillHeaderAndEncrypt (PAYLOAD_TYPE_PEER_TEST, buf, 80); FillHeaderAndEncrypt (PAYLOAD_TYPE_PEER_TEST, buf, 80);
Send (buf, 80); Send (buf, 80);
} }
delete [] buf;
} }
void SSUSession::SendPeerTest () void SSUSession::SendPeerTest ()
@ -1128,7 +1124,7 @@ namespace transport
{ {
if (m_State == eSessionStateEstablished) if (m_State == eSessionStateEstablished)
{ {
uint8_t * buf = new uint8_t[48 + 18]; uint8_t buf[48 + 18] = {0};
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 0; // flags *payload = 0; // flags
payload++; payload++;
@ -1138,7 +1134,6 @@ namespace transport
Send (buf, 48); Send (buf, 48);
LogPrint (eLogDebug, "SSU: keep-alive sent"); LogPrint (eLogDebug, "SSU: keep-alive sent");
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
delete [] buf;
} }
} }
@ -1146,7 +1141,7 @@ namespace transport
{ {
if (m_IsSessionKey) if (m_IsSessionKey)
{ {
uint8_t * buf = new uint8_t[48 + 18]; uint8_t buf[48 + 18] = {0};
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48);
try try
@ -1158,13 +1153,12 @@ namespace transport
LogPrint (eLogWarning, "SSU: exception while sending session destoroyed: ", ex.what ()); LogPrint (eLogWarning, "SSU: exception while sending session destoroyed: ", ex.what ());
} }
LogPrint (eLogDebug, "SSU: session destroyed sent"); LogPrint (eLogDebug, "SSU: session destroyed sent");
delete [] buf;
} }
} }
void SSUSession::Send (uint8_t type, const uint8_t * payload, size_t len) void SSUSession::Send (uint8_t type, const uint8_t * payload, size_t len)
{ {
uint8_t * buf = new uint8_t[SSU_MTU_V4 + 18]; uint8_t buf[SSU_MTU_V4 + 18] = {0};
size_t msgSize = len + sizeof (SSUHeader); size_t msgSize = len + sizeof (SSUHeader);
size_t paddingSize = msgSize & 0x0F; // %16 size_t paddingSize = msgSize & 0x0F; // %16
if (paddingSize > 0) msgSize += (16 - paddingSize); if (paddingSize > 0) msgSize += (16 - paddingSize);
@ -1177,7 +1171,6 @@ namespace transport
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (type, buf, msgSize); FillHeaderAndEncrypt (type, buf, msgSize);
Send (buf, msgSize); Send (buf, msgSize);
delete [] buf;
} }
void SSUSession::Send (const uint8_t * buf, size_t size) void SSUSession::Send (const uint8_t * buf, size_t size)

Loading…
Cancel
Save