mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-08-26 10:10:24 +01:00
handle multiple ECIESx25519 encryption keys
Some checks failed
Build Debian packages / bookworm (push) Has been cancelled
Build Debian packages / bullseye (push) Has been cancelled
Build Debian packages / trixie (push) Has been cancelled
Build on FreeBSD / with UPnP (push) Has been cancelled
Build on OSX / With USE_UPNP=no (push) Has been cancelled
Build on OSX / With USE_UPNP=yes (push) Has been cancelled
Build on Windows / clang-x86_64 (push) Has been cancelled
Build on Windows / i686 (push) Has been cancelled
Build on Windows / ucrt-x86_64 (push) Has been cancelled
Build on Windows / x86_64 (push) Has been cancelled
Build on Windows / CMake clang-x86_64 (push) Has been cancelled
Build on Windows / CMake i686 (push) Has been cancelled
Build on Windows / CMake ucrt-x86_64 (push) Has been cancelled
Build on Windows / XP (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=no (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Has been cancelled
Build containers / Building container for linux/amd64 (push) Has been cancelled
Build containers / Building container for linux/arm64 (push) Has been cancelled
Build containers / Building container for linux/arm/v7 (push) Has been cancelled
Build containers / Pushing merged manifest (push) Has been cancelled
Build on Windows / CMake x86_64 (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=yes (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Has been cancelled
Build containers / Building container for linux/386 (push) Has been cancelled
Some checks failed
Build Debian packages / bookworm (push) Has been cancelled
Build Debian packages / bullseye (push) Has been cancelled
Build Debian packages / trixie (push) Has been cancelled
Build on FreeBSD / with UPnP (push) Has been cancelled
Build on OSX / With USE_UPNP=no (push) Has been cancelled
Build on OSX / With USE_UPNP=yes (push) Has been cancelled
Build on Windows / clang-x86_64 (push) Has been cancelled
Build on Windows / i686 (push) Has been cancelled
Build on Windows / ucrt-x86_64 (push) Has been cancelled
Build on Windows / x86_64 (push) Has been cancelled
Build on Windows / CMake clang-x86_64 (push) Has been cancelled
Build on Windows / CMake i686 (push) Has been cancelled
Build on Windows / CMake ucrt-x86_64 (push) Has been cancelled
Build on Windows / XP (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=no (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Has been cancelled
Build containers / Building container for linux/amd64 (push) Has been cancelled
Build containers / Building container for linux/arm64 (push) Has been cancelled
Build containers / Building container for linux/arm/v7 (push) Has been cancelled
Build containers / Pushing merged manifest (push) Has been cancelled
Build on Windows / CMake x86_64 (push) Has been cancelled
Build on Ubuntu / Make with USE_UPNP=yes (push) Has been cancelled
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Has been cancelled
Build containers / Building container for linux/386 (push) Has been cancelled
This commit is contained in:
parent
edc27d5bcb
commit
3a18e7ab91
2 changed files with 68 additions and 36 deletions
|
@ -28,8 +28,7 @@ namespace client
|
|||
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, bool isSameThread,
|
||||
const std::map<std::string, std::string>& params):
|
||||
LeaseSetDestination (service, isPublic, ¶ms),
|
||||
m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()),
|
||||
m_IsCreatingLeaseSet (false), m_IsSameThread (isSameThread),
|
||||
m_Owner (owner), m_Identity (identity), m_IsCreatingLeaseSet (false), m_IsSameThread (isSameThread),
|
||||
m_LeaseSetCreationTimer (service), m_ReadinessCheckTimer (service)
|
||||
{
|
||||
}
|
||||
|
@ -42,26 +41,59 @@ namespace client
|
|||
m_Owner = nullptr;
|
||||
}
|
||||
|
||||
void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key)
|
||||
void I2CPDestination::SetEncryptionPrivateKey (i2p::data::CryptoKeyType keyType, const uint8_t * key)
|
||||
{
|
||||
m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key);
|
||||
bool exist = false;
|
||||
auto it = m_EncryptionKeys.find (keyType);
|
||||
if (it != m_EncryptionKeys.end () && !memcmp (it->second->priv.data (), key, it->second->priv.size ())) // new key?
|
||||
exist = true;
|
||||
if (!exist)
|
||||
{
|
||||
auto encryptionKey = std::make_shared<i2p::crypto::LocalEncryptionKey> (keyType);
|
||||
memcpy (encryptionKey->priv.data (), key, encryptionKey->priv.size ());
|
||||
encryptionKey->CreateDecryptor (); // from private key
|
||||
m_EncryptionKeys.insert_or_assign (keyType, encryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
void I2CPDestination::SetECIESx25519EncryptionPrivateKey (const uint8_t * key)
|
||||
void I2CPDestination::SetECIESx25519EncryptionPrivateKey (i2p::data::CryptoKeyType keyType, const uint8_t * key)
|
||||
{
|
||||
if (!m_ECIESx25519Decryptor || memcmp (m_ECIESx25519PrivateKey, key, 32)) // new key?
|
||||
bool exist = false;
|
||||
auto it = m_EncryptionKeys.find (keyType);
|
||||
if (it != m_EncryptionKeys.end () && !memcmp (it->second->priv.data (), key, it->second->priv.size ())) // new key?
|
||||
exist = true;
|
||||
if (!exist)
|
||||
{
|
||||
m_ECIESx25519Decryptor = std::make_shared<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key, true); // calculate public
|
||||
memcpy (m_ECIESx25519PrivateKey, key, 32);
|
||||
auto encryptionKey = std::make_shared<i2p::crypto::LocalEncryptionKey> (keyType);
|
||||
memcpy (encryptionKey->priv.data (), key, encryptionKey->priv.size ());
|
||||
// create decryptor manually
|
||||
auto decryptor = std::make_shared<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key, true); // calculate publicKey
|
||||
encryptionKey->decryptor = decryptor;
|
||||
// assign public key from decryptor
|
||||
memcpy (encryptionKey->pub.data (), decryptor->GetPubicKey (), encryptionKey->pub.size ());
|
||||
// insert or replace new
|
||||
m_EncryptionKeys.insert_or_assign (keyType, encryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const
|
||||
{
|
||||
if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor)
|
||||
return m_ECIESx25519Decryptor->Decrypt (encrypted, data);
|
||||
if (m_Decryptor)
|
||||
return m_Decryptor->Decrypt (encrypted, data);
|
||||
std::shared_ptr<i2p::crypto::LocalEncryptionKey> encryptionKey;
|
||||
if (!m_EncryptionKeys.empty ())
|
||||
{
|
||||
if (m_EncryptionKeys.rbegin ()->first == preferredCrypto)
|
||||
encryptionKey = m_EncryptionKeys.rbegin ()->second;
|
||||
else
|
||||
{
|
||||
auto it = m_EncryptionKeys.find (preferredCrypto);
|
||||
if (it != m_EncryptionKeys.end ())
|
||||
encryptionKey = it->second;
|
||||
}
|
||||
if (!encryptionKey)
|
||||
encryptionKey = m_EncryptionKeys.rbegin ()->second;
|
||||
}
|
||||
if (encryptionKey)
|
||||
return encryptionKey->decryptor->Decrypt (encrypted, data);
|
||||
else
|
||||
LogPrint (eLogError, "I2CP: Decryptor is not set");
|
||||
return false;
|
||||
|
@ -69,21 +101,31 @@ namespace client
|
|||
|
||||
const uint8_t * I2CPDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const
|
||||
{
|
||||
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor)
|
||||
return m_ECIESx25519Decryptor->GetPubicKey ();
|
||||
auto it = m_EncryptionKeys.find (keyType);
|
||||
if (it != m_EncryptionKeys.end ())
|
||||
return it->second->pub.data ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool I2CPDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const
|
||||
{
|
||||
return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType;
|
||||
#if __cplusplus >= 202002L // C++20
|
||||
return m_EncryptionKeys.contains (keyType);
|
||||
#else
|
||||
return m_EncryptionKeys.count (keyType) > 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
i2p::data::CryptoKeyType I2CPDestination::GetPreferredCryptoType () const
|
||||
{
|
||||
if (m_ECIESx25519Decryptor)
|
||||
return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD;
|
||||
return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
||||
return !m_EncryptionKeys.empty () ? m_EncryptionKeys.rbegin ()->first : 0;
|
||||
}
|
||||
|
||||
i2p::data::CryptoKeyType I2CPDestination::GetRatchetsHighestCryptoType () const
|
||||
{
|
||||
if (m_EncryptionKeys.empty ()) return 0;
|
||||
auto cryptoType = m_EncryptionKeys.rbegin ()->first;
|
||||
return cryptoType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? cryptoType : 0;
|
||||
}
|
||||
|
||||
void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len,
|
||||
|
@ -813,7 +855,7 @@ namespace client
|
|||
// we always assume this field as 20 bytes (DSA) regardless actual size
|
||||
// instead of
|
||||
//offset += m_Destination->GetIdentity ()->GetSigningPrivateKeyLen ();
|
||||
m_Destination->SetEncryptionPrivateKey (buf + offset);
|
||||
m_Destination->SetEncryptionPrivateKey (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, buf + offset);
|
||||
offset += 256;
|
||||
m_Destination->LeaseSetCreated (buf + offset, len - offset);
|
||||
}
|
||||
|
@ -846,13 +888,10 @@ namespace client
|
|||
uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type
|
||||
uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length
|
||||
if (offset + keyLen > len) return;
|
||||
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
||||
m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
|
||||
if (keyType >= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
||||
m_Destination->SetECIESx25519EncryptionPrivateKey (keyType, buf + offset);
|
||||
else
|
||||
{
|
||||
m_Destination->SetEncryptionType (keyType);
|
||||
m_Destination->SetEncryptionPrivateKey (buf + offset);
|
||||
}
|
||||
m_Destination->SetEncryptionPrivateKey (keyType, buf + offset); // from identity
|
||||
offset += keyLen;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,9 +92,8 @@ namespace client
|
|||
|
||||
void Stop () override;
|
||||
|
||||
void SetEncryptionPrivateKey (const uint8_t * key);
|
||||
void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; };
|
||||
void SetECIESx25519EncryptionPrivateKey (const uint8_t * key);
|
||||
void SetEncryptionPrivateKey (i2p::data::CryptoKeyType keyType, const uint8_t * key);
|
||||
void SetECIESx25519EncryptionPrivateKey (i2p::data::CryptoKeyType keyType, const uint8_t * key);
|
||||
void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession
|
||||
void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession
|
||||
void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession
|
||||
|
@ -109,10 +108,7 @@ namespace client
|
|||
protected:
|
||||
|
||||
// GarlicDestination
|
||||
i2p::data::CryptoKeyType GetRatchetsHighestCryptoType () const override
|
||||
{
|
||||
return m_ECIESx25519Decryptor ? i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD : 0;
|
||||
}
|
||||
i2p::data::CryptoKeyType GetRatchetsHighestCryptoType () const override;
|
||||
// LeaseSetDestination
|
||||
void CleanupDestination () override;
|
||||
i2p::data::CryptoKeyType GetPreferredCryptoType () const override;
|
||||
|
@ -134,10 +130,7 @@ namespace client
|
|||
|
||||
std::shared_ptr<I2CPSession> m_Owner;
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_Identity;
|
||||
i2p::data::CryptoKeyType m_EncryptionKeyType;
|
||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor; // standard
|
||||
std::shared_ptr<i2p::crypto::ECIESX25519AEADRatchetDecryptor> m_ECIESx25519Decryptor;
|
||||
uint8_t m_ECIESx25519PrivateKey[32];
|
||||
std::map<i2p::data::CryptoKeyType, std::shared_ptr<i2p::crypto::LocalEncryptionKey> > m_EncryptionKeys; // last is most preferable
|
||||
uint64_t m_LeaseSetExpirationTime;
|
||||
bool m_IsCreatingLeaseSet, m_IsSameThread;
|
||||
boost::asio::deadline_timer m_LeaseSetCreationTimer, m_ReadinessCheckTimer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue