mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
extract and verify LS2 transient key
This commit is contained in:
parent
812e2814bc
commit
bce4224d6e
@ -64,7 +64,8 @@ namespace data
|
||||
i2p::crypto::bn2buf (x, signingKey, 32);
|
||||
i2p::crypto::bn2buf (y, signingKey + 32, 32);
|
||||
BN_free (x); BN_free (y);
|
||||
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(signingKey);
|
||||
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>();
|
||||
verifier->SetPublicKey (signingKey);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
||||
|
@ -318,62 +318,56 @@ namespace data
|
||||
return CRYPTO_KEY_TYPE_ELGAMAL;
|
||||
}
|
||||
|
||||
void IdentityEx::CreateVerifier () const
|
||||
i2p::crypto::Verifier * IdentityEx::CreateVerifier (uint16_t keyType)
|
||||
{
|
||||
if (m_Verifier) return; // don't create again
|
||||
auto keyType = GetSigningKeyType ();
|
||||
switch (keyType)
|
||||
{
|
||||
case SIGNING_KEY_TYPE_DSA_SHA1:
|
||||
UpdateVerifier (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey));
|
||||
break;
|
||||
return new i2p::crypto::DSAVerifier ();
|
||||
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
|
||||
{
|
||||
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
|
||||
UpdateVerifier (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
return new i2p::crypto::ECDSAP256Verifier ();
|
||||
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
|
||||
{
|
||||
size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96
|
||||
UpdateVerifier (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
return new i2p::crypto::ECDSAP384Verifier ();
|
||||
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
{
|
||||
uint8_t signingKey[i2p::crypto::ECDSAP521_KEY_LENGTH];
|
||||
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
|
||||
size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128
|
||||
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
|
||||
UpdateVerifier (new i2p::crypto::ECDSAP521Verifier (signingKey));
|
||||
break;
|
||||
}
|
||||
return new i2p::crypto::ECDSAP521Verifier ();
|
||||
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
return new i2p::crypto::EDDSA25519Verifier ();
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
return new i2p::crypto::GOSTR3410_256_Verifier (i2p::crypto::eGOSTR3410CryptoProA);
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
return new i2p::crypto::GOSTR3410_512_Verifier (i2p::crypto::eGOSTR3410TC26A512);
|
||||
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||
LogPrint (eLogError, "Identity: RSA signing key type ", (int)keyType, " is not supported");
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
{
|
||||
size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32
|
||||
UpdateVerifier (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
{
|
||||
size_t padding = 128 - i2p::crypto::GOSTR3410_256_PUBLIC_KEY_LENGTH; // 64 = 128 - 64
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_256_Verifier (i2p::crypto::eGOSTR3410CryptoProA, m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
{
|
||||
// zero padding
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_512_Verifier (i2p::crypto::eGOSTR3410TC26A512, m_StandardIdentity.signingKey));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void IdentityEx::CreateVerifier () const
|
||||
{
|
||||
if (m_Verifier) return; // don't create again
|
||||
auto verifier = CreateVerifier (GetSigningKeyType ());
|
||||
if (verifier)
|
||||
{
|
||||
auto keyLen = verifier->GetPublicKeyLen ();
|
||||
if (keyLen <= 128)
|
||||
verifier->SetPublicKey (m_StandardIdentity.signingKey + 128 - keyLen);
|
||||
else
|
||||
{
|
||||
// for P521
|
||||
uint8_t * signingKey = new uint8_t[keyLen];
|
||||
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
|
||||
size_t excessLen = keyLen - 128;
|
||||
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
|
||||
verifier->SetPublicKey (signingKey);
|
||||
delete[] signingKey;
|
||||
}
|
||||
}
|
||||
UpdateVerifier (verifier);
|
||||
}
|
||||
|
||||
void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const
|
||||
|
@ -91,11 +91,11 @@ namespace data
|
||||
size_t ToBuffer (uint8_t * buf, size_t len) const;
|
||||
size_t FromBase64(const std::string& s);
|
||||
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 uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; };
|
||||
uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; };
|
||||
const uint8_t * GetEncryptionPublicKey () const { 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 GetSigningPublicKeyLen () const;
|
||||
@ -107,10 +107,11 @@ namespace data
|
||||
CryptoKeyType GetCryptoKeyType () const;
|
||||
void DropVerifier () const; // to save memory
|
||||
|
||||
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
||||
|
||||
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
||||
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
|
||||
void RecalculateIdentHash(uint8_t * buff=nullptr);
|
||||
|
||||
static i2p::crypto::Verifier * CreateVerifier (uint16_t keyType);
|
||||
|
||||
private:
|
||||
|
||||
void CreateVerifier () const;
|
||||
|
@ -245,14 +245,34 @@ namespace data
|
||||
uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
|
||||
SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
|
||||
uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags
|
||||
if (flags) return; // offline keys not supported
|
||||
std::unique_ptr<i2p::crypto::Verifier> offlineVerifier;
|
||||
if (flags & 0x0001)
|
||||
{
|
||||
// offline key
|
||||
uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
|
||||
offlineVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
|
||||
if (!offlineVerifier) return;
|
||||
auto keyLen = offlineVerifier->GetPublicKeyLen ();
|
||||
if (offset + keyLen >= len) return;
|
||||
offlineVerifier->SetPublicKey (buf + offset); offset += keyLen;
|
||||
if (offset + offlineVerifier->GetSignatureLen () >= len) return;
|
||||
uint8_t * signedData = new uint8_t[keyLen + 6];
|
||||
htobe32buf (signedData, timestamp + expires);
|
||||
htobe16buf (signedData + 4, keyType);
|
||||
memcpy (signedData + 6, buf + offset - keyLen, keyLen);
|
||||
bool verified = identity->Verify (signedData, keyLen + 6, buf + offset);
|
||||
delete[] signedData;
|
||||
if (!verified) return;
|
||||
offset += offlineVerifier->GetSignatureLen ();
|
||||
}
|
||||
|
||||
// properties
|
||||
uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2;
|
||||
offset += propertiesLen; // skip for now. TODO: implement properties
|
||||
if (offset + 1 >= len) return;
|
||||
// key sections
|
||||
//int numKeySections = buf[offset]; offset++;
|
||||
//for (int i = 0; i < numKeySections; i++)
|
||||
int numKeySections = buf[offset]; offset++;
|
||||
for (int i = 0; i < numKeySections; i++)
|
||||
{
|
||||
// skip key for now. TODO: implement encryption key
|
||||
offset += 2; // encryption key type
|
||||
@ -269,7 +289,7 @@ namespace data
|
||||
uint8_t * buf1 = new uint8_t[offset + 1];
|
||||
buf1[0] = m_StoreType;
|
||||
memcpy (buf1 + 1, buf, offset); // TODO: implement it better
|
||||
bool verified = identity->Verify (buf1, offset + 1, buf + offset); // assume online keys
|
||||
bool verified = offlineVerifier ? offlineVerifier->Verify (buf1, offset + 1, buf + offset) : identity->Verify (buf1, offset + 1, buf + offset);
|
||||
delete[] buf1;
|
||||
if (!verified)
|
||||
LogPrint (eLogWarning, "LeaseSet2: verification failed");
|
||||
|
@ -7,35 +7,43 @@ namespace i2p
|
||||
namespace crypto
|
||||
{
|
||||
#if OPENSSL_EDDSA
|
||||
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey)
|
||||
EDDSA25519Verifier::EDDSA25519Verifier ()
|
||||
{
|
||||
m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32);
|
||||
m_MDCtx = EVP_MD_CTX_create ();
|
||||
EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
|
||||
}
|
||||
|
||||
EDDSA25519Verifier::~EDDSA25519Verifier ()
|
||||
{
|
||||
EVP_MD_CTX_destroy (m_MDCtx);
|
||||
EVP_PKEY_free (m_Pkey);
|
||||
if (m_Pkey) EVP_PKEY_free (m_Pkey);
|
||||
}
|
||||
|
||||
void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey)
|
||||
{
|
||||
m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32);
|
||||
EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
|
||||
}
|
||||
|
||||
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
|
||||
{
|
||||
return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len);
|
||||
}
|
||||
|
||||
#else
|
||||
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey)
|
||||
EDDSA25519Verifier::EDDSA25519Verifier ()
|
||||
{
|
||||
}
|
||||
|
||||
EDDSA25519Verifier::~EDDSA25519Verifier ()
|
||||
{
|
||||
}
|
||||
|
||||
void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey)
|
||||
{
|
||||
memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH);
|
||||
BN_CTX * ctx = BN_CTX_new ();
|
||||
m_PublicKey = GetEd25519 ()->DecodePublicKey (m_PublicKeyEncoded, ctx);
|
||||
BN_CTX_free (ctx);
|
||||
}
|
||||
|
||||
EDDSA25519Verifier::~EDDSA25519Verifier ()
|
||||
{
|
||||
}
|
||||
|
||||
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
|
||||
|
@ -24,6 +24,7 @@ namespace crypto
|
||||
virtual size_t GetPublicKeyLen () const = 0;
|
||||
virtual size_t GetSignatureLen () const = 0;
|
||||
virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; };
|
||||
virtual void SetPublicKey (const uint8_t * signingKey) = 0;
|
||||
};
|
||||
|
||||
class Signer
|
||||
@ -41,9 +42,13 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
DSAVerifier (const uint8_t * signingKey)
|
||||
DSAVerifier ()
|
||||
{
|
||||
m_PublicKey = CreateDSA ();
|
||||
}
|
||||
|
||||
void SetPublicKey (const uint8_t * signingKey)
|
||||
{
|
||||
DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL);
|
||||
}
|
||||
|
||||
@ -154,9 +159,13 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
ECDSAVerifier (const uint8_t * signingKey)
|
||||
ECDSAVerifier ()
|
||||
{
|
||||
m_PublicKey = EC_KEY_new_by_curve_name (curve);
|
||||
}
|
||||
|
||||
void SetPublicKey (const uint8_t * signingKey)
|
||||
{
|
||||
BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL);
|
||||
BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL);
|
||||
EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y);
|
||||
@ -275,7 +284,8 @@ namespace crypto
|
||||
{
|
||||
public:
|
||||
|
||||
EDDSA25519Verifier (const uint8_t * signingKey);
|
||||
EDDSA25519Verifier ();
|
||||
void SetPublicKey (const uint8_t * signingKey);
|
||||
~EDDSA25519Verifier ();
|
||||
|
||||
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
|
||||
@ -386,15 +396,22 @@ namespace crypto
|
||||
|
||||
enum { keyLen = Hash::hashLen };
|
||||
|
||||
GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey):
|
||||
m_ParamSet (paramSet)
|
||||
GOSTR3410Verifier (GOSTR3410ParamSet paramSet):
|
||||
m_ParamSet (paramSet), m_PublicKey (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void SetPublicKey (const uint8_t * signingKey)
|
||||
{
|
||||
BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL);
|
||||
BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL);
|
||||
m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y);
|
||||
BN_free (x); BN_free (y);
|
||||
}
|
||||
~GOSTR3410Verifier () { EC_POINT_free (m_PublicKey); }
|
||||
~GOSTR3410Verifier ()
|
||||
{
|
||||
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
||||
}
|
||||
|
||||
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user