From b7f17d4cb1567286452baa62a25533d37a8eb7ae Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Sep 2019 11:02:19 -0400 Subject: [PATCH] client auth flag for B33 address --- daemon/HTTPServer.cpp | 2 +- libi2pd/Blinding.cpp | 18 ++++++++++++++---- libi2pd/Blinding.h | 3 ++- libi2pd/Destination.cpp | 35 ++++++++++++++++++++++------------- libi2pd/Destination.h | 7 ++++--- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 38b53ff3..7dc6a9d2 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -356,7 +356,7 @@ namespace http { s << dest->GetIdentity ()->ToBase64 () << "
\r\n
\r\n"; if (dest->IsEncryptedLeaseSet ()) { - i2p::data::BlindedPublicKey blinded (dest->GetIdentity ()); + i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); s << "
\r\n\r\n

\r\n"; s << blinded.ToB33 () << ".b32.i2p
\r\n"; s << "

\r\n
\r\n"; diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index e51c0fcc..6bf11c9e 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -124,8 +124,14 @@ namespace data return publicKeyLength; } +//---------------------------------------------------------- - BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity) + const uint8_t B33_TWO_BYTES_SIGTYPE_FLAG = 0x01; + const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now + const uint8_t B33_PER_CLIENT_AUTH_FLAG = 0x04; + + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, bool clientAuth): + m_IsClientAuth (clientAuth) { if (!identity) return; auto len = identity->GetSigningPublicKeyLen (); @@ -147,9 +153,9 @@ namespace data uint32_t checksum = crc32 (0, addr + 3, l - 3); // checksum is Little Endian addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); - uint8_t flag = addr[0]; + uint8_t flags = addr[0]; size_t offset = 1; - if (flag & 0x01) // two bytes signatures + if (flags & B33_TWO_BYTES_SIGTYPE_FLAG) // two bytes signatures { m_SigType = bufbe16toh (addr + offset); offset += 2; m_BlindedSigType = bufbe16toh (addr + offset); offset += 2; @@ -159,6 +165,8 @@ namespace data m_SigType = addr[offset]; offset++; m_BlindedSigType = addr[offset]; offset++; } + m_IsClientAuth = flags & B33_PER_CLIENT_AUTH_FLAG; + std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (m_SigType)); if (blindedVerifier) { @@ -179,7 +187,9 @@ namespace data { if (m_PublicKey.size () > 32) return ""; // assume 25519 uint8_t addr[35]; char str[60]; // TODO: define actual length - addr[0] = 0; // flags + uint8_t flags = 0; + if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG; + addr[0] = flags; // flags addr[1] = m_SigType; // sig type addr[2] = m_BlindedSigType; // blinded sig type memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 9a3fe633..9d274fd0 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -14,7 +14,7 @@ namespace data { public: - BlindedPublicKey (std::shared_ptr identity); + BlindedPublicKey (std::shared_ptr identity, bool clientAuth = false); BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p std::string ToB33 () const; @@ -38,6 +38,7 @@ namespace data std::vector m_PublicKey; i2p::data::SigningKeyType m_SigType, m_BlindedSigType; + bool m_IsClientAuth = false; }; } } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 34ff374f..ca60f0fb 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -17,7 +17,7 @@ namespace client m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), - m_LeaseSetType (DEFAULT_LEASESET_TYPE) + m_LeaseSetType (DEFAULT_LEASESET_TYPE), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) { int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH; int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY; @@ -70,6 +70,19 @@ namespace client it = params->find (I2CP_PARAM_LEASESET_TYPE); if (it != params->end ()) m_LeaseSetType = std::stoi(it->second); + if (m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + { + // authentication for encrypted LeaseSet + it = params->find (I2CP_PARAM_LEASESET_AUTH_TYPE); + if (it != params->end ()) + { + auto authType = std::stoi (it->second); + if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) + m_AuthType = authType; + else + LogPrint (eLogError, "Destination: Unknown auth type ", authType); + } + } it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY); if (it != params->end ()) { @@ -846,7 +859,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_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) + m_ReadyChecker(GetService()) { 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 @@ -880,25 +893,21 @@ namespace client 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) + auto authType = GetAuthType (); + if (authType > 0) { m_AuthKeys = std::make_shared >(); - if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) + if (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) + else if (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; - } + LogPrint (eLogError, "Destination: Unexpected auth type ", authType); 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); + LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType); m_AuthKeys = nullptr; } } @@ -1184,7 +1193,7 @@ namespace client auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic (), isPublishedEncrypted); if (isPublishedEncrypted) // encrypt if type 5 - ls2 = std::make_shared (ls2, m_Keys, m_AuthType, m_AuthKeys); + ls2 = std::make_shared (ls2, m_Keys, GetAuthType (), m_AuthKeys); leaseSet = ls2; } SetLeaseSet (leaseSet); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 148a6101..a32d3ed1 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -134,6 +134,7 @@ namespace client void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; }; + int GetAuthType () const { return m_AuthType; }; bool IsPublic () const { return m_IsPublic; }; virtual void CleanupDestination () {}; // additional clean up in derived classes // I2CP @@ -179,7 +180,7 @@ namespace client boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, m_PublishDelayTimer, m_CleanupTimer; std::string m_Nickname; - int m_LeaseSetType; + int m_LeaseSetType, m_AuthType; std::unique_ptr > m_LeaseSetPrivKey; // non-null if presented public: @@ -188,6 +189,7 @@ namespace client int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; }; bool IsEncryptedLeaseSet () const { return m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; }; + bool IsPerClientAuth () const { return m_AuthType > 0; }; }; class ClientDestination: public LeaseSetDestination @@ -270,8 +272,7 @@ namespace client boost::asio::deadline_timer m_ReadyChecker; - int m_AuthType; - std::shared_ptr > m_AuthKeys; + std::shared_ptr > m_AuthKeys; // we don't need them for I2CP public: