diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 5ef51176..89baf945 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -272,7 +272,8 @@ namespace client if (!m_Pool) return nullptr; if (!m_LeaseSet) UpdateLeaseSet (); - return GetLeaseSetMt (); + auto ls = GetLeaseSetMt (); + return (ls && ls->GetInnerLeaseSet ()) ? ls->GetInnerLeaseSet () : ls; // always non-encrypted } std::shared_ptr LeaseSetDestination::GetLeaseSetMt () @@ -592,27 +593,31 @@ namespace client { if (ecode != boost::asio::error::operation_aborted) { + auto ls = GetLeaseSetMt (); + if (!ls) + { + LogPrint (eLogWarning, "Destination: couldn't verify LeaseSet for ", GetIdentHash().ToBase32()); + return; + } auto s = shared_from_this (); - RequestLeaseSet (GetIdentHash (), - // "this" added due to bug in gcc 4.7-4.8 - [s,this](std::shared_ptr leaseSet) + RequestLeaseSet (ls->GetStoreHash (), + [s, ls](std::shared_ptr leaseSet) { if (leaseSet) { - auto ls = s->GetLeaseSetMt (); - if (ls && *ls == *leaseSet) + if (*ls == *leaseSet) { // we got latest LeasetSet - LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32()); + LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", s->GetIdentHash().ToBase32()); s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL)); s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); return; } else - LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", GetIdentHash().ToBase32()); + LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", s->GetIdentHash().ToBase32()); } else - LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", GetIdentHash().ToBase32()); + LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", s->GetIdentHash().ToBase32()); // we have to publish again s->Publish (); }); @@ -1121,10 +1126,13 @@ namespace client } else { - // standard LS2 (type 3) assumed for now. TODO: implement others + // standard LS2 (type 3) first auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; - leaseSet = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, + auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels); + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) // encrypt if type 5 + ls2 = std::make_shared (ls2, m_Keys); + leaseSet = ls2; } SetLeaseSet (leaseSet); } diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index a8eccbc2..d8030a45 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -266,7 +266,7 @@ namespace data BlindedPublicKey::BlindedPublicKey (const std::string& b33) { - uint8_t addr[40]; // TODO: define lenght from b33 + uint8_t addr[40]; // TODO: define length from b33 size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40); uint32_t checksum = crc32 (0, addr + 3, l - 3); // checksum is Little Endian @@ -650,7 +650,7 @@ namespace data ReadFromBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1); } else - LogPrint (eLogError, "LeaseSet2: unxpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet"); + LogPrint (eLogError, "LeaseSet2: unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet"); } } @@ -853,8 +853,8 @@ namespace data m_Buffer[0] = storeType; } - LocalLeaseSet2::LocalLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, i2p::data::SigningKeyType blindedKeyType): - LocalLeaseSet (ls->GetIdentity (), nullptr, 0) + LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, i2p::data::SigningKeyType blindedKeyType): + LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { size_t lenInnerPlaintext = ls->GetBufferLen () + 1, lenOuterPlaintext = lenInnerPlaintext + 32 + 1, lenOuterCiphertext = lenOuterPlaintext + 32; @@ -905,7 +905,7 @@ namespace data // signature blindedSigner->Sign (m_Buffer, offset, m_Buffer + offset); // store hash - m_StoreHash.reset (new IdentHash (blindedKey.GetStoreHash ())); + m_StoreHash = blindedKey.GetStoreHash (); } } } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index b526728a..7fd4eb90 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -26,7 +26,7 @@ namespace data IdentHash tunnelGateway; uint32_t tunnelID; uint64_t endDate; // 0 means invalid - bool isUpdated; // trasient + bool isUpdated; // transient /* return true if this lease expires within t millisecond + fudge factor */ bool ExpiresWithin( const uint64_t t, const uint64_t fudge = 1000 ) const { auto expire = i2p::util::GetMillisecondsSinceEpoch (); @@ -237,6 +237,7 @@ namespace data virtual uint8_t GetStoreType () const { return NETDB_STORE_TYPE_LEASESET; }; virtual const IdentHash& GetStoreHash () const { return GetIdentHash (); }; // differ from ident hash for encrypted LeaseSet2 + virtual std::shared_ptr GetInnerLeaseSet () const { return nullptr; }; // non-null for encrypted LeaseSet2 private: @@ -254,7 +255,6 @@ namespace data uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, std::vector > tunnels); LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); - LocalLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, i2p::data::SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); // encrypted virtual ~LocalLeaseSet2 () { delete[] m_Buffer; }; @@ -262,13 +262,30 @@ namespace data size_t GetBufferLen () const { return m_BufferLen; }; uint8_t GetStoreType () const { return m_Buffer[0]; }; - const IdentHash& GetStoreHash () const { return m_StoreHash ? *m_StoreHash : LocalLeaseSet::GetStoreHash (); }; - private: + protected: + + LocalLeaseSet2 (std::shared_ptr identity): LocalLeaseSet (identity, nullptr, 0), m_Buffer (nullptr), m_BufferLen(0) {}; // called from LocalEncryptedLeaseSet2 + + protected: uint8_t * m_Buffer; // 1 byte store type + actual buffer size_t m_BufferLen; - std::unique_ptr m_StoreHash; // for encrypted + }; + + class LocalEncryptedLeaseSet2: public LocalLeaseSet2 + { + public: + + LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, i2p::data::SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + + const IdentHash& GetStoreHash () const { return m_StoreHash; }; + std::shared_ptr GetInnerLeaseSet () const { return m_InnerLeaseSet; }; + + private: + + IdentHash m_StoreHash; + std::shared_ptr m_InnerLeaseSet; }; } }