use EVP_PKEY for family signature verification

This commit is contained in:
orignal 2024-10-08 13:44:25 -04:00
parent 1a6109109a
commit 78847306e9
2 changed files with 29 additions and 52 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2023, The PurpleI2P Project * Copyright (c) 2013-2024, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -7,7 +7,6 @@
*/ */
#include <string.h> #include <string.h>
#include <openssl/evp.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include "Crypto.h" #include "Crypto.h"
#include "FS.h" #include "FS.h"
@ -25,6 +24,8 @@ namespace data
Families::~Families () Families::~Families ()
{ {
for (auto it : m_SigningKeys)
if (it.second.first) EVP_PKEY_free (it.second.first);
} }
void Families::LoadCertificate (const std::string& filename) void Families::LoadCertificate (const std::string& filename)
@ -47,48 +48,16 @@ namespace data
cn += 3; cn += 3;
char * family = strstr (cn, ".family"); char * family = strstr (cn, ".family");
if (family) family[0] = 0; if (family) family[0] = 0;
} auto pkey = X509_get_pubkey (cert);
auto pkey = X509_get_pubkey (cert); if (pkey)
int keyType = EVP_PKEY_base_id (pkey);
switch (keyType)
{
case EVP_PKEY_DSA:
// TODO:
break;
case EVP_PKEY_EC:
{ {
EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey); if (!m_SigningKeys.emplace (cn, std::make_pair(pkey, (int)m_SigningKeys.size () + 1)).second)
if (ecKey)
{ {
auto group = EC_KEY_get0_group (ecKey); EVP_PKEY_free (pkey);
if (group) LogPrint (eLogError, "Family: Duplicated family name ", cn);
{
int curve = EC_GROUP_get_curve_name (group);
if (curve == NID_X9_62_prime256v1)
{
uint8_t signingKey[64];
BIGNUM * x = BN_new(), * y = BN_new();
EC_POINT_get_affine_coordinates_GFp (group,
EC_KEY_get0_public_key (ecKey), x, y, NULL);
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>();
verifier->SetPublicKey (signingKey);
}
else
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
}
EC_KEY_free (ecKey);
} }
break;
} }
default:
LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported");
} }
EVP_PKEY_free (pkey);
if (verifier && cn)
m_SigningKeys.emplace (cn, std::make_pair(verifier, (int)m_SigningKeys.size () + 1));
} }
SSL_free (ssl); SSL_free (ssl);
} }
@ -130,14 +99,22 @@ namespace data
LogPrint (eLogError, "Family: ", family, " is too long"); LogPrint (eLogError, "Family: ", family, " is too long");
return false; return false;
} }
memcpy (buf, family.c_str (), len);
memcpy (buf + len, (const uint8_t *)ident, 32);
len += 32;
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
auto it = m_SigningKeys.find (family); auto it = m_SigningKeys.find (family);
if (it != m_SigningKeys.end ()) if (it != m_SigningKeys.end () && it->second.first)
return it->second.first->Verify (buf, len, signatureBuf); {
memcpy (buf, family.c_str (), len);
memcpy (buf + len, (const uint8_t *)ident, 32);
len += 32;
auto signatureBufLen = Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
if (signatureBufLen)
{
EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, it->second.first);
auto ret = EVP_DigestVerify (ctx, signatureBuf, signatureBufLen, buf, len);
EVP_MD_CTX_destroy (ctx);
return ret;
}
}
// TODO: process key // TODO: process key
return true; return true;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2024, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -12,7 +12,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <memory> #include <memory>
#include "Signature.h" #include <openssl/evp.h>
#include "Identity.h" #include "Identity.h"
namespace i2p namespace i2p
@ -37,7 +37,7 @@ namespace data
private: private:
std::map<std::string, std::pair<std::shared_ptr<i2p::crypto::Verifier>, FamilyID> > m_SigningKeys; // family -> (verifier, id) std::map<std::string, std::pair<EVP_PKEY *, FamilyID> > m_SigningKeys; // family -> (verification pkey, id)
}; };
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident); std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);