M2-PT-DRP/source/utils/crypto/rsa/RsaKeyPair.cpp

98 lines
2.8 KiB
C++

#include "RsaKeyPair.hpp"
#include <openssl/x509.h>
namespace drp::util::crypto {
RsaKeyPair::RsaKeyPair(const std::size_t size, const int padMode) {
// create the context
const std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> 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<int>(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<EVP_PKEY, decltype(&EVP_PKEY_free)> keyPair(
rawKeyPair,
EVP_PKEY_free
);
// extract the private key
const std::unique_ptr<BIO, decltype(&BIO_free)> 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<std::uint8_t> privateKeyData(BIO_pending(privateBio.get()));
if (BIO_read(
privateBio.get(),
privateKeyData.data(),
static_cast<int>(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<BIO, decltype(&BIO_free)> 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<std::uint8_t> publicKeyData(BIO_pending(publicBio.get()));
if (BIO_read(
publicBio.get(),
publicKeyData.data(),
static_cast<int>(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;
}
}