diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ea884aa4..9355e75d 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -846,7 +846,7 @@ namespace client ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), - m_ReadyChecker(GetService()) + m_ReadyChecker(GetService()), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) { if (keys.IsOfflineSignature () && GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // offline keys can be published with LS2 only @@ -868,12 +868,46 @@ namespace client if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); - // extract streaming params - if (params) + try + { + if (params) + { + // extract streaming params + auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY); + if (it != params->end ()) + m_StreamingAckDelay = std::stoi(it->second); + + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + { + // authentication for encrypted LeaseSet + it = params->find (I2CP_PARAM_LEASESET_AUTH_TYPE); + m_AuthType = std::stoi (it->second); + if (m_AuthType > 0) + { + m_AuthKeys = std::make_shared >(); + if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); + else if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); + else + { + LogPrint (eLogError, "Destination: Unexpected auth type ", m_AuthType); + m_AuthType = 0; + } + if (m_AuthKeys->size ()) + LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read"); + else + { + LogPrint (eLogError, "Destination: No auth keys read for auth type ", m_AuthType); + m_AuthKeys = nullptr; + } + } + } + } + } + catch (std::exception & ex) { - auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY); - if (it != params->end ()) - m_StreamingAckDelay = std::stoi(it->second); + LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what()); } } @@ -1149,7 +1183,7 @@ namespace client auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic ()); if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) // encrypt if type 5 - ls2 = std::make_shared (ls2, m_Keys); + ls2 = std::make_shared (ls2, m_Keys, m_AuthType, m_AuthKeys); leaseSet = ls2; } SetLeaseSet (leaseSet); @@ -1168,5 +1202,22 @@ namespace client LogPrint (eLogError, "Destinations: decryptor is not set"); return false; } + + void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) + { + for (auto it: *params) + if (it.first.length () >= group.length () && !it.first.compare (0, group.length (), group)) + { + auto pos = it.second.find (':'); + if (pos != std::string::npos) + { + i2p::data::AuthPublicKey pubKey; + if (pubKey.FromBase64 (it.second.substr (pos+1))) + m_AuthKeys->push_back (pubKey); + else + LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1)); + } + } + } } } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index dcbe9768..148a6101 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -252,6 +252,9 @@ namespace client void ScheduleCheckForReady(ReadyPromise * p); void HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p); #endif + + void ReadAuthKey (const std::string& group, const std::map * params); + private: i2p::data::PrivateKeys m_Keys; @@ -267,6 +270,9 @@ namespace client boost::asio::deadline_timer m_ReadyChecker; + int m_AuthType; + std::shared_ptr > m_AuthKeys; + public: // for HTTP only diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index bd2fca75..bc50e013 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -812,7 +812,7 @@ namespace data } LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, - LeaseSetAuthType authType, std::shared_ptr > authKeys): + int authType, std::shared_ptr > authKeys): LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { size_t lenInnerPlaintext = ls->GetBufferLen () + 1, lenOuterPlaintext = lenInnerPlaintext + 32 + 1, @@ -821,8 +821,8 @@ namespace data uint8_t layer1Flags = 0; if (authKeys) { - if (authType == eLeaseSetAuthTypeDH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 - else if (authType == eLeaseSetAuthTypePSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 + if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 + else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 if (layer1Flags) m_BufferLen += authKeys->size ()*40 + 2; // auth data len } m_Buffer = new uint8_t[m_BufferLen + 1]; @@ -905,9 +905,9 @@ namespace data LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); } - void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, LeaseSetAuthType authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const + void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const { - if (authType == eLeaseSetAuthTypeDH) + if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) { i2p::crypto::X25519Keys ek; ek.GenerateKeys (); // esk and epk diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 03e0e543..b9979e00 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -251,21 +251,17 @@ namespace data }; - class LocalEncryptedLeaseSet2: public LocalLeaseSet2 - { - public: + const int ENCRYPTED_LEASESET_AUTH_TYPE_NONE = 0; + const int ENCRYPTED_LEASESET_AUTH_TYPE_DH = 1; + const int ENCRYPTED_LEASESET_AUTH_TYPE_PSK = 2; - enum LeaseSetAuthType - { - eLeaseSetAuthTypeNone = 0, - eLeaseSetAuthTypeDH = 1, - eLeaseSetAuthTypePSK = 2 - }; - typedef i2p::data::Tag<32> AuthPublicKey; + typedef i2p::data::Tag<32> AuthPublicKey; + class LocalEncryptedLeaseSet2: public LocalLeaseSet2 + { public: - LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, LeaseSetAuthType authType = eLeaseSetAuthTypeNone, std::shared_ptr > authKeys = nullptr); + LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType = ENCRYPTED_LEASESET_AUTH_TYPE_NONE, std::shared_ptr > authKeys = nullptr); LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP @@ -274,7 +270,7 @@ namespace data private: - void CreateClientAuthData (const uint8_t * subcredential, LeaseSetAuthType authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const; + void CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const; private: