add setting to force legacy encryption
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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"); | ||||
|       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(); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user