diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 252a85b7..4714506a 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -59,7 +59,7 @@ namespace transport 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) @@ -91,7 +91,7 @@ namespace transport void NTCP2Establisher::KDF3Alice () { uint8_t inputKeyMaterial[32]; - i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); + i2p::context.GetNTCP2StaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); MixKey (inputKeyMaterial); } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index e442df01..533d718c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -174,17 +174,30 @@ namespace i2p void RouterContext::NewNTCP2Keys () { - m_StaticKeys.reset (new i2p::crypto::X25519Keys ()); - m_StaticKeys->GenerateKeys (); + m_NTCP2StaticKeys.reset (new i2p::crypto::X25519Keys ()); + m_NTCP2StaticKeys->GenerateKeys (); m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); - m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey); - memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32); + m_NTCP2StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey); + memcpy (m_NTCP2Keys->staticPublicKey, m_NTCP2StaticKeys->GetPublicKey (), 32); RAND_bytes (m_NTCP2Keys->iv, 16); // save std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); 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) { if (status != m_Status) @@ -910,17 +923,31 @@ namespace i2p 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 (); auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey); - if (!m_StaticKeys) - m_StaticKeys.reset (x); + if (!m_NTCP2StaticKeys) + m_NTCP2StaticKeys.reset (x); else 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; + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index a3970605..714b3623 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -29,6 +29,7 @@ namespace garlic const char ROUTER_INFO[] = "router.info"; const char ROUTER_KEYS[] = "router.keys"; const char NTCP2_KEYS[] = "ntcp2.keys"; + const char SSU2_KEYS[] = "ssu2.keys"; const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes enum RouterStatus @@ -61,6 +62,13 @@ namespace garlic uint8_t iv[16]; }; + struct SSU2PrivateKeys + { + uint8_t staticPublicKey[32]; + uint8_t staticPrivateKey[32]; + uint8_t intro[32]; + }; + public: RouterContext (); @@ -78,11 +86,17 @@ namespace garlic return std::shared_ptr (this, [](i2p::garlic::GarlicDestination *) {}); } + 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 * 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 uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; @@ -156,6 +170,7 @@ namespace garlic void NewRouterInfo (); void UpdateRouterInfo (); void NewNTCP2Keys (); + void NewSSU2Keys (); bool Load (); void SaveKeys (); @@ -177,7 +192,8 @@ namespace garlic int m_NetID; std::mutex m_GarlicMutex; std::unique_ptr m_NTCP2Keys; - std::unique_ptr m_StaticKeys; + std::unique_ptr m_SSU2Keys; + std::unique_ptr m_NTCP2StaticKeys, m_SSU2StaticKeys; // for ECIESx25519 i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; }; diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 35334aeb..af02c29a 100644 --- a/libi2pd/SSU2.cpp +++ b/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) { 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); connID ^= key; auto it = m_Sessions.find (connID);