Browse Source

generic encryption for RoutingDestination

pull/996/head
orignal 7 years ago
parent
commit
81658d2ff9
  1. 25
      libi2pd/CryptoKey.cpp
  2. 20
      libi2pd/CryptoKey.h
  3. 37
      libi2pd/Identity.cpp
  4. 17
      libi2pd/Identity.h
  5. 7
      libi2pd/LeaseSet.cpp
  6. 3
      libi2pd/LeaseSet.h
  7. 6
      libi2pd/RouterInfo.cpp
  8. 8
      libi2pd/RouterInfo.h

25
libi2pd/CryptoKey.cpp

@ -11,11 +11,9 @@ namespace crypto
memcpy (m_PublicKey, pub, 256); 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); ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, true);
BN_CTX_free (ctx);
} }
ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv)
@ -23,11 +21,9 @@ namespace crypto
memcpy (m_PrivateKey, priv, 256); 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 (); return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, true);
ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, true);
BN_CTX_free (ctx);
} }
ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub)
@ -47,14 +43,10 @@ namespace crypto
if (m_PublicKey) EC_POINT_free (m_PublicKey); 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) if (m_Curve && m_PublicKey)
{
BN_CTX * ctx = BN_CTX_new ();
ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx); ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx);
BN_CTX_free (ctx);
}
} }
ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv)
@ -69,14 +61,11 @@ namespace crypto
if (m_PrivateKey) BN_free (m_PrivateKey); 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) if (m_Curve && m_PrivateKey)
{ return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx);
BN_CTX * ctx = BN_CTX_new (); return false;;
ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx);
BN_CTX_free (ctx);
}
} }
void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub) void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub)

20
libi2pd/CryptoKey.h

@ -13,7 +13,7 @@ namespace crypto
public: public:
virtual ~CryptoKeyEncryptor () {}; 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 class CryptoKeyDecryptor
@ -21,40 +21,40 @@ namespace crypto
public: public:
virtual ~CryptoKeyDecryptor () {}; 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: public:
ElGamalEncryptor (const uint8_t * pub); 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: private:
uint8_t m_PublicKey[256]; uint8_t m_PublicKey[256];
}; };
class ElGamalDecryptor // for destination class ElGamalDecryptor: public CryptoKeyDecryptor // for destination
{ {
public: public:
ElGamalDecryptor (const uint8_t * priv); 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: private:
uint8_t m_PrivateKey[256]; uint8_t m_PrivateKey[256];
}; };
class ECIESP256Encryptor class ECIESP256Encryptor: public CryptoKeyEncryptor
{ {
public: public:
ECIESP256Encryptor (const uint8_t * pub); ECIESP256Encryptor (const uint8_t * pub);
~ECIESP256Encryptor (); ~ECIESP256Encryptor ();
void Encrypt (const uint8_t * data, uint8_t * encrypted); void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx);
private: private:
@ -63,13 +63,13 @@ namespace crypto
}; };
class ECIESP256Decryptor class ECIESP256Decryptor: public CryptoKeyDecryptor
{ {
public: public:
ECIESP256Decryptor (const uint8_t * priv); ECIESP256Decryptor (const uint8_t * priv);
~ECIESP256Decryptor (); ~ECIESP256Decryptor ();
void Decrypt (const uint8_t * encrypted, uint8_t * data); bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx);
private: private:

37
libi2pd/Identity.cpp

@ -1,7 +1,6 @@
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include "Crypto.h" #include "Crypto.h"
#include "CryptoKey.h"
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Log.h" #include "Log.h"
#include "Identity.h" #include "Identity.h"
@ -443,6 +442,23 @@ namespace data
m_Verifier = nullptr; m_Verifier = nullptr;
} }
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> IdentityEx::CreateEncryptor (const uint8_t * key) const
{
if (!key) key = GetEncryptionPublicKey (); // use publicKey
switch (GetCryptoKeyType ())
{
case CRYPTO_KEY_TYPE_ELGAMAL:
return std::make_shared<i2p::crypto::ElGamalEncryptor>(key);
break;
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
return std::make_shared<i2p::crypto::ECIESP256Encryptor>(key);
break;
default:
LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)GetCryptoKeyType ());
};
return nullptr;
}
PrivateKeys& PrivateKeys::operator=(const Keys& keys) PrivateKeys& PrivateKeys::operator=(const Keys& keys)
{ {
m_Public = std::make_shared<IdentityEx>(Identity (keys)); m_Public = std::make_shared<IdentityEx>(Identity (keys));
@ -568,6 +584,23 @@ namespace data
return nullptr; // TODO: implement me return nullptr; // TODO: implement me
} }
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> 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<i2p::crypto::ElGamalDecryptor>(key);
break;
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
return std::make_shared<i2p::crypto::ECIESP256Decryptor>(key);
break;
default:
LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)m_Public->GetCryptoKeyType ());
};
return nullptr;
}
PrivateKeys PrivateKeys::CreateRandomKeys (SigningKeyType type, CryptoKeyType cryptoType) PrivateKeys PrivateKeys::CreateRandomKeys (SigningKeyType type, CryptoKeyType cryptoType)
{ {
if (type != SIGNING_KEY_TYPE_DSA_SHA1) if (type != SIGNING_KEY_TYPE_DSA_SHA1)
@ -627,7 +660,7 @@ namespace data
case CRYPTO_KEY_TYPE_ELGAMAL: case CRYPTO_KEY_TYPE_ELGAMAL:
i2p::crypto::GenerateElGamalKeyPair(priv, pub); i2p::crypto::GenerateElGamalKeyPair(priv, pub);
break; break;
case CRYPTO_KEY_TYPE_ECICS_P256_SHA256_AES256CBC: case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
i2p::crypto::CreateECIESP256RandomKeys (priv, pub); i2p::crypto::CreateECIESP256RandomKeys (priv, pub);
break; break;
default: default:

17
libi2pd/Identity.h

@ -8,6 +8,7 @@
#include <atomic> #include <atomic>
#include "Base.h" #include "Base.h"
#include "Signature.h" #include "Signature.h"
#include "CryptoKey.h"
namespace i2p namespace i2p
{ {
@ -52,7 +53,7 @@ namespace data
const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes
const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; 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_DSA_SHA1 = 0;
const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1; 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 ToBuffer (uint8_t * buf, size_t len) const;
size_t FromBase64(const std::string& s); size_t FromBase64(const std::string& s);
std::string ToBase64 () const; 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 IdentHash& GetIdentHash () const { return m_IdentHash; };
const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; }; const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; };
uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; }; uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; };
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (const uint8_t * key) const;
size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; }; size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; };
size_t GetSigningPublicKeyLen () const; size_t GetSigningPublicKeyLen () const;
size_t GetSigningPrivateKeyLen () const; size_t GetSigningPrivateKeyLen () const;
@ -136,7 +138,7 @@ namespace data
const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
uint8_t * GetPadding(); 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; void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); }; 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); size_t FromBase64(const std::string& s);
std::string ToBase64 () const; std::string ToBase64 () const;
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> CreateDecryptor (const uint8_t * key) const;
static PrivateKeys CreateRandomKeys (SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1, CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL); 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 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 ~RoutingDestination () {};
virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0; virtual std::shared_ptr<const IdentityEx> 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 virtual bool IsDestination () const = 0; // for garlic
const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); };

7
libi2pd/LeaseSet.cpp

@ -208,6 +208,13 @@ namespace data
return ts > m_ExpirationTime; 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<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels): LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * encryptionPublicKey, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels):
m_ExpirationTime (0), m_Identity (identity) m_ExpirationTime (0), m_Identity (identity)
{ {

3
libi2pd/LeaseSet.h

@ -76,7 +76,8 @@ namespace data
// implements RoutingDestination // implements RoutingDestination
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; }; std::shared_ptr<const IdentityEx> 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; }; bool IsDestination () const { return true; };
private: private:

6
libi2pd/RouterInfo.cpp

@ -828,5 +828,11 @@ namespace data
m_Profile = GetRouterProfile (GetIdentHash ()); m_Profile = GetRouterProfile (GetIdentHash ());
return m_Profile; 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);
}
} }
} }

8
libi2pd/RouterInfo.h

@ -181,12 +181,14 @@ namespace data
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
bool IsNewer (const uint8_t * buf, size_t len) const; bool IsNewer (const uint8_t * buf, size_t len) const;
/** return true if we are in a router family and the signature is valid */ /** return true if we are in a router family and the signature is valid */
bool IsFamily(const std::string & fam) const; bool IsFamily(const std::string & fam) const;
// implements RoutingDestination // implements RoutingDestination
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; }; std::shared_ptr<const IdentityEx> 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; }; bool IsDestination () const { return false; };
private: private:

Loading…
Cancel
Save