From 81658d2ff918de09a1810dcf5b6f84a95e920a61 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Nov 2017 15:05:22 -0500 Subject: [PATCH] generic encryption for RoutingDestination --- libi2pd/CryptoKey.cpp | 25 +++++++------------------ libi2pd/CryptoKey.h | 20 ++++++++++---------- libi2pd/Identity.cpp | 37 +++++++++++++++++++++++++++++++++++-- libi2pd/Identity.h | 17 +++++++++++------ libi2pd/LeaseSet.cpp | 7 +++++++ libi2pd/LeaseSet.h | 3 ++- libi2pd/RouterInfo.cpp | 6 ++++++ libi2pd/RouterInfo.h | 8 +++++--- 8 files changed, 83 insertions(+), 40 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 000475d3..a0858b91 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -11,11 +11,9 @@ namespace crypto memcpy (m_PublicKey, pub, 256); } - void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) + void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) { - BN_CTX * ctx = BN_CTX_new (); ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, true); - BN_CTX_free (ctx); } ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) @@ -23,11 +21,9 @@ namespace crypto memcpy (m_PrivateKey, priv, 256); } - void ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) + bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { - BN_CTX * ctx = BN_CTX_new (); - ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, true); - BN_CTX_free (ctx); + return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, true); } ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) @@ -47,14 +43,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) + void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) { if (m_Curve && m_PublicKey) - { - BN_CTX * ctx = BN_CTX_new (); ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx); - BN_CTX_free (ctx); - } } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -69,14 +61,11 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - void ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) + bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_Curve && m_PrivateKey) - { - BN_CTX * ctx = BN_CTX_new (); - ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); - BN_CTX_free (ctx); - } + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); + return false;; } void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub) diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index abd51d5a..f08a15b2 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -13,7 +13,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 512 bytes encrypted + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) = 0; // 222 bytes data, 512 bytes encrypted }; class CryptoKeyDecryptor @@ -21,40 +21,40 @@ namespace crypto public: virtual ~CryptoKeyDecryptor () {}; - virtual void Decrypt (const uint8_t * encrypted, uint8_t * data); // 512 bytes encrypted, 222 bytes data + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; // 512 bytes encrypted, 222 bytes data }; - class ElGamalEncryptor // for destination + class ElGamalEncryptor: public CryptoKeyEncryptor // for destination { public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); private: uint8_t m_PublicKey[256]; }; - class ElGamalDecryptor // for destination + class ElGamalDecryptor: public CryptoKeyDecryptor // for destination { public: ElGamalDecryptor (const uint8_t * priv); - void Decrypt (const uint8_t * encrypted, uint8_t * data); + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); private: uint8_t m_PrivateKey[256]; }; - class ECIESP256Encryptor + class ECIESP256Encryptor: public CryptoKeyEncryptor { public: ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); private: @@ -63,13 +63,13 @@ namespace crypto }; - class ECIESP256Decryptor + class ECIESP256Decryptor: public CryptoKeyDecryptor { public: ECIESP256Decryptor (const uint8_t * priv); ~ECIESP256Decryptor (); - void Decrypt (const uint8_t * encrypted, uint8_t * data); + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); private: diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 87a5d84c..04e1c576 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -1,7 +1,6 @@ #include #include #include "Crypto.h" -#include "CryptoKey.h" #include "I2PEndian.h" #include "Log.h" #include "Identity.h" @@ -443,6 +442,23 @@ namespace data m_Verifier = nullptr; } + std::shared_ptr IdentityEx::CreateEncryptor (const uint8_t * key) const + { + if (!key) key = GetEncryptionPublicKey (); // use publicKey + switch (GetCryptoKeyType ()) + { + case CRYPTO_KEY_TYPE_ELGAMAL: + return std::make_shared(key); + break; + case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: + return std::make_shared(key); + break; + default: + LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)GetCryptoKeyType ()); + }; + return nullptr; + } + PrivateKeys& PrivateKeys::operator=(const Keys& keys) { m_Public = std::make_shared(Identity (keys)); @@ -568,6 +584,23 @@ namespace data return nullptr; // TODO: implement me } + std::shared_ptr PrivateKeys::CreateDecryptor (const uint8_t * key) const + { + if (!key) key = m_PrivateKey; // use privateKey + switch (m_Public->GetCryptoKeyType ()) + { + case CRYPTO_KEY_TYPE_ELGAMAL: + return std::make_shared(key); + break; + case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: + return std::make_shared(key); + break; + default: + LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)m_Public->GetCryptoKeyType ()); + }; + return nullptr; + } + PrivateKeys PrivateKeys::CreateRandomKeys (SigningKeyType type, CryptoKeyType cryptoType) { if (type != SIGNING_KEY_TYPE_DSA_SHA1) @@ -627,7 +660,7 @@ namespace data case CRYPTO_KEY_TYPE_ELGAMAL: i2p::crypto::GenerateElGamalKeyPair(priv, pub); break; - case CRYPTO_KEY_TYPE_ECICS_P256_SHA256_AES256CBC: + case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: i2p::crypto::CreateECIESP256RandomKeys (priv, pub); break; default: diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 84c396c1..d321e726 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -8,6 +8,7 @@ #include #include "Base.h" #include "Signature.h" +#include "CryptoKey.h" namespace i2p { @@ -52,7 +53,7 @@ namespace data const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; - const uint16_t CRYPTO_KEY_TYPE_ECICS_P256_SHA256_AES256CBC = 65280; // TODO: change to actual code + const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 65280; // TODO: change to actual code const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0; const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1; @@ -88,11 +89,12 @@ namespace data size_t ToBuffer (uint8_t * buf, size_t len) const; size_t FromBase64(const std::string& s); std::string ToBase64 () const; - const Identity& GetStandardIdentity () const { return m_StandardIdentity; }; + const Identity& GetStandardIdentity () const { return m_StandardIdentity; }; const IdentHash& GetIdentHash () const { return m_IdentHash; }; - const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; }; - uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; }; + const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; }; + uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; }; + std::shared_ptr CreateEncryptor (const uint8_t * key) const; size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; }; size_t GetSigningPublicKeyLen () const; size_t GetSigningPrivateKeyLen () const; @@ -136,7 +138,7 @@ namespace data const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; uint8_t * GetPadding(); - void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } + void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } void Sign (const uint8_t * buf, int len, uint8_t * signature) const; size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); }; @@ -146,6 +148,8 @@ namespace data size_t FromBase64(const std::string& s); std::string ToBase64 () const; + std::shared_ptr CreateDecryptor (const uint8_t * key) const; + static PrivateKeys CreateRandomKeys (SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1, CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL); static void GenerateCryptoKeyPair (CryptoKeyType type, uint8_t * priv, uint8_t * pub); // priv and pub are 256 bytes long @@ -187,7 +191,8 @@ namespace data virtual ~RoutingDestination () {}; virtual std::shared_ptr GetIdentity () const = 0; - virtual const uint8_t * GetEncryptionPublicKey () const = 0; + virtual const uint8_t * GetEncryptionPublicKey () const = 0; // deprecated + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) = 0; // encrypt data for virtual bool IsDestination () const = 0; // for garlic const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 8b8a17c0..3faf085a 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -208,6 +208,13 @@ namespace data return ts > m_ExpirationTime; } + void LeaseSet::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + { + auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey); + if (encryptor) + encryptor->Encrypt (data, encrypted, ctx); + } + LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels): m_ExpirationTime (0), m_Identity (identity) { diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 68b993f3..ec9744eb 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -76,7 +76,8 @@ namespace data // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_Identity; }; - const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionKey; }; + const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionKey; }; // deprecated + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); bool IsDestination () const { return true; }; private: diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3719e68a..c73b8afa 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -828,5 +828,11 @@ namespace data m_Profile = GetRouterProfile (GetIdentHash ()); return m_Profile; } + + void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + { + // TODO: we always assume ElGamal for RouterInfo, might change later + i2p::crypto::ElGamalEncrypt (m_RouterIdentity->GetEncryptionPublicKey (), data, encrypted, ctx); + } } } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 544639f7..2f4800e6 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -181,12 +181,14 @@ namespace data void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; bool IsNewer (const uint8_t * buf, size_t len) const; - /** return true if we are in a router family and the signature is valid */ - bool IsFamily(const std::string & fam) const; + /** return true if we are in a router family and the signature is valid */ + bool IsFamily(const std::string & fam) const; // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_RouterIdentity; }; - const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity->GetStandardIdentity ().publicKey; }; + const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity->GetStandardIdentity ().publicKey; }; // deprecated + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); + bool IsDestination () const { return false; }; private: