updated build system
This commit is contained in:
		| @@ -806,11 +806,11 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path, | |||||||
|   } else if (not reader_lookup_.contains(file_data.source_path)) { |   } else if (not reader_lookup_.contains(file_data.source_path)) { | ||||||
|     auto info{std::make_shared<reader_info>()}; |     auto info{std::make_shared<reader_info>()}; | ||||||
|     info->reader = std::make_unique<utils::encryption::encrypting_reader>( |     info->reader = std::make_unique<utils::encryption::encrypting_reader>( | ||||||
|         api_path, file_data.source_path, |  | ||||||
|         [&stop_requested]() -> bool { |         [&stop_requested]() -> bool { | ||||||
|           return stop_requested || app_config::get_stop_requested(); |           return stop_requested || app_config::get_stop_requested(); | ||||||
|         }, |         }, | ||||||
|         cfg.encryption_token, std::move(file_data.iv_list)); |         api_path, file_data.source_path, cfg.encryption_token, | ||||||
|  |         std::move(file_data.iv_list)); | ||||||
|     reader_lookup_[file_data.source_path] = info; |     reader_lookup_[file_data.source_path] = info; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -425,6 +425,8 @@ using vlc_string_t = std::unique_ptr<char, vlc_string_deleter>; | |||||||
|  |  | ||||||
| namespace repertory { | namespace repertory { | ||||||
| using data_buffer = std::vector<unsigned char>; | 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 mutex_lock = std::lock_guard<std::mutex>; | ||||||
| using recur_mutex_lock = std::lock_guard<std::recursive_mutex>; | using recur_mutex_lock = std::lock_guard<std::recursive_mutex>; | ||||||
| using stop_type = std::atomic_bool; | using stop_type = std::atomic_bool; | ||||||
|   | |||||||
| @@ -38,14 +38,15 @@ public: | |||||||
|                     std::optional<std::string> relative_parent_path, |                     std::optional<std::string> relative_parent_path, | ||||||
|                     std::size_t error_return = 0U); |                     std::size_t error_return = 0U); | ||||||
|  |  | ||||||
|   encrypting_reader(std::string_view encrypted_file_path, |   encrypting_reader(stop_type_callback stop_requested_cb, | ||||||
|                     std::string_view source_path, |                     std::string_view encrypted_file_path, | ||||||
|                     stop_type_callback stop_requested_cb, |                     std::string_view source_path, std::string_view token, | ||||||
|                     std::string_view token, std::size_t error_return = 0U); |                     std::size_t error_return = 0U); | ||||||
|  |  | ||||||
|   encrypting_reader( |   encrypting_reader( | ||||||
|  |       stop_type_callback stop_requested_cb, | ||||||
|       std::string_view encrypted_file_path, std::string_view source_path, |       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, |       std::vector<std::array<unsigned char, | ||||||
|                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> |                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||||
|           iv_list, |           iv_list, | ||||||
| @@ -57,16 +58,37 @@ public: | |||||||
|                     std::optional<std::string> relative_parent_path, |                     std::optional<std::string> relative_parent_path, | ||||||
|                     std::size_t error_return = 0U); |                     std::size_t error_return = 0U); | ||||||
|  |  | ||||||
|   encrypting_reader(std::string_view encrypted_file_path, |   encrypting_reader(stop_type_callback stop_requested_cb, | ||||||
|                     std::string_view source_path, |                     std::string_view encrypted_file_path, | ||||||
|                     stop_type_callback stop_requested_cb, |                     std::string_view source_path, std::string_view token, | ||||||
|                     std::string_view token, kdf_config cfg, |                     kdf_config cfg, std::size_t error_return = 0U); | ||||||
|                     std::size_t error_return = 0U); |  | ||||||
|  |  | ||||||
|   encrypting_reader( |   encrypting_reader( | ||||||
|  |       stop_type_callback stop_requested_cb, | ||||||
|       std::string_view encrypted_file_path, std::string_view source_path, |       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, kdf_config cfg, | ||||||
|       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, |       std::vector<std::array<unsigned char, | ||||||
|                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> |                              crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||||
|           iv_list, |           iv_list, | ||||||
| @@ -82,10 +104,13 @@ public: | |||||||
|  |  | ||||||
| public: | public: | ||||||
|   using iostream = std::basic_iostream<char, std::char_traits<char>>; |   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>>; |   using streambuf = std::basic_streambuf<char, std::char_traits<char>>; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|   utils::hash::hash_256_t key_; |   key_pair_t keys_; | ||||||
|   stop_type_callback stop_requested_cb_; |   stop_type_callback stop_requested_cb_; | ||||||
|   size_t error_return_; |   size_t error_return_; | ||||||
|   std::unique_ptr<utils::file::i_file> source_file_; |   std::unique_ptr<utils::file::i_file> source_file_; | ||||||
| @@ -97,7 +122,7 @@ private: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|   std::unordered_map<std::size_t, data_buffer> chunk_buffers_; |   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_{}; | ||||||
|   std::size_t last_data_chunk_size_{}; |   std::size_t last_data_chunk_size_{}; | ||||||
|   std::uint64_t read_offset_{}; |   std::uint64_t read_offset_{}; | ||||||
| @@ -113,6 +138,11 @@ private: | |||||||
|  |  | ||||||
|   void common_initialize(bool procces_iv_list); |   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, |   void create_encrypted_paths(std::string_view file_name, | ||||||
|                               std::optional<std::string> relative_parent_path); |                               std::optional<std::string> relative_parent_path); | ||||||
|  |  | ||||||
| @@ -157,7 +187,11 @@ public: | |||||||
|     return iv_list_; |     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 { |   [[nodiscard]] auto get_stop_requested() const -> bool { | ||||||
|     return stop_requested_cb_(); |     return stop_requested_cb_(); | ||||||
|   | |||||||
| @@ -25,6 +25,9 @@ | |||||||
|  |  | ||||||
| #include "utils/config.hpp" | #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/error.hpp" | ||||||
| #include "utils/hash.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 { | [[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) { |   switch (memlimit) { | ||||||
|   case memlimit_level::level1: |   case memlimit_level::level1: | ||||||
| @@ -88,25 +91,64 @@ enum class opslimit_level : std::uint8_t { | |||||||
|   return crypto_pwhash_OPSLIMIT_MODERATE; |   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) | #pragma pack(push, 1) | ||||||
| struct kdf_config final { | struct kdf_config final { | ||||||
|   static constexpr std::uint32_t repertory_magic{0x52505432}; |  | ||||||
|   using salt_t = std::array<std::uint8_t, crypto_pwhash_SALTBYTES>; |   using salt_t = std::array<std::uint8_t, crypto_pwhash_SALTBYTES>; | ||||||
|  |  | ||||||
|   std::uint32_t magic{repertory_magic}; |  | ||||||
|   kdf_version version{kdf_version::v1}; |   kdf_version version{kdf_version::v1}; | ||||||
|   kdf_type kdf{kdf_type::argon2id}; |   kdf_type kdf{kdf_type::argon2id}; | ||||||
|   memlimit_level memlimit{memlimit_level::level3}; |   memlimit_level memlimit{memlimit_level::level3}; | ||||||
|   opslimit_level opslimit{opslimit_level::level2}; |   opslimit_level opslimit{opslimit_level::level2}; | ||||||
|  |   std::uint64_t unique_id{}; | ||||||
|   salt_t salt{}; |   salt_t salt{}; | ||||||
|   std::uint64_t checksum{}; |   std::uint64_t checksum{}; | ||||||
|  |  | ||||||
|   [[nodiscard]] static auto from_header(std::span<const unsigned char> data, |   template <typename hash_t> | ||||||
|                                         kdf_config &cfg) -> bool; |   [[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; |   [[nodiscard]] auto generate_checksum() const -> std::uint64_t; | ||||||
|  |  | ||||||
|   void generate_salt(); |   void seal(); | ||||||
|  |  | ||||||
|   [[nodiscard]] static constexpr auto size() -> std::size_t { |   [[nodiscard]] static constexpr auto size() -> std::size_t { | ||||||
|     return sizeof(kdf_config); |     return sizeof(kdf_config); | ||||||
| @@ -160,21 +202,18 @@ template <typename string_t> | |||||||
|  |  | ||||||
| template <typename hash_t, typename string_t> | template <typename hash_t, typename string_t> | ||||||
| [[nodiscard]] inline bool | [[nodiscard]] inline bool | ||||||
| detect_and_recreate_key(string_t password, | detect_and_recreate_key(string_t password, data_cspan header, hash_t &key, | ||||||
|                         std::span<const unsigned char> header, hash_t &key, |  | ||||||
|                         std::optional<kdf_config> &cfg); |                         std::optional<kdf_config> &cfg); | ||||||
|  |  | ||||||
| template <typename hash_t> | template <typename hash_t> | ||||||
| [[nodiscard]] inline bool | [[nodiscard]] inline bool | ||||||
| detect_and_recreate_key(std::string_view password, | detect_and_recreate_key(std::string_view password, data_cspan header, | ||||||
|                         std::span<const unsigned char> header, hash_t &key, |                         hash_t &key, std::optional<kdf_config> &cfg); | ||||||
|                         std::optional<kdf_config> &cfg); |  | ||||||
|  |  | ||||||
| template <typename hash_t> | template <typename hash_t> | ||||||
| [[nodiscard]] inline bool | [[nodiscard]] inline bool | ||||||
| detect_and_recreate_key(std::wstring_view password, | detect_and_recreate_key(std::wstring_view password, data_cspan header, | ||||||
|                         std::span<const unsigned char> header, hash_t &key, |                         hash_t &key, std::optional<kdf_config> &cfg); | ||||||
|                         std::optional<kdf_config> &cfg); |  | ||||||
|  |  | ||||||
| [[nodiscard]] auto decrypt_file_name(std::string_view encryption_token, | [[nodiscard]] auto decrypt_file_name(std::string_view encryption_token, | ||||||
|                                      std::string &file_name) -> bool; |                                      std::string &file_name) -> bool; | ||||||
| @@ -396,7 +435,7 @@ read_encrypted_range(const http_range &range, | |||||||
| template <typename string_t> | template <typename string_t> | ||||||
| auto create_key_argon2id(string_t password, kdf_config &cfg, | auto create_key_argon2id(string_t password, kdf_config &cfg, | ||||||
|                          utils::hash::hash_256_t &key) -> bool { |                          utils::hash::hash_256_t &key) -> bool { | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|  |  | ||||||
|   return recreate_key_argon2id(password, cfg, key); |   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> | template <typename hash_t, typename string_t> | ||||||
| inline bool detect_and_recreate_key(string_t password, | inline bool detect_and_recreate_key(string_t password, data_cspan header, | ||||||
|                                     std::span<const unsigned char> header, |  | ||||||
|                                     hash_t &key, |                                     hash_t &key, | ||||||
|                                     std::optional<kdf_config> &cfg) { |                                     std::optional<kdf_config> &cfg) { | ||||||
|   if (header.size() >= kdf_config::size()) { |   if (header.size() >= kdf_config::size()) { | ||||||
| @@ -550,8 +588,7 @@ inline bool detect_and_recreate_key(string_t password, | |||||||
|  |  | ||||||
| template <typename hash_t> | template <typename hash_t> | ||||||
| inline bool detect_and_recreate_key(std::string_view password, | inline bool detect_and_recreate_key(std::string_view password, | ||||||
|                                     std::span<const unsigned char> header, |                                     data_cspan header, hash_t &key, | ||||||
|                                     hash_t &key, |  | ||||||
|                                     std::optional<kdf_config> &cfg) { |                                     std::optional<kdf_config> &cfg) { | ||||||
|   return detect_and_recreate_key<hash_t, std::string_view>(password, header, |   return detect_and_recreate_key<hash_t, std::string_view>(password, header, | ||||||
|                                                            key, cfg); |                                                            key, cfg); | ||||||
| @@ -559,14 +596,96 @@ inline bool detect_and_recreate_key(std::string_view password, | |||||||
|  |  | ||||||
| template <typename hash_t> | template <typename hash_t> | ||||||
| inline bool detect_and_recreate_key(std::wstring_view password, | inline bool detect_and_recreate_key(std::wstring_view password, | ||||||
|                                     std::span<const unsigned char> header, |                                     data_cspan header, hash_t &key, | ||||||
|                                     hash_t &key, |  | ||||||
|                                     std::optional<kdf_config> &cfg) { |                                     std::optional<kdf_config> &cfg) { | ||||||
|   return detect_and_recreate_key<hash_t, std::wstring_view>(password, header, |   return detect_and_recreate_key<hash_t, std::wstring_view>(password, header, | ||||||
|                                                             key, cfg); |                                                             key, cfg); | ||||||
| } | } | ||||||
|  |  | ||||||
| #endif // defined(PROJECT_ENABLE_BOOST) | #endif // defined(PROJECT_ENABLE_BOOST) | ||||||
| } // namespace repertory::utils::encryption | } // 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 // defined(PROJECT_ENABLE_LIBSODIUM) | ||||||
| #endif // REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_ | #endif // REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_ | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ public: | |||||||
|   using entry_t = atomic_t<data_t>; |   using entry_t = atomic_t<data_t>; | ||||||
|   using entry_ptr_t = std::shared_ptr<entry_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: | private: | ||||||
|   struct entry final { |   struct entry final { | ||||||
|   | |||||||
| @@ -181,7 +181,8 @@ encrypting_reader::encrypting_reader( | |||||||
|     std::string_view file_name, std::string_view source_path, |     std::string_view file_name, std::string_view source_path, | ||||||
|     stop_type_callback stop_requested_cb, std::string_view token, |     stop_type_callback stop_requested_cb, std::string_view token, | ||||||
|     std::optional<std::string> relative_parent_path, std::size_t error_return) |     std::optional<std::string> relative_parent_path, std::size_t error_return) | ||||||
|     : key_(utils::encryption::generate_key<utils::hash::hash_256_t>(token)), |     : keys_(utils::encryption::generate_key<utils::hash::hash_256_t>(token), | ||||||
|  |             utils::encryption::generate_key<utils::hash::hash_256_t>(token)), | ||||||
|       stop_requested_cb_(std::move(stop_requested_cb)), |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|       error_return_(error_return), |       error_return_(error_return), | ||||||
|       source_file_(utils::file::file::open_or_create_file(source_path, true)) { |       source_file_(utils::file::file::open_or_create_file(source_path, true)) { | ||||||
| @@ -189,12 +190,13 @@ encrypting_reader::encrypting_reader( | |||||||
|   create_encrypted_paths(file_name, relative_parent_path); |   create_encrypted_paths(file_name, relative_parent_path); | ||||||
| } | } | ||||||
|  |  | ||||||
| encrypting_reader::encrypting_reader(std::string_view encrypted_file_path, | encrypting_reader::encrypting_reader(stop_type_callback stop_requested_cb, | ||||||
|  |                                      std::string_view encrypted_file_path, | ||||||
|                                      std::string_view source_path, |                                      std::string_view source_path, | ||||||
|                                      stop_type_callback stop_requested_cb, |  | ||||||
|                                      std::string_view token, |                                      std::string_view token, | ||||||
|                                      std::size_t error_return) |                                      std::size_t error_return) | ||||||
|     : key_(utils::encryption::generate_key<utils::hash::hash_256_t>(token)), |     : keys_(utils::encryption::generate_key<utils::hash::hash_256_t>(token), | ||||||
|  |             utils::encryption::generate_key<utils::hash::hash_256_t>(token)), | ||||||
|       stop_requested_cb_(std::move(stop_requested_cb)), |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|       error_return_(error_return), |       error_return_(error_return), | ||||||
|       source_file_(utils::file::file::open_or_create_file(source_path, true)), |       source_file_(utils::file::file::open_or_create_file(source_path, true)), | ||||||
| @@ -205,13 +207,14 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path, | |||||||
| } | } | ||||||
|  |  | ||||||
| encrypting_reader::encrypting_reader( | encrypting_reader::encrypting_reader( | ||||||
|     std::string_view encrypted_file_path, std::string_view source_path, |     stop_type_callback stop_requested_cb, std::string_view encrypted_file_path, | ||||||
|     stop_type_callback stop_requested_cb, std::string_view token, |     std::string_view source_path, std::string_view token, | ||||||
|     std::vector< |     std::vector< | ||||||
|         std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> |         std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||||
|         iv_list, |         iv_list, | ||||||
|     std::size_t error_return) |     std::size_t error_return) | ||||||
|     : key_(utils::encryption::generate_key<utils::hash::hash_256_t>(token)), |     : keys_(utils::encryption::generate_key<utils::hash::hash_256_t>(token), | ||||||
|  |             utils::encryption::generate_key<utils::hash::hash_256_t>(token)), | ||||||
|       stop_requested_cb_(std::move(stop_requested_cb)), |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|       error_return_(error_return), |       error_return_(error_return), | ||||||
|       source_file_(utils::file::file::open_or_create_file(source_path, true)), |       source_file_(utils::file::file::open_or_create_file(source_path, true)), | ||||||
| @@ -227,48 +230,50 @@ encrypting_reader::encrypting_reader( | |||||||
|     stop_type_callback stop_requested_cb, std::string_view token, |     stop_type_callback stop_requested_cb, std::string_view token, | ||||||
|     kdf_config cfg, std::optional<std::string> relative_parent_path, |     kdf_config cfg, std::optional<std::string> relative_parent_path, | ||||||
|     std::size_t error_return) |     std::size_t error_return) | ||||||
|     : key_( |     : keys_( | ||||||
|           utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg)), |           utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg), | ||||||
|  |           utils::encryption::generate_key<utils::hash::hash_256_t>(token)), | ||||||
|       stop_requested_cb_(std::move(stop_requested_cb)), |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|       error_return_(error_return), |       error_return_(error_return), | ||||||
|       source_file_(utils::file::file::open_or_create_file(source_path, true)) { |       source_file_(utils::file::file::open_or_create_file(source_path, true)) { | ||||||
|   kdf_header_ = cfg.to_header(); |   kdf_headers_ = {cfg.to_header(), cfg.to_header()}; | ||||||
|  |  | ||||||
|   data_buffer result; |   data_buffer result; | ||||||
|   utils::encryption::encrypt_data( |   utils::encryption::encrypt_data( | ||||||
|       key_, reinterpret_cast<const unsigned char *>(file_name.data()), |       keys_.second, reinterpret_cast<const unsigned char *>(file_name.data()), | ||||||
|       file_name.size(), result); |       file_name.size(), result); | ||||||
|   common_initialize(true); |   common_initialize(true); | ||||||
|   create_encrypted_paths(file_name, relative_parent_path); |   create_encrypted_paths(file_name, relative_parent_path); | ||||||
| } | } | ||||||
|  |  | ||||||
| encrypting_reader::encrypting_reader(std::string_view encrypted_file_path, | encrypting_reader::encrypting_reader(stop_type_callback stop_requested_cb, | ||||||
|  |                                      std::string_view encrypted_file_path, | ||||||
|                                      std::string_view source_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::size_t error_return) |                                      std::size_t error_return) | ||||||
|     : key_( |     : keys_( | ||||||
|           utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg)), |           utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg), | ||||||
|  |           utils::encryption::generate_key<utils::hash::hash_256_t>(token)), | ||||||
|       stop_requested_cb_(std::move(stop_requested_cb)), |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|       error_return_(error_return), |       error_return_(error_return), | ||||||
|       source_file_(utils::file::file::open_or_create_file(source_path, true)), |       source_file_(utils::file::file::open_or_create_file(source_path, true)), | ||||||
|       encrypted_file_name_( |       encrypted_file_name_( | ||||||
|           utils::path::strip_to_file_name(std::string{encrypted_file_path})), |           utils::path::strip_to_file_name(std::string{encrypted_file_path})), | ||||||
|       encrypted_file_path_(encrypted_file_path) { |       encrypted_file_path_(encrypted_file_path) { | ||||||
|   kdf_header_ = cfg.to_header(); |   kdf_headers_ = {cfg.to_header(), cfg.to_header()}; | ||||||
|   common_initialize(true); |   common_initialize(true); | ||||||
| } | } | ||||||
|  |  | ||||||
| encrypting_reader::encrypting_reader( | encrypting_reader::encrypting_reader( | ||||||
|     std::string_view encrypted_file_path, std::string_view source_path, |     stop_type_callback stop_requested_cb, std::string_view encrypted_file_path, | ||||||
|     stop_type_callback stop_requested_cb, std::string_view token, |     std::string_view source_path, std::string_view token, kdf_config cfg, | ||||||
|     kdf_config cfg, |  | ||||||
|     std::vector< |     std::vector< | ||||||
|         std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> |         std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||||
|         iv_list, |         iv_list, | ||||||
|     std::size_t error_return) |     std::size_t error_return) | ||||||
|     : key_( |     : keys_( | ||||||
|           utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg)), |           utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg), | ||||||
|  |           utils::encryption::generate_key<utils::hash::hash_256_t>(token)), | ||||||
|       stop_requested_cb_(std::move(stop_requested_cb)), |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|       error_return_(error_return), |       error_return_(error_return), | ||||||
|       source_file_(utils::file::file::open_or_create_file(source_path, true)), |       source_file_(utils::file::file::open_or_create_file(source_path, true)), | ||||||
| @@ -276,12 +281,74 @@ encrypting_reader::encrypting_reader( | |||||||
|           utils::path::strip_to_file_name(std::string{encrypted_file_path})), |           utils::path::strip_to_file_name(std::string{encrypted_file_path})), | ||||||
|       encrypted_file_path_(encrypted_file_path), |       encrypted_file_path_(encrypted_file_path), | ||||||
|       iv_list_(std::move(iv_list)) { |       iv_list_(std::move(iv_list)) { | ||||||
|   kdf_header_ = cfg.to_header(); |   kdf_headers_ = {cfg.to_header(), cfg.to_header()}; | ||||||
|  |   common_initialize(false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | encrypting_reader::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) | ||||||
|  |     : stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|  |       error_return_(error_return), | ||||||
|  |       source_file_(utils::file::file::open_or_create_file(source_path, true)) { | ||||||
|  |   common_initialize_kdf_data(cfg, master_key); | ||||||
|  |  | ||||||
|  |   kdf_config path_cfg; | ||||||
|  |   std::tie(keys_.second, path_cfg) = cfg.create_subkey( | ||||||
|  |       kdf_context::path, utils::generate_secure_random<std::uint64_t>(), | ||||||
|  |       master_key); | ||||||
|  |   kdf_headers_->second = path_cfg.to_header(); | ||||||
|  |  | ||||||
|  |   data_buffer result; | ||||||
|  |   utils::encryption::encrypt_data( | ||||||
|  |       keys_.second, reinterpret_cast<const unsigned char *>(file_name.data()), | ||||||
|  |       file_name.size(), result); | ||||||
|  |   common_initialize(true); | ||||||
|  |   create_encrypted_paths(file_name, relative_parent_path); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | encrypting_reader::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) | ||||||
|  |     : keys_(), | ||||||
|  |       stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|  |       error_return_(error_return), | ||||||
|  |       source_file_(utils::file::file::open_or_create_file(source_path, true)), | ||||||
|  |       encrypted_file_name_( | ||||||
|  |           utils::path::strip_to_file_name(std::string{encrypted_file_path})), | ||||||
|  |       encrypted_file_path_(encrypted_file_path) { | ||||||
|  |   common_initialize_kdf_data(cfg, master_key); | ||||||
|  |   common_initialize_kdf_path(master_key); | ||||||
|  |   common_initialize(true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | encrypting_reader::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, | ||||||
|  |     std::size_t error_return) | ||||||
|  |     : stop_requested_cb_(std::move(stop_requested_cb)), | ||||||
|  |       error_return_(error_return), | ||||||
|  |       source_file_(utils::file::file::open_or_create_file(source_path, true)), | ||||||
|  |       encrypted_file_name_( | ||||||
|  |           utils::path::strip_to_file_name(std::string{encrypted_file_path})), | ||||||
|  |       encrypted_file_path_(encrypted_file_path), | ||||||
|  |       iv_list_(std::move(iv_list)) { | ||||||
|  |   common_initialize_kdf_data(cfg, master_key); | ||||||
|  |   common_initialize_kdf_path(master_key); | ||||||
|   common_initialize(false); |   common_initialize(false); | ||||||
| } | } | ||||||
|  |  | ||||||
| encrypting_reader::encrypting_reader(const encrypting_reader &reader) | encrypting_reader::encrypting_reader(const encrypting_reader &reader) | ||||||
|     : key_(reader.key_), |     : keys_(reader.keys_), | ||||||
|       stop_requested_cb_(reader.stop_requested_cb_), |       stop_requested_cb_(reader.stop_requested_cb_), | ||||||
|       error_return_(reader.error_return_), |       error_return_(reader.error_return_), | ||||||
|       source_file_( |       source_file_( | ||||||
| @@ -290,7 +357,7 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader) | |||||||
|       encrypted_file_path_(reader.encrypted_file_path_), |       encrypted_file_path_(reader.encrypted_file_path_), | ||||||
|       iv_list_(reader.iv_list_), |       iv_list_(reader.iv_list_), | ||||||
|       chunk_buffers_(reader.chunk_buffers_), |       chunk_buffers_(reader.chunk_buffers_), | ||||||
|       kdf_header_(reader.kdf_header_), |       kdf_headers_(reader.kdf_headers_), | ||||||
|       last_data_chunk_(reader.last_data_chunk_), |       last_data_chunk_(reader.last_data_chunk_), | ||||||
|       last_data_chunk_size_(reader.last_data_chunk_size_), |       last_data_chunk_size_(reader.last_data_chunk_size_), | ||||||
|       read_offset_(reader.read_offset_), |       read_offset_(reader.read_offset_), | ||||||
| @@ -307,46 +374,6 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader) | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void encrypting_reader::common_initialize(bool procces_iv_list) { |  | ||||||
|   REPERTORY_USES_FUNCTION_NAME(); |  | ||||||
|  |  | ||||||
|   if (not *source_file_) { |  | ||||||
|     throw utils::error::create_exception(function_name, |  | ||||||
|                                          { |  | ||||||
|                                              "file open failed", |  | ||||||
|                                              source_file_->get_path(), |  | ||||||
|                                          }); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   auto opt_size = source_file_->size(); |  | ||||||
|   if (not opt_size.has_value()) { |  | ||||||
|     throw utils::error::create_exception(function_name, |  | ||||||
|                                          { |  | ||||||
|                                              "failed to get file size", |  | ||||||
|                                              source_file_->get_path(), |  | ||||||
|                                          }); |  | ||||||
|   } |  | ||||||
|   auto file_size = opt_size.value(); |  | ||||||
|  |  | ||||||
|   auto total_chunks = utils::divide_with_ceiling( |  | ||||||
|       file_size, static_cast<std::uint64_t>(data_chunk_size_)); |  | ||||||
|   total_size_ = file_size + (total_chunks * encryption_header_size) + |  | ||||||
|                 (kdf_header_.has_value() ? kdf_header_->size() : 0U); |  | ||||||
|   last_data_chunk_ = total_chunks - 1U; |  | ||||||
|   last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size |  | ||||||
|                           : (file_size % data_chunk_size_) == 0U |  | ||||||
|                               ? data_chunk_size_ |  | ||||||
|                               : file_size % data_chunk_size_; |  | ||||||
|   if (not procces_iv_list) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   iv_list_.resize(total_chunks); |  | ||||||
|   for (auto &data : iv_list_) { |  | ||||||
|     randombytes_buf(data.data(), data.size()); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| auto encrypting_reader::calculate_decrypted_size(std::uint64_t total_size, | auto encrypting_reader::calculate_decrypted_size(std::uint64_t total_size, | ||||||
|                                                  bool uses_kdf) |                                                  bool uses_kdf) | ||||||
|     -> std::uint64_t { |     -> std::uint64_t { | ||||||
| @@ -382,15 +409,88 @@ auto encrypting_reader::calculate_encrypted_size(std::string_view source_path, | |||||||
|          (uses_kdf ? kdf_config::size() : 0U); |          (uses_kdf ? kdf_config::size() : 0U); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void encrypting_reader::common_initialize(bool procces_iv_list) { | ||||||
|  |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|  |   if (not *source_file_) { | ||||||
|  |     throw utils::error::create_exception(function_name, | ||||||
|  |                                          { | ||||||
|  |                                              "file open failed", | ||||||
|  |                                              source_file_->get_path(), | ||||||
|  |                                          }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   auto opt_size = source_file_->size(); | ||||||
|  |   if (not opt_size.has_value()) { | ||||||
|  |     throw utils::error::create_exception(function_name, | ||||||
|  |                                          { | ||||||
|  |                                              "failed to get file size", | ||||||
|  |                                              source_file_->get_path(), | ||||||
|  |                                          }); | ||||||
|  |   } | ||||||
|  |   auto file_size = opt_size.value(); | ||||||
|  |  | ||||||
|  |   auto total_chunks = utils::divide_with_ceiling( | ||||||
|  |       file_size, static_cast<std::uint64_t>(data_chunk_size_)); | ||||||
|  |   total_size_ = file_size + (total_chunks * encryption_header_size) + | ||||||
|  |                 (kdf_headers_.has_value() ? kdf_headers_->first.size() : 0U); | ||||||
|  |   last_data_chunk_ = total_chunks - 1U; | ||||||
|  |   last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size | ||||||
|  |                           : (file_size % data_chunk_size_) == 0U | ||||||
|  |                               ? data_chunk_size_ | ||||||
|  |                               : file_size % data_chunk_size_; | ||||||
|  |   if (not procces_iv_list) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   iv_list_.resize(total_chunks); | ||||||
|  |   for (auto &data : iv_list_) { | ||||||
|  |     randombytes_buf(data.data(), data.size()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void encrypting_reader::common_initialize_kdf_data( | ||||||
|  |     const kdf_config &cfg, const utils::hash::hash_256_t &master_key) { | ||||||
|  |   auto [data_key, data_cfg] = cfg.create_subkey( | ||||||
|  |       kdf_context::data, utils::generate_secure_random<std::uint64_t>(), | ||||||
|  |       master_key); | ||||||
|  |   keys_.first = std::move(data_key); | ||||||
|  |   kdf_headers_ = {data_cfg.to_header(), {}}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void encrypting_reader::common_initialize_kdf_path( | ||||||
|  |     const utils::hash::hash_256_t &master_key) { | ||||||
|  |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|  |   data_buffer buffer; | ||||||
|  |   if (not utils::collection::from_hex_string(encrypted_file_path_, buffer)) { | ||||||
|  |     throw utils::error::create_exception( | ||||||
|  |         function_name, {"failed to convert encrypted path from hex to bytes"}); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   kdf_config path_cfg; | ||||||
|  |   if (not kdf_config::from_header(buffer, path_cfg)) { | ||||||
|  |     throw utils::error::create_exception( | ||||||
|  |         function_name, {"failed to create path kdf config from header"}); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   utils::hash::hash_256_t path_key; | ||||||
|  |   std::tie(path_key, std::ignore) = | ||||||
|  |       path_cfg.create_subkey(kdf_context::path, path_cfg.unique_id, master_key); | ||||||
|  |  | ||||||
|  |   kdf_headers_->second = path_cfg.to_header(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void encrypting_reader::create_encrypted_paths( | void encrypting_reader::create_encrypted_paths( | ||||||
|     std::string_view file_name, |     std::string_view file_name, | ||||||
|     std::optional<std::string> relative_parent_path) { |     std::optional<std::string> relative_parent_path) { | ||||||
|   data_buffer result; |   data_buffer result; | ||||||
|   utils::encryption::encrypt_data( |   utils::encryption::encrypt_data( | ||||||
|       key_, reinterpret_cast<const unsigned char *>(file_name.data()), |       keys_.second, reinterpret_cast<const unsigned char *>(file_name.data()), | ||||||
|       file_name.size(), result); |       file_name.size(), result); | ||||||
|   if (kdf_header_.has_value()) { |   if (kdf_headers_.has_value()) { | ||||||
|     result.insert(result.begin(), kdf_header_->begin(), kdf_header_->end()); |     result.insert(result.begin(), kdf_headers_->second.begin(), | ||||||
|  |                   kdf_headers_->second.end()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   encrypted_file_name_ = utils::collection::to_hex_string(result); |   encrypted_file_name_ = utils::collection::to_hex_string(result); | ||||||
| @@ -403,10 +503,11 @@ void encrypting_reader::create_encrypted_paths( | |||||||
|        utils::string::split(relative_parent_path.value(), |        utils::string::split(relative_parent_path.value(), | ||||||
|                             utils::path::directory_seperator, false)) { |                             utils::path::directory_seperator, false)) { | ||||||
|     utils::encryption::encrypt_data( |     utils::encryption::encrypt_data( | ||||||
|         key_, reinterpret_cast<const unsigned char *>(part.c_str()), |         keys_.second, reinterpret_cast<const unsigned char *>(part.c_str()), | ||||||
|         strnlen(part.c_str(), part.size()), result); |         strnlen(part.c_str(), part.size()), result); | ||||||
|     if (kdf_header_.has_value()) { |     if (kdf_headers_.has_value()) { | ||||||
|       result.insert(result.begin(), kdf_header_->begin(), kdf_header_->end()); |       result.insert(result.begin(), kdf_headers_->second.begin(), | ||||||
|  |                     kdf_headers_->second.end()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     encrypted_file_path_ += '/' + utils::collection::to_hex_string(result); |     encrypted_file_path_ += '/' + utils::collection::to_hex_string(result); | ||||||
| @@ -421,15 +522,35 @@ auto encrypting_reader::create_iostream() const | |||||||
|       std::make_unique<encrypting_streambuf>(*this)); |       std::make_unique<encrypting_streambuf>(*this)); | ||||||
| } | } | ||||||
|  |  | ||||||
| auto encrypting_reader::get_kdf_config() const -> std::optional<kdf_config> { | auto encrypting_reader::get_kdf_config_for_data() const | ||||||
|  |     -> std::optional<kdf_config> { | ||||||
|   REPERTORY_USES_FUNCTION_NAME(); |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|   if (not kdf_header_.has_value()) { |   if (not kdf_headers_.has_value()) { | ||||||
|     return std::nullopt; |     return std::nullopt; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   kdf_config cfg; |   kdf_config cfg; | ||||||
|   if (not kdf_config::from_header(kdf_header_.value(), cfg)) { |   if (not kdf_config::from_header(kdf_headers_->first, cfg)) { | ||||||
|  |     throw utils::error::create_exception(function_name, | ||||||
|  |                                          { | ||||||
|  |                                              "invalid kdf header", | ||||||
|  |                                          }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return cfg; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto encrypting_reader::get_kdf_config_for_path() const | ||||||
|  |     -> std::optional<kdf_config> { | ||||||
|  |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|  |   if (not kdf_headers_.has_value()) { | ||||||
|  |     return std::nullopt; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   kdf_config cfg; | ||||||
|  |   if (not kdf_config::from_header(kdf_headers_->second, cfg)) { | ||||||
|     throw utils::error::create_exception(function_name, |     throw utils::error::create_exception(function_name, | ||||||
|                                          { |                                          { | ||||||
|                                              "invalid kdf header", |                                              "invalid kdf header", | ||||||
| @@ -443,6 +564,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, | |||||||
|                                         size_t nitems) -> size_t { |                                         size_t nitems) -> size_t { | ||||||
|   REPERTORY_USES_FUNCTION_NAME(); |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|  |   std::span<char> dest(buffer, size); | ||||||
|  |  | ||||||
|   auto read_size = |   auto read_size = | ||||||
|       static_cast<std::uint64_t>(size) * static_cast<std::uint64_t>(nitems); |       static_cast<std::uint64_t>(size) * static_cast<std::uint64_t>(nitems); | ||||||
|   if (read_size == 0U) { |   if (read_size == 0U) { | ||||||
| @@ -453,17 +576,17 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, | |||||||
|   std::size_t total_read{}; |   std::size_t total_read{}; | ||||||
|   auto total_size{total_size_}; |   auto total_size{total_size_}; | ||||||
|  |  | ||||||
|   if (kdf_header_.has_value()) { |   if (kdf_headers_.has_value()) { | ||||||
|     total_size -= kdf_header_->size(); |     auto &hdr = kdf_headers_->first; | ||||||
|  |     total_size -= hdr.size(); | ||||||
|  |  | ||||||
|     if (read_offset < kdf_header_->size()) { |     if (read_offset < hdr.size()) { | ||||||
|       auto to_read{ |       auto to_read{ | ||||||
|           utils::calculate_read_size(kdf_header_->size(), read_size, |           utils::calculate_read_size(hdr.size(), read_size, read_offset), | ||||||
|                                      read_offset), |  | ||||||
|       }; |       }; | ||||||
|       read_offset_ += to_read; |       read_offset_ += to_read; | ||||||
|  |  | ||||||
|       std::memcpy(buffer, &kdf_header_->data()[read_offset], to_read); |       std::memcpy(&dest[total_read], &hdr.at(read_offset), to_read); | ||||||
|       if (read_size - to_read == 0) { |       if (read_size - to_read == 0) { | ||||||
|         return to_read; |         return to_read; | ||||||
|       } |       } | ||||||
| @@ -471,9 +594,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, | |||||||
|       read_offset = 0U; |       read_offset = 0U; | ||||||
|       read_size -= to_read; |       read_size -= to_read; | ||||||
|       total_read += to_read; |       total_read += to_read; | ||||||
|       buffer += to_read; |  | ||||||
|     } else { |     } else { | ||||||
|       read_offset -= kdf_header_->size(); |       read_offset -= hdr.size(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -501,8 +623,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, | |||||||
|                   static_cast<std::uint64_t>(data_chunk_size_), |                   static_cast<std::uint64_t>(data_chunk_size_), | ||||||
|               &bytes_read); |               &bytes_read); | ||||||
|           if (ret) { |           if (ret) { | ||||||
|             utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data, |             utils::encryption::encrypt_data(iv_list_.at(chunk), keys_.first, | ||||||
|                                             chunk_buffer); |                                             file_data, chunk_buffer); | ||||||
|           } |           } | ||||||
|         } else if (chunk != 0U) { |         } else if (chunk != 0U) { | ||||||
|           chunk_buffers_.erase(chunk - 1U); |           chunk_buffers_.erase(chunk - 1U); | ||||||
| @@ -510,7 +632,7 @@ auto encrypting_reader::reader_function(char *buffer, size_t size, | |||||||
|  |  | ||||||
|         auto &chunk_buffer = chunk_buffers_[chunk]; |         auto &chunk_buffer = chunk_buffers_[chunk]; | ||||||
|         auto to_read = std::min(chunk_buffer.size() - chunk_offset, remain); |         auto to_read = std::min(chunk_buffer.size() - chunk_offset, remain); | ||||||
|         std::memcpy(buffer + total_read, &chunk_buffer[chunk_offset], to_read); |         std::memcpy(&dest[total_read], &chunk_buffer[chunk_offset], to_read); | ||||||
|         total_read += to_read; |         total_read += to_read; | ||||||
|         remain -= to_read; |         remain -= to_read; | ||||||
|         chunk_offset = 0U; |         chunk_offset = 0U; | ||||||
|   | |||||||
| @@ -28,11 +28,24 @@ | |||||||
| #include "utils/hash.hpp" | #include "utils/hash.hpp" | ||||||
| #include "utils/path.hpp" | #include "utils/path.hpp" | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  | constexpr auto resize_by(repertory::data_span &data, std::size_t /* size */) | ||||||
|  |     -> repertory::data_span & { | ||||||
|  |   return data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto resize_by(repertory::data_buffer &data, std::size_t size) | ||||||
|  |     -> repertory::data_buffer & { | ||||||
|  |   data.resize(data.size() + size); | ||||||
|  |   return data; | ||||||
|  | } | ||||||
|  | } // namespace | ||||||
|  |  | ||||||
| namespace repertory::utils::encryption { | namespace repertory::utils::encryption { | ||||||
| auto kdf_config::to_header() const -> data_buffer { | auto kdf_config::to_header() const -> data_buffer { | ||||||
|   kdf_config tmp{*this}; |   kdf_config tmp{*this}; | ||||||
|   tmp.checksum = boost::endian::native_to_big(tmp.checksum); |   tmp.checksum = boost::endian::native_to_big(tmp.checksum); | ||||||
|   tmp.magic = boost::endian::native_to_big(tmp.magic); |   tmp.unique_id = boost::endian::native_to_big(tmp.unique_id); | ||||||
|  |  | ||||||
|   data_buffer ret(size()); |   data_buffer ret(size()); | ||||||
|   std::memcpy(ret.data(), &tmp, ret.size()); |   std::memcpy(ret.data(), &tmp, ret.size()); | ||||||
| @@ -49,24 +62,15 @@ auto kdf_config::generate_checksum() const -> std::uint64_t { | |||||||
|   return *reinterpret_cast<std::uint64_t *>(hash.data()); |   return *reinterpret_cast<std::uint64_t *>(hash.data()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void kdf_config::generate_salt() { | auto kdf_config::from_header(data_cspan data, kdf_config &cfg) -> bool { | ||||||
|   randombytes_buf(salt.data(), salt.size()); |  | ||||||
|   checksum = generate_checksum(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| auto kdf_config::from_header(std::span<const unsigned char> data, |  | ||||||
|                              kdf_config &cfg) -> bool { |  | ||||||
|   if (data.size() < kdf_config::size()) { |   if (data.size() < kdf_config::size()) { | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   std::memcpy(&cfg, data.data(), kdf_config::size()); |   std::memcpy(&cfg, data.data(), kdf_config::size()); | ||||||
|   cfg.magic = boost::endian::big_to_native(cfg.magic); |  | ||||||
|   if (cfg.magic != repertory_magic) { |  | ||||||
|     return false; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   cfg.checksum = boost::endian::big_to_native(cfg.checksum); |   cfg.checksum = boost::endian::big_to_native(cfg.checksum); | ||||||
|  |   cfg.unique_id = boost::endian::big_to_native(cfg.unique_id); | ||||||
|   return cfg.version == kdf_version::v1 && cfg.kdf == kdf_type::argon2id && |   return cfg.version == kdf_version::v1 && cfg.kdf == kdf_type::argon2id && | ||||||
|          cfg.memlimit >= memlimit_level::level1 && |          cfg.memlimit >= memlimit_level::level1 && | ||||||
|          cfg.memlimit <= memlimit_level::level4 && |          cfg.memlimit <= memlimit_level::level4 && | ||||||
| @@ -75,6 +79,11 @@ auto kdf_config::from_header(std::span<const unsigned char> data, | |||||||
|          cfg.checksum == cfg.generate_checksum(); |          cfg.checksum == cfg.generate_checksum(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void kdf_config::seal() { | ||||||
|  |   randombytes_buf(salt.data(), salt.size()); | ||||||
|  |   checksum = generate_checksum(); | ||||||
|  | } | ||||||
|  |  | ||||||
| auto decrypt_file_path(std::string_view encryption_token, | auto decrypt_file_path(std::string_view encryption_token, | ||||||
|                        std::string &file_path) -> bool { |                        std::string &file_path) -> bool { | ||||||
|   std::vector<std::string> decrypted_parts; |   std::vector<std::string> decrypted_parts; | ||||||
| @@ -140,16 +149,6 @@ auto decrypt_file_name(std::string_view encryption_token, const kdf_config &cfg, | |||||||
|                                          file_name); |                                          file_name); | ||||||
| } | } | ||||||
|  |  | ||||||
| constexpr auto resize_by(std::span<unsigned char> &data, std::size_t size) |  | ||||||
|     -> std::span<unsigned char> & { |  | ||||||
|   return data; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static auto resize_by(data_buffer &data, std::size_t size) -> data_buffer & { |  | ||||||
|   data.resize(data.size() + size); |  | ||||||
|   return data; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename data_t> | template <typename data_t> | ||||||
| [[nodiscard]] auto | [[nodiscard]] auto | ||||||
| read_encrypted_range(http_range range, const utils::hash::hash_256_t &key, | read_encrypted_range(http_range range, const utils::hash::hash_256_t &key, | ||||||
| @@ -215,12 +214,12 @@ read_encrypted_range(http_range range, const utils::hash::hash_256_t &key, | |||||||
|  |  | ||||||
|     auto data_size = static_cast<std::size_t>(std::min( |     auto data_size = static_cast<std::size_t>(std::min( | ||||||
|         remain, static_cast<std::uint64_t>(data_chunk_size - source_offset))); |         remain, static_cast<std::uint64_t>(data_chunk_size - source_offset))); | ||||||
|     resize_by(data, data_size); |  | ||||||
|     std::copy(std::next(source_buffer.begin(), |     std::copy(std::next(source_buffer.begin(), | ||||||
|                         static_cast<std::int64_t>(source_offset)), |                         static_cast<std::int64_t>(source_offset)), | ||||||
|               std::next(source_buffer.begin(), |               std::next(source_buffer.begin(), | ||||||
|                         static_cast<std::int64_t>(source_offset + data_size)), |                         static_cast<std::int64_t>(source_offset + data_size)), | ||||||
|               std::next(data.begin(), static_cast<std::int64_t>(bytes_read))); |               std::next(resize_by(data, data_size).begin(), | ||||||
|  |                         static_cast<std::int64_t>(bytes_read))); | ||||||
|     remain -= data_size; |     remain -= data_size; | ||||||
|     bytes_read += data_size; |     bytes_read += data_size; | ||||||
|     source_offset = 0U; |     source_offset = 0U; | ||||||
| @@ -243,8 +242,8 @@ auto read_encrypted_range(const http_range &range, | |||||||
|     const http_range &range, const utils::hash::hash_256_t &key, bool uses_kdf, |     const http_range &range, const utils::hash::hash_256_t &key, bool uses_kdf, | ||||||
|     reader_func_t reader_func, std::uint64_t total_size, unsigned char *data, |     reader_func_t reader_func, std::uint64_t total_size, unsigned char *data, | ||||||
|     std::size_t size, std::size_t &bytes_read) -> bool { |     std::size_t size, std::size_t &bytes_read) -> bool { | ||||||
|   std::span dest_buffer(data, size); |   data_span dest_buffer(data, size); | ||||||
|   return read_encrypted_range<std::span<unsigned char>>( |   return read_encrypted_range<data_span>( | ||||||
|       range, key, reader_func, total_size, dest_buffer, |       range, key, reader_func, total_size, dest_buffer, | ||||||
|       uses_kdf ? kdf_config::size() : 0U, bytes_read); |       uses_kdf ? kdf_config::size() : 0U, bytes_read); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,7 +51,7 @@ auto from_utf8(std::string_view str) -> std::wstring { | |||||||
|   while (idx < len) { |   while (idx < len) { | ||||||
|     UChar32 uni_ch{}; |     UChar32 uni_ch{}; | ||||||
|     U8_NEXT(str_ptr, idx, len, uni_ch); |     U8_NEXT(str_ptr, idx, len, uni_ch); | ||||||
|     if (uni_ch < 0 || !U_IS_UNICODE_CHAR(uni_ch)) { |     if (uni_ch < 0 || not U_IS_UNICODE_CHAR(uni_ch)) { | ||||||
|       throw std::runtime_error("from_utf8: invalid UTF-8 sequence"); |       throw std::runtime_error("from_utf8: invalid UTF-8 sequence"); | ||||||
|     } |     } | ||||||
|     std::array<UChar, 2U> units{}; |     std::array<UChar, 2U> units{}; | ||||||
| @@ -71,7 +71,7 @@ auto from_utf8(std::string_view str) -> std::wstring { | |||||||
|   while (idx < len) { |   while (idx < len) { | ||||||
|     UChar32 uni_ch{}; |     UChar32 uni_ch{}; | ||||||
|     U8_NEXT(str_ptr, idx, len, uni_ch); |     U8_NEXT(str_ptr, idx, len, uni_ch); | ||||||
|     if (uni_ch < 0 || !U_IS_UNICODE_CHAR(uni_ch)) { |     if (uni_ch < 0 || not U_IS_UNICODE_CHAR(uni_ch)) { | ||||||
|       throw std::runtime_error("from_utf8: invalid UTF-8 sequence"); |       throw std::runtime_error("from_utf8: invalid UTF-8 sequence"); | ||||||
|     } |     } | ||||||
|     out.push_back(static_cast<wchar_t>(uni_ch)); |     out.push_back(static_cast<wchar_t>(uni_ch)); | ||||||
| @@ -183,7 +183,7 @@ auto to_utf8(std::wstring_view str) -> std::string { | |||||||
|   while (idx < len) { |   while (idx < len) { | ||||||
|     UChar32 uni_ch{}; |     UChar32 uni_ch{}; | ||||||
|     U16_NEXT(u16, idx, len, uni_ch); |     U16_NEXT(u16, idx, len, uni_ch); | ||||||
|     if (uni_ch < 0 || !U_IS_UNICODE_CHAR(uni_ch)) { |     if (uni_ch < 0 || not U_IS_UNICODE_CHAR(uni_ch)) { | ||||||
|       throw std::runtime_error("to_utf8: invalid UTF-16 sequence"); |       throw std::runtime_error("to_utf8: invalid UTF-16 sequence"); | ||||||
|     } |     } | ||||||
|     std::array<std::uint8_t, U8_MAX_LENGTH> buf{}; |     std::array<std::uint8_t, U8_MAX_LENGTH> buf{}; | ||||||
| @@ -197,9 +197,9 @@ auto to_utf8(std::wstring_view str) -> std::string { | |||||||
|                static_cast<std::size_t>(off)); |                static_cast<std::size_t>(off)); | ||||||
|   } |   } | ||||||
| #else  // WCHAR_MAX > 0xFFFF | #else  // WCHAR_MAX > 0xFFFF | ||||||
|   for (auto cur_ch : str) { |   for (const auto &cur_ch : str) { | ||||||
|     auto uni_char{static_cast<UChar32>(cur_ch)}; |     auto uni_char{static_cast<UChar32>(cur_ch)}; | ||||||
|     if (!U_IS_UNICODE_CHAR(uni_char)) { |     if (not U_IS_UNICODE_CHAR(uni_char)) { | ||||||
|       throw std::runtime_error("to_utf8: invalid Unicode scalar value"); |       throw std::runtime_error("to_utf8: invalid Unicode scalar value"); | ||||||
|     } |     } | ||||||
|     std::array<std::uint8_t, U8_MAX_LENGTH> buf{}; |     std::array<std::uint8_t, U8_MAX_LENGTH> buf{}; | ||||||
|   | |||||||
| @@ -32,8 +32,8 @@ namespace { | |||||||
|  |  | ||||||
|   std::vector<gid_t> groups{}; |   std::vector<gid_t> groups{}; | ||||||
| #if defined(__APPLE__) | #if defined(__APPLE__) | ||||||
|   constexpr const int buffer_count{8}; |   constexpr int buffer_count{8}; | ||||||
|   constexpr const int max_group_count{1024}; |   constexpr int max_group_count{1024}; | ||||||
|   groups.resize(buffer_count); |   groups.resize(buffer_count); | ||||||
|  |  | ||||||
|   std::size_t orig_count{0U}; |   std::size_t orig_count{0U}; | ||||||
|   | |||||||
| @@ -35,7 +35,8 @@ TEST(utils_encrypting_reader, read_file_data) { | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token); |         "test.dat", source_file.get_path(), get_stop_requested, token, | ||||||
|  |         std::nullopt); | ||||||
|  |  | ||||||
|     for (std::uint8_t i = 0U; i < 8U; i++) { |     for (std::uint8_t i = 0U; i < 8U; i++) { | ||||||
|       data_buffer buffer( |       data_buffer buffer( | ||||||
| @@ -76,14 +77,14 @@ TEST(utils_encrypting_reader, read_file_data_using_argon2id) { | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token, cfg); |         "test.dat", source_file.get_path(), get_stop_requested, token, cfg, | ||||||
|  |         std::nullopt); | ||||||
|  |  | ||||||
|     std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr; |     std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr; | ||||||
|     EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function( |     EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function( | ||||||
|                               reinterpret_cast<char *>(hdr.data()), hdr.size(), |                               reinterpret_cast<char *>(hdr.data()), hdr.size(), | ||||||
|                               1U, &reader)); |                               1U, &reader)); | ||||||
|     EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg)); |     EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg)); | ||||||
|     // EXPECT_EQ(cfg, reader.get_kdf_config().value()); |  | ||||||
|  |  | ||||||
|     for (std::uint8_t i = 0U; i < 8U; i++) { |     for (std::uint8_t i = 0U; i < 8U; i++) { | ||||||
|       data_buffer buffer( |       data_buffer buffer( | ||||||
| @@ -98,7 +99,62 @@ TEST(utils_encrypting_reader, read_file_data_using_argon2id) { | |||||||
|  |  | ||||||
|       data_buffer decrypted_data; |       data_buffer decrypted_data; | ||||||
|       EXPECT_TRUE(utils::encryption::decrypt_data( |       EXPECT_TRUE(utils::encryption::decrypt_data( | ||||||
|           token, *reader.get_kdf_config(), buffer, decrypted_data)); |           token, *reader.get_kdf_config_for_data(), buffer, decrypted_data)); | ||||||
|  |  | ||||||
|  |       EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), | ||||||
|  |                 decrypted_data.size()); | ||||||
|  |  | ||||||
|  |       std::size_t bytes_read{}; | ||||||
|  |       data_buffer file_data(decrypted_data.size()); | ||||||
|  |       EXPECT_TRUE(source_file.read( | ||||||
|  |           file_data, | ||||||
|  |           utils::encryption::encrypting_reader::get_data_chunk_size() * i, | ||||||
|  |           &bytes_read)); | ||||||
|  |       EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(), | ||||||
|  |                                file_data.size())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encrypting_reader, read_file_data_using_argon2id_master_key) { | ||||||
|  |   const auto token = std::string("moose"); | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |  | ||||||
|  |   auto master_key = | ||||||
|  |       utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg); | ||||||
|  |  | ||||||
|  |   auto &source_file = test::create_random_file( | ||||||
|  |       8U * utils::encryption::encrypting_reader::get_data_chunk_size()); | ||||||
|  |   EXPECT_TRUE(source_file); | ||||||
|  |   if (source_file) { | ||||||
|  |     utils::encryption::encrypting_reader reader( | ||||||
|  |         "test.dat", source_file.get_path(), get_stop_requested, master_key, cfg, | ||||||
|  |         std::nullopt); | ||||||
|  |  | ||||||
|  |     std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr; | ||||||
|  |     EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function( | ||||||
|  |                               reinterpret_cast<char *>(hdr.data()), hdr.size(), | ||||||
|  |                               1U, &reader)); | ||||||
|  |     EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg)); | ||||||
|  |  | ||||||
|  |     for (std::uint8_t i = 0U; i < 8U; i++) { | ||||||
|  |       data_buffer buffer( | ||||||
|  |           utils::encryption::encrypting_reader::get_encrypted_chunk_size()); | ||||||
|  |       for (std::uint8_t j = 0U; j < 2U; j++) { | ||||||
|  |         ASSERT_EQ( | ||||||
|  |             buffer.size() / 2U, | ||||||
|  |             utils::encryption::encrypting_reader::reader_function( | ||||||
|  |                 reinterpret_cast<char *>(&buffer[(buffer.size() / 2U) * j]), | ||||||
|  |                 buffer.size() / 2U, 1U, &reader)); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       auto data_cfg = *reader.get_kdf_config_for_data(); | ||||||
|  |       utils::hash::hash_256_t data_key; | ||||||
|  |       std::tie(data_key, std::ignore) = cfg.create_subkey( | ||||||
|  |           utils::encryption::kdf_context::data, data_cfg.unique_id, master_key); | ||||||
|  |       data_buffer decrypted_data; | ||||||
|  |       EXPECT_TRUE( | ||||||
|  |           utils::encryption::decrypt_data(data_key, buffer, decrypted_data)); | ||||||
|  |  | ||||||
|       EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), |       EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), | ||||||
|                 decrypted_data.size()); |                 decrypted_data.size()); | ||||||
| @@ -122,7 +178,8 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks) { | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token); |         "test.dat", source_file.get_path(), get_stop_requested, token, | ||||||
|  |         std::nullopt); | ||||||
|  |  | ||||||
|     for (std::uint8_t i = 0U; i < 8U; i += 2U) { |     for (std::uint8_t i = 0U; i < 8U; i += 2U) { | ||||||
|       data_buffer buffer( |       data_buffer buffer( | ||||||
| @@ -172,14 +229,14 @@ TEST(utils_encrypting_reader, | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token, cfg); |         "test.dat", source_file.get_path(), get_stop_requested, token, cfg, | ||||||
|  |         std::nullopt); | ||||||
|  |  | ||||||
|     std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr; |     std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr; | ||||||
|     EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function( |     EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function( | ||||||
|                               reinterpret_cast<char *>(hdr.data()), hdr.size(), |                               reinterpret_cast<char *>(hdr.data()), hdr.size(), | ||||||
|                               1U, &reader)); |                               1U, &reader)); | ||||||
|     EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg)); |     EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg)); | ||||||
|     // EXPECT_EQ(cfg, reader.get_kdf_config().value()); |  | ||||||
|  |  | ||||||
|     for (std::uint8_t i = 0U; i < 8U; i += 2U) { |     for (std::uint8_t i = 0U; i < 8U; i += 2U) { | ||||||
|       data_buffer buffer( |       data_buffer buffer( | ||||||
| @@ -194,7 +251,72 @@ TEST(utils_encrypting_reader, | |||||||
|         data_buffer decrypted_data; |         data_buffer decrypted_data; | ||||||
|         const auto offset = (j * (buffer.size() / 2U)); |         const auto offset = (j * (buffer.size() / 2U)); | ||||||
|         EXPECT_TRUE(utils::encryption::decrypt_data( |         EXPECT_TRUE(utils::encryption::decrypt_data( | ||||||
|             token, *reader.get_kdf_config(), |             token, *reader.get_kdf_config_for_data(), | ||||||
|  |             data_buffer( | ||||||
|  |                 std::next(buffer.begin(), static_cast<std::int64_t>(offset)), | ||||||
|  |                 std::next(buffer.begin(), static_cast<std::int64_t>( | ||||||
|  |                                               offset + (buffer.size() / 2U)))), | ||||||
|  |             decrypted_data)); | ||||||
|  |  | ||||||
|  |         EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), | ||||||
|  |                   decrypted_data.size()); | ||||||
|  |  | ||||||
|  |         std::size_t bytes_read{}; | ||||||
|  |         data_buffer file_data(decrypted_data.size()); | ||||||
|  |         EXPECT_TRUE(source_file.read( | ||||||
|  |             file_data, | ||||||
|  |             (utils::encryption::encrypting_reader::get_data_chunk_size() * i) + | ||||||
|  |                 (j * | ||||||
|  |                  utils::encryption::encrypting_reader::get_data_chunk_size()), | ||||||
|  |             &bytes_read)); | ||||||
|  |         EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(), | ||||||
|  |                                  file_data.size())); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encrypting_reader, | ||||||
|  |      read_file_data_in_multiple_chunks_using_argon2id_master_key) { | ||||||
|  |   const auto token = std::string("moose"); | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |  | ||||||
|  |   auto master_key = | ||||||
|  |       utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg); | ||||||
|  |  | ||||||
|  |   auto &source_file = test::create_random_file( | ||||||
|  |       8U * utils::encryption::encrypting_reader::get_data_chunk_size()); | ||||||
|  |   EXPECT_TRUE(source_file); | ||||||
|  |   if (source_file) { | ||||||
|  |     utils::encryption::encrypting_reader reader( | ||||||
|  |         "test.dat", source_file.get_path(), get_stop_requested, master_key, cfg, | ||||||
|  |         std::nullopt); | ||||||
|  |  | ||||||
|  |     std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr; | ||||||
|  |     EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function( | ||||||
|  |                               reinterpret_cast<char *>(hdr.data()), hdr.size(), | ||||||
|  |                               1U, &reader)); | ||||||
|  |     EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg)); | ||||||
|  |  | ||||||
|  |     for (std::uint8_t i = 0U; i < 8U; i += 2U) { | ||||||
|  |       data_buffer buffer( | ||||||
|  |           utils::encryption::encrypting_reader::get_encrypted_chunk_size() * | ||||||
|  |           2U); | ||||||
|  |       EXPECT_EQ(buffer.size(), | ||||||
|  |                 utils::encryption::encrypting_reader::reader_function( | ||||||
|  |                     reinterpret_cast<char *>(buffer.data()), buffer.size(), 1U, | ||||||
|  |                     &reader)); | ||||||
|  |  | ||||||
|  |       auto data_cfg = *reader.get_kdf_config_for_data(); | ||||||
|  |       utils::hash::hash_256_t data_key; | ||||||
|  |       std::tie(data_key, std::ignore) = cfg.create_subkey( | ||||||
|  |           utils::encryption::kdf_context::data, data_cfg.unique_id, master_key); | ||||||
|  |  | ||||||
|  |       for (std::uint8_t j = 0U; j < 2U; j++) { | ||||||
|  |         data_buffer decrypted_data; | ||||||
|  |         const auto offset = (j * (buffer.size() / 2U)); | ||||||
|  |         EXPECT_TRUE(utils::encryption::decrypt_data( | ||||||
|  |             data_key, | ||||||
|             data_buffer( |             data_buffer( | ||||||
|                 std::next(buffer.begin(), static_cast<std::int64_t>(offset)), |                 std::next(buffer.begin(), static_cast<std::int64_t>(offset)), | ||||||
|                 std::next(buffer.begin(), static_cast<std::int64_t>( |                 std::next(buffer.begin(), static_cast<std::int64_t>( | ||||||
| @@ -226,7 +348,8 @@ TEST(utils_encrypting_reader, read_file_data_as_stream) { | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token); |         "test.dat", source_file.get_path(), get_stop_requested, token, | ||||||
|  |         std::nullopt); | ||||||
|     auto io_stream = reader.create_iostream(); |     auto io_stream = reader.create_iostream(); | ||||||
|     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); | ||||||
|     EXPECT_TRUE(io_stream->good()); |     EXPECT_TRUE(io_stream->good()); | ||||||
| @@ -280,7 +403,8 @@ TEST(utils_encrypting_reader, read_file_data_as_stream_using_argon2id) { | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token, cfg); |         "test.dat", source_file.get_path(), get_stop_requested, token, cfg, | ||||||
|  |         std::nullopt); | ||||||
|     auto io_stream = reader.create_iostream(); |     auto io_stream = reader.create_iostream(); | ||||||
|     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); | ||||||
|     EXPECT_TRUE(io_stream->good()); |     EXPECT_TRUE(io_stream->good()); | ||||||
| @@ -310,7 +434,73 @@ TEST(utils_encrypting_reader, read_file_data_as_stream_using_argon2id) { | |||||||
|  |  | ||||||
|       data_buffer decrypted_data; |       data_buffer decrypted_data; | ||||||
|       EXPECT_TRUE(utils::encryption::decrypt_data( |       EXPECT_TRUE(utils::encryption::decrypt_data( | ||||||
|           token, *reader.get_kdf_config(), buffer, decrypted_data)); |           token, *reader.get_kdf_config_for_data(), buffer, decrypted_data)); | ||||||
|  |  | ||||||
|  |       EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), | ||||||
|  |                 decrypted_data.size()); | ||||||
|  |  | ||||||
|  |       std::size_t bytes_read{}; | ||||||
|  |       data_buffer file_data(decrypted_data.size()); | ||||||
|  |       EXPECT_TRUE(source_file.read( | ||||||
|  |           file_data, | ||||||
|  |           utils::encryption::encrypting_reader::get_data_chunk_size() * i, | ||||||
|  |           &bytes_read)); | ||||||
|  |       EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(), | ||||||
|  |                                file_data.size())); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encrypting_reader, | ||||||
|  |      read_file_data_as_stream_using_argon2id_master_key) { | ||||||
|  |   const auto token = std::string("moose"); | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |  | ||||||
|  |   auto master_key = | ||||||
|  |       utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg); | ||||||
|  |  | ||||||
|  |   auto &source_file = test::create_random_file( | ||||||
|  |       8U * utils::encryption::encrypting_reader::get_data_chunk_size()); | ||||||
|  |   EXPECT_TRUE(source_file); | ||||||
|  |   if (source_file) { | ||||||
|  |     utils::encryption::encrypting_reader reader( | ||||||
|  |         "test.dat", source_file.get_path(), get_stop_requested, master_key, cfg, | ||||||
|  |         std::nullopt); | ||||||
|  |     auto io_stream = reader.create_iostream(); | ||||||
|  |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); | ||||||
|  |     EXPECT_TRUE(io_stream->good()); | ||||||
|  |     EXPECT_EQ(reader.get_total_size(), | ||||||
|  |               static_cast<std::uint64_t>(io_stream->tellg())); | ||||||
|  |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail()); | ||||||
|  |     EXPECT_TRUE(io_stream->good()); | ||||||
|  |  | ||||||
|  |     for (std::uint8_t i = 0U; i < 8U; i++) { | ||||||
|  |       data_buffer buffer( | ||||||
|  |           utils::encryption::encrypting_reader::get_encrypted_chunk_size()); | ||||||
|  |       EXPECT_FALSE( | ||||||
|  |           io_stream | ||||||
|  |               ->seekg(static_cast<std::streamoff>( | ||||||
|  |                   i * buffer.size() + utils::encryption::kdf_config::size())) | ||||||
|  |               .fail()); | ||||||
|  |       EXPECT_TRUE(io_stream->good()); | ||||||
|  |       for (std::uint8_t j = 0U; j < 2U; j++) { | ||||||
|  |         EXPECT_FALSE( | ||||||
|  |             io_stream | ||||||
|  |                 ->read( | ||||||
|  |                     reinterpret_cast<char *>(&buffer[(buffer.size() / 2U) * j]), | ||||||
|  |                     static_cast<std::streamsize>(buffer.size()) / 2U) | ||||||
|  |                 .fail()); | ||||||
|  |         EXPECT_TRUE(io_stream->good()); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       auto data_cfg = *reader.get_kdf_config_for_data(); | ||||||
|  |       utils::hash::hash_256_t data_key; | ||||||
|  |       std::tie(data_key, std::ignore) = cfg.create_subkey( | ||||||
|  |           utils::encryption::kdf_context::data, data_cfg.unique_id, master_key); | ||||||
|  |  | ||||||
|  |       data_buffer decrypted_data; | ||||||
|  |       EXPECT_TRUE( | ||||||
|  |           utils::encryption::decrypt_data(data_key, buffer, decrypted_data)); | ||||||
|  |  | ||||||
|       EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), |       EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), | ||||||
|                 decrypted_data.size()); |                 decrypted_data.size()); | ||||||
| @@ -334,7 +524,8 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks_as_stream) { | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token); |         "test.dat", source_file.get_path(), get_stop_requested, token, | ||||||
|  |         std::nullopt); | ||||||
|     auto io_stream = reader.create_iostream(); |     auto io_stream = reader.create_iostream(); | ||||||
|     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); | ||||||
|     EXPECT_TRUE(io_stream->good()); |     EXPECT_TRUE(io_stream->good()); | ||||||
| @@ -392,7 +583,8 @@ TEST(utils_encrypting_reader, | |||||||
|   EXPECT_TRUE(source_file); |   EXPECT_TRUE(source_file); | ||||||
|   if (source_file) { |   if (source_file) { | ||||||
|     utils::encryption::encrypting_reader reader( |     utils::encryption::encrypting_reader reader( | ||||||
|         "test.dat", source_file.get_path(), get_stop_requested, token, cfg); |         "test.dat", source_file.get_path(), get_stop_requested, token, cfg, | ||||||
|  |         std::nullopt); | ||||||
|     auto io_stream = reader.create_iostream(); |     auto io_stream = reader.create_iostream(); | ||||||
|     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); | ||||||
|     EXPECT_TRUE(io_stream->good()); |     EXPECT_TRUE(io_stream->good()); | ||||||
| @@ -420,7 +612,79 @@ TEST(utils_encrypting_reader, | |||||||
|         data_buffer decrypted_data; |         data_buffer decrypted_data; | ||||||
|         const auto offset = (j * (buffer.size() / 2U)); |         const auto offset = (j * (buffer.size() / 2U)); | ||||||
|         EXPECT_TRUE(utils::encryption::decrypt_data( |         EXPECT_TRUE(utils::encryption::decrypt_data( | ||||||
|             token, *reader.get_kdf_config(), |             token, *reader.get_kdf_config_for_data(), | ||||||
|  |             data_buffer( | ||||||
|  |                 std::next(buffer.begin(), static_cast<std::int64_t>(offset)), | ||||||
|  |                 std::next(buffer.begin(), static_cast<std::int64_t>( | ||||||
|  |                                               offset + (buffer.size() / 2U)))), | ||||||
|  |             decrypted_data)); | ||||||
|  |  | ||||||
|  |         EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(), | ||||||
|  |                   decrypted_data.size()); | ||||||
|  |  | ||||||
|  |         std::size_t bytes_read{}; | ||||||
|  |         data_buffer file_data(decrypted_data.size()); | ||||||
|  |         EXPECT_TRUE(source_file.read( | ||||||
|  |             file_data, | ||||||
|  |             (utils::encryption::encrypting_reader::get_data_chunk_size() * i) + | ||||||
|  |                 (j * | ||||||
|  |                  utils::encryption::encrypting_reader::get_data_chunk_size()), | ||||||
|  |             &bytes_read)); | ||||||
|  |         EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(), | ||||||
|  |                                  file_data.size())); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encrypting_reader, | ||||||
|  |      read_file_data_in_multiple_chunks_as_stream_using_argon2id_master_key) { | ||||||
|  |   const auto token = std::string("moose"); | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |  | ||||||
|  |   auto master_key = | ||||||
|  |       utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg); | ||||||
|  |  | ||||||
|  |   auto &source_file = test::create_random_file( | ||||||
|  |       8u * utils::encryption::encrypting_reader::get_data_chunk_size()); | ||||||
|  |   EXPECT_TRUE(source_file); | ||||||
|  |   if (source_file) { | ||||||
|  |     utils::encryption::encrypting_reader reader( | ||||||
|  |         "test.dat", source_file.get_path(), get_stop_requested, master_key, cfg, | ||||||
|  |         std::nullopt); | ||||||
|  |     auto io_stream = reader.create_iostream(); | ||||||
|  |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail()); | ||||||
|  |     EXPECT_TRUE(io_stream->good()); | ||||||
|  |     EXPECT_EQ(reader.get_total_size(), | ||||||
|  |               static_cast<std::uint64_t>(io_stream->tellg())); | ||||||
|  |     EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail()); | ||||||
|  |     EXPECT_TRUE(io_stream->good()); | ||||||
|  |  | ||||||
|  |     EXPECT_FALSE(io_stream | ||||||
|  |                      ->seekg(static_cast<std::streamoff>( | ||||||
|  |                          utils::encryption::kdf_config::size())) | ||||||
|  |                      .fail()); | ||||||
|  |  | ||||||
|  |     for (std::uint8_t i = 0U; i < 8U; i += 2U) { | ||||||
|  |       data_buffer buffer( | ||||||
|  |           utils::encryption::encrypting_reader::get_encrypted_chunk_size() * | ||||||
|  |           2U); | ||||||
|  |       EXPECT_FALSE(io_stream | ||||||
|  |                        ->read(reinterpret_cast<char *>(buffer.data()), | ||||||
|  |                               static_cast<std::streamsize>(buffer.size())) | ||||||
|  |                        .fail()); | ||||||
|  |       EXPECT_TRUE(io_stream->good()); | ||||||
|  |  | ||||||
|  |       auto data_cfg = *reader.get_kdf_config_for_data(); | ||||||
|  |       utils::hash::hash_256_t data_key; | ||||||
|  |       std::tie(data_key, std::ignore) = cfg.create_subkey( | ||||||
|  |           utils::encryption::kdf_context::data, data_cfg.unique_id, master_key); | ||||||
|  |  | ||||||
|  |       for (std::uint8_t j = 0U; j < 2U; j++) { | ||||||
|  |         data_buffer decrypted_data; | ||||||
|  |         const auto offset = (j * (buffer.size() / 2U)); | ||||||
|  |         EXPECT_TRUE(utils::encryption::decrypt_data( | ||||||
|  |             data_key, | ||||||
|             data_buffer( |             data_buffer( | ||||||
|                 std::next(buffer.begin(), static_cast<std::int64_t>(offset)), |                 std::next(buffer.begin(), static_cast<std::int64_t>(offset)), | ||||||
|                 std::next(buffer.begin(), static_cast<std::int64_t>( |                 std::next(buffer.begin(), static_cast<std::int64_t>( | ||||||
|   | |||||||
| @@ -27,40 +27,41 @@ namespace repertory { | |||||||
| TEST(utils_encryption_kdf_config, can_construct_using_default_constructor) { | TEST(utils_encryption_kdf_config, can_construct_using_default_constructor) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|  |  | ||||||
|   EXPECT_EQ(utils::encryption::kdf_config::repertory_magic, cfg.magic); |  | ||||||
|   EXPECT_EQ(utils::encryption::kdf_version::v1, cfg.version); |   EXPECT_EQ(utils::encryption::kdf_version::v1, cfg.version); | ||||||
|   EXPECT_EQ(utils::encryption::kdf_type::argon2id, cfg.kdf); |   EXPECT_EQ(utils::encryption::kdf_type::argon2id, cfg.kdf); | ||||||
|   EXPECT_EQ(utils::encryption::memlimit_level::level3, cfg.memlimit); |   EXPECT_EQ(utils::encryption::memlimit_level::level3, cfg.memlimit); | ||||||
|   EXPECT_EQ(utils::encryption::opslimit_level::level2, cfg.opslimit); |   EXPECT_EQ(utils::encryption::opslimit_level::level2, cfg.opslimit); | ||||||
|   EXPECT_EQ(utils::encryption::kdf_config::salt_t{}, cfg.salt); |   EXPECT_EQ(utils::encryption::kdf_config::salt_t{}, cfg.salt); | ||||||
|  |   EXPECT_EQ(0U, cfg.unique_id); | ||||||
|   EXPECT_EQ(0U, cfg.checksum); |   EXPECT_EQ(0U, cfg.checksum); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, can_generate_salt) { | TEST(utils_encryption_kdf_config, can_seal) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|   EXPECT_NE(utils::encryption::kdf_config::salt_t{}, cfg.salt); |   EXPECT_NE(utils::encryption::kdf_config::salt_t{}, cfg.salt); | ||||||
|  |  | ||||||
|   auto orig_salt = cfg.salt; |   auto orig_salt = cfg.salt; | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|   EXPECT_NE(orig_salt, cfg.salt); |   EXPECT_NE(orig_salt, cfg.salt); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, can_generate_checksum) { | TEST(utils_encryption_kdf_config, can_generate_checksum) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   EXPECT_EQ(8853559678329530327ULL, cfg.generate_checksum()); |   EXPECT_EQ(13087047540462255120ULL, cfg.generate_checksum()); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, generate_salt_calculates_checksum) { | TEST(utils_encryption_kdf_config, seal_calculates_checksum) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|  |  | ||||||
|   EXPECT_NE(0U, cfg.checksum); |   EXPECT_NE(0U, cfg.checksum); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, can_create_header_and_restore) { | TEST(utils_encryption_kdf_config, can_create_header_and_restore) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.generate_salt(); |   cfg.unique_id = 2U; | ||||||
|  |   cfg.seal(); | ||||||
|   auto hdr = cfg.to_header(); |   auto hdr = cfg.to_header(); | ||||||
|  |  | ||||||
|   EXPECT_EQ(utils::encryption::kdf_config::size(), hdr.size()); |   EXPECT_EQ(utils::encryption::kdf_config::size(), hdr.size()); | ||||||
| @@ -70,30 +71,20 @@ TEST(utils_encryption_kdf_config, can_create_header_and_restore) { | |||||||
|   auto restored_hdr = restored_cfg.to_header(); |   auto restored_hdr = restored_cfg.to_header(); | ||||||
|  |  | ||||||
|   EXPECT_EQ(hdr, restored_hdr); |   EXPECT_EQ(hdr, restored_hdr); | ||||||
|   EXPECT_EQ(cfg.magic, restored_cfg.magic); |  | ||||||
|   EXPECT_EQ(cfg.version, restored_cfg.version); |   EXPECT_EQ(cfg.version, restored_cfg.version); | ||||||
|   EXPECT_EQ(cfg.kdf, restored_cfg.kdf); |   EXPECT_EQ(cfg.kdf, restored_cfg.kdf); | ||||||
|   EXPECT_EQ(cfg.memlimit, restored_cfg.memlimit); |   EXPECT_EQ(cfg.memlimit, restored_cfg.memlimit); | ||||||
|   EXPECT_EQ(cfg.opslimit, restored_cfg.opslimit); |   EXPECT_EQ(cfg.opslimit, restored_cfg.opslimit); | ||||||
|   EXPECT_EQ(cfg.salt, restored_cfg.salt); |   EXPECT_EQ(cfg.salt, restored_cfg.salt); | ||||||
|   EXPECT_EQ(cfg.checksum, restored_cfg.checksum); |   EXPECT_EQ(cfg.checksum, restored_cfg.checksum); | ||||||
|  |   EXPECT_EQ(cfg.unique_id, restored_cfg.unique_id); | ||||||
|   EXPECT_EQ(cfg, restored_cfg); |   EXPECT_EQ(cfg, restored_cfg); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, header_restore_fails_if_magic_is_invalid) { |  | ||||||
|   utils::encryption::kdf_config cfg; |  | ||||||
|   cfg.magic = 0x11; |  | ||||||
|   cfg.generate_salt(); |  | ||||||
|  |  | ||||||
|   auto hdr = cfg.to_header(); |  | ||||||
|   utils::encryption::kdf_config restored_cfg; |  | ||||||
|   EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, header_restore_fails_if_version_is_invalid) { | TEST(utils_encryption_kdf_config, header_restore_fails_if_version_is_invalid) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.version = static_cast<utils::encryption::kdf_version>(0x11); |   cfg.version = static_cast<utils::encryption::kdf_version>(0x11); | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|  |  | ||||||
|   auto hdr = cfg.to_header(); |   auto hdr = cfg.to_header(); | ||||||
|   utils::encryption::kdf_config restored_cfg; |   utils::encryption::kdf_config restored_cfg; | ||||||
| @@ -103,7 +94,7 @@ TEST(utils_encryption_kdf_config, header_restore_fails_if_version_is_invalid) { | |||||||
| TEST(utils_encryption_kdf_config, header_restore_fails_if_kdf_is_invalid) { | TEST(utils_encryption_kdf_config, header_restore_fails_if_kdf_is_invalid) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.kdf = static_cast<utils::encryption::kdf_type>(0x11); |   cfg.kdf = static_cast<utils::encryption::kdf_type>(0x11); | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|  |  | ||||||
|   auto hdr = cfg.to_header(); |   auto hdr = cfg.to_header(); | ||||||
|   utils::encryption::kdf_config restored_cfg; |   utils::encryption::kdf_config restored_cfg; | ||||||
| @@ -113,7 +104,7 @@ TEST(utils_encryption_kdf_config, header_restore_fails_if_kdf_is_invalid) { | |||||||
| TEST(utils_encryption_kdf_config, header_restore_fails_if_memlimit_is_invalid) { | TEST(utils_encryption_kdf_config, header_restore_fails_if_memlimit_is_invalid) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.memlimit = static_cast<utils::encryption::memlimit_level>(0x11); |   cfg.memlimit = static_cast<utils::encryption::memlimit_level>(0x11); | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|  |  | ||||||
|   auto hdr = cfg.to_header(); |   auto hdr = cfg.to_header(); | ||||||
|   utils::encryption::kdf_config restored_cfg; |   utils::encryption::kdf_config restored_cfg; | ||||||
| @@ -123,7 +114,7 @@ TEST(utils_encryption_kdf_config, header_restore_fails_if_memlimit_is_invalid) { | |||||||
| TEST(utils_encryption_kdf_config, header_restore_fails_if_opslimit_is_invalid) { | TEST(utils_encryption_kdf_config, header_restore_fails_if_opslimit_is_invalid) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.opslimit = static_cast<utils::encryption::opslimit_level>(0x11); |   cfg.opslimit = static_cast<utils::encryption::opslimit_level>(0x11); | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|  |  | ||||||
|   auto hdr = cfg.to_header(); |   auto hdr = cfg.to_header(); | ||||||
|   utils::encryption::kdf_config restored_cfg; |   utils::encryption::kdf_config restored_cfg; | ||||||
| @@ -132,13 +123,280 @@ TEST(utils_encryption_kdf_config, header_restore_fails_if_opslimit_is_invalid) { | |||||||
|  |  | ||||||
| TEST(utils_encryption_kdf_config, header_restore_fails_if_salt_is_invalid) { | TEST(utils_encryption_kdf_config, header_restore_fails_if_salt_is_invalid) { | ||||||
|   utils::encryption::kdf_config cfg; |   utils::encryption::kdf_config cfg; | ||||||
|   cfg.generate_salt(); |   cfg.seal(); | ||||||
|   cfg.salt = utils::encryption::kdf_config::salt_t{}; |   cfg.salt = utils::encryption::kdf_config::salt_t{}; | ||||||
|  |  | ||||||
|   auto hdr = cfg.to_header(); |   auto hdr = cfg.to_header(); | ||||||
|   utils::encryption::kdf_config restored_cfg; |   utils::encryption::kdf_config restored_cfg; | ||||||
|   EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg)); |   EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, header_restore_fails_if_id_is_invalid) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |   cfg.unique_id = 22U; | ||||||
|  |  | ||||||
|  |   auto hdr = cfg.to_header(); | ||||||
|  |   utils::encryption::kdf_config restored_cfg; | ||||||
|  |   EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, create_subkey_sets_id_and_updates_checksum) { | ||||||
|  |   using hash_t = utils::hash::hash_256_t; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   hash_t master_key = | ||||||
|  |       utils::encryption::generate_key<hash_t>("root-master-key"); | ||||||
|  |  | ||||||
|  |   constexpr std::size_t sub_id = 42; | ||||||
|  |   auto [subkey, out_cfg] = cfg.create_subkey<hash_t>( | ||||||
|  |       utils::encryption::kdf_context::path, sub_id, master_key); | ||||||
|  |  | ||||||
|  |   EXPECT_NE(subkey, hash_t{}); | ||||||
|  |   EXPECT_NE(subkey, master_key); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ(out_cfg.unique_id, static_cast<std::uint64_t>(sub_id)); | ||||||
|  |   EXPECT_EQ(out_cfg.checksum, out_cfg.generate_checksum()); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ(out_cfg.version, cfg.version); | ||||||
|  |   EXPECT_EQ(out_cfg.kdf, cfg.kdf); | ||||||
|  |   EXPECT_EQ(out_cfg.memlimit, cfg.memlimit); | ||||||
|  |   EXPECT_EQ(out_cfg.opslimit, cfg.opslimit); | ||||||
|  |   EXPECT_EQ(out_cfg.salt, cfg.salt); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, | ||||||
|  |      create_subkey_is_deterministic_for_same_inputs) { | ||||||
|  |   using hash_t = utils::hash::hash_256_t; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   hash_t master_key = | ||||||
|  |       utils::encryption::generate_key<hash_t>("root-master-key"); | ||||||
|  |  | ||||||
|  |   constexpr auto ctx = utils::encryption::kdf_context::data; | ||||||
|  |   constexpr std::size_t sub_id = 7; | ||||||
|  |  | ||||||
|  |   auto [k1, c1] = cfg.create_subkey<hash_t>(ctx, sub_id, master_key); | ||||||
|  |   auto [k2, c2] = cfg.create_subkey<hash_t>(ctx, sub_id, master_key); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ(k1, k2); | ||||||
|  |   EXPECT_EQ(c1.unique_id, c2.unique_id); | ||||||
|  |   EXPECT_EQ(c1.checksum, c2.checksum); | ||||||
|  |   EXPECT_EQ(c1, c2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, create_subkey_varies_with_different_id) { | ||||||
|  |   using hash_t = utils::hash::hash_256_t; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   hash_t master_key = | ||||||
|  |       utils::encryption::generate_key<hash_t>("root-master-key"); | ||||||
|  |  | ||||||
|  |   constexpr auto ctx = utils::encryption::kdf_context::data; | ||||||
|  |  | ||||||
|  |   auto [k1, c1] = cfg.create_subkey<hash_t>(ctx, 1, master_key); | ||||||
|  |   auto [k2, c2] = cfg.create_subkey<hash_t>(ctx, 2, master_key); | ||||||
|  |  | ||||||
|  |   EXPECT_NE(k1, k2); | ||||||
|  |   EXPECT_NE(c1.unique_id, c2.unique_id); | ||||||
|  |   EXPECT_NE(c1.checksum, c2.checksum); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ(c1.version, c2.version); | ||||||
|  |   EXPECT_EQ(c1.kdf, c2.kdf); | ||||||
|  |   EXPECT_EQ(c1.memlimit, c2.memlimit); | ||||||
|  |   EXPECT_EQ(c1.opslimit, c2.opslimit); | ||||||
|  |   EXPECT_EQ(c1.salt, c2.salt); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, create_subkey_varies_with_different_context) { | ||||||
|  |   using hash_t = utils::hash::hash_256_t; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   hash_t master_key = | ||||||
|  |       utils::encryption::generate_key<hash_t>("root-master-key"); | ||||||
|  |  | ||||||
|  |   constexpr std::size_t sub_id = 123; | ||||||
|  |  | ||||||
|  |   auto [ka, ca] = cfg.create_subkey<hash_t>( | ||||||
|  |       utils::encryption::kdf_context::data, sub_id, master_key); | ||||||
|  |   auto [kb, cb] = cfg.create_subkey<hash_t>( | ||||||
|  |       utils::encryption::kdf_context::path, sub_id, master_key); | ||||||
|  |  | ||||||
|  |   EXPECT_NE(ka, kb); | ||||||
|  |   EXPECT_EQ(ca.unique_id, cb.unique_id); | ||||||
|  |   EXPECT_EQ(ca.checksum, cb.checksum); | ||||||
|  |   EXPECT_EQ(ca, cb); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, | ||||||
|  |      create_subkey_with_undefined_context_uses_fallback) { | ||||||
|  |   using hash_t = utils::hash::hash_256_t; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   hash_t master_key = | ||||||
|  |       utils::encryption::generate_key<hash_t>("root-master-key"); | ||||||
|  |  | ||||||
|  |   constexpr std::size_t sub_id = 55; | ||||||
|  |  | ||||||
|  |   auto [k_def, c_def] = cfg.create_subkey<hash_t>( | ||||||
|  |       utils::encryption::kdf_context::undefined, sub_id, master_key); | ||||||
|  |   auto [k_dat, c_dat] = cfg.create_subkey<hash_t>( | ||||||
|  |       utils::encryption::kdf_context::data, sub_id, master_key); | ||||||
|  |  | ||||||
|  |   EXPECT_NE(k_def, hash_t{}); | ||||||
|  |   EXPECT_NE(k_dat, hash_t{}); | ||||||
|  |   EXPECT_NE(k_def, k_dat); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ(c_def, c_dat); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #if defined(PROJECT_ENABLE_JSON) | ||||||
|  | TEST(utils_encryption_kdf_config, can_convert_kdf_config_to_and_from_json) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.unique_id = 2U; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   nlohmann::json json_kdf(cfg); | ||||||
|  |  | ||||||
|  |   auto cfg2 = json_kdf.get<utils::encryption::kdf_config>(); | ||||||
|  |   EXPECT_EQ(cfg, cfg2); | ||||||
|  | } | ||||||
|  | #endif // defined(PROJECT_ENABLE_JSON) | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, equality) { | ||||||
|  |   { | ||||||
|  |     utils::encryption::kdf_config cfg; | ||||||
|  |     utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(cfg, cfg2); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     utils::encryption::kdf_config cfg; | ||||||
|  |     utils::encryption::kdf_config cfg2{cfg}; | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(cfg, cfg2); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     utils::encryption::kdf_config cfg; | ||||||
|  |     cfg.seal(); | ||||||
|  |  | ||||||
|  |     utils::encryption::kdf_config cfg2{cfg}; | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(cfg, cfg2); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     utils::encryption::kdf_config cfg; | ||||||
|  |     utils::encryption::kdf_config cfg2; | ||||||
|  |     cfg2 = cfg; | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(cfg, cfg2); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     utils::encryption::kdf_config cfg; | ||||||
|  |     cfg.seal(); | ||||||
|  |  | ||||||
|  |     utils::encryption::kdf_config cfg2; | ||||||
|  |     cfg2 = cfg; | ||||||
|  |  | ||||||
|  |     EXPECT_EQ(cfg, cfg2); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, sealed_is_not_equal_to_unsealed) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, sealed_is_not_equal_to_sealed) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.seal(); | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |   cfg2.seal(); | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_id) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.unique_id = 2UL; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_version) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.version = static_cast<utils::encryption::kdf_version>(0x11); | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_kdf) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.kdf = static_cast<utils::encryption::kdf_type>(0x11); | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_memlimit) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.memlimit = static_cast<utils::encryption::memlimit_level>(0x11); | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_opslimit) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.opslimit = static_cast<utils::encryption::opslimit_level>(0x11); | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_salt) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.salt[0U] = 1U; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(utils_encryption_kdf_config, is_not_equal_to_different_checksum) { | ||||||
|  |   utils::encryption::kdf_config cfg; | ||||||
|  |   cfg.checksum = 2U; | ||||||
|  |  | ||||||
|  |   utils::encryption::kdf_config cfg2; | ||||||
|  |  | ||||||
|  |   EXPECT_NE(cfg, cfg2); | ||||||
|  | } | ||||||
| } // namespace repertory | } // namespace repertory | ||||||
|  |  | ||||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||||
|   | |||||||
| @@ -375,6 +375,10 @@ TEST(utils_encryption, encrypt_data_pointer_using_argon2id) { | |||||||
| // TEST(utils_encryption, decrypt_file_name_using_argon2id) {} | // TEST(utils_encryption, decrypt_file_name_using_argon2id) {} | ||||||
|  |  | ||||||
| // TEST(utils_encryption, decrypt_file_path_using_argon2id) {} | // TEST(utils_encryption, decrypt_file_path_using_argon2id) {} | ||||||
|  | // | ||||||
|  | // TEST(utils_encryption, decrypt_file_name_using_argon2id_master_key) {} | ||||||
|  |  | ||||||
|  | // TEST(utils_encryption, decrypt_file_path_using_argon2id_master_key) {} | ||||||
| #endif // defined(PROJECT_ENABLE_BOOST) | #endif // defined(PROJECT_ENABLE_BOOST) | ||||||
| } // namespace repertory | } // namespace repertory | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user