From 8e4b9da97d9e18ed9a143bdaea2d2e40208786df Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 Mar 2019 15:32:13 -0400 Subject: [PATCH] pass blinded key instead identity for encrypted LS2 --- libi2pd/Destination.cpp | 16 +++++++++------- libi2pd/Destination.h | 4 ++-- libi2pd/LeaseSet.cpp | 37 ++++++++++++++++++++++++------------- libi2pd/LeaseSet.h | 25 +++++++++++++++++++++---- 4 files changed, 56 insertions(+), 26 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index dab62712..06065640 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -419,9 +419,9 @@ namespace client case i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2: // 5 { auto it2 = m_LeaseSetRequests.find (key); - if (it2 != m_LeaseSetRequests.end () && it2->second->requestedIdentity) + if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedIdentity); + auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key @@ -644,9 +644,10 @@ namespace client m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; } + auto blindedKey = std::make_shared(dest, i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); // always assume type 11 i2p::data::IdentHash ident; - i2p::data::LeaseSet2::CalculateStoreHash (dest, i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519, ident); // always assume type 11 - m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), ident, requestComplete, dest)); + i2p::data::LeaseSet2::CalculateStoreHash (blindedKey, ident); + m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), ident, requestComplete, blindedKey)); return true; } @@ -667,19 +668,20 @@ namespace client void LeaseSetDestination::CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify) { + auto blindedKey = std::make_shared(dest, i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); // always assume type 11 i2p::data::IdentHash ident; - i2p::data::LeaseSet2::CalculateStoreHash (dest, i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519, ident); // always assume type 11 + i2p::data::LeaseSet2::CalculateStoreHash (blindedKey, ident); CancelDestinationRequest (ident, notify); } - void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedIdentity) + void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedBlindedKey) { std::set excluded; auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, excluded); if (floodfill) { auto request = std::make_shared (m_Service); - request->requestedIdentity = requestedIdentity; // for encrypted LeaseSet2 + request->requestedBlindedKey = requestedBlindedKey; // for encrypted LeaseSet2 if (requestComplete) request->requestComplete.push_back (requestComplete); auto ts = i2p::util::GetSecondsSinceEpoch (); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 57b6e114..d2ef9f7a 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -82,7 +82,7 @@ namespace client std::list requestComplete; std::shared_ptr outboundTunnel; std::shared_ptr replyTunnel; - std::shared_ptr requestedIdentity; // for encrypted LeaseSet2 only + std::shared_ptr requestedBlindedKey; // for encrypted LeaseSet2 only void Complete (std::shared_ptr ls) { @@ -148,7 +148,7 @@ namespace client void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len); void HandleDeliveryStatusMessage (std::shared_ptr msg); - void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedIdentity = nullptr); + void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedBlindedKey = nullptr); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 0c0ea35f..f0f2d56d 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -253,6 +253,16 @@ namespace data memcpy (m_Buffer, buf, len); } + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType): + m_BlindedSigType (blindedKeyType) + { + if (!identity) return; + auto len = identity->GetSigningPublicKeyLen (); + m_PublicKey.resize (len); + memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); + m_SigType = identity->GetSigningKeyType (); + } + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases): LeaseSet (storeLeases), m_StoreType (storeType) { @@ -263,10 +273,10 @@ namespace data ReadFromBuffer (buf, len); } - LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr identity): + LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key): LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { - ReadFromBufferEncrypted (buf, len, identity); + ReadFromBufferEncrypted (buf, len, key); } void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature) @@ -423,7 +433,7 @@ namespace data return offset; } - void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr identity) + void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key) { size_t offset = 0; // blinded key @@ -463,7 +473,7 @@ namespace data VerifySignature (blindedVerifier, buf, len, offset); SetIsValid (verified); // handle ciphertext - if (verified && identity && lenOuterCiphertext >= 32) + if (verified && key && lenOuterCiphertext >= 32) { SetIsValid (false); // we must verify it again in Layer 2 if (blindedKeyType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519) @@ -472,7 +482,7 @@ namespace data char date[9]; i2p::util::GetCurrentDate (date); uint8_t blinded[32]; - BlindPublicKey (identity, date, blindedKeyType, blinded); + BlindPublicKey (key, date, blinded); if (memcmp (blindedPublicKey, blinded, 32)) { LogPrint (eLogError, "LeaseSet2: blinded public key doesn't match"); @@ -483,9 +493,9 @@ namespace data uint8_t credential[32], subcredential[36]; // A = destination's signing public key // stA = signature type of A, 2 bytes big endian - uint16_t stA = htobe16 (identity->GetSigningKeyType ()); + uint16_t stA = htobe16 (key->GetSigType ()); // credential = H("credential", A || stA || stA1) - H ("credential", { {identity->GetSigningPublicKeyBuffer (), identity->GetSigningPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {stA1, 2} }, credential); + H ("credential", { {key->GetPublicKey (), key->GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {stA1, 2} }, credential); // subcredential = H("subcredential", credential || blindedPublicKey) H ("subcredential", { {credential, 32}, {blindedPublicKey, blindedKeyLen} }, subcredential); // outer key @@ -535,18 +545,19 @@ namespace data SHA256_Final (hash, &ctx); } - void LeaseSet2::BlindPublicKey (std::shared_ptr identity, const char * date, SigningKeyType blindedKeyType, uint8_t * blindedKey) + void LeaseSet2::BlindPublicKey (std::shared_ptr key, const char * date, uint8_t * blindedKey) { - uint16_t stA = htobe16 (identity->GetSigningKeyType ()), stA1 = htobe16 (blindedKeyType); + uint16_t stA = htobe16 (key->GetSigType ()), stA1 = htobe16 (key->GetBlindedSigType ()); uint8_t salt[32], seed[64]; //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) - H ("I2PGenerateAlpha", { {identity->GetSigningPublicKeyBuffer (), identity->GetSigningPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); + H ("I2PGenerateAlpha", { {key->GetPublicKey (), key->GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); - i2p::crypto::GetEd25519 ()->BlindPublicKey (identity->GetSigningPublicKeyBuffer (), seed, blindedKey); + i2p::crypto::GetEd25519 ()->BlindPublicKey (key->GetPublicKey (), seed, blindedKey); } - void LeaseSet2::CalculateStoreHash (std::shared_ptr identity, SigningKeyType blindedKeyType, i2p::data::IdentHash& hash) + void LeaseSet2::CalculateStoreHash (std::shared_ptr key, i2p::data::IdentHash& hash) { + auto blindedKeyType = key->GetBlindedSigType (); if (blindedKeyType != i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 && blindedKeyType != SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) { @@ -556,7 +567,7 @@ namespace data char date[9]; i2p::util::GetCurrentDate (date); uint8_t blinded[32]; - BlindPublicKey (identity, date, blindedKeyType, blinded); + BlindPublicKey (key, date, blinded); auto stA1 = htobe16 (blindedKeyType); SHA256_CTX ctx; SHA256_Init (&ctx); diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index d3e7cfc3..dcb21221 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -127,19 +127,36 @@ namespace data const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7; const uint16_t LEASESET2_FLAG_OFFLINE_KEYS = 0x0001; + + class BlindedPublicKey // for encrypted LS2 + { + public: + + BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + + const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; + size_t GetPublicKeyLen () const { return m_PublicKey.size (); }; + SigningKeyType GetSigType () const { return m_SigType; }; + SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; + + private: + + std::vector m_PublicKey; + i2p::data::SigningKeyType m_SigType, m_BlindedSigType; + }; class LeaseSet2: public LeaseSet { public: LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true); - LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr identity); // store type 5, called from local netdb only + LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key); // store type 5, called from local netdb only uint8_t GetStoreType () const { return m_StoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; std::shared_ptr GetTransientVerifier () const { return m_TransientVerifier; }; void Update (const uint8_t * buf, size_t len, bool verifySignature); - static void CalculateStoreHash (std::shared_ptr identity, SigningKeyType blindedKeyType, i2p::data::IdentHash& hash); + static void CalculateStoreHash (std::shared_ptr key, i2p::data::IdentHash& hash); // implements RoutingDestination void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; @@ -147,7 +164,7 @@ namespace data private: void ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity = true, bool verifySignature = true); - void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr identity); + void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key); size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len); size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len); @@ -158,7 +175,7 @@ namespace data // for encrypted LS static void H (const std::string& p, const std::vector >& bufs, uint8_t * hash); - static void BlindPublicKey (std::shared_ptr identity, const char * date, SigningKeyType blindedKeyType, uint8_t * blindedKey); // blinded key 32 bytes, date is 8 chars "YYYYMMDD" + static void BlindPublicKey (std::shared_ptr key, const char * date, uint8_t * blindedKey); // blinded key 32 bytes, date is 8 chars "YYYYMMDD" private: