updated build system
This commit is contained in:
		| @@ -425,6 +425,8 @@ using vlc_string_t = std::unique_ptr<char, vlc_string_deleter>; | ||||
|  | ||||
| namespace repertory { | ||||
| using data_buffer = std::vector<unsigned char>; | ||||
| using data_span = std::span<unsigned char>; | ||||
| using data_cspan = std::span<const unsigned char>; | ||||
| using mutex_lock = std::lock_guard<std::mutex>; | ||||
| using recur_mutex_lock = std::lock_guard<std::recursive_mutex>; | ||||
| using stop_type = std::atomic_bool; | ||||
|   | ||||
| @@ -38,14 +38,15 @@ public: | ||||
|                     std::optional<std::string> relative_parent_path, | ||||
|                     std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader(std::string_view encrypted_file_path, | ||||
|                     std::string_view source_path, | ||||
|                     stop_type_callback stop_requested_cb, | ||||
|                     std::string_view token, std::size_t error_return = 0U); | ||||
|   encrypting_reader(stop_type_callback stop_requested_cb, | ||||
|                     std::string_view encrypted_file_path, | ||||
|                     std::string_view source_path, std::string_view token, | ||||
|                     std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader( | ||||
|       stop_type_callback stop_requested_cb, | ||||
|       std::string_view encrypted_file_path, std::string_view source_path, | ||||
|       stop_type_callback stop_requested_cb, std::string_view token, | ||||
|       std::string_view token, | ||||
|       std::vector<std::array<unsigned char, | ||||
|                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||
|           iv_list, | ||||
| @@ -57,16 +58,37 @@ public: | ||||
|                     std::optional<std::string> relative_parent_path, | ||||
|                     std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader(std::string_view encrypted_file_path, | ||||
|                     std::string_view source_path, | ||||
|                     stop_type_callback stop_requested_cb, | ||||
|                     std::string_view token, kdf_config cfg, | ||||
|                     std::size_t error_return = 0U); | ||||
|   encrypting_reader(stop_type_callback stop_requested_cb, | ||||
|                     std::string_view encrypted_file_path, | ||||
|                     std::string_view source_path, std::string_view token, | ||||
|                     kdf_config cfg, std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader( | ||||
|       stop_type_callback stop_requested_cb, | ||||
|       std::string_view encrypted_file_path, std::string_view source_path, | ||||
|       stop_type_callback stop_requested_cb, std::string_view token, | ||||
|       kdf_config cfg, | ||||
|       std::string_view token, kdf_config cfg, | ||||
|       std::vector<std::array<unsigned char, | ||||
|                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||
|           iv_list, | ||||
|       std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader(std::string_view file_name, std::string_view source_path, | ||||
|                     stop_type_callback stop_requested_cb, | ||||
|                     const utils::hash::hash_256_t &master_key, | ||||
|                     const kdf_config &cfg, | ||||
|                     std::optional<std::string> relative_parent_path, | ||||
|                     std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader(stop_type_callback stop_requested_cb, | ||||
|                     std::string_view encrypted_file_path, | ||||
|                     std::string_view source_path, | ||||
|                     const utils::hash::hash_256_t &master_key, | ||||
|                     const kdf_config &cfg, std::size_t error_return = 0U); | ||||
|  | ||||
|   encrypting_reader( | ||||
|       stop_type_callback stop_requested_cb, | ||||
|       std::string_view encrypted_file_path, std::string_view source_path, | ||||
|       const utils::hash::hash_256_t &master_key, const kdf_config &cfg, | ||||
|       std::vector<std::array<unsigned char, | ||||
|                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||
|           iv_list, | ||||
| @@ -82,10 +104,13 @@ public: | ||||
|  | ||||
| public: | ||||
|   using iostream = std::basic_iostream<char, std::char_traits<char>>; | ||||
|   using kdf_pair_t = std::pair<data_buffer, data_buffer>; | ||||
|   using key_pair_t = | ||||
|       std::pair<utils::hash::hash_256_t, utils::hash::hash_256_t>; | ||||
|   using streambuf = std::basic_streambuf<char, std::char_traits<char>>; | ||||
|  | ||||
| private: | ||||
|   utils::hash::hash_256_t key_; | ||||
|   key_pair_t keys_; | ||||
|   stop_type_callback stop_requested_cb_; | ||||
|   size_t error_return_; | ||||
|   std::unique_ptr<utils::file::i_file> source_file_; | ||||
| @@ -97,7 +122,7 @@ private: | ||||
|  | ||||
| private: | ||||
|   std::unordered_map<std::size_t, data_buffer> chunk_buffers_; | ||||
|   std::optional<data_buffer> kdf_header_; | ||||
|   std::optional<kdf_pair_t> kdf_headers_; | ||||
|   std::size_t last_data_chunk_{}; | ||||
|   std::size_t last_data_chunk_size_{}; | ||||
|   std::uint64_t read_offset_{}; | ||||
| @@ -113,6 +138,11 @@ private: | ||||
|  | ||||
|   void common_initialize(bool procces_iv_list); | ||||
|  | ||||
|   void common_initialize_kdf_data(const kdf_config &cfg, | ||||
|                                   const utils::hash::hash_256_t &master_key); | ||||
|  | ||||
|   void common_initialize_kdf_path(const utils::hash::hash_256_t &master_key); | ||||
|  | ||||
|   void create_encrypted_paths(std::string_view file_name, | ||||
|                               std::optional<std::string> relative_parent_path); | ||||
|  | ||||
| @@ -157,7 +187,11 @@ public: | ||||
|     return iv_list_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_kdf_config() const -> std::optional<kdf_config>; | ||||
|   [[nodiscard]] auto get_kdf_config_for_data() const | ||||
|       -> std::optional<kdf_config>; | ||||
|  | ||||
|   [[nodiscard]] auto get_kdf_config_for_path() const | ||||
|       -> std::optional<kdf_config>; | ||||
|  | ||||
|   [[nodiscard]] auto get_stop_requested() const -> bool { | ||||
|     return stop_requested_cb_(); | ||||
|   | ||||
| @@ -25,6 +25,9 @@ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON) | ||||
| #include "utils/collection.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON) | ||||
| #include "utils/error.hpp" | ||||
| #include "utils/hash.hpp" | ||||
|  | ||||
| @@ -53,7 +56,7 @@ enum class opslimit_level : std::uint8_t { | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] inline auto get_memlimit(memlimit_level memlimit) -> size_t { | ||||
|   constexpr const auto mib512{512ULL * 1024ULL * 1024ULL}; | ||||
|   constexpr auto mib512{512ULL * 1024ULL * 1024ULL}; | ||||
|  | ||||
|   switch (memlimit) { | ||||
|   case memlimit_level::level1: | ||||
| @@ -88,25 +91,64 @@ enum class opslimit_level : std::uint8_t { | ||||
|   return crypto_pwhash_OPSLIMIT_MODERATE; | ||||
| } | ||||
|  | ||||
| enum class kdf_context : std::uint8_t { | ||||
|   data, | ||||
|   path, | ||||
|   undefined, | ||||
| }; | ||||
| using kdf_ctx_t = std::array<char, crypto_kdf_CONTEXTBYTES>; | ||||
|  | ||||
| namespace kdf { | ||||
| constexpr inline std::array< | ||||
|     kdf_ctx_t, static_cast<std::size_t>(kdf_context::undefined) + 1U> | ||||
|     KDF_CTXS{ | ||||
|         { | ||||
|             {'D', 'A', 'T', 'A', '_', 'C', 'T', 'X'}, | ||||
|             {'F', 'I', 'L', 'E', '_', 'C', 'T', 'X'}, | ||||
|             {'D', 'E', 'F', 'L', '_', 'C', 'T', 'X'}, | ||||
|         }, | ||||
|     }; | ||||
| } // namespace kdf | ||||
|  | ||||
| [[nodiscard]] constexpr inline auto get_kdf_context_name(kdf_context ctx) | ||||
|     -> kdf_ctx_t { | ||||
|   const auto idx = static_cast<std::size_t>(ctx); | ||||
|   return idx < kdf::KDF_CTXS.size() ? kdf::KDF_CTXS.at(idx) | ||||
|                                     : kdf::KDF_CTXS.back(); | ||||
| } | ||||
|  | ||||
| #pragma pack(push, 1) | ||||
| struct kdf_config final { | ||||
|   static constexpr std::uint32_t repertory_magic{0x52505432}; | ||||
|   using salt_t = std::array<std::uint8_t, crypto_pwhash_SALTBYTES>; | ||||
|  | ||||
|   std::uint32_t magic{repertory_magic}; | ||||
|   kdf_version version{kdf_version::v1}; | ||||
|   kdf_type kdf{kdf_type::argon2id}; | ||||
|   memlimit_level memlimit{memlimit_level::level3}; | ||||
|   opslimit_level opslimit{opslimit_level::level2}; | ||||
|   std::uint64_t unique_id{}; | ||||
|   salt_t salt{}; | ||||
|   std::uint64_t checksum{}; | ||||
|  | ||||
|   [[nodiscard]] static auto from_header(std::span<const unsigned char> data, | ||||
|                                         kdf_config &cfg) -> bool; | ||||
|   template <typename hash_t> | ||||
|   [[nodiscard]] auto create_subkey(kdf_context ctx, std::size_t unique_id_, | ||||
|                                    const hash_t &master_key) const | ||||
|       -> std::pair<hash_t, kdf_config> { | ||||
|     hash_t sub_key; | ||||
|     crypto_kdf_derive_from_key(sub_key.data(), sub_key.size(), unique_id_, | ||||
|                                get_kdf_context_name(ctx).data(), | ||||
|                                master_key.data()); | ||||
|     auto cfg = *this; | ||||
|     cfg.unique_id = unique_id_; | ||||
|     cfg.checksum = cfg.generate_checksum(); | ||||
|     return {sub_key, cfg}; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] static auto from_header(data_cspan data, kdf_config &cfg) | ||||
|       -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto generate_checksum() const -> std::uint64_t; | ||||
|  | ||||
|   void generate_salt(); | ||||
|   void seal(); | ||||
|  | ||||
|   [[nodiscard]] static constexpr auto size() -> std::size_t { | ||||
|     return sizeof(kdf_config); | ||||
| @@ -160,21 +202,18 @@ template <typename string_t> | ||||
|  | ||||
| template <typename hash_t, typename string_t> | ||||
| [[nodiscard]] inline bool | ||||
| detect_and_recreate_key(string_t password, | ||||
|                         std::span<const unsigned char> header, hash_t &key, | ||||
| detect_and_recreate_key(string_t password, data_cspan header, hash_t &key, | ||||
|                         std::optional<kdf_config> &cfg); | ||||
|  | ||||
| template <typename hash_t> | ||||
| [[nodiscard]] inline bool | ||||
| detect_and_recreate_key(std::string_view password, | ||||
|                         std::span<const unsigned char> header, hash_t &key, | ||||
|                         std::optional<kdf_config> &cfg); | ||||
| detect_and_recreate_key(std::string_view password, data_cspan header, | ||||
|                         hash_t &key, std::optional<kdf_config> &cfg); | ||||
|  | ||||
| template <typename hash_t> | ||||
| [[nodiscard]] inline bool | ||||
| detect_and_recreate_key(std::wstring_view password, | ||||
|                         std::span<const unsigned char> header, hash_t &key, | ||||
|                         std::optional<kdf_config> &cfg); | ||||
| detect_and_recreate_key(std::wstring_view password, data_cspan header, | ||||
|                         hash_t &key, std::optional<kdf_config> &cfg); | ||||
|  | ||||
| [[nodiscard]] auto decrypt_file_name(std::string_view encryption_token, | ||||
|                                      std::string &file_name) -> bool; | ||||
| @@ -396,7 +435,7 @@ read_encrypted_range(const http_range &range, | ||||
| template <typename string_t> | ||||
| auto create_key_argon2id(string_t password, kdf_config &cfg, | ||||
|                          utils::hash::hash_256_t &key) -> bool { | ||||
|   cfg.generate_salt(); | ||||
|   cfg.seal(); | ||||
|  | ||||
|   return recreate_key_argon2id(password, cfg, key); | ||||
| } | ||||
| @@ -531,8 +570,7 @@ inline auto recreate_key(std::wstring_view password, const kdf_config &cfg) | ||||
| } | ||||
|  | ||||
| template <typename hash_t, typename string_t> | ||||
| inline bool detect_and_recreate_key(string_t password, | ||||
|                                     std::span<const unsigned char> header, | ||||
| inline bool detect_and_recreate_key(string_t password, data_cspan header, | ||||
|                                     hash_t &key, | ||||
|                                     std::optional<kdf_config> &cfg) { | ||||
|   if (header.size() >= kdf_config::size()) { | ||||
| @@ -550,8 +588,7 @@ inline bool detect_and_recreate_key(string_t password, | ||||
|  | ||||
| template <typename hash_t> | ||||
| inline bool detect_and_recreate_key(std::string_view password, | ||||
|                                     std::span<const unsigned char> header, | ||||
|                                     hash_t &key, | ||||
|                                     data_cspan header, hash_t &key, | ||||
|                                     std::optional<kdf_config> &cfg) { | ||||
|   return detect_and_recreate_key<hash_t, std::string_view>(password, header, | ||||
|                                                            key, cfg); | ||||
| @@ -559,14 +596,96 @@ inline bool detect_and_recreate_key(std::string_view password, | ||||
|  | ||||
| template <typename hash_t> | ||||
| inline bool detect_and_recreate_key(std::wstring_view password, | ||||
|                                     std::span<const unsigned char> header, | ||||
|                                     hash_t &key, | ||||
|                                     data_cspan header, hash_t &key, | ||||
|                                     std::optional<kdf_config> &cfg) { | ||||
|   return detect_and_recreate_key<hash_t, std::wstring_view>(password, header, | ||||
|                                                             key, cfg); | ||||
| } | ||||
|  | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
| } // namespace repertory::utils::encryption | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON) | ||||
| NLOHMANN_JSON_NAMESPACE_BEGIN | ||||
|  | ||||
| namespace kdf { | ||||
| inline constexpr std::string_view JSON_CHECKSUM{"checksum"}; | ||||
| inline constexpr std::string_view JSON_KDF{"kdf"}; | ||||
| inline constexpr std::string_view JSON_MEMLIMIT{"memlimit"}; | ||||
| inline constexpr std::string_view JSON_OPSLIMIT{"opslimit"}; | ||||
| inline constexpr std::string_view JSON_SALT{"salt"}; | ||||
| inline constexpr std::string_view JSON_UNIQUE_ID{"unique_id"}; | ||||
| inline constexpr std::string_view JSON_VERSION{"version"}; | ||||
| } // namespace kdf | ||||
|  | ||||
| template <> | ||||
| struct adl_serializer<repertory::utils::encryption::kdf_config::salt_t> { | ||||
|   static void | ||||
|   to_json(json &data, | ||||
|           const repertory::utils::encryption::kdf_config::salt_t &value) { | ||||
|     data = repertory::utils::collection::to_hex_string(value); | ||||
|   } | ||||
|  | ||||
|   static void | ||||
|   from_json(const json &data, | ||||
|             repertory::utils::encryption::kdf_config::salt_t &value) { | ||||
|     REPERTORY_USES_FUNCTION_NAME(); | ||||
|  | ||||
|     repertory::data_buffer buffer{}; | ||||
|     if (not repertory::utils::collection::from_hex_string( | ||||
|             data.get<std::string>(), buffer)) { | ||||
|       throw repertory::utils::error::create_exception( | ||||
|           function_name, { | ||||
|                              "failed to convert hex string to salt", | ||||
|                              data.get<std::string>(), | ||||
|                          }); | ||||
|     } | ||||
|  | ||||
|     if (buffer.size() != value.size()) { | ||||
|       throw repertory::utils::error::create_exception( | ||||
|           function_name, { | ||||
|                              "unexpected length for salt after hex conversion", | ||||
|                              "expected", | ||||
|                              std::to_string(value.size()), | ||||
|                              "actual", | ||||
|                              std::to_string(buffer.size()), | ||||
|                          }); | ||||
|     } | ||||
|  | ||||
|     std::copy_n(buffer.begin(), value.size(), value.begin()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::utils::encryption::kdf_config> { | ||||
|   static void to_json(json &data, | ||||
|                       const repertory::utils::encryption::kdf_config &value) { | ||||
|     data[kdf::JSON_CHECKSUM] = value.checksum; | ||||
|     data[kdf::JSON_KDF] = value.kdf; | ||||
|     data[kdf::JSON_MEMLIMIT] = value.memlimit; | ||||
|     data[kdf::JSON_OPSLIMIT] = value.opslimit; | ||||
|     data[kdf::JSON_SALT] = value.salt; | ||||
|     data[kdf::JSON_UNIQUE_ID] = value.unique_id; | ||||
|     data[kdf::JSON_VERSION] = value.version; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, | ||||
|                         repertory::utils::encryption::kdf_config &value) { | ||||
|     data.at(kdf::JSON_CHECKSUM).get_to<std::uint64_t>(value.checksum); | ||||
|     data.at(kdf::JSON_KDF) | ||||
|         .get_to<repertory::utils::encryption::kdf_type>(value.kdf); | ||||
|     data.at(kdf::JSON_MEMLIMIT) | ||||
|         .get_to<repertory::utils::encryption::memlimit_level>(value.memlimit); | ||||
|     data.at(kdf::JSON_OPSLIMIT) | ||||
|         .get_to<repertory::utils::encryption::opslimit_level>(value.opslimit); | ||||
|     data.at(kdf::JSON_SALT) | ||||
|         .get_to<repertory::utils::encryption::kdf_config::salt_t>(value.salt); | ||||
|     data.at(kdf::JSON_UNIQUE_ID).get_to<std::uint64_t>(value.unique_id); | ||||
|     data.at(kdf::JSON_VERSION) | ||||
|         .get_to<repertory::utils::encryption::kdf_version>(value.version); | ||||
|   } | ||||
| }; | ||||
| NLOHMANN_JSON_NAMESPACE_END | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON) | ||||
|  | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| #endif // REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_ | ||||
|   | ||||
| @@ -12,7 +12,7 @@ public: | ||||
|   using entry_t = atomic_t<data_t>; | ||||
|   using entry_ptr_t = std::shared_ptr<entry_t>; | ||||
|  | ||||
|   static constexpr const auto default_expiration{duration(60000U)}; | ||||
|   static constexpr auto default_expiration{duration(60000U)}; | ||||
|  | ||||
| private: | ||||
|   struct entry final { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user