Browse Source

verify signature and send peer test msg 5

webconsole-inja
orignal 3 years ago
parent
commit
47460d86b2
  1. 8
      libi2pd/SSU2.cpp
  2. 1
      libi2pd/SSU2.h
  3. 49
      libi2pd/SSU2Session.cpp
  4. 3
      libi2pd/SSU2Session.h

8
libi2pd/SSU2.cpp

@ -237,6 +237,14 @@ namespace transport
m_PendingOutgoingSessions.emplace (session->GetRemoteEndpoint (), session); m_PendingOutgoingSessions.emplace (session->GetRemoteEndpoint (), session);
} }
std::shared_ptr<SSU2Session> SSU2Server::FindSession (const i2p::data::IdentHash& ident) const
{
auto it = m_SessionsByRouterHash.find (ident);
if (it != m_SessionsByRouterHash.end ())
return it->second;
return nullptr;
}
void SSU2Server::AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay) void SSU2Server::AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay)
{ {
m_Relays.emplace (tag, relay); m_Relays.emplace (tag, relay);

1
libi2pd/SSU2.h

@ -53,6 +53,7 @@ namespace transport
void RemoveSession (uint64_t connID); void RemoveSession (uint64_t connID);
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session); void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session); void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
std::shared_ptr<SSU2Session> FindSession (const i2p::data::IdentHash& ident) const;
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay); void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
void RemoveRelay (uint32_t tag); void RemoveRelay (uint32_t tag);

49
libi2pd/SSU2Session.cpp

@ -839,8 +839,7 @@ namespace transport
return true; return true;
} }
void SSU2Session::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, void SSU2Session::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, const uint8_t * introKey)
const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey)
{ {
Header header; Header header;
uint8_t h[32], payload[SSU2_MAX_PAYLOAD_SIZE]; uint8_t h[32], payload[SSU2_MAX_PAYLOAD_SIZE];
@ -859,7 +858,7 @@ namespace transport
htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ());
size_t payloadSize = 7; size_t payloadSize = 7;
if (msg == 6 || msg == 7) if (msg == 6 || msg == 7)
payloadSize += CreateAddressBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, ep); payloadSize += CreateAddressBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, m_RemoteEndpoint);
payloadSize += CreatePeerTestBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize, payloadSize += CreatePeerTestBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize,
msg, eSSU2PeerTestCodeAccept, nullptr, signedData, signedDataLen); msg, eSSU2PeerTestCodeAccept, nullptr, signedData, signedDataLen);
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize); payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
@ -873,7 +872,7 @@ namespace transport
memset (n, 0, 12); memset (n, 0, 12);
i2p::crypto::ChaCha20 (h + 16, 16, introKey, n, h + 16); i2p::crypto::ChaCha20 (h + 16, 16, introKey, n, h + 16);
// send // send
m_Server.Send (header.buf, 16, h + 16, 16, payload, payloadSize, ep); m_Server.Send (header.buf, 16, h + 16, 16, payload, payloadSize, m_RemoteEndpoint);
} }
bool SSU2Session::ProcessPeerTest (uint8_t * buf, size_t len) bool SSU2Session::ProcessPeerTest (uint8_t * buf, size_t len)
@ -1348,7 +1347,43 @@ namespace transport
auto r = i2p::data::netdb.FindRouter (buf + 3); // find Alice auto r = i2p::data::netdb.FindRouter (buf + 3); // find Alice
if (r) if (r)
{ {
// TODO: send msg 5 to Alice size_t signatureLen = r->GetIdentity ()->GetSignatureLen ();
if (len >= 35 + signatureLen)
{
SignedData s;
s.Insert ((const uint8_t *)"PeerTestValidate", 16); // prologue
s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash
s.Insert (buf + 35 + signatureLen, len - 35 - signatureLen); // signed data
if (s.Verify (r->GetIdentity (), buf + (len - signatureLen)))
{
if (!m_Server.FindSession (r->GetIdentity ()->GetIdentHash ()))
{
boost::asio::ip::udp::endpoint ep;
std::shared_ptr<const i2p::data::RouterInfo::Address> addr;
if (ExtractEndpoint (buf + 44, len - 44, ep))
addr = ep.address ().is_v4 () ? r->GetSSU2V4Address () : r->GetSSU2V6Address ();
if (addr)
{
// TODO: compare ep with addr
// send msg 5 to Alice
auto session = std::make_shared<SSU2Session> (m_Server, r, addr);
session->SetState (eSSU2SessionStatePeerTest);
session->m_DestConnID = htobe64 (((uint64_t)nonce << 32) | nonce);
session->m_SourceConnID = ~session->m_SourceConnID;
m_Server.AddSession (session);
session->SendPeerTest (5, buf + 35, len - 35, addr->i);
}
else
code = eSSU2PeerTestCodeCharlieUnsupportedAddress;
}
else
code = eSSU2PeerTestCodeCharlieAliceIsAlreadyConnected;
}
else
code = eSSU2PeerTestCodeCharlieSignatureFailure;
}
else // maformed message
code = eSSU2PeerTestCodeCharlieReasonUnspecified;
} }
else else
code = eSSU2PeerTestCodeCharlieAliceIsUnknown; code = eSSU2PeerTestCodeCharlieAliceIsUnknown;
@ -1393,9 +1428,11 @@ namespace transport
if (htobe64 (((uint64_t)nonce << 32) | nonce) != m_SourceConnID) if (htobe64 (((uint64_t)nonce << 32) | nonce) != m_SourceConnID)
LogPrint (eLogWarning, "SSU2: Peer test 5 nonce mismatch ", nonce); LogPrint (eLogWarning, "SSU2: Peer test 5 nonce mismatch ", nonce);
break; break;
case 6: // Chralie from Alice case 6: // Charlie from Alice
m_Server.RemoveSession (~htobe64 (((uint64_t)nonce << 32) | nonce));
break; break;
case 7: // Alice from Charlie 2 case 7: // Alice from Charlie 2
m_Server.RemoveSession (htobe64 (((uint64_t)nonce << 32) | nonce));
break; break;
default: default:
LogPrint (eLogWarning, "SSU2: PeerTest unexpected msg num ", buf[0]); LogPrint (eLogWarning, "SSU2: PeerTest unexpected msg num ", buf[0]);

3
libi2pd/SSU2Session.h

@ -205,8 +205,7 @@ namespace transport
void SendQuickAck (); void SendQuickAck ();
void SendTermination (); void SendTermination ();
void SendHolePunch (uint32_t nonce, const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey); void SendHolePunch (uint32_t nonce, const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey);
void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, void SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, const uint8_t * introKey); // PeerTest message
const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey); // PeerTest message
void HandlePayload (const uint8_t * buf, size_t len); void HandlePayload (const uint8_t * buf, size_t len);
void HandleAck (const uint8_t * buf, size_t len); void HandleAck (const uint8_t * buf, size_t len);

Loading…
Cancel
Save