Browse Source

support multiple encryption keys through the I2CP

pull/1535/head
orignal 5 years ago
parent
commit
e135696530
  1. 9
      libi2pd/Crypto.cpp
  2. 2
      libi2pd/Crypto.h
  3. 2
      libi2pd/CryptoKey.cpp
  4. 3
      libi2pd/CryptoKey.h
  5. 42
      libi2pd_client/I2CP.cpp
  6. 9
      libi2pd_client/I2CP.h

9
libi2pd/Crypto.cpp

@ -375,15 +375,22 @@ namespace crypto
#endif #endif
} }
void X25519Keys::SetPrivateKey (const uint8_t * priv) void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic)
{ {
#if OPENSSL_X25519 #if OPENSSL_X25519
if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx);
if (m_Pkey) EVP_PKEY_free (m_Pkey); if (m_Pkey) EVP_PKEY_free (m_Pkey);
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL);
if (calculatePublic)
{
size_t len = 32;
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
}
#else #else
memcpy (m_PrivateKey, priv, 32); memcpy (m_PrivateKey, priv, 32);
if (calculatePublic)
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
#endif #endif
} }

2
libi2pd/Crypto.h

@ -88,7 +88,7 @@ namespace crypto
void GenerateKeys (); void GenerateKeys ();
const uint8_t * GetPublicKey () const { return m_PublicKey; }; const uint8_t * GetPublicKey () const { return m_PublicKey; };
void GetPrivateKey (uint8_t * priv) const; void GetPrivateKey (uint8_t * priv) const;
void SetPrivateKey (const uint8_t * priv); // wihout calculating public void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false);
void Agree (const uint8_t * pub, uint8_t * shared); void Agree (const uint8_t * pub, uint8_t * shared);
private: private:

2
libi2pd/CryptoKey.cpp

@ -166,7 +166,7 @@ namespace crypto
memcpy (pub, m_PublicKey, 32); memcpy (pub, m_PublicKey, 32);
} }
ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic)
{ {
m_StaticKeys.SetPrivateKey (priv); m_StaticKeys.SetPrivateKey (priv);
} }

3
libi2pd/CryptoKey.h

@ -145,11 +145,12 @@ namespace crypto
{ {
public: public:
ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false);
~ECIESX25519AEADRatchetDecryptor () {}; ~ECIESX25519AEADRatchetDecryptor () {};
bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding);
// agree with static and return in sharedSecret (32 bytes) // agree with static and return in sharedSecret (32 bytes)
size_t GetPublicKeyLen () const { return 32; }; size_t GetPublicKeyLen () const { return 32; };
const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); };
private: private:

42
libi2pd_client/I2CP.cpp

@ -55,12 +55,18 @@ namespace client
void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key)
{ {
memcpy (m_EncryptionPrivateKey, key, 256); m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key);
m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), m_EncryptionPrivateKey); }
void I2CPDestination::SetECIESx25519EncryptionPrivateKey (const uint8_t * key)
{
m_ECIESx25519Decryptor = std::make_shared<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key, true); // calculate public
} }
bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const
{ {
if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor)
return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true);
if (m_Decryptor) if (m_Decryptor)
return m_Decryptor->Decrypt (encrypted, data, ctx, true); return m_Decryptor->Decrypt (encrypted, data, ctx, true);
else else
@ -68,6 +74,19 @@ namespace client
return false; return false;
} }
const uint8_t * I2CPDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const
{
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor)
return m_ECIESx25519Decryptor->GetPubicKey ();
return nullptr;
}
bool I2CPDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const
{
return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType;
}
void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len) void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len)
{ {
uint32_t length = bufbe32toh (buf); uint32_t length = bufbe32toh (buf);
@ -77,7 +96,8 @@ namespace client
void I2CPDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels) void I2CPDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels)
{ {
i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPrivateKey, tunnels); // we don't care about encryption key uint8_t priv[256] = {0};
i2p::data::LocalLeaseSet ls (m_Identity, priv, tunnels); // we don't care about encryption key, we need leases only
m_LeaseSetExpirationTime = ls.GetExpirationTime (); m_LeaseSetExpirationTime = ls.GetExpirationTime ();
uint8_t * leases = ls.GetLeases (); uint8_t * leases = ls.GetLeases ();
leases[-1] = tunnels.size (); leases[-1] = tunnels.size ();
@ -572,27 +592,21 @@ namespace client
offset += ls.GetBufferLen (); offset += ls.GetBufferLen ();
// private keys // private keys
int numPrivateKeys = buf[offset]; offset++; int numPrivateKeys = buf[offset]; offset++;
uint16_t currentKeyType = 0;
const uint8_t * currentKey = nullptr;
for (int i = 0; i < numPrivateKeys; i++) for (int i = 0; i < numPrivateKeys; i++)
{ {
if (offset + 4 > len) return; if (offset + 4 > len) return;
uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type
uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length
if (offset + keyLen > len) return; if (offset + keyLen > len) return;
if (!currentKey || keyType > currentKeyType) if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)
m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
else
{ {
currentKeyType = keyType; m_Destination->SetEncryptionType (keyType);
currentKey = buf + offset; m_Destination->SetEncryptionPrivateKey (buf + offset);
} }
offset += keyLen; offset += keyLen;
} }
// TODO: support multiple keys
if (currentKey)
{
m_Destination->SetEncryptionPrivateKey (currentKey);
m_Destination->SetEncryptionType (currentKeyType);
}
m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ());
} }

9
libi2pd_client/I2CP.h

@ -75,14 +75,15 @@ namespace client
void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionPrivateKey (const uint8_t * key);
void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; };
void SetECIESx25519EncryptionPrivateKey (const uint8_t * key);
void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession 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 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 void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession
// implements LocalDestination // implements LocalDestination
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const;
bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const;
// TODO: implement GetEncryptionPublicKey const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Identity; }; std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Identity; };
protected: protected:
@ -101,9 +102,9 @@ namespace client
std::shared_ptr<I2CPSession> m_Owner; std::shared_ptr<I2CPSession> m_Owner;
std::shared_ptr<const i2p::data::IdentityEx> m_Identity; std::shared_ptr<const i2p::data::IdentityEx> m_Identity;
uint8_t m_EncryptionPrivateKey[256];
i2p::data::CryptoKeyType m_EncryptionKeyType; i2p::data::CryptoKeyType m_EncryptionKeyType;
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor; std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor; // standard
std::shared_ptr<i2p::crypto::ECIESX25519AEADRatchetDecryptor> m_ECIESx25519Decryptor;
uint64_t m_LeaseSetExpirationTime; uint64_t m_LeaseSetExpirationTime;
}; };

Loading…
Cancel
Save