mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-08 22:13:48 +01:00
support multiple encryption keys through the I2CP
This commit is contained in:
parent
9135772f89
commit
e135696530
6 changed files with 46 additions and 23 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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 ());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Add table
Reference in a new issue