extract and verify LS2 transient key

pull/1278/head
orignal 6 years ago
parent 812e2814bc
commit bce4224d6e

@ -64,7 +64,8 @@ namespace data
i2p::crypto::bn2buf (x, signingKey, 32); i2p::crypto::bn2buf (x, signingKey, 32);
i2p::crypto::bn2buf (y, signingKey + 32, 32); i2p::crypto::bn2buf (y, signingKey + 32, 32);
BN_free (x); BN_free (y); 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 else
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");

@ -318,62 +318,56 @@ namespace data
return CRYPTO_KEY_TYPE_ELGAMAL; 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) switch (keyType)
{ {
case SIGNING_KEY_TYPE_DSA_SHA1: case SIGNING_KEY_TYPE_DSA_SHA1:
UpdateVerifier (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); return new i2p::crypto::DSAVerifier ();
break;
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
{ return new i2p::crypto::ECDSAP256Verifier ();
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
UpdateVerifier (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding));
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384: case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
{ return new i2p::crypto::ECDSAP384Verifier ();
size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96
UpdateVerifier (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding));
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521: case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
{ return new i2p::crypto::ECDSAP521Verifier ();
uint8_t signingKey[i2p::crypto::ECDSAP521_KEY_LENGTH]; case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
memcpy (signingKey, m_StandardIdentity.signingKey, 128); return new i2p::crypto::EDDSA25519Verifier ();
size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128 case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types return new i2p::crypto::GOSTR3410_256_Verifier (i2p::crypto::eGOSTR3410CryptoProA);
UpdateVerifier (new i2p::crypto::ECDSAP521Verifier (signingKey)); case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
break; return new i2p::crypto::GOSTR3410_512_Verifier (i2p::crypto::eGOSTR3410TC26A512);
}
case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA256_2048:
case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA384_3072:
case SIGNING_KEY_TYPE_RSA_SHA512_4096: case SIGNING_KEY_TYPE_RSA_SHA512_4096:
LogPrint (eLogError, "Identity: RSA signing key type ", (int)keyType, " is not supported"); LogPrint (eLogError, "Identity: RSA signing key type ", (int)keyType, " is not supported");
break; break;
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: default:
{ LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported");
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: return nullptr;
{
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:
void IdentityEx::CreateVerifier () const
{ {
// zero padding if (m_Verifier) return; // don't create again
UpdateVerifier (new i2p::crypto::GOSTR3410_512_Verifier (i2p::crypto::eGOSTR3410TC26A512, m_StandardIdentity.signingKey)); auto verifier = CreateVerifier (GetSigningKeyType ());
break; 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;
} }
default:
LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported");
} }
UpdateVerifier (verifier);
} }
void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const

@ -108,9 +108,10 @@ namespace data
void DropVerifier () const; // to save memory void DropVerifier () const; // to save memory
bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); } bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
void RecalculateIdentHash(uint8_t * buff=nullptr); void RecalculateIdentHash(uint8_t * buff=nullptr);
static i2p::crypto::Verifier * CreateVerifier (uint16_t keyType);
private: private:
void CreateVerifier () const; void CreateVerifier () const;

@ -245,14 +245,34 @@ namespace data
uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds) uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags 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 // properties
uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2;
offset += propertiesLen; // skip for now. TODO: implement properties offset += propertiesLen; // skip for now. TODO: implement properties
if (offset + 1 >= len) return; if (offset + 1 >= len) return;
// key sections // key sections
//int numKeySections = buf[offset]; offset++; int numKeySections = buf[offset]; offset++;
//for (int i = 0; i < numKeySections; i++) for (int i = 0; i < numKeySections; i++)
{ {
// skip key for now. TODO: implement encryption key // skip key for now. TODO: implement encryption key
offset += 2; // encryption key type offset += 2; // encryption key type
@ -269,7 +289,7 @@ namespace data
uint8_t * buf1 = new uint8_t[offset + 1]; uint8_t * buf1 = new uint8_t[offset + 1];
buf1[0] = m_StoreType; buf1[0] = m_StoreType;
memcpy (buf1 + 1, buf, offset); // TODO: implement it better 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; delete[] buf1;
if (!verified) if (!verified)
LogPrint (eLogWarning, "LeaseSet2: verification failed"); LogPrint (eLogWarning, "LeaseSet2: verification failed");

@ -7,17 +7,21 @@ namespace i2p
namespace crypto namespace crypto
{ {
#if OPENSSL_EDDSA #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 (); m_MDCtx = EVP_MD_CTX_create ();
EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
} }
EDDSA25519Verifier::~EDDSA25519Verifier () EDDSA25519Verifier::~EDDSA25519Verifier ()
{ {
EVP_MD_CTX_destroy (m_MDCtx); 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 bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
@ -26,18 +30,22 @@ namespace crypto
} }
#else #else
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) EDDSA25519Verifier::EDDSA25519Verifier ()
{ {
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 () 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);
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{ {
uint8_t digest[64]; uint8_t digest[64];

@ -24,6 +24,7 @@ namespace crypto
virtual size_t GetPublicKeyLen () const = 0; virtual size_t GetPublicKeyLen () const = 0;
virtual size_t GetSignatureLen () const = 0; virtual size_t GetSignatureLen () const = 0;
virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; }; virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; };
virtual void SetPublicKey (const uint8_t * signingKey) = 0;
}; };
class Signer class Signer
@ -41,9 +42,13 @@ namespace crypto
{ {
public: public:
DSAVerifier (const uint8_t * signingKey) DSAVerifier ()
{ {
m_PublicKey = CreateDSA (); m_PublicKey = CreateDSA ();
}
void SetPublicKey (const uint8_t * signingKey)
{
DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL); DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL);
} }
@ -154,9 +159,13 @@ namespace crypto
{ {
public: public:
ECDSAVerifier (const uint8_t * signingKey) ECDSAVerifier ()
{ {
m_PublicKey = EC_KEY_new_by_curve_name (curve); m_PublicKey = EC_KEY_new_by_curve_name (curve);
}
void SetPublicKey (const uint8_t * signingKey)
{
BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL); BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL);
BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL);
EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y); EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y);
@ -275,7 +284,8 @@ namespace crypto
{ {
public: public:
EDDSA25519Verifier (const uint8_t * signingKey); EDDSA25519Verifier ();
void SetPublicKey (const uint8_t * signingKey);
~EDDSA25519Verifier (); ~EDDSA25519Verifier ();
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
@ -386,15 +396,22 @@ namespace crypto
enum { keyLen = Hash::hashLen }; enum { keyLen = Hash::hashLen };
GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey): GOSTR3410Verifier (GOSTR3410ParamSet paramSet):
m_ParamSet (paramSet) m_ParamSet (paramSet), m_PublicKey (nullptr)
{
}
void SetPublicKey (const uint8_t * signingKey)
{ {
BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL); BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL);
BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL);
m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y); m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y);
BN_free (x); BN_free (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 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{ {

Loading…
Cancel
Save