add setting to force legacy encryption
This commit is contained in:
		| @@ -102,7 +102,8 @@ private: | |||||||
|     return s3_config_; |     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 |   [[nodiscard]] auto | ||||||
|   search_keys_for_master_kdf(const std::string &encryption_token) -> bool; |   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 access_key; | ||||||
|   std::string bucket; |   std::string bucket; | ||||||
|   std::string encryption_token; |   std::string encryption_token; | ||||||
|  |   bool force_legacy_encryption{false}; | ||||||
|   std::string region{"any"}; |   std::string region{"any"}; | ||||||
|   std::string secret_key; |   std::string secret_key; | ||||||
|   std::uint32_t timeout_ms{default_timeout_ms}; |   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 { |   auto operator==(const s3_config &cfg) const noexcept -> bool { | ||||||
|     if (&cfg != this) { |     if (&cfg != this) { | ||||||
|       return access_key == cfg.access_key && bucket == cfg.bucket && |       return access_key == cfg.access_key && bucket == cfg.bucket && | ||||||
|              encryption_token == cfg.encryption_token && region == cfg.region && |              encryption_token == cfg.encryption_token && | ||||||
|              secret_key == cfg.secret_key && timeout_ms == cfg.timeout_ms && |              force_legacy_encryption == cfg.force_legacy_encryption && | ||||||
|              url == cfg.url && use_path_style == cfg.use_path_style && |              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; |              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_EVENT_LEVEL{"EventLevel"}; | ||||||
| inline constexpr auto JSON_EVICTION_DELAY_MINS{"EvictionDelayMinutes"}; | inline constexpr auto JSON_EVICTION_DELAY_MINS{"EvictionDelayMinutes"}; | ||||||
| inline constexpr auto JSON_EVICTION_USE_ACCESS_TIME{"EvictionUseAccessedTime"}; | 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_HIGH_FREQ_INTERVAL_SECS{"HighFreqIntervalSeconds"}; | ||||||
| inline constexpr auto JSON_HOST_CONFIG{"HostConfig"}; | inline constexpr auto JSON_HOST_CONFIG{"HostConfig"}; | ||||||
| inline constexpr auto JSON_HOST_NAME_OR_IP{"HostNameOrIp"}; | 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_ACCESS_KEY] = value.access_key; | ||||||
|     data[repertory::JSON_BUCKET] = value.bucket; |     data[repertory::JSON_BUCKET] = value.bucket; | ||||||
|     data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token; |     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_REGION] = value.region; | ||||||
|     data[repertory::JSON_SECRET_KEY] = value.secret_key; |     data[repertory::JSON_SECRET_KEY] = value.secret_key; | ||||||
|     data[repertory::JSON_TIMEOUT_MS] = value.timeout_ms; |     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_URL).get_to(value.url); | ||||||
|     data.at(repertory::JSON_USE_PATH_STYLE).get_to(value.use_path_style); |     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); |     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); |   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(); |   REPERTORY_USES_FUNCTION_NAME(); | ||||||
|  |  | ||||||
|   auto ret{true}; |   auto ret{true}; | ||||||
| @@ -792,7 +793,8 @@ auto s3_provider::initialize_crypto(const s3_config &cfg) -> bool { | |||||||
|   case api_error::item_not_found: { |   case api_error::item_not_found: { | ||||||
|     try { |     try { | ||||||
|       if (not search_keys_for_master_kdf(cfg.encryption_token)) { |       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; |           legacy_bucket_ = false; | ||||||
|           master_kdf_cfg_.seal(); |           master_kdf_cfg_.seal(); | ||||||
|           master_key_ = |           master_key_ = | ||||||
| @@ -818,9 +820,23 @@ auto s3_provider::initialize_crypto(const s3_config &cfg) -> bool { | |||||||
|     legacy_bucket_ = false; |     legacy_bucket_ = false; | ||||||
|     if (not utils::encryption::recreate_key_argon2id( |     if (not utils::encryption::recreate_key_argon2id( | ||||||
|             cfg.encryption_token, master_kdf_cfg_, master_key_)) { |             cfg.encryption_token, master_kdf_cfg_, master_key_)) { | ||||||
|       utils::error::raise_error( |       if (is_retry) { | ||||||
|           function_name, "failed to recreate master key from kdf config"); |         utils::error::raise_api_path_error( | ||||||
|       ret = false; |             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; |   } break; | ||||||
|  |  | ||||||
| @@ -1048,8 +1064,15 @@ auto s3_provider::search_keys_for_master_kdf( | |||||||
|                                          {"failed to get object list"}); |                                          {"failed to get object list"}); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   std::uint8_t count{0U}; | ||||||
|  |   constexpr const max_count{3U}; | ||||||
|  |  | ||||||
|   auto node_list = doc.select_nodes("/ListBucketResult/Contents"); |   auto node_list = doc.select_nodes("/ListBucketResult/Contents"); | ||||||
|   for (const auto &node : node_list) { |   for (const auto &node : node_list) { | ||||||
|  |     if (++count > max_count) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     std::string object_name{ |     std::string object_name{ | ||||||
|         node.node().select_node("Key").node().text().as_string(), |         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); |   auto ret = base_provider::start(api_item_added, mgr); | ||||||
|   if (ret && not cfg.encryption_token.empty()) { |   if (ret && not cfg.encryption_token.empty()) { | ||||||
|     if (not initialize_crypto(cfg)) { |     if (not initialize_crypto(cfg, false)) { | ||||||
|       base_provider::stop(); |       base_provider::stop(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -623,6 +623,7 @@ static void common_tests(app_config &config, provider_type prov) { | |||||||
|          cfg1.url = "7"; |          cfg1.url = "7"; | ||||||
|          cfg1.use_path_style = false; |          cfg1.use_path_style = false; | ||||||
|          cfg1.use_region_in_url = false; |          cfg1.use_region_in_url = false; | ||||||
|  |          cfg1.force_legacy_encryption = false; | ||||||
|  |  | ||||||
|          s3_config cfg2{}; |          s3_config cfg2{}; | ||||||
|          cfg2.access_key = "8"; |          cfg2.access_key = "8"; | ||||||
| @@ -634,6 +635,7 @@ static void common_tests(app_config &config, provider_type prov) { | |||||||
|          cfg2.url = "14"; |          cfg2.url = "14"; | ||||||
|          cfg2.use_path_style = true; |          cfg2.use_path_style = true; | ||||||
|          cfg2.use_region_in_url = true; |          cfg2.use_region_in_url = true; | ||||||
|  |          cfg2.force_legacy_encryption = true; | ||||||
|  |  | ||||||
|          ASSERT_NE(cfg1, cfg2); |          ASSERT_NE(cfg1, cfg2); | ||||||
|  |  | ||||||
| @@ -650,6 +652,7 @@ static void common_tests(app_config &config, provider_type prov) { | |||||||
|          cfg3.url = "14"; |          cfg3.url = "14"; | ||||||
|          cfg3.use_path_style = true; |          cfg3.use_path_style = true; | ||||||
|          cfg3.use_region_in_url = true; |          cfg3.use_region_in_url = true; | ||||||
|  |          cfg3.force_legacy_encryption = true; | ||||||
|  |  | ||||||
|          auto value = cfg.set_value_by_name( |          auto value = cfg.set_value_by_name( | ||||||
|              fmt::format("{}.{}", JSON_S3_CONFIG, JSON_ACCESS_KEY), |              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)); |              utils::string::from_bool(cfg3.use_region_in_url)); | ||||||
|          EXPECT_STREQ(utils::string::from_bool(cfg3.use_region_in_url).c_str(), |          EXPECT_STREQ(utils::string::from_bool(cfg3.use_region_in_url).c_str(), | ||||||
|                       value.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, |       {JSON_SIA_CONFIG, | ||||||
|        [](app_config &cfg) { |        [](app_config &cfg) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user