Browse Source

try intro key if mac key failed

pull/46/head
orignal 11 years ago
parent
commit
411ac5b898
  1. 80
      SSU.cpp
  2. 3
      SSU.h

80
SSU.cpp

@ -97,9 +97,18 @@ namespace ssu
LogPrint ("Unexpected SSU payload type ", (int)payloadType); LogPrint ("Unexpected SSU payload type ", (int)payloadType);
} }
} }
// TODO: try intro key
else else
{ {
LogPrint ("MAC key failed. Trying intro key");
auto introKey = GetIntroKey ();
if (introKey && Validate (buf, len, introKey))
{
Decrypt (buf, len, introKey);
SSUHeader * header = (SSUHeader *)buf;
LogPrint ("Unexpected SSU payload type ", (int)(header->flag >> 4));
// TODO:
}
else
LogPrint ("MAC verifcation failed"); LogPrint ("MAC verifcation failed");
m_State = eSessionStateUnknown; m_State = eSessionStateUnknown;
} }
@ -109,8 +118,7 @@ namespace ssu
{ {
LogPrint ("Process session request"); LogPrint ("Process session request");
// use our intro key // use our intro key
if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_REQUEST, if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_REQUEST, buf, len))
i2p::context.GetRouterInfo (), buf, len))
{ {
m_State = eSessionStateRequestReceived; m_State = eSessionStateRequestReceived;
LogPrint ("Session request received"); LogPrint ("Session request received");
@ -129,7 +137,7 @@ namespace ssu
} }
// use remote intro key // use remote intro key
if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_CREATED, *m_RemoteRouter, buf, len)) if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_CREATED, buf, len))
{ {
m_State = eSessionStateCreatedReceived; m_State = eSessionStateCreatedReceived;
LogPrint ("Session created received"); LogPrint ("Session created received");
@ -167,10 +175,10 @@ namespace ssu
void SSUSession::SendSessionRequest () void SSUSession::SendSessionRequest ()
{ {
auto address = m_RemoteRouter ? m_RemoteRouter->GetSSUAddress () : nullptr; auto introKey = GetIntroKey ();
if (!address) if (!introKey)
{ {
LogPrint ("Missing remote SSU address"); LogPrint ("SSU is not supported");
return; return;
} }
@ -183,7 +191,7 @@ namespace ssu
uint8_t iv[16]; uint8_t iv[16];
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
rnd.GenerateBlock (iv, 16); // random iv rnd.GenerateBlock (iv, 16); // random iv
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, 304, address->key, iv, address->key); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, 304, introKey, iv, introKey);
m_State = eSessionStateRequestSent; m_State = eSessionStateRequestSent;
m_Server->Send (buf, 304, m_RemoteEndpoint); m_Server->Send (buf, 304, m_RemoteEndpoint);
@ -191,10 +199,10 @@ namespace ssu
void SSUSession::SendSessionCreated (const uint8_t * x) void SSUSession::SendSessionCreated (const uint8_t * x)
{ {
auto address = m_RemoteRouter ? m_RemoteRouter->GetSSUAddress () : nullptr; auto introKey = GetIntroKey ();
if (!address) if (!introKey)
{ {
LogPrint ("Missing remote SSU address"); LogPrint ("SSU is not supported");
return; return;
} }
uint8_t signedData[532]; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time uint8_t signedData[532]; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time
@ -230,20 +238,13 @@ namespace ssu
m_Encryption.ProcessData (payload, payload, 48); m_Encryption.ProcessData (payload, payload, 48);
// encrypt message with intro key // encrypt message with intro key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, 368, address->key, iv, address->key); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, 368, introKey, iv, introKey);
m_State = eSessionStateRequestSent; m_State = eSessionStateRequestSent;
m_Server->Send (buf, 368, m_RemoteEndpoint); m_Server->Send (buf, 368, m_RemoteEndpoint);
} }
void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag) void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag)
{ {
auto address = m_RemoteRouter ? m_RemoteRouter->GetSSUAddress () : nullptr;
if (!address)
{
LogPrint ("Missing remote SSU address");
return;
}
uint8_t buf[480 + 18]; uint8_t buf[480 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 1; // 1 fragment *payload = 1; // 1 fragment
@ -281,15 +282,15 @@ namespace ssu
m_Server->Send (buf, 480, m_RemoteEndpoint); m_Server->Send (buf, 480, m_RemoteEndpoint);
} }
bool SSUSession::ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, const i2p::data::RouterInfo& r, uint8_t * buf, size_t len) bool SSUSession::ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, uint8_t * buf, size_t len)
{ {
auto address = r.GetSSUAddress (); auto introKey = GetIntroKey ();
if (address) if (introKey)
{ {
// use intro key for verification and decryption // use intro key for verification and decryption
if (Validate (buf, len, address->key)) if (Validate (buf, len, introKey))
{ {
Decrypt (buf, len, address->key); Decrypt (buf, len, introKey);
SSUHeader * header = (SSUHeader *)buf; SSUHeader * header = (SSUHeader *)buf;
if ((header->flag >> 4) == expectedPayloadType) if ((header->flag >> 4) == expectedPayloadType)
{ {
@ -303,7 +304,7 @@ namespace ssu
LogPrint ("MAC verifcation failed"); LogPrint ("MAC verifcation failed");
} }
else else
LogPrint ("SSU is not supported by ", r.GetIdentHashAbbreviation ()); LogPrint ("SSU is not supported");
return false; return false;
} }
@ -389,6 +390,22 @@ namespace ssu
} }
} }
const uint8_t * SSUSession::GetIntroKey () const
{
if (m_RemoteRouter)
{
// we are client
auto address = m_RemoteRouter->GetSSUAddress ();
return address ? address->key : nullptr;
}
else
{
// we are server
auto address = i2p::context.GetRouterInfo ().GetSSUAddress ();
return address ? address->key : nullptr;
}
}
void SSUSession::SendI2NPMessage (I2NPMessage * msg) void SSUSession::SendI2NPMessage (I2NPMessage * msg)
{ {
if (msg) if (msg)
@ -520,8 +537,21 @@ namespace ssu
uint8_t buf[48 + 18], iv[16]; uint8_t buf[48 + 18], iv[16];
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
rnd.GenerateBlock (iv, 16); // random iv rnd.GenerateBlock (iv, 16); // random iv
if (m_State == eSessionStateEstablished)
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48, m_SessionKey, iv, m_MacKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48, m_SessionKey, iv, m_MacKey);
else
{
auto introKey = GetIntroKey ();
if (introKey)
// encrypt message with intro key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48, introKey, iv, introKey);
else
{
LogPrint ("SSU: can't send SessionDestroyed message");
return;
}
}
m_Server->Send (buf, 48, m_RemoteEndpoint); m_Server->Send (buf, 48, m_RemoteEndpoint);
} }

3
SSU.h

@ -89,10 +89,11 @@ namespace ssu
void SendSesionDestroyed (); void SendSesionDestroyed ();
void Send (i2p::I2NPMessage * msg); void Send (i2p::I2NPMessage * msg);
bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, const i2p::data::RouterInfo& r, uint8_t * buf, size_t len); bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, uint8_t * buf, size_t len);
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey); void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey);
void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey); void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey);
bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey); bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey);
const uint8_t * GetIntroKey () const;
private: private:

Loading…
Cancel
Save