Browse Source

handle payload blocks

pull/1742/head
orignal 3 years ago
parent
commit
40c8a1bc1d
  1. 91
      libi2pd/SSU2.cpp
  2. 28
      libi2pd/SSU2.h

91
libi2pd/SSU2.cpp

@ -54,8 +54,7 @@ namespace transport
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
Header header; Header header;
uint8_t headerX[48], payload[1200]; // TODO: correct payload size uint8_t headerX[48], payload[48];
size_t payloadSize = 8;
// fill packet // fill packet
RAND_bytes ((uint8_t *)&m_DestConnID, 8); RAND_bytes ((uint8_t *)&m_DestConnID, 8);
header.h.connID = m_DestConnID; // dest id header.h.connID = m_DestConnID; // dest id
@ -68,7 +67,15 @@ namespace transport
memcpy (headerX, &m_SourceConnID, 8); // source id memcpy (headerX, &m_SourceConnID, 8); // source id
RAND_bytes (headerX + 8, 8); // token RAND_bytes (headerX + 8, 8); // token
memcpy (headerX + 16, m_EphemeralKeys->GetPublicKey (), 32); // X memcpy (headerX + 16, m_EphemeralKeys->GetPublicKey (), 32); // X
m_Server.AddPendingOutgoingSession (boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port), shared_from_this ()); // payload
payload[0] = eSSU2BlkDateTime;
htobe16buf (payload + 1, 4);
htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ());
size_t payloadSize = 7;
uint8_t paddingSize = (rand () & 0x0F) + 9; // 9 - 24
payload[payloadSize] = eSSU2BlkPadding;
htobe16buf (payload + payloadSize + 1, paddingSize);
payloadSize += paddingSize + 3;
// KDF for session request // KDF for session request
m_NoiseState->MixHash ({ {header.buf, 16}, {headerX, 16} }); // h = SHA256(h || header) m_NoiseState->MixHash ({ {header.buf, 16}, {headerX, 16} }); // h = SHA256(h || header)
m_NoiseState->MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk); m_NoiseState->MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk);
@ -84,6 +91,7 @@ namespace transport
i2p::crypto::ChaCha20 (headerX, 48, m_Address->i, nonce, headerX); i2p::crypto::ChaCha20 (headerX, 48, m_Address->i, nonce, headerX);
m_NoiseState->MixHash (payload, 32); // h = SHA256(h || 32 byte encrypted payload from Session Request) for SessionCreated m_NoiseState->MixHash (payload, 32); // h = SHA256(h || 32 byte encrypted payload from Session Request) for SessionCreated
// send // send
m_Server.AddPendingOutgoingSession (boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port), shared_from_this ());
m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint); m_Server.Send (header.buf, 16, headerX, 48, payload, payloadSize, m_RemoteEndpoint);
} }
@ -117,7 +125,8 @@ namespace transport
LogPrint (eLogWarning, "SSU2: SessionRequest AEAD verification failed "); LogPrint (eLogWarning, "SSU2: SessionRequest AEAD verification failed ");
return; return;
} }
// process payload // payload
HandlePayload (payload, len - 80);
m_Server.AddSession (m_SourceConnID, shared_from_this ()); m_Server.AddSession (m_SourceConnID, shared_from_this ());
SendSessionCreated (headerX + 16); SendSessionCreated (headerX + 16);
@ -190,13 +199,85 @@ namespace transport
LogPrint (eLogWarning, "SSU2: SessionCreated AEAD verification failed "); LogPrint (eLogWarning, "SSU2: SessionCreated AEAD verification failed ");
return false; return false;
} }
// process payload // payload
HandlePayload (payload, len - 80);
m_Server.AddSession (m_SourceConnID, shared_from_this ()); m_Server.AddSession (m_SourceConnID, shared_from_this ());
return true; return true;
} }
void SSU2Session::HandlePayload (const uint8_t * buf, size_t len)
{
size_t offset = 0;
while (offset < len)
{
uint8_t blk = buf[offset];
offset++;
auto size = bufbe16toh (buf + offset);
offset += 2;
LogPrint (eLogDebug, "SSU2: Block type ", (int)blk, " of size ", size);
if (size > len)
{
LogPrint (eLogError, "SSU2: Unexpected block length ", size);
break;
}
switch (blk)
{
case eSSU2BlkDateTime:
LogPrint (eLogDebug, "SSU2: Datetime");
break;
case eSSU2BlkOptions:
LogPrint (eLogDebug, "SSU2: Options");
break;
case eSSU2BlkRouterInfo:
break;
case eSSU2BlkI2NPMessage:
break;
case eSSU2BlkFirstFragment:
break;
case eSSU2BlkFollowOnFragment:
break;
case eSSU2BlkTermination:
break;
case eSSU2BlkRelayRequest:
break;
case eSSU2BlkRelayResponse:
break;
case eSSU2BlkRelayIntro:
break;
case eSSU2BlkPeerTest:
break;
case eSSU2BlkNextNonce:
break;
case eSSU2BlkAck:
break;
case eSSU2BlkAddress:
break;
case eSSU2BlkIntroKey:
break;
case eSSU2BlkRelayTagRequest:
break;
case eSSU2BlkRelayTag:
break;
case eSSU2BlkNewToken:
break;
case eSSU2BlkPathChallenge:
break;
case eSSU2BlkPathResponse:
break;
case eSSU2BlkFirstPacketNumber:
break;
case eSSU2BlkPadding:
LogPrint (eLogDebug, "SSU2: Padding");
break;
default:
LogPrint (eLogWarning, "SSU2: Unknown block type ", (int)blk);
}
offset += size;
}
}
SSU2Server::SSU2Server (): SSU2Server::SSU2Server ():
RunnableServiceWithWork ("SSU2"), m_Socket (GetService ()) RunnableServiceWithWork ("SSU2"), m_Socket (GetService ())
{ {

28
libi2pd/SSU2.h

@ -32,6 +32,32 @@ namespace transport
eSSU2SessionCreated = 1 eSSU2SessionCreated = 1
}; };
enum SSU2BlockType
{
eSSU2BlkDateTime = 0,
eSSU2BlkOptions, // 1
eSSU2BlkRouterInfo, // 2
eSSU2BlkI2NPMessage, // 3
eSSU2BlkFirstFragment, // 4
eSSU2BlkFollowOnFragment, // 5
eSSU2BlkTermination, // 6
eSSU2BlkRelayRequest, // 7
eSSU2BlkRelayResponse, // 8
eSSU2BlkRelayIntro, // 9
eSSU2BlkPeerTest, // 10
eSSU2BlkNextNonce, // 11
eSSU2BlkAck, // 12
eSSU2BlkAddress, // 13
eSSU2BlkIntroKey, // 14
eSSU2BlkRelayTagRequest, // 15
eSSU2BlkRelayTag, // 16
eSSU2BlkNewToken, // 17
eSSU2BlkPathChallenge, // 18
eSSU2BlkPathResponse, // 19
eSSU2BlkFirstPacketNumber, // 20
eSSU2BlkPadding = 254
};
class SSU2Server; class SSU2Server;
class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session> class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session>
{ {
@ -67,6 +93,8 @@ namespace transport
void SendSessionRequest (); void SendSessionRequest ();
void SendSessionCreated (const uint8_t * X); void SendSessionCreated (const uint8_t * X);
void HandlePayload (const uint8_t * buf, size_t len);
private: private:
SSU2Server& m_Server; SSU2Server& m_Server;

Loading…
Cancel
Save