diff --git a/repertory/librepertory/include/providers/s3/s3_provider.hpp b/repertory/librepertory/include/providers/s3/s3_provider.hpp index f9180a10..c319f8bb 100644 --- a/repertory/librepertory/include/providers/s3/s3_provider.hpp +++ b/repertory/librepertory/include/providers/s3/s3_provider.hpp @@ -102,8 +102,10 @@ private: return s3_config_; } + [[nodiscard]] auto initialize_crypto(const s3_config &cfg) -> bool; + [[nodiscard]] auto - search_keys_for_master_kdf(std::string_view encryption_token) -> bool; + search_keys_for_master_kdf(const std::string &encryption_token) -> bool; [[nodiscard]] auto set_meta_key(const std::string &api_path, api_meta_map &meta) -> api_error; @@ -177,8 +179,8 @@ public: const std::string &to_api_path) -> api_error override; - [[nodiscard]] auto start(api_item_added_callback api_item_added, - i_file_manager *mgr) -> bool override; + auto start(api_item_added_callback api_item_added, i_file_manager *mgr) + -> bool override; void stop() override; }; diff --git a/repertory/librepertory/src/providers/s3/s3_provider.cpp b/repertory/librepertory/src/providers/s3/s3_provider.cpp index 64d9f6ff..58d2019f 100644 --- a/repertory/librepertory/src/providers/s3/s3_provider.cpp +++ b/repertory/librepertory/src/providers/s3/s3_provider.cpp @@ -771,6 +771,69 @@ auto s3_provider::get_total_drive_space() const -> std::uint64_t { return std::numeric_limits::max() / std::int64_t(2); } +auto s3_provider::initialize_crypto(const s3_config &cfg) -> bool { + REPERTORY_USES_FUNCTION_NAME(); + + auto ret{true}; + + auto res = get_kdf_config_from_meta("/", master_kdf_cfg_); + switch (res) { + case api_error::item_not_found: { + try { + event_system::instance().raise( + function_name, "searching for master kdf config"); + 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 config for empty bucket"); + legacy_bucket_ = false; + master_kdf_cfg_.seal(); + master_key_ = + utils::encryption::generate_key( + cfg.encryption_token, master_kdf_cfg_); + + res = set_item_meta("/", META_KDF, + nlohmann::json(master_kdf_cfg_).dump()); + event_system::instance().raise( + function_name, + fmt::format("master_kdf|{}", + nlohmann::json(master_kdf_cfg_).dump(2))); + if (res != api_error::success) { + utils::error::raise_api_path_error(function_name, "/", res, + "set kdf config in meta failed"); + ret = false; + } + } + } + } catch (const std::exception &e) { + utils::error::raise_error(function_name, e, "exception occurred"); + ret = false; + } + } break; + + case api_error::success: { + event_system::instance().raise( + function_name, "recreating master kdf config 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, "failed to recreate master key from kdf config"); + ret = false; + } + } break; + + default: { + utils::error::raise_api_path_error(function_name, "/", res, + "get kdf config from meta failed"); + ret = false; + } + } + + return ret; +} + auto s3_provider::is_directory(const std::string &api_path, bool &exists) const -> api_error { REPERTORY_USES_FUNCTION_NAME(); @@ -955,8 +1018,8 @@ auto s3_provider::rename_file(const std::string & /* from_api_path */, return api_error::not_implemented; } -auto s3_provider::search_keys_for_master_kdf(std::string_view encryption_token) - -> bool { +auto s3_provider::search_keys_for_master_kdf( + const std::string &encryption_token) -> bool { REPERTORY_USES_FUNCTION_NAME(); std::string token{}; @@ -998,30 +1061,34 @@ auto s3_provider::search_keys_for_master_kdf(std::string_view encryption_token) continue; } - utils::encryption::kdf_config cfg; - if (not utils::encryption::kdf_config::from_header(buffer, cfg)) { + if (not utils::encryption::kdf_config::from_header(buffer, + master_kdf_cfg_)) { continue; } - cfg.unique_id = 0U; - cfg.seal(); + master_kdf_cfg_.unique_id = 0U; + master_kdf_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"}); + function_name, {"failed to recreate master key from kdf config"}); } auto res = set_item_meta("/", META_KDF, nlohmann::json(master_kdf_cfg_).dump()); + event_system::instance().raise( + function_name, + fmt::format("master_kdf|{}", nlohmann::json(master_kdf_cfg_).dump(2))); if (res == api_error::success) { legacy_bucket_ = false; + event_system::instance().raise(function_name, + "found master kdf config"); return true; } throw utils::error::create_exception(function_name, - {"failed to set meta kdf"}); + {"failed to set meta kdf config"}); } return false; @@ -1081,61 +1148,11 @@ auto s3_provider::start(api_item_added_callback api_item_added, event_system::instance().raise(function_name, "s3_provider"); - auto ret = base_provider::start(api_item_added, mgr); const auto &cfg{get_s3_config()}; + + auto ret = base_provider::start(api_item_added, mgr); 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 { - 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_ = - utils::encryption::generate_key( - cfg.encryption_token, master_kdf_cfg_); - - res = set_item_meta("/", META_KDF, - nlohmann::json(master_kdf_cfg_).dump()); - if (res != api_error::success) { - utils::error::raise_api_path_error(function_name, "/", res, - "set kdf in meta failed"); - ret = false; - } - } - } - } catch (const std::exception &e) { - utils::error::raise_error(function_name, e, "exception occurred"); - ret = false; - } - } 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, - "failed to recreate master key from kdf"); - ret = false; - } - } break; - - default: { - utils::error::raise_api_path_error(function_name, "/", res, - "get kdf from meta failed"); - ret = false; - } - } - - if (not ret) { + if (not initialize_crypto(cfg)) { base_provider::stop(); } } @@ -1218,6 +1235,12 @@ auto s3_provider::upload_file_impl(const std::string &api_path, res = set_item_meta( api_path, META_KDF, nlohmann::json(*put_file.reader->get_kdf_config_for_data()).dump()); + event_system::instance().raise( + function_name, + fmt::format( + "file_kdf|{}", + nlohmann::json(*put_file.reader->get_kdf_config_for_data()) + .dump(2))); if (res != api_error::success) { return res; }