add setting to force legacy encryption

This commit is contained in:
2025-09-03 08:51:22 -05:00
parent 4f63d0bb32
commit 8ac7b06d68
4 changed files with 53 additions and 10 deletions

View File

@@ -102,7 +102,8 @@ private:
return s3_config_;
}
[[nodiscard]] auto initialize_crypto(const s3_config &cfg) -> bool;
[[nodiscard]] auto initialize_crypto(const s3_config &cfg, bool is_retry)
-> bool;
[[nodiscard]] auto
search_keys_for_master_kdf(const std::string &encryption_token) -> bool;

View File

@@ -336,6 +336,7 @@ struct s3_config final {
std::string access_key;
std::string bucket;
std::string encryption_token;
bool force_legacy_encryption{false};
std::string region{"any"};
std::string secret_key;
std::uint32_t timeout_ms{default_timeout_ms};
@@ -346,9 +347,11 @@ struct s3_config final {
auto operator==(const s3_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return access_key == cfg.access_key && bucket == cfg.bucket &&
encryption_token == cfg.encryption_token && region == cfg.region &&
secret_key == cfg.secret_key && timeout_ms == cfg.timeout_ms &&
url == cfg.url && use_path_style == cfg.use_path_style &&
encryption_token == cfg.encryption_token &&
force_legacy_encryption == cfg.force_legacy_encryption &&
region == cfg.region && secret_key == cfg.secret_key &&
timeout_ms == cfg.timeout_ms && url == cfg.url &&
use_path_style == cfg.use_path_style &&
use_region_in_url == cfg.use_region_in_url;
}
@@ -412,6 +415,7 @@ inline constexpr auto JSON_ENCRYPT_CONFIG{"EncryptConfig"};
inline constexpr auto JSON_EVENT_LEVEL{"EventLevel"};
inline constexpr auto JSON_EVICTION_DELAY_MINS{"EvictionDelayMinutes"};
inline constexpr auto JSON_EVICTION_USE_ACCESS_TIME{"EvictionUseAccessedTime"};
inline constexpr auto JSON_FORCE_LEGACY_ENCRYPTION{"ForceLegacyEncryption"};
inline constexpr auto JSON_HIGH_FREQ_INTERVAL_SECS{"HighFreqIntervalSeconds"};
inline constexpr auto JSON_HOST_CONFIG{"HostConfig"};
inline constexpr auto JSON_HOST_NAME_OR_IP{"HostNameOrIp"};
@@ -530,6 +534,7 @@ template <> struct adl_serializer<repertory::s3_config> {
data[repertory::JSON_ACCESS_KEY] = value.access_key;
data[repertory::JSON_BUCKET] = value.bucket;
data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token;
data[repertory::JSON_ENCRYPTION_TOKEN] = value.force_legacy_encryption;
data[repertory::JSON_REGION] = value.region;
data[repertory::JSON_SECRET_KEY] = value.secret_key;
data[repertory::JSON_TIMEOUT_MS] = value.timeout_ms;
@@ -548,6 +553,10 @@ template <> struct adl_serializer<repertory::s3_config> {
data.at(repertory::JSON_URL).get_to(value.url);
data.at(repertory::JSON_USE_PATH_STYLE).get_to(value.use_path_style);
data.at(repertory::JSON_USE_REGION_IN_URL).get_to(value.use_region_in_url);
if (data.contains(repertory::JSON_FORCE_LEGACY_ENCRYPTION)) {
data.at(repertory::JSON_FORCE_LEGACY_ENCRYPTION)
.get_to(value.force_legacy_encryption);
}
}
};

View File

@@ -782,7 +782,8 @@ auto s3_provider::get_total_drive_space() const -> std::uint64_t {
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
}
auto s3_provider::initialize_crypto(const s3_config &cfg) -> bool {
auto s3_provider::initialize_crypto(const s3_config &cfg, bool is_retry)
-> bool {
REPERTORY_USES_FUNCTION_NAME();
auto ret{true};
@@ -792,7 +793,8 @@ auto s3_provider::initialize_crypto(const s3_config &cfg) -> bool {
case api_error::item_not_found: {
try {
if (not search_keys_for_master_kdf(cfg.encryption_token)) {
if (get_directory_item_count("/") == 0U) {
if (not cfg.force_legacy_encryption &&
get_directory_item_count("/") == 0U) {
legacy_bucket_ = false;
master_kdf_cfg_.seal();
master_key_ =
@@ -818,9 +820,23 @@ auto s3_provider::initialize_crypto(const s3_config &cfg) -> bool {
legacy_bucket_ = false;
if (not utils::encryption::recreate_key_argon2id(
cfg.encryption_token, master_kdf_cfg_, master_key_)) {
utils::error::raise_error(
function_name, "failed to recreate master key from kdf config");
ret = false;
if (is_retry) {
utils::error::raise_api_path_error(
function_name, "/", res, "failed to recreate master key from kdf");
ret = false;
} else {
utils::error::raise_error(function_name,
"failed to recreate master key from kdf "
"config: re-initializing kdf configuration");
res = set_item_meta("/", META_KDF, "");
if (res == api_error::success) {
ret = initialize_crypto(cfg, true);
} else {
utils::error::raise_api_path_error(function_name, "/", res,
"reset kdf config in meta failed");
ret = false;
}
}
}
} break;
@@ -1048,8 +1064,15 @@ auto s3_provider::search_keys_for_master_kdf(
{"failed to get object list"});
}
std::uint8_t count{0U};
constexpr const max_count{3U};
auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
if (++count > max_count) {
return false;
}
std::string object_name{
node.node().select_node("Key").node().text().as_string(),
};
@@ -1151,7 +1174,7 @@ auto s3_provider::start(api_item_added_callback api_item_added,
auto ret = base_provider::start(api_item_added, mgr);
if (ret && not cfg.encryption_token.empty()) {
if (not initialize_crypto(cfg)) {
if (not initialize_crypto(cfg, false)) {
base_provider::stop();
}
}

View File

@@ -623,6 +623,7 @@ static void common_tests(app_config &config, provider_type prov) {
cfg1.url = "7";
cfg1.use_path_style = false;
cfg1.use_region_in_url = false;
cfg1.force_legacy_encryption = false;
s3_config cfg2{};
cfg2.access_key = "8";
@@ -634,6 +635,7 @@ static void common_tests(app_config &config, provider_type prov) {
cfg2.url = "14";
cfg2.use_path_style = true;
cfg2.use_region_in_url = true;
cfg2.force_legacy_encryption = true;
ASSERT_NE(cfg1, cfg2);
@@ -650,6 +652,7 @@ static void common_tests(app_config &config, provider_type prov) {
cfg3.url = "14";
cfg3.use_path_style = true;
cfg3.use_region_in_url = true;
cfg3.force_legacy_encryption = true;
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_ACCESS_KEY),
@@ -694,6 +697,13 @@ static void common_tests(app_config &config, provider_type prov) {
utils::string::from_bool(cfg3.use_region_in_url));
EXPECT_STREQ(utils::string::from_bool(cfg3.use_region_in_url).c_str(),
value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_FORCE_LEGACY_ENCRYPTION),
utils::string::from_bool(cfg3.force_legacy_encryption));
EXPECT_STREQ(
utils::string::from_bool(cfg3.force_legacy_encryption).c_str(),
value.c_str());
}},
{JSON_SIA_CONFIG,
[](app_config &cfg) {