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