mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-07 11:54:16 +00:00
calculate shared key in separate thread for incoming connection
This commit is contained in:
parent
34939f9381
commit
a746f5657f
@ -36,12 +36,12 @@ namespace transport
|
|||||||
delete m_Establisher;
|
delete m_Establisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCPSession::CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key)
|
void NTCPSession::CreateAESKey (uint8_t * pubKey)
|
||||||
{
|
{
|
||||||
uint8_t sharedKey[256];
|
uint8_t sharedKey[256];
|
||||||
m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation
|
m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation
|
||||||
|
|
||||||
uint8_t * aesKey = key;
|
i2p::crypto::AESKey aesKey;
|
||||||
if (sharedKey[0] & 0x80)
|
if (sharedKey[0] & 0x80)
|
||||||
{
|
{
|
||||||
aesKey[0] = 0;
|
aesKey[0] = 0;
|
||||||
@ -64,6 +64,9 @@ namespace transport
|
|||||||
}
|
}
|
||||||
memcpy (aesKey, nonZero, 32);
|
memcpy (aesKey, nonZero, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Decryption.SetKey (aesKey);
|
||||||
|
m_Encryption.SetKey (aesKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCPSession::Done ()
|
void NTCPSession::Done ()
|
||||||
@ -164,15 +167,25 @@ namespace transport
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPhase2 ();
|
// TODO: check for number of pending keys
|
||||||
|
auto s = shared_from_this ();
|
||||||
|
auto keyCreated = std::async (std::launch::async, [s] ()
|
||||||
|
{
|
||||||
|
if (!s->m_DHKeysPair)
|
||||||
|
s->m_DHKeysPair = transports.GetNextDHKeysPair ();
|
||||||
|
s->CreateAESKey (s->m_Establisher->phase1.pubKey);
|
||||||
|
}).share ();
|
||||||
|
m_Server.GetService ().post ([s, keyCreated]()
|
||||||
|
{
|
||||||
|
keyCreated.get ();
|
||||||
|
s->SendPhase2 ();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCPSession::SendPhase2 ()
|
void NTCPSession::SendPhase2 ()
|
||||||
{
|
{
|
||||||
if (!m_DHKeysPair)
|
|
||||||
m_DHKeysPair = transports.GetNextDHKeysPair ();
|
|
||||||
const uint8_t * y = m_DHKeysPair->GetPublicKey ();
|
const uint8_t * y = m_DHKeysPair->GetPublicKey ();
|
||||||
memcpy (m_Establisher->phase2.pubKey, y, 256);
|
memcpy (m_Establisher->phase2.pubKey, y, 256);
|
||||||
uint8_t xy[512];
|
uint8_t xy[512];
|
||||||
@ -183,11 +196,7 @@ namespace transport
|
|||||||
memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4);
|
memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4);
|
||||||
RAND_bytes (m_Establisher->phase2.encrypted.filler, 12);
|
RAND_bytes (m_Establisher->phase2.encrypted.filler, 12);
|
||||||
|
|
||||||
i2p::crypto::AESKey aesKey;
|
|
||||||
CreateAESKey (m_Establisher->phase1.pubKey, aesKey);
|
|
||||||
m_Encryption.SetKey (aesKey);
|
|
||||||
m_Encryption.SetIV (y + 240);
|
m_Encryption.SetIV (y + 240);
|
||||||
m_Decryption.SetKey (aesKey);
|
|
||||||
m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
|
m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
|
||||||
|
|
||||||
m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
|
m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
|
||||||
@ -232,26 +241,22 @@ namespace transport
|
|||||||
{
|
{
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
// create AES key in separate thread
|
// create AES key in separate thread
|
||||||
auto createKey = std::async (std::launch::async, [s] ()->i2p::crypto::AESKey
|
auto keyCreated = std::async (std::launch::async, [s] ()
|
||||||
{
|
{
|
||||||
i2p::crypto::AESKey aesKey;
|
s->CreateAESKey (s->m_Establisher->phase2.pubKey);
|
||||||
s->CreateAESKey (s->m_Establisher->phase2.pubKey, aesKey);
|
|
||||||
return std::move (aesKey);
|
|
||||||
}).share (); // TODO: use move capture in C++ 14 instead shared_future
|
}).share (); // TODO: use move capture in C++ 14 instead shared_future
|
||||||
// let other operations execute while a key gets created
|
// let other operations execute while a key gets created
|
||||||
m_Server.GetService ().post ([s, createKey]()
|
m_Server.GetService ().post ([s, keyCreated]()
|
||||||
{
|
{
|
||||||
auto aesKey = createKey.get (); // we might wait if no more pending operations
|
keyCreated.get (); // we might wait if no more pending operations
|
||||||
s->HandlePhase2 (aesKey);
|
s->HandlePhase2 ();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCPSession::HandlePhase2 (const i2p::crypto::AESKey& aesKey)
|
void NTCPSession::HandlePhase2 ()
|
||||||
{
|
{
|
||||||
m_Decryption.SetKey (aesKey);
|
|
||||||
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
|
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
|
||||||
m_Encryption.SetKey (aesKey);
|
|
||||||
m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
|
m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
|
||||||
|
|
||||||
m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
|
m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
|
||||||
|
@ -67,13 +67,13 @@ namespace transport
|
|||||||
void SendTimeSyncMessage ();
|
void SendTimeSyncMessage ();
|
||||||
void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; }
|
void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; }
|
||||||
|
|
||||||
void CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key);
|
void CreateAESKey (uint8_t * pubKey);
|
||||||
|
|
||||||
// client
|
// client
|
||||||
void SendPhase3 ();
|
void SendPhase3 ();
|
||||||
void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||||
void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||||
void HandlePhase2 (const i2p::crypto::AESKey& aesKey);
|
void HandlePhase2 ();
|
||||||
void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
|
void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
|
||||||
void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
|
void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user