mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-11 13:27:52 +00:00
support multiple encryption keys through the I2CP
This commit is contained in:
parent
9135772f89
commit
e135696530
@ -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
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
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
|
||||
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 ());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
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…
Reference in New Issue
Block a user