From 7bfc3562af5befe514cd76693b6989aa8b40dcc4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Feb 2016 16:13:46 -0500 Subject: [PATCH] extract EcDSA key from family certificate --- Family.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- Family.h | 3 +++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/Family.cpp b/Family.cpp index 5470a92c..7e2d6e6c 100644 --- a/Family.cpp +++ b/Family.cpp @@ -1,7 +1,9 @@ +#include #include "util.h" #include #include #include "Log.h" +#include "Crypto.h" #include "Family.h" namespace i2p @@ -24,12 +26,14 @@ namespace data { SSL * ssl = SSL_new (ctx); X509 * cert = SSL_get_certificate (ssl); - // verify if (cert) { + std::shared_ptr verifier; // extract issuer name char name[100]; X509_NAME_oneline (X509_get_issuer_name(cert), name, 100); + char * family = strstr (name, ".family"); + if (family) family[0] = 0; auto pkey = X509_get_pubkey (cert); int keyType = EVP_PKEY_type(pkey->type); switch (keyType) @@ -39,13 +43,37 @@ namespace data break; case EVP_PKEY_EC: { - //EC_KEY * ecKey = EVP_PKEY_get0_EC_KEY (pkey); + EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey); + if (ecKey) + { + auto group = EC_KEY_get0_group (ecKey); + if (group) + { + 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(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) + m_SigningKeys[name] = verifier; } SSL_free (ssl); } @@ -72,6 +100,23 @@ namespace data if (numCertificates > 0) LogPrint (eLogInfo, "Family: ", numCertificates, " certificates loaded"); } + + bool Families::VerifyFamily (const char * family, const IdentHash& ident, + const char * signature, const char * key) + { + uint8_t buf[50], signatureBuf[64]; + size_t len = strlen (family), signatureLen = strlen (signature); + memcpy (buf, family, len); + memcpy (buf + len, (const uint8_t *)ident, 32); + len += 32; + Base64ToByteStream (signature, signatureLen, signatureBuf, 64); + auto it = m_SigningKeys.find (family); + if (it != m_SigningKeys.end ()) + return it->second->Verify (buf, len, signatureBuf); + // TODO: process key + return true; + } + } } diff --git a/Family.h b/Family.h index ca8dac3f..78abd5b6 100644 --- a/Family.h +++ b/Family.h @@ -5,6 +5,7 @@ #include #include #include "Signature.h" +#include "Identity.h" namespace i2p { @@ -17,6 +18,8 @@ namespace data Families (); ~Families (); void LoadCertificates (); + bool VerifyFamily (const char * family, const IdentHash& ident, + const char * signature, const char * key); private: