Skip to content
Snippets Groups Projects
rsa.hh 4.10 KiB
#ifndef __VEREIGN_CRYPTO_RSA_HH
#define __VEREIGN_CRYPTO_RSA_HH

#include <vereign/bytes/view.hh>
#include <vereign/bytes/buffer.hh>

#include <openssl/base.h>
#include <openssl/evp.h>

namespace vereign::crypto::rsa {

/**
 * Generates new RSA key.
 *
 * Example:
 * @code
 * auto key = crypto::rsa::GenerateKey(2048);
 * @endcode
 *
 * @param bits The length of the key.
 * @returns the newly generated key.
 *
 * @throws crypto::OpenSSLError on failure.
 */
auto GenerateKey(int bits) -> bssl::UniquePtr<EVP_PKEY>;

/**
 * Encrypts given bytes with RSA public key.
 *
 * Example:
 * @code
 * const std::string input{"foo bar"};
 * auto key = crypto::rsa::GenerateKey(2048);
 * bytes::Buffer encrypted;
 *
 * crypto::rsa::PublicKeyEncrypt(key.get(), bytes::View(input), encrypted);
 *
 * bytes::Buffer decrypted;
 * crypto::rsa::PrivateKeyDecrypt(key.get(), encrypted.View(), decrypted);
 *
 * assert(decrypted.View() == bytes.View(input));
 * @endcode
 *
 * @param key The RSA key.
 * @param src The bytes that will be encrypted.
 * @param encrypted The result of the encryption.
 *
 * @throws crypto::OpenSSLError on failure.
 */
void PublicKeyEncrypt(EVP_PKEY* key, bytes::View src, bytes::Buffer& encrypted);

/**
 * Decrypts given bytes with RSA private key.
 *
 * Example:
 * @code
 * const std::string input{"foo bar"};
 * auto key = crypto::rsa::GenerateKey(2048);
 * bytes::Buffer encrypted;
 *
 * crypto::rsa::PublicKeyEncrypt(key.get(), bytes::View(input), encrypted);
 *
 * bytes::Buffer decrypted;
 * crypto::rsa::PrivateKeyDecrypt(key.get(), encrypted.View(), decrypted);
 *
 * assert(decrypted.View() == bytes.View(input));
 * @endcode
 *
 * @param key The RSA key.
 * @param src The bytes that will be decrypted.
 * @param decrypted The result of the decryption.
 *
 * @throws crypto::OpenSSLError on failure.
 */
void PrivateKeyDecrypt(EVP_PKEY* key, bytes::View src, bytes::Buffer& decrypted);

/**
 * Exports a public key part to PEM format.
 *
 * @code
 * auto key = crypto::rsa::GenerateKey(2048);
 *
 * auto bio = crypto::rsa::ExportPublicKeyToPEM(key.get());
 * std::cout << crypto::bio::View(bio.get()).String() << std::endl;
 * @endcode
 *
 * @param key The key to export.
 * @returns a memory BIO with the exported key.
 *
 * @throws crypto::OpenSSLError on failure.
 */
auto ExportPublicKeyToPEM(EVP_PKEY* key) -> bssl::UniquePtr<BIO>;

/**
 * Import public key from PEM format.
 *
 * @code
 * auto key = crypto::rsa::GenerateKey(2048);
 *
 * auto bio = crypto::rsa::ExportPublicKeyToPEM(key.get());
 * auto imported_key = crypto::rsa::ImportPublicKeyFromPEM(crypto::bio::View(bio.get()));
 * @endcode
 *
 * @param pem PEM encoded key.
 * @returns imported key.
 *
 * @throws crypto::OpenSSLError on failure.
 */
auto ImportPublicKeyFromPEM(bytes::View pem) -> bssl::UniquePtr<EVP_PKEY>;

/**
 * Export private key from PEM format.
 *
 * @code
 * auto key = crypto::rsa::GenerateKey(2048);
 *
 * auto bio = crypto::rsa::ExportPrivateKeyToPEM(key.get());
 * std::cout << crypto::bio::View(bio.get()).String() << std::endl;
 * @endcode
 *
 * @param key The key to export.
 * @returns a memory BIO with the exported key.
 *
 * @throws crypto::OpenSSLError on failure.
 */
auto ExportPrivateKeyToPEM(EVP_PKEY* key) -> bssl::UniquePtr<BIO>;

/**
 * Export private key from PEM format.
 *
 * @code
 * auto key = crypto::rsa::GenerateKey(2048);
 *
 * auto pem  = crypto::rsa::ExportPrivateKeyToPEMString(key.get());
 * std::cout << pem << std::endl;
 * @endcode
 *
 * @param key The key to export.
 * @returns the exported key in PEM format.
 *
 * @throws crypto::OpenSSLError on failure.
 */
auto ExportPrivateKeyToPEMString(EVP_PKEY* key) -> std::string;

/**
 * Import private key from PEM format.
 *
 * @code
 * auto key = crypto::rsa::GenerateKey(2048);
 *
 * auto bio = crypto::rsa::ExportPrivateKeyToPEM(key.get());
 * auto imported_key = crypto::rsa::ImportPrivateKeyFromPEM(crypto::bio::View(bio.get()));
 * @endcode
 *
 * @param pem PEM encoded key.
 * @returns imported key.
 *
 * @throws crypto::OpenSSLError on failure.
 */
auto ImportPrivateKeyFromPEM(bytes::View pem) -> bssl::UniquePtr<EVP_PKEY>;

} // vereign::crypto::rsa

#endif // __VEREIGN_CRYPTO_RSA_HH