rsa_cipher.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #pragma once
  2. #include <string>
  3. #include <optional>
  4. #include <openssl/err.h>
  5. #include <openssl/rsa.h>
  6. #include "resource_wrapper.hpp"
  7. #include "resource_traits/openssl/rsa.hpp"
  8. #include "exception.hpp"
  9. #define NKG_CURRENT_SOURCE_FILE() u8".\\common\\rsa_cipher.hpp"
  10. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  11. namespace nkg {
  12. class rsa_cipher {
  13. public:
  14. class no_key_assigned_error : public ::nkg::exception {
  15. public:
  16. no_key_assigned_error(std::string_view file, int line, std::string_view message) noexcept :
  17. ::nkg::exception(file, line, message) {}
  18. };
  19. class backend_error : public ::nkg::exception {
  20. public:
  21. using error_code_t = decltype(ERR_get_error());
  22. private:
  23. std::optional<error_code_t> m_error_code;
  24. std::string m_error_string;
  25. public:
  26. backend_error(std::string_view file, int line, std::string_view message) noexcept :
  27. ::nkg::exception(file, line, message) {}
  28. backend_error(std::string_view file, int line, error_code_t openssl_errno, std::string_view message) noexcept :
  29. ::nkg::exception(file, line, message), m_error_code(openssl_errno) {}
  30. [[nodiscard]]
  31. virtual bool error_code_exists() const noexcept override {
  32. return m_error_code.has_value();
  33. }
  34. [[nodiscard]]
  35. virtual intptr_t error_code() const noexcept override {
  36. if (error_code_exists()) { return m_error_code.value(); } else { trap_then_terminate(); }
  37. }
  38. [[nodiscard]]
  39. virtual const std::string& error_string() const noexcept override {
  40. if (error_code_exists()) { return m_error_string; } else { trap_then_terminate(); }
  41. }
  42. };
  43. private:
  44. resource_wrapper<resource_traits::openssl::rsa> m_rsa;
  45. [[nodiscard]]
  46. static RSA* _read_private_key_from_bio(BIO* p_bio);
  47. [[nodiscard]]
  48. static RSA* _read_public_key_pem_from_bio(BIO* p_bio);
  49. [[nodiscard]]
  50. static RSA* _read_public_key_pkcs1_from_bio(BIO* p_bio);
  51. static void _write_private_key_to_bio(RSA* p_rsa, BIO* p_bio);
  52. static void _write_public_key_pem_to_bio(RSA* p_rsa, BIO* p_bio);
  53. static void _write_public_key_pkcs1_to_bio(RSA* p_rsa, BIO* p_bio);
  54. public:
  55. rsa_cipher();
  56. [[nodiscard]]
  57. size_t bits() const;
  58. void generate_key(int bits, unsigned int e = RSA_F4);
  59. void export_private_key_file(std::string_view file_path) const;
  60. void export_public_key_file_pem(std::string_view file_path) const;
  61. void export_public_key_file_pkcs1(std::string_view file_path) const;
  62. void import_private_key_file(std::string_view file_path);
  63. void import_public_key_file_pem(std::string_view file_path);
  64. void import_public_key_file_pkcs1(std::string_view file_path);
  65. [[nodiscard]]
  66. std::string export_private_key_string() const;
  67. [[nodiscard]]
  68. std::string export_public_key_string_pem() const;
  69. [[nodiscard]]
  70. std::string export_public_key_string_pkcs1() const;
  71. void import_private_key_string(std::string_view key_string);
  72. void import_public_key_string_pem(std::string_view key_string);
  73. void import_public_key_string_pkcs1(std::string_view key_string);
  74. size_t public_encrypt(const void* plaintext, size_t plaintext_size, void* ciphertext, int padding) const;
  75. size_t private_encrypt(const void* plaintext, size_t plaintext_size, void* ciphertext, int padding) const;
  76. size_t public_decrypt(const void* ciphertext, size_t ciphertext_size, void* plaintext, int padding) const;
  77. size_t private_decrypt(const void* ciphertext, size_t ciphertext_size, void* plaintext, int padding) const;
  78. };
  79. }
  80. #undef NKG_CURRENT_SOURCE_FILE
  81. #undef NKG_CURRENT_SOURCE_LINE