Browse Source

SSU2 keys

pull/1742/head
orignal 3 years ago
parent
commit
f6ba776c12
  1. 4
      libi2pd/NTCP2.cpp
  2. 45
      libi2pd/RouterContext.cpp
  3. 20
      libi2pd/RouterContext.h
  4. 2
      libi2pd/SSU2.cpp

4
libi2pd/NTCP2.cpp

@ -59,7 +59,7 @@ namespace transport
void NTCP2Establisher::KDF1Bob () void NTCP2Establisher::KDF1Bob ()
{ {
KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetStaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ());
} }
void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub)
@ -91,7 +91,7 @@ namespace transport
void NTCP2Establisher::KDF3Alice () void NTCP2Establisher::KDF3Alice ()
{ {
uint8_t inputKeyMaterial[32]; uint8_t inputKeyMaterial[32];
i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); i2p::context.GetNTCP2StaticKeys ().Agree (GetRemotePub (), inputKeyMaterial);
MixKey (inputKeyMaterial); MixKey (inputKeyMaterial);
} }

45
libi2pd/RouterContext.cpp

@ -174,17 +174,30 @@ namespace i2p
void RouterContext::NewNTCP2Keys () void RouterContext::NewNTCP2Keys ()
{ {
m_StaticKeys.reset (new i2p::crypto::X25519Keys ()); m_NTCP2StaticKeys.reset (new i2p::crypto::X25519Keys ());
m_StaticKeys->GenerateKeys (); m_NTCP2StaticKeys->GenerateKeys ();
m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey); m_NTCP2StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey);
memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32); memcpy (m_NTCP2Keys->staticPublicKey, m_NTCP2StaticKeys->GetPublicKey (), 32);
RAND_bytes (m_NTCP2Keys->iv, 16); RAND_bytes (m_NTCP2Keys->iv, 16);
// save // save
std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
} }
void RouterContext::NewSSU2Keys ()
{
m_SSU2StaticKeys.reset (new i2p::crypto::X25519Keys ());
m_SSU2StaticKeys->GenerateKeys ();
m_SSU2Keys.reset (new SSU2PrivateKeys ());
m_SSU2StaticKeys->GetPrivateKey (m_SSU2Keys->staticPrivateKey);
memcpy (m_SSU2Keys->staticPublicKey, m_SSU2StaticKeys->GetPublicKey (), 32);
RAND_bytes (m_SSU2Keys->intro, 32);
// save
std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out);
fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
}
void RouterContext::SetStatus (RouterStatus status) void RouterContext::SetStatus (RouterStatus status)
{ {
if (status != m_Status) if (status != m_Status)
@ -910,17 +923,31 @@ namespace i2p
return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE);
} }
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () i2p::crypto::X25519Keys& RouterContext::GetNTCP2StaticKeys ()
{ {
if (!m_StaticKeys) if (!m_NTCP2StaticKeys)
{ {
if (!m_NTCP2Keys) NewNTCP2Keys (); if (!m_NTCP2Keys) NewNTCP2Keys ();
auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey); auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey);
if (!m_StaticKeys) if (!m_NTCP2StaticKeys)
m_StaticKeys.reset (x); m_NTCP2StaticKeys.reset (x);
else else
delete x; delete x;
} }
return *m_StaticKeys; return *m_NTCP2StaticKeys;
} }
i2p::crypto::X25519Keys& RouterContext::GetSSU2StaticKeys ()
{
if (!m_SSU2StaticKeys)
{
if (!m_SSU2Keys) NewSSU2Keys ();
auto x = new i2p::crypto::X25519Keys (m_SSU2Keys->staticPrivateKey, m_SSU2Keys->staticPublicKey);
if (!m_SSU2StaticKeys)
m_SSU2StaticKeys.reset (x);
else
delete x;
}
return *m_SSU2StaticKeys;
}
} }

20
libi2pd/RouterContext.h

@ -29,6 +29,7 @@ namespace garlic
const char ROUTER_INFO[] = "router.info"; const char ROUTER_INFO[] = "router.info";
const char ROUTER_KEYS[] = "router.keys"; const char ROUTER_KEYS[] = "router.keys";
const char NTCP2_KEYS[] = "ntcp2.keys"; const char NTCP2_KEYS[] = "ntcp2.keys";
const char SSU2_KEYS[] = "ssu2.keys";
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
enum RouterStatus enum RouterStatus
@ -61,6 +62,13 @@ namespace garlic
uint8_t iv[16]; uint8_t iv[16];
}; };
struct SSU2PrivateKeys
{
uint8_t staticPublicKey[32];
uint8_t staticPrivateKey[32];
uint8_t intro[32];
};
public: public:
RouterContext (); RouterContext ();
@ -78,11 +86,17 @@ namespace garlic
return std::shared_ptr<i2p::garlic::GarlicDestination> (this, return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
[](i2p::garlic::GarlicDestination *) {}); [](i2p::garlic::GarlicDestination *) {});
} }
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; }; const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
i2p::crypto::X25519Keys& GetStaticKeys (); i2p::crypto::X25519Keys& GetNTCP2StaticKeys ();
const uint8_t * GetSSU2StaticPublicKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPublicKey : nullptr; };
const uint8_t * GetSSU2StaticPrivateKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
i2p::crypto::X25519Keys& GetSSU2StaticKeys ();
uint32_t GetUptime () const; // in seconds uint32_t GetUptime () const; // in seconds
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; };
@ -156,6 +170,7 @@ namespace garlic
void NewRouterInfo (); void NewRouterInfo ();
void UpdateRouterInfo (); void UpdateRouterInfo ();
void NewNTCP2Keys (); void NewNTCP2Keys ();
void NewSSU2Keys ();
bool Load (); bool Load ();
void SaveKeys (); void SaveKeys ();
@ -177,7 +192,8 @@ namespace garlic
int m_NetID; int m_NetID;
std::mutex m_GarlicMutex; std::mutex m_GarlicMutex;
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys; std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys; std::unique_ptr<SSU2PrivateKeys> m_SSU2Keys;
std::unique_ptr<i2p::crypto::X25519Keys> m_NTCP2StaticKeys, m_SSU2StaticKeys;
// for ECIESx25519 // for ECIESx25519
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
}; };

2
libi2pd/SSU2.cpp

@ -117,7 +117,7 @@ namespace transport
void SSU2Server::ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) void SSU2Server::ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
{ {
uint64_t key = 0, connID; uint64_t key = 0, connID;
i2p::crypto::ChaCha20 ((uint8_t *)&key, 8, i2p::context.GetNTCP2IV (), buf + (len - 24), (uint8_t *)&key); // TODO: use SSU2 intro key i2p::crypto::ChaCha20 ((uint8_t *)&key, 8, i2p::context.GetSSU2IntroKey (), buf + (len - 24), (uint8_t *)&key); // TODO: use SSU2 intro key
memcpy (&connID, buf, 8); memcpy (&connID, buf, 8);
connID ^= key; connID ^= key;
auto it = m_Sessions.find (connID); auto it = m_Sessions.find (connID);

Loading…
Cancel
Save