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. 44
      libi2pd_client/I2CP.cpp
  6. 9
      libi2pd_client/I2CP.h

9
libi2pd/Crypto.cpp

@ -375,15 +375,22 @@ namespace crypto @@ -375,15 +375,22 @@ namespace crypto
#endif
}
void X25519Keys::SetPrivateKey (const uint8_t * priv)
void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic)
{
#if OPENSSL_X25519
if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx);
if (m_Pkey) EVP_PKEY_free (m_Pkey);
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
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
memcpy (m_PrivateKey, priv, 32);
if (calculatePublic)
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
#endif
}

2
libi2pd/Crypto.h

@ -88,7 +88,7 @@ namespace crypto @@ -88,7 +88,7 @@ namespace crypto
void GenerateKeys ();
const uint8_t * GetPublicKey () const { return m_PublicKey; };
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);
private:

2
libi2pd/CryptoKey.cpp

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

3
libi2pd/CryptoKey.h

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

44
libi2pd_client/I2CP.cpp

@ -55,12 +55,18 @@ namespace client @@ -55,12 +55,18 @@ namespace client
void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key)
{
memcpy (m_EncryptionPrivateKey, key, 256);
m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), m_EncryptionPrivateKey);
m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key);
}
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
{
if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor)
return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true);
if (m_Decryptor)
return m_Decryptor->Decrypt (encrypted, data, ctx, true);
else
@ -68,6 +74,19 @@ namespace client @@ -68,6 +74,19 @@ namespace client
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)
{
uint32_t length = bufbe32toh (buf);
@ -77,7 +96,8 @@ namespace client @@ -77,7 +96,8 @@ namespace client
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 ();
uint8_t * leases = ls.GetLeases ();
leases[-1] = tunnels.size ();
@ -572,28 +592,22 @@ namespace client @@ -572,28 +592,22 @@ namespace client
offset += ls.GetBufferLen ();
// private keys
int numPrivateKeys = buf[offset]; offset++;
uint16_t currentKeyType = 0;
const uint8_t * currentKey = nullptr;
for (int i = 0; i < numPrivateKeys; i++)
{
if (offset + 4 > len) return;
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 (!currentKey || keyType > currentKeyType)
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)
m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
else
{
currentKeyType = keyType;
currentKey = buf + offset;
m_Destination->SetEncryptionType (keyType);
m_Destination->SetEncryptionPrivateKey (buf + offset);
}
offset += keyLen;
}
// TODO: support multiple keys
if (currentKey)
{
m_Destination->SetEncryptionPrivateKey (currentKey);
m_Destination->SetEncryptionType (currentKeyType);
}
m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ());
}
}

9
libi2pd_client/I2CP.h

@ -75,14 +75,15 @@ namespace client @@ -75,14 +75,15 @@ namespace client
void SetEncryptionPrivateKey (const uint8_t * key);
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 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
// implements LocalDestination
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; };
// TODO: implement GetEncryptionPublicKey
bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const;
const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Identity; };
protected:
@ -101,9 +102,9 @@ namespace client @@ -101,9 +102,9 @@ namespace client
std::shared_ptr<I2CPSession> m_Owner;
std::shared_ptr<const i2p::data::IdentityEx> m_Identity;
uint8_t m_EncryptionPrivateKey[256];
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;
};

Loading…
Cancel
Save