#include "RsaPrivateKey.hpp" #include #include #include #include "utils/serialize/basics.hpp" namespace drp::util::crypto { RsaPrivateKey::RsaPrivateKey() = default; RsaPrivateKey::RsaPrivateKey(const std::vector& data, const int padMode) { this->_data = data; this->padMode = padMode; } std::vector RsaPrivateKey::decrypt(const std::vector& encryptedData) 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_decrypt_init(context.get()) <= 0) throw std::runtime_error("Could not initialize encryption."); // set the padding if (EVP_PKEY_CTX_set_rsa_padding(context.get(), RSA_PKCS1_OAEP_PADDING) <= 0) throw std::runtime_error("Could not set RSA padding."); // get the size of the output buffer std::size_t decryptedDataLength; if (EVP_PKEY_decrypt( context.get(), nullptr, &decryptedDataLength, encryptedData.data(), encryptedData.size() ) <= 0) throw std::runtime_error("Could not determine output length."); std::vector decryptedData(decryptedDataLength); // encrypt the data if (EVP_PKEY_decrypt( context.get(), decryptedData.data(), &decryptedDataLength, encryptedData.data(), encryptedData.size() ) <= 0) throw std::runtime_error("Could not decrypt data."); decryptedData.resize(decryptedDataLength); return decryptedData; } std::vector RsaPrivateKey::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; } RsaPrivateKey RsaPrivateKey::deserialize(std::vector& data) { // deserialize the members const auto keyData = serialize::deserializeVector(data); const auto keyPadding = static_cast(serialize::deserializeObject(data)); return RsaPrivateKey(keyData, keyPadding); } [[nodiscard]] std::unique_ptr RsaPrivateKey::getOpenSslKey() const { // get the bio from the private 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 private key."); // get the key from the bio EVP_PKEY* rawKey = nullptr; if (!d2i_PrivateKey_bio( bio.get(), &rawKey )) throw std::runtime_error("Could not deserialize RSA private key."); return { rawKey, EVP_PKEY_free }; } }