#include "RsaPublicKey.hpp" #include #include #include #include "utils/serialize/basics.hpp" namespace drp::util::crypto { RsaPublicKey::RsaPublicKey() = default; RsaPublicKey::RsaPublicKey(const std::vector& data, const int padMode) { this->_data = data; this->padMode = padMode; } [[nodiscard]] std::vector RsaPublicKey::encrypt(const std::vector& plainData) const { const auto key = this->getOpenSslKey(); // initialize the encryption context const std::unique_ptr context( EVP_PKEY_CTX_new(key.get(), nullptr), EVP_PKEY_CTX_free ); if (context == nullptr) throw std::runtime_error("Could not create EVP_PKEY_CTX."); // initialize the encryption operation if (EVP_PKEY_encrypt_init(context.get()) <= 0) throw std::runtime_error("Could not initialize encryption."); // set the padding if (EVP_PKEY_CTX_set_rsa_padding(context.get(), this->padMode) <= 0) throw std::runtime_error("Could not set RSA padding."); // get the size of the output buffer std::size_t encryptedDataLength; if (EVP_PKEY_encrypt( context.get(), nullptr, &encryptedDataLength, plainData.data(), plainData.size() ) <= 0) throw std::runtime_error("Could not determine output length."); std::vector encryptedData(encryptedDataLength); // encrypt the data if (EVP_PKEY_encrypt( context.get(), encryptedData.data(), &encryptedDataLength, plainData.data(), plainData.size() ) <= 0) throw std::runtime_error("Could not encrypt data."); encryptedData.resize(encryptedDataLength); return encryptedData; } std::vector RsaPublicKey::serialize() const { // serialize the members const auto serializedData = serialize::serializeVector(this->_data); const auto serializedPadMode = serialize::serializeObject(static_cast(this->padMode)); // create a buffer to store our members std::vector data; // store our members data.insert(data.end(), serializedData.begin(), serializedData.end()); data.insert(data.end(), serializedPadMode.begin(), serializedPadMode.end()); return data; } RsaPublicKey RsaPublicKey::deserialize(std::vector& data) { // deserialize the members const auto keyData = serialize::deserializeVector(data); const auto keyPadding = static_cast(serialize::deserializeObject(data)); return RsaPublicKey(keyData, keyPadding); } [[nodiscard]] std::unique_ptr RsaPublicKey::getOpenSslKey() const { // get the bio from the public key data const std::unique_ptr bio( BIO_new_mem_buf( this->_data.data(), static_cast(this->_data.size()) ), BIO_free ); if (bio == nullptr) throw std::runtime_error("Could not create BIO for public key."); // get the key from the bio EVP_PKEY* rawKey = nullptr; if (!d2i_PUBKEY_bio( bio.get(), &rawKey )) throw std::runtime_error("Could not deserialize RSA public key."); return { rawKey, EVP_PKEY_free }; } }