diff --git a/repertory/librepertory/include/providers/s3/s3_provider.hpp b/repertory/librepertory/include/providers/s3/s3_provider.hpp index c33728f5..f9180a10 100644 --- a/repertory/librepertory/include/providers/s3/s3_provider.hpp +++ b/repertory/librepertory/include/providers/s3/s3_provider.hpp @@ -102,8 +102,8 @@ private: return s3_config_; } - [[nodiscard]] auto search_keys_for_kdf(std::string_view encryption_token) - -> bool; + [[nodiscard]] auto + search_keys_for_master_kdf(std::string_view encryption_token) -> bool; [[nodiscard]] auto set_meta_key(const std::string &api_path, api_meta_map &meta) -> api_error; diff --git a/repertory/librepertory/src/providers/s3/s3_provider.cpp b/repertory/librepertory/src/providers/s3/s3_provider.cpp index 1b652c23..26df755f 100644 --- a/repertory/librepertory/src/providers/s3/s3_provider.cpp +++ b/repertory/librepertory/src/providers/s3/s3_provider.cpp @@ -24,6 +24,7 @@ #include "app_config.hpp" #include "comm/i_http_comm.hpp" #include "events/event_system.hpp" +#include "events/types/debug_log.hpp" #include "events/types/service_start_begin.hpp" #include "events/types/service_start_end.hpp" #include "events/types/service_stop_begin.hpp" @@ -952,87 +953,73 @@ auto s3_provider::rename_file(const std::string & /* from_api_path */, return api_error::not_implemented; } -auto s3_provider::search_keys_for_kdf(std::string_view encryption_token) +auto s3_provider::search_keys_for_master_kdf(std::string_view encryption_token) -> bool { REPERTORY_USES_FUNCTION_NAME(); - auto grab_more{true}; std::string token{}; - while (grab_more) { - std::string response_data{}; - long response_code{}; - if (not get_object_list(response_data, response_code, "/", "", token)) { - throw utils::error::create_exception(function_name, - {"failed to get object list"}); + std::string response_data{}; + long response_code{}; + if (not get_object_list(response_data, response_code, "/", "", token)) { + throw utils::error::create_exception(function_name, + {"failed to get object list"}); + } + + if (response_code == http_error_codes::not_found) { + throw utils::error::create_exception(function_name, + {"failed to get object list"}); + } + + if (response_code != http_error_codes::ok) { + throw utils::error::create_exception(function_name, + {"failed to get object list"}); + } + + pugi::xml_document doc; + auto parse_res{doc.load_string(response_data.c_str())}; + if (parse_res.status != pugi::xml_parse_status::status_ok) { + throw utils::error::create_exception(function_name, + {"failed to get object list"}); + } + + auto node_list = doc.select_nodes("/ListBucketResult/Contents"); + for (const auto &node : node_list) { + std::string object_name{ + node.node().select_node("Key").node().text().as_string(), + }; + if (object_name == "/") { + continue; } - if (response_code == http_error_codes::not_found) { - throw utils::error::create_exception(function_name, - {"failed to get object list"}); + data_buffer buffer; + if (not utils::collection::from_hex_string(object_name, buffer)) { + continue; } - if (response_code != http_error_codes::ok) { - throw utils::error::create_exception(function_name, - {"failed to get object list"}); + utils::encryption::kdf_config cfg; + if (not utils::encryption::kdf_config::from_header(buffer, cfg)) { + continue; } - pugi::xml_document doc; - auto parse_res{doc.load_string(response_data.c_str())}; - if (parse_res.status != pugi::xml_parse_status::status_ok) { - throw utils::error::create_exception(function_name, - {"failed to get object list"}); + cfg.unique_id = 0U; + cfg.seal(); + + master_kdf_cfg_ = cfg; + if (not utils::encryption::recreate_key_argon2id( + encryption_token, master_kdf_cfg_, master_key_)) { + throw utils::error::create_exception( + function_name, {"failed to recreate master key from kdf"}); } - grab_more = doc.select_node("/ListBucketResult/IsTruncated") - .node() - .text() - .as_bool(); - if (grab_more) { - token = doc.select_node("/ListBucketResult/NextContinuationToken") - .node() - .text() - .as_string(); + auto res = + set_item_meta("/", META_KDF, nlohmann::json(master_kdf_cfg_).dump()); + if (res == api_error::success) { + legacy_bucket_ = false; + return true; } - auto node_list = doc.select_nodes("/ListBucketResult/Contents"); - for (const auto &node : node_list) { - std::string object_name{ - node.node().select_node("Key").node().text().as_string(), - }; - if (object_name == "/") { - continue; - } - - data_buffer buffer; - if (not utils::collection::from_hex_string(object_name, buffer)) { - continue; - } - - utils::encryption::kdf_config cfg; - if (not utils::encryption::kdf_config::from_header(buffer, cfg)) { - continue; - } - - cfg.unique_id = 0U; - cfg.seal(); - - master_kdf_cfg_ = cfg; - if (not utils::encryption::recreate_key_argon2id( - encryption_token, master_kdf_cfg_, master_key_)) { - throw utils::error::create_exception( - function_name, {"failed to recreate master key from kdf"}); - } - - auto res = - set_item_meta("/", META_KDF, nlohmann::json(master_kdf_cfg_).dump()); - if (res == api_error::success) { - legacy_bucket_ = false; - return true; - } - - throw utils::error::create_exception(function_name, - {"failed to set meta kdf"}); - } + throw utils::error::create_exception(function_name, + {"failed to set meta kdf"}); } return false; @@ -1091,16 +1078,20 @@ auto s3_provider::start(api_item_added_callback api_item_added, event_system::instance().raise(function_name, "s3_provider"); - const auto &cfg{get_s3_config()}; auto ret = base_provider::start(api_item_added, mgr); + const auto &cfg{get_s3_config()}; if (ret && not cfg.encryption_token.empty()) { auto res = get_kdf_config_from_meta("/", master_kdf_cfg_); switch (res) { case api_error::item_not_found: { try { - if (not search_keys_for_kdf(cfg.encryption_token)) { + event_system::instance().raise(function_name, + "searching for master kdf"); + if (not search_keys_for_master_kdf(cfg.encryption_token)) { if (get_directory_item_count("/") == 0U) { + event_system::instance().raise( + function_name, "creating master kdf for empty bucket"); legacy_bucket_ = false; master_kdf_cfg_.seal(); master_key_ = @@ -1123,6 +1114,10 @@ auto s3_provider::start(api_item_added_callback api_item_added, } break; case api_error::success: { + event_system::instance().raise( + function_name, "recreating master kdf for existing bucket"); + + legacy_bucket_ = false; if (not utils::encryption::recreate_key_argon2id( cfg.encryption_token, master_kdf_cfg_, master_key_)) { utils::error::raise_error(function_name, @@ -1143,6 +1138,11 @@ auto s3_provider::start(api_item_added_callback api_item_added, } } + event_system::instance().raise( + function_name, + fmt::format("encrypted|{}|legacy_bucket|{}|ret|{}", + not cfg.encryption_token.empty(), legacy_bucket_, ret)); + event_system::instance().raise(function_name, "s3_provider"); return ret; @@ -1214,7 +1214,7 @@ auto s3_provider::upload_file_impl(const std::string &api_path, master_key_, master_kdf_cfg_, std::nullopt, -1); res = set_item_meta( - "/", META_KDF, + api_path, META_KDF, nlohmann::json(*put_file.reader->get_kdf_config_for_data()).dump()); if (res == api_error::success) { return res;