diff --git a/src/libaktualizr/crypto/crypto.cc b/src/libaktualizr/crypto/crypto.cc index 3138a53d80..76747d01a2 100644 --- a/src/libaktualizr/crypto/crypto.cc +++ b/src/libaktualizr/crypto/crypto.cc @@ -347,32 +347,40 @@ StructGuard Crypto::generateRSAKeyPairEVP(KeyType key_type) { return {nullptr, EVP_PKEY_free}; } + return Crypto::generateRSAKeyPairEVP(bits); +} + +StructGuard Crypto::generateRSAKeyPairEVP(const int bits) { int ret; ret = RAND_status(); if (ret != 1) { /* random generator has NOT been seeded with enough data */ ret = RAND_poll(); if (ret != 1) { /* seed data was NOT generated */ - return {nullptr, EVP_PKEY_free}; + throw std::runtime_error("Random generator has not been sufficiently seeded."); } } + /* exponent - RSA_F4 is defined as 0x10001L */ StructGuard bne(BN_new(), BN_free); - ret = BN_set_word(bne.get(), RSA_F4); - if (ret != 1) { - return {nullptr, EVP_PKEY_free}; + if (BN_set_word(bne.get(), RSA_F4) != 1) { + throw std::runtime_error(std::string("BN_set_word failed: ") + ERR_error_string(ERR_get_error(), nullptr)); } + StructGuard rsa(RSA_new(), RSA_free); - ret = RSA_generate_key_ex(rsa.get(), bits, /* number of bits for the key - 2048 is a sensible value */ - bne.get(), /* exponent - RSA_F4 is defined as 0x10001L */ - nullptr); /* callback argument - not needed in this case */ - if (ret != 1) { - return {nullptr, EVP_PKEY_free}; + if (RSA_generate_key_ex(rsa.get(), bits, bne.get(), nullptr) != 1) { + throw std::runtime_error(std::string("RSA_generate_key_ex failed: ") + ERR_error_string(ERR_get_error(), nullptr)); } StructGuard pkey(EVP_PKEY_new(), EVP_PKEY_free); + if (pkey.get() == nullptr) { + throw std::runtime_error(std::string("EVP_PKEY_new failed: ") + ERR_error_string(ERR_get_error(), nullptr)); + } + // release the rsa pointer here, pkey is the new owner - EVP_PKEY_assign_RSA(pkey.get(), rsa.release()); // NOLINT + if (!EVP_PKEY_assign_RSA(pkey.get(), rsa.release())) { // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) + throw std::runtime_error(std::string("EVP_PKEY_assign_RSA failed: ") + ERR_error_string(ERR_get_error(), nullptr)); + } return pkey; } @@ -543,28 +551,8 @@ StructGuard Crypto::generateCert(const int rsa_bits, const int cert_days, ERR_error_string(ERR_get_error(), nullptr)); } - // create and set key (would be nice to reuse generateRSAKeyPairEVP but the - // complications with reusing certificate_rsa below make that hard). - - StructGuard bne(BN_new(), BN_free); - if (BN_set_word(bne.get(), RSA_F4) != 1) { - throw std::runtime_error(std::string("BN_set_word failed: ") + ERR_error_string(ERR_get_error(), nullptr)); - } - - // freed by owner EVP_PKEY - RSA *certificate_rsa = RSA_new(); - if (RSA_generate_key_ex(certificate_rsa, rsa_bits, bne.get(), nullptr) != 1) { - throw std::runtime_error(std::string("RSA_generate_key_ex failed: ") + ERR_error_string(ERR_get_error(), nullptr)); - } - - StructGuard certificate_pkey(EVP_PKEY_new(), EVP_PKEY_free); - if (certificate_pkey.get() == nullptr) { - throw std::runtime_error(std::string("EVP_PKEY_new failed: ") + ERR_error_string(ERR_get_error(), nullptr)); - } - - if (!EVP_PKEY_assign_RSA(certificate_pkey.get(), certificate_rsa)) { // NOLINT - throw std::runtime_error(std::string("EVP_PKEY_assign_RSA failed: ") + ERR_error_string(ERR_get_error(), nullptr)); - } + // create and set key. + StructGuard certificate_pkey(Crypto::generateRSAKeyPairEVP(rsa_bits)); if (X509_set_pubkey(certificate.get(), certificate_pkey.get()) == 0) { throw std::runtime_error(std::string("X509_set_pubkey failed: ") + ERR_error_string(ERR_get_error(), nullptr)); diff --git a/src/libaktualizr/crypto/crypto.h b/src/libaktualizr/crypto/crypto.h index 5f923ec6c7..61e628895e 100644 --- a/src/libaktualizr/crypto/crypto.h +++ b/src/libaktualizr/crypto/crypto.h @@ -82,6 +82,7 @@ class Crypto { std::string *out_ca); static std::string extractSubjectCN(const std::string &cert); static StructGuard generateRSAKeyPairEVP(KeyType key_type); + static StructGuard generateRSAKeyPairEVP(const int bits); static bool generateRSAKeyPair(KeyType key_type, std::string *public_key, std::string *private_key); static bool generateEDKeyPair(std::string *public_key, std::string *private_key); static bool generateKeyPair(KeyType key_type, std::string *public_key, std::string *private_key);