|
|
@ -520,6 +520,11 @@ namespace transport |
|
|
|
case eSSU2PeerTest: |
|
|
|
case eSSU2PeerTest: |
|
|
|
{ |
|
|
|
{ |
|
|
|
// TODO: remove later
|
|
|
|
// TODO: remove later
|
|
|
|
|
|
|
|
if (len < 32) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: PeerTest message too short ", len); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
const uint8_t nonce[12] = {0}; |
|
|
|
const uint8_t nonce[12] = {0}; |
|
|
|
uint64_t headerX[2]; |
|
|
|
uint64_t headerX[2]; |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
|
|
@ -603,6 +608,11 @@ namespace transport |
|
|
|
void SSU2Session::ProcessSessionRequest (Header& header, uint8_t * buf, size_t len) |
|
|
|
void SSU2Session::ProcessSessionRequest (Header& header, uint8_t * buf, size_t len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// we are Bob
|
|
|
|
// we are Bob
|
|
|
|
|
|
|
|
if (len < 80) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: SessionRequest message too short ", len); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
const uint8_t nonce[12] = {0}; |
|
|
|
const uint8_t nonce[12] = {0}; |
|
|
|
uint8_t headerX[48]; |
|
|
|
uint8_t headerX[48]; |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 48, i2p::context.GetSSU2IntroKey (), nonce, headerX); |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 48, i2p::context.GetSSU2IntroKey (), nonce, headerX); |
|
|
@ -723,6 +733,11 @@ namespace transport |
|
|
|
if (header.h.type != eSSU2SessionCreated) |
|
|
|
if (header.h.type != eSSU2SessionCreated) |
|
|
|
// this situation is valid, because it might be Retry with different encryption
|
|
|
|
// this situation is valid, because it might be Retry with different encryption
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (len < 80) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: SessionCreated message too short ", len); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
const uint8_t nonce[12] = {0}; |
|
|
|
const uint8_t nonce[12] = {0}; |
|
|
|
uint8_t headerX[48]; |
|
|
|
uint8_t headerX[48]; |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 48, kh2, nonce, headerX); |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 48, kh2, nonce, headerX); |
|
|
@ -863,6 +878,12 @@ namespace transport |
|
|
|
LogPrint (eLogError, "SSU2: Too many fragments ", numFragments, " in SessionConfirmed"); |
|
|
|
LogPrint (eLogError, "SSU2: Too many fragments ", numFragments, " in SessionConfirmed"); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (len < 32) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: SessionConfirmed fragment too short ", len); |
|
|
|
|
|
|
|
if (m_SessionConfirmedFragment) m_SessionConfirmedFragment.reset (nullptr); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
if (!(header.h.flags[0] & 0xF0)) |
|
|
|
if (!(header.h.flags[0] & 0xF0)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// first fragment
|
|
|
|
// first fragment
|
|
|
@ -910,6 +931,12 @@ namespace transport |
|
|
|
len = m_SessionConfirmedFragment->payloadSize + 16; |
|
|
|
len = m_SessionConfirmedFragment->payloadSize + 16; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (len < 80) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: SessionConfirmed message too short ", len); |
|
|
|
|
|
|
|
if (m_SessionConfirmedFragment) m_SessionConfirmedFragment.reset (nullptr); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
// KDF for Session Confirmed part 1
|
|
|
|
// KDF for Session Confirmed part 1
|
|
|
|
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
|
|
|
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
|
|
|
// decrypt part1
|
|
|
|
// decrypt part1
|
|
|
@ -1118,6 +1145,11 @@ namespace transport |
|
|
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2Retry); |
|
|
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2Retry); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (len < 48) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: Retry message too short ", len); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
uint8_t nonce[12] = {0}; |
|
|
|
uint8_t nonce[12] = {0}; |
|
|
|
uint64_t headerX[2]; // sourceConnID, token
|
|
|
|
uint64_t headerX[2]; // sourceConnID, token
|
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, m_Address->i, nonce, (uint8_t *)headerX); |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, m_Address->i, nonce, (uint8_t *)headerX); |
|
|
@ -1202,6 +1234,11 @@ namespace transport |
|
|
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2HolePunch); |
|
|
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2HolePunch); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (len < 48) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: HolePunch message too short ", len); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
uint8_t nonce[12] = {0}; |
|
|
|
uint8_t nonce[12] = {0}; |
|
|
|
uint64_t headerX[2]; // sourceConnID, token
|
|
|
|
uint64_t headerX[2]; // sourceConnID, token
|
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
|
|
@ -1273,6 +1310,11 @@ namespace transport |
|
|
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2PeerTest); |
|
|
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type, " instead ", (int)eSSU2PeerTest); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (len < 48) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: PeerTest message too short ", len); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
uint8_t nonce[12] = {0}; |
|
|
|
uint8_t nonce[12] = {0}; |
|
|
|
uint64_t headerX[2]; // sourceConnID, token
|
|
|
|
uint64_t headerX[2]; // sourceConnID, token
|
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
|
|
|
i2p::crypto::ChaCha20 (buf + 16, 16, i2p::context.GetSSU2IntroKey (), nonce, (uint8_t *)headerX); |
|
|
@ -1340,6 +1382,11 @@ namespace transport |
|
|
|
m_RemoteEndpoint = from; |
|
|
|
m_RemoteEndpoint = from; |
|
|
|
SendPathChallenge (); |
|
|
|
SendPathChallenge (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (len < 32) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "SSU2: Data message too short ", len); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
uint8_t payload[SSU2_MAX_PACKET_SIZE]; |
|
|
|
uint8_t payload[SSU2_MAX_PACKET_SIZE]; |
|
|
|
size_t payloadSize = len - 32; |
|
|
|
size_t payloadSize = len - 32; |
|
|
|
uint32_t packetNum = be32toh (header.h.packetNum); |
|
|
|
uint32_t packetNum = be32toh (header.h.packetNum); |
|
|
|