#include "RsaKeyPair.hpp" #include namespace drp::util::crypto { RsaKeyPair::RsaKeyPair(const std::size_t size, const int padMode) { // create the context const std::unique_ptr context( EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr), EVP_PKEY_CTX_free ); if (context == nullptr) throw std::runtime_error("Could not create an EVP context."); if (EVP_PKEY_keygen_init(context.get()) <= 0) throw std::runtime_error("Could not initialize the EVP context."); // configure the context if (EVP_PKEY_CTX_set_rsa_keygen_bits(context.get(), static_cast(size)) <= 0) throw std::runtime_error("Error setting RSA key size."); // create the key pair EVP_PKEY* rawKeyPair = nullptr; if (EVP_PKEY_keygen(context.get(), &rawKeyPair) <= 0) throw std::runtime_error("Could not generate RSA key pair."); if (rawKeyPair == nullptr) throw std::runtime_error("Could not generate RSA key pair."); std::unique_ptr keyPair( rawKeyPair, EVP_PKEY_free ); // extract the private key const std::unique_ptr privateBio( BIO_new(BIO_s_mem()), BIO_free ); if (privateBio == nullptr) throw std::runtime_error("Could not create RSA private key."); if (!i2d_PrivateKey_bio( privateBio.get(), keyPair.get() )) throw std::runtime_error("Could not generate RSA private key."); std::vector privateKeyData(BIO_pending(privateBio.get())); if (BIO_read( privateBio.get(), privateKeyData.data(), static_cast(privateKeyData.size()) ) <= 0) throw std::runtime_error("Could not read RSA private key."); this->privateKey = RsaPrivateKey(privateKeyData, padMode); // extract the public key const std::unique_ptr publicBio( BIO_new(BIO_s_mem()), BIO_free ); if (publicBio == nullptr) throw std::runtime_error("Could not create RSA public key."); if (!i2d_PUBKEY_bio( publicBio.get(), keyPair.get() )) throw std::runtime_error("Could not generate RSA public key."); std::vector publicKeyData(BIO_pending(publicBio.get())); if (BIO_read( publicBio.get(), publicKeyData.data(), static_cast(publicKeyData.size()) ) <= 0) throw std::runtime_error("Could not read RSA public key."); this->publicKey = RsaPublicKey(publicKeyData, padMode); } RsaPublicKey RsaKeyPair::getPublicKey() const { return this->publicKey; } RsaPrivateKey RsaKeyPair::getPrivateKey() const { return this->privateKey; } }