From 07ff7b7e5f8b65048058e8880ed7950a7649e55a Mon Sep 17 00:00:00 2001 From: "S. Santos" Date: Thu, 5 Dec 2024 09:39:35 -0300 Subject: [PATCH] Add support to Filesystem key manager (not suitable for production) --- lockbox/CMakeLists.txt | 12 ++- lockbox/README.md | 3 +- lockbox/Settings.toml | 5 +- lockbox/include/filesystem_key_manager.h | 11 +++ .../{key_manager.h => google_key_manager.h} | 6 +- lockbox/include/server.h | 2 +- lockbox/src/enclave.cpp | 17 ----- lockbox/src/filesystem_key_manager.cpp | 76 +++++++++++++++++++ ...key_manager.cpp => google_key_manager.cpp} | 2 +- lockbox/src/main.cpp | 14 +--- lockbox/src/server.cpp | 25 +++++- 11 files changed, 129 insertions(+), 44 deletions(-) create mode 100644 lockbox/include/filesystem_key_manager.h rename lockbox/include/{key_manager.h => google_key_manager.h} (72%) create mode 100644 lockbox/src/filesystem_key_manager.cpp rename lockbox/src/{key_manager.cpp => google_key_manager.cpp} (98%) diff --git a/lockbox/CMakeLists.txt b/lockbox/CMakeLists.txt index 1dbbc88e..cdca62d2 100644 --- a/lockbox/CMakeLists.txt +++ b/lockbox/CMakeLists.txt @@ -29,8 +29,9 @@ include(secp256k1_zkp) add_library(LockboxLibrary src/server.cpp src/utils.cpp - src/key_manager.cpp + src/google_key_manager.cpp src/hashicorp_key_manager.cpp + src/filesystem_key_manager.cpp src/enclave.cpp src/monocypher.c src/db_manager.cpp) @@ -52,7 +53,9 @@ target_link_libraries(LockboxLibrary google-cloud-cpp::storage google-cloud-cpp::kms google-cloud-cpp::secretmanager - secp256k1_zkp) + secp256k1_zkp + OpenSSL::SSL + OpenSSL::Crypto) include(FetchContent) FetchContent_Declare( @@ -75,6 +78,7 @@ find_package(cpr REQUIRED) find_package(google_cloud_cpp_storage REQUIRED) find_package(google_cloud_cpp_kms REQUIRED) find_package(google_cloud_cpp_secretmanager REQUIRED) +find_package(OpenSSL REQUIRED) target_include_directories(MercuryLockbox PRIVATE include) # Link the library to the main executable @@ -87,7 +91,9 @@ target_link_libraries(MercuryLockbox PRIVATE google-cloud-cpp::storage google-cloud-cpp::kms google-cloud-cpp::secretmanager - secp256k1_zkp) + secp256k1_zkp + OpenSSL::SSL + OpenSSL::Crypto) # Copy Settings.toml after building MercuryLockbox add_custom_command(TARGET MercuryLockbox POST_BUILD diff --git a/lockbox/README.md b/lockbox/README.md index ccc1da7d..c37d7f2a 100644 --- a/lockbox/README.md +++ b/lockbox/README.md @@ -11,5 +11,6 @@ $ mkdir -p build && cd build $ cmake --preset=vcpkg .. $ cmake --build . ``` +4. Set the desired key manager in `Settings.toml`. Currently, there are 3 available: `google_kms`, `hashicorp`, `filesystem`. -4. Then, to run the server: `./MercuryLockbox --key_provider=google_kms` or `./MercuryLockbox --key_provider=hashicorp`. \ No newline at end of file +5. Then, to run the server: `./MercuryLockbox`. \ No newline at end of file diff --git a/lockbox/Settings.toml b/lockbox/Settings.toml index 086dbba5..114a4f26 100644 --- a/lockbox/Settings.toml +++ b/lockbox/Settings.toml @@ -1,8 +1,9 @@ [general] database_connection_string = "postgresql://postgres:postgres@localhost/enclave" server_port = 18080 -replication_server_url = "http://localhost:18082" -seed_dir = "./seed" +key_manager = "filesystem" # "google_kms", "hashicorp", "filesystem" +[filesystem] +seed_filepath = "./seed" [gcloud] project_id = "mercury-441416" project_number = "100600525477" diff --git a/lockbox/include/filesystem_key_manager.h b/lockbox/include/filesystem_key_manager.h new file mode 100644 index 00000000..e1076ce2 --- /dev/null +++ b/lockbox/include/filesystem_key_manager.h @@ -0,0 +1,11 @@ +#ifndef FILESYSTEM_KEY_MANAGER_H +#define FILESYSTEM_KEY_MANAGER_H + +#include +#include + +namespace filesystem_key_manager { + std::vector get_seed(); +} // namespace key_manager + +#endif // FILESYSTEM_KEY_MANAGER_H \ No newline at end of file diff --git a/lockbox/include/key_manager.h b/lockbox/include/google_key_manager.h similarity index 72% rename from lockbox/include/key_manager.h rename to lockbox/include/google_key_manager.h index 0ab6d3fe..a82b1799 100644 --- a/lockbox/include/key_manager.h +++ b/lockbox/include/google_key_manager.h @@ -1,5 +1,5 @@ -#ifndef KEY_MANAGER_H -#define KEY_MANAGER_H +#ifndef GOOGLE_KEY_MANAGER_H +#define GOOGLE_KEY_MANAGER_H #include #include @@ -10,4 +10,4 @@ namespace key_manager { std::vector get_seed(); } // namespace key_manager -#endif // KEY_MANAGER_H \ No newline at end of file +#endif // GOOGLE_KEY_MANAGER_H \ No newline at end of file diff --git a/lockbox/include/server.h b/lockbox/include/server.h index 59e9421f..2dd7a398 100644 --- a/lockbox/include/server.h +++ b/lockbox/include/server.h @@ -4,7 +4,7 @@ #include namespace lockbox { - void start_server(const std::string& key_provider); + void start_server(); } // namespace lockbox #endif // SERVER_H \ No newline at end of file diff --git a/lockbox/src/enclave.cpp b/lockbox/src/enclave.cpp index 4cd17ca2..167ec770 100644 --- a/lockbox/src/enclave.cpp +++ b/lockbox/src/enclave.cpp @@ -25,23 +25,6 @@ void encrypt_data( encrypted_data->data_len = raw_data_size; crypto_aead_lock(encrypted_data->data, encrypted_data->mac, seed, encrypted_data->nonce, ad, ad_size, raw_data, raw_data_size); - - /* char* seed_hex = data_to_hex(seed, sizeof(seed)); - ocall_print_string("seed:"); - ocall_print_string(seed_hex); - - char* mac_hex = data_to_hex(encrypted_data->mac, sizeof(encrypted_data->mac)); - ocall_print_string("mac:"); - ocall_print_string(mac_hex); - - char* nonce_hex = data_to_hex(encrypted_data->nonce, sizeof(encrypted_data->nonce)); - ocall_print_string("nonce:"); - ocall_print_string(nonce_hex); - - char* encrypted_hex = data_to_hex(encrypted_data->data, encrypted_data->data_len); - ocall_print_string("encrypted:"); - ocall_print_string(encrypted_hex); */ - } int decrypt_data( diff --git a/lockbox/src/filesystem_key_manager.cpp b/lockbox/src/filesystem_key_manager.cpp new file mode 100644 index 00000000..33db57c5 --- /dev/null +++ b/lockbox/src/filesystem_key_manager.cpp @@ -0,0 +1,76 @@ +#include "hashicorp_key_manager.h" + +#include +#include +#include +#include +#include +#include "utils.h" +#include + +namespace filesystem_key_manager { + + std::string getSeedFilePath() { + const char* value = std::getenv("SEED_FILEPATH"); + + if (value == nullptr) { + auto config = toml::parse_file("Settings.toml"); + return config["filesystem"]["seed_filepath"].as_string()->get(); + } else { + return std::string(value); + } + } + + std::vector get_seed() { + const std::string seed_file = getSeedFilePath(); + + if (std::filesystem::exists(seed_file)) { + // The seed file exists + std::ifstream seed_in(seed_file, std::ios::binary); + if (!seed_in) { + throw std::runtime_error("Error opening seed file for reading."); + } + + // Read the contents into a vector + std::vector key((std::istreambuf_iterator(seed_in)), + std::istreambuf_iterator()); + + // Check if the key is 32 bytes + if (key.size() != 32) { + throw std::runtime_error("Seed file has invalid size."); + } + + return key; + } else { + // Seed file does not exist, generate a new seed + std::vector key(32); // 256-bit key + + // Generate cryptographically secure random bytes + if (RAND_bytes(key.data(), key.size()) != 1) { + throw std::runtime_error("Error generating random bytes."); + } + + // Write the key to the seed file + std::ofstream seed_out(seed_file, std::ios::binary | std::ios::trunc); + if (!seed_out) { + throw std::runtime_error("Error opening seed file for writing."); + } + + seed_out.write(reinterpret_cast(key.data()), key.size()); + if (!seed_out) { + throw std::runtime_error("Error writing seed to file."); + } + + // Optionally, set file permissions to owner read/write only (platform-dependent) +#ifdef __unix__ + seed_out.close(); // Close the file before changing permissions + std::filesystem::permissions(seed_file, + std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, + std::filesystem::perm_options::replace); +#endif + + return key; + } + } + +} \ No newline at end of file diff --git a/lockbox/src/key_manager.cpp b/lockbox/src/google_key_manager.cpp similarity index 98% rename from lockbox/src/key_manager.cpp rename to lockbox/src/google_key_manager.cpp index 742d9efc..4d05e1ae 100644 --- a/lockbox/src/key_manager.cpp +++ b/lockbox/src/google_key_manager.cpp @@ -1,4 +1,4 @@ -#include "key_manager.h" +#include "google_key_manager.h" #include "google/cloud/kms/v1/key_management_client.h" #include "google/cloud/secretmanager/v1/secret_manager_client.h" diff --git a/lockbox/src/main.cpp b/lockbox/src/main.cpp index fd26e4eb..8ad552a9 100644 --- a/lockbox/src/main.cpp +++ b/lockbox/src/main.cpp @@ -7,19 +7,9 @@ int main(int argc, char *argv[]) { CLI::App cli_app{"Lockbox Server"}; cli_app.set_version_flag("--version", std::string("0.0.1")); - // Add the mandatory key_provider option - std::string key_provider; - cli_app.add_option("--key_provider", key_provider, "Key provider (google_kms or hashicorp)") - ->required() // Mark it as mandatory - ->check(CLI::IsMember({"google_kms", "hashicorp"})); // Validate allowed values + CLI11_PARSE(cli_app, argc, argv); - try { - CLI11_PARSE(cli_app, argc, argv); - } catch (const CLI::ParseError &e) { - return cli_app.exit(e); // Exit gracefully on parse errors - } - - lockbox::start_server(key_provider); + lockbox::start_server(); return 0; } \ No newline at end of file diff --git a/lockbox/src/server.cpp b/lockbox/src/server.cpp index 2336f38a..e0492b19 100644 --- a/lockbox/src/server.cpp +++ b/lockbox/src/server.cpp @@ -3,9 +3,11 @@ #include #include "utils.h" #include "enclave.h" -#include "key_manager.h" +#include "google_key_manager.h" #include "hashicorp_key_manager.h" +#include "filesystem_key_manager.h" #include "db_manager.h" +#include namespace lockbox { @@ -183,16 +185,31 @@ namespace lockbox { return crow::response{result}; } - void start_server(const std::string& key_provider) { + std::string getKeyManager() { + const char* value = std::getenv("KEY_MANAGER"); + + if (value == nullptr) { + auto config = toml::parse_file("Settings.toml"); + return config["general"]["key_manager"].as_string()->get(); + } else { + return std::string(value); + } + } + + void start_server() { std::vector seed; - if (key_provider == "google_kms") { + auto key_provider = getKeyManager(); + + if (key_provider == "filesystem") { + seed = filesystem_key_manager::get_seed(); + } else if (key_provider == "google_kms") { seed = key_manager::get_seed(); } else if (key_provider == "hashicorp") { seed = hashicorp_key_manager::get_seed(); } else { - throw std::runtime_error("Invalid key provider: " + key_provider); + throw std::runtime_error("Invalid key manager: " + key_provider); } /* std::string seed_hex = utils::key_to_string(seed.data(), seed.size());