From e7d1063c434327fd6c64e3faeb96238e83ce8824 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Mon, 3 Aug 2026 20:21:12 +0200 Subject: [PATCH] PBS-39 feature: Add binlog encryption config and keyring support (part 4) https://perconadev.atlassian.net/browse/PBS-39 JSON responses generated by the 'list' / 'search_by_timestamp' / 'search_by_gtid_set' / 'purge_binlogs' extended with the optional 'encryption' subobject (of the same structure as in binlog metadata files). 'binsrv::file_key_envelope' renamed/moved to 'binsrv::models::file_key_envelope_record'. 'binsrv::file_data_envelope' renamed/moved to 'binsrv::models::file_data_envelope_record'. 'binsrv::binlog_file_encryption_metadata' renamed/moved to 'binsrv::models::binlog_file_encryption_record'. 'binsrv::models::binlog_file_record' extended with a new optional field 'encryption' of class 'binsrv::models::binlog_file_encryption_record'. Added "record to model" / "model to record" conversion functions for the 'binsrv::storage::binlog_encryption_record' structure. Updated README.md with the new 'encryption' subobject in JSON responses of the 'list' / 'search_by_timestamp' / 'search_by_gtid_set' / 'purge_binlogs' commands. --- CMakeLists.txt | 18 +-- README.md | 28 +++- src/app.cpp | 22 ++- src/binsrv/binlog_file_metadata.hpp | 6 +- src/binsrv/events/unknown_body_fwd.hpp | 2 +- .../binlog_file_encryption_record.hpp} | 22 +-- .../binlog_file_encryption_record_fwd.hpp} | 16 +- src/binsrv/models/binlog_file_record.hpp | 5 +- .../file_data_envelope_record.hpp} | 16 +- .../file_data_envelope_record_fwd.hpp} | 12 +- .../file_key_envelope_record.hpp} | 16 +- .../file_key_envelope_record_fwd.hpp} | 12 +- src/binsrv/models/search_response.cpp | 17 +-- src/binsrv/models/search_response.hpp | 7 +- src/binsrv/storage.cpp | 137 +++++++++--------- src/binsrv/storage.hpp | 10 +- 16 files changed, 184 insertions(+), 162 deletions(-) rename src/binsrv/{binlog_file_encryption_metadata.hpp => models/binlog_file_encryption_record.hpp} (57%) rename src/binsrv/{binlog_file_encryption_metadata_fwd.hpp => models/binlog_file_encryption_record_fwd.hpp} (66%) rename src/binsrv/{file_data_envelope.hpp => models/file_data_envelope_record.hpp} (73%) rename src/binsrv/{file_data_envelope_fwd.hpp => models/file_data_envelope_record_fwd.hpp} (73%) rename src/binsrv/{file_key_envelope.hpp => models/file_key_envelope_record.hpp} (75%) rename src/binsrv/{file_key_envelope_fwd.hpp => models/file_key_envelope_record_fwd.hpp} (74%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d8cb95..476f3bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -404,10 +404,19 @@ set(models_source_files src/binsrv/models/binlog_file_record_fwd.hpp src/binsrv/models/binlog_file_record.hpp + src/binsrv/models/binlog_file_encryption_record_fwd.hpp + src/binsrv/models/binlog_file_encryption_record.hpp + src/binsrv/models/error_response_fwd.hpp src/binsrv/models/error_response.hpp src/binsrv/models/error_response.cpp + src/binsrv/models/file_data_envelope_record_fwd.hpp + src/binsrv/models/file_data_envelope_record.hpp + + src/binsrv/models/file_key_envelope_record_fwd.hpp + src/binsrv/models/file_key_envelope_record.hpp + src/binsrv/models/response_status_type_fwd.hpp src/binsrv/models/response_status_type.hpp @@ -455,9 +464,6 @@ set(binsrv_source_files src/binsrv/binlog_file_metadata.hpp src/binsrv/binlog_file_metadata.cpp - src/binsrv/binlog_file_encryption_metadata_fwd.hpp - src/binsrv/binlog_file_encryption_metadata.hpp - src/binsrv/cout_logger.hpp src/binsrv/cout_logger.cpp @@ -471,12 +477,6 @@ set(binsrv_source_files src/binsrv/exception_handling_helpers.hpp src/binsrv/exception_handling_helpers.cpp - src/binsrv/file_data_envelope_fwd.hpp - src/binsrv/file_data_envelope.hpp - - src/binsrv/file_key_envelope_fwd.hpp - src/binsrv/file_key_envelope.hpp - src/binsrv/file_keyring.hpp src/binsrv/file_keyring.cpp diff --git a/README.md b/README.md index a079bfd..374733e 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,19 @@ may print "min_timestamp": "2026-02-09T17:22:01", "max_timestamp": "2026-02-09T17:22:08", "previous_gtids": "", - "added_gtids": "11111111-aaaa-1111-aaaa-111111111111:1-123456" + "added_gtids": "11111111-aaaa-1111-aaaa-111111111111:1-123456", + "encryption": { + "file_key_envelope": { + "kek_id": "beta", + "data_hex": "A4F6F06C40C44538BB9DE0A468D1708A", + "iv_hex": "52A9AF1A96B5ACB05F6FD720", + "tag_hex": "000102030405060708090A0B0C0D0E0F" + }, + "file_data_envelope": { + "cipher": "AES-128-CTR", + "iv_hex": "4515D10B1607C71C6CA883B052A9AF1A" + } + } }, { "name": "binlog.000002", @@ -214,7 +226,19 @@ may print "min_timestamp": "2026-02-09T17:22:08", "max_timestamp": "2026-02-09T17:22:09", "previous_gtids": "11111111-aaaa-1111-aaaa-111111111111:1-123456", - "added_gtids": "11111111-aaaa-1111-aaaa-111111111111:123457-246912" + "added_gtids": "11111111-aaaa-1111-aaaa-111111111111:123457-246912", + "encryption": { + "file_key_envelope": { + "kek_id": "beta", + "data_hex": "BB9DE0A468D1708AA4F6F06C40C44538", + "iv_hex": "ACB05F6FD72052A9AF1A96B5", + "tag_hex": "000102030405060708090A0B0C0D0E0F" + }, + "file_data_envelope": { + "cipher": "AES-128-CTR", + "iv_hex": "6CA883B052A9AF1A4515D10B1607C71C" + } + } } ] } diff --git a/src/app.cpp b/src/app.cpp index ff36af8..eb0ad13 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -57,6 +57,7 @@ #include "binsrv/gtids/common_types.hpp" #include "binsrv/gtids/gtid_set.hpp" +#include "binsrv/models/binlog_file_record.hpp" #include "binsrv/models/error_response.hpp" #include "binsrv/models/response_status_type.hpp" #include "binsrv/models/search_response.hpp" @@ -995,12 +996,21 @@ bool handle_version() { // a record of the response model void append_record_to_response(binsrv::models::search_response &response, const binsrv::storage &storage, - const auto &record) { - response.add_record(record.name.str(), record.size, - storage.get_binlog_uri(record.name), - record.previous_gtids, record.added_gtids, - record.timestamps.get_min_timestamp().get_value(), - record.timestamps.get_max_timestamp().get_value()); + const binsrv::storage::binlog_record &record) { + binsrv::models::binlog_file_record model_record{ + {{record.name.str()}, + {record.size}, + {storage.get_binlog_uri(record.name)}, + {record.previous_gtids}, + {record.added_gtids}, + {record.timestamps.get_min_timestamp()}, + {record.timestamps.get_max_timestamp()}, + {record.encryption.has_value() + ? binsrv::storage::binlog_encryption_record::to_model( + *record.encryption) + : binsrv::models::optional_binlog_file_encryption_record{}}}}; + + response.add_record(std::move(model_record)); } bool handle_list(std::string_view config_file_path) { diff --git a/src/binsrv/binlog_file_metadata.hpp b/src/binsrv/binlog_file_metadata.hpp index e0bb168..824fef0 100644 --- a/src/binsrv/binlog_file_metadata.hpp +++ b/src/binsrv/binlog_file_metadata.hpp @@ -22,12 +22,12 @@ #include #include -#include "binsrv/binlog_file_encryption_metadata.hpp" // IWYU pragma: export - #include "binsrv/events/common_types.hpp" #include "binsrv/gtids/gtid_set.hpp" +#include "binsrv/models/binlog_file_encryption_record.hpp" // IWYU pragma: export + #include "util/ctime_timestamp.hpp" #include "util/nv_tuple.hpp" @@ -50,7 +50,7 @@ class [[nodiscard]] binlog_file_metadata { util::nv<"min_timestamp", util::ctime_timestamp>, util::nv<"max_timestamp", util::ctime_timestamp>, util::nv<"last_sequence_number", events::seq_no_t>, - util::nv<"encryption", optional_binlog_file_encryption_metadata> + util::nv<"encryption", models::optional_binlog_file_encryption_record> // clang-format on >; diff --git a/src/binsrv/events/unknown_body_fwd.hpp b/src/binsrv/events/unknown_body_fwd.hpp index e513403..080e4b6 100644 --- a/src/binsrv/events/unknown_body_fwd.hpp +++ b/src/binsrv/events/unknown_body_fwd.hpp @@ -25,4 +25,4 @@ std::ostream &operator<<(std::ostream &output, const unknown_body &obj); } // namespace binsrv::events -#endif // BINSRV_EVENTS_UNKNOWN_BODY_FWD_HPPß +#endif // BINSRV_EVENTS_UNKNOWN_BODY_FWD_HPP diff --git a/src/binsrv/binlog_file_encryption_metadata.hpp b/src/binsrv/models/binlog_file_encryption_record.hpp similarity index 57% rename from src/binsrv/binlog_file_encryption_metadata.hpp rename to src/binsrv/models/binlog_file_encryption_record.hpp index 5281f8f..01465c4 100644 --- a/src/binsrv/binlog_file_encryption_metadata.hpp +++ b/src/binsrv/models/binlog_file_encryption_record.hpp @@ -13,26 +13,26 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef BINSRV_BINLOG_FILE_ENCRYPTION_METADATA_HPP -#define BINSRV_BINLOG_FILE_ENCRYPTION_METADATA_HPP +#ifndef BINSRV_MODELS_BINLOG_FILE_ENCRYPTION_RECORD_HPP +#define BINSRV_MODELS_BINLOG_FILE_ENCRYPTION_RECORD_HPP -#include "binsrv/binlog_file_encryption_metadata_fwd.hpp" // IWYU pragma: export +#include "binsrv/models/binlog_file_encryption_record_fwd.hpp" // IWYU pragma: export -#include "binsrv/file_data_envelope.hpp" // IWYU pragma: export -#include "binsrv/file_key_envelope.hpp" // IWYU pragma: export +#include "binsrv/models/file_data_envelope_record.hpp" // IWYU pragma: export +#include "binsrv/models/file_key_envelope_record.hpp" // IWYU pragma: export #include "util/nv_tuple.hpp" -namespace binsrv { +namespace binsrv::models { -class [[nodiscard]] binlog_file_encryption_metadata +class [[nodiscard]] binlog_file_encryption_record : public util::nv_tuple< // clang-format off - util::nv<"file_key_envelope", file_key_envelope>, - util::nv<"file_data_envelope", file_data_envelope> + util::nv<"file_key_envelope", file_key_envelope_record>, + util::nv<"file_data_envelope", file_data_envelope_record> // clang-format on > {}; -} // namespace binsrv +} // namespace binsrv::models -#endif // BINSRV_BINLOG_FILE_ENCRYPTION_METADATA_HPP +#endif // BINSRV_MODELS_BINLOG_FILE_ENCRYPTION_RECORD_HPP diff --git a/src/binsrv/binlog_file_encryption_metadata_fwd.hpp b/src/binsrv/models/binlog_file_encryption_record_fwd.hpp similarity index 66% rename from src/binsrv/binlog_file_encryption_metadata_fwd.hpp rename to src/binsrv/models/binlog_file_encryption_record_fwd.hpp index d100748..e652a25 100644 --- a/src/binsrv/binlog_file_encryption_metadata_fwd.hpp +++ b/src/binsrv/models/binlog_file_encryption_record_fwd.hpp @@ -13,17 +13,17 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef BINSRV_BINLOG_FILE_ENCRYPTION_METADATA_FWD_HPP -#define BINSRV_BINLOG_FILE_ENCRYPTION_METADATA_FWD_HPP +#ifndef BINSRV_MODELS_BINLOG_FILE_ENCRYPTION_RECORD_FWD_HPP +#define BINSRV_MODELS_BINLOG_FILE_ENCRYPTION_RECORD_FWD_HPP #include -namespace binsrv { +namespace binsrv::models { -class binlog_file_encryption_metadata; -using optional_binlog_file_encryption_metadata = - std::optional; +class binlog_file_encryption_record; +using optional_binlog_file_encryption_record = + std::optional; -} // namespace binsrv +} // namespace binsrv::models -#endif // BINSRV_BINLOG_FILE_ENCRYPTION_METADATA_FWD_HPP +#endif // BINSRV_MODELS_BINLOG_FILE_ENCRYPTION_RECORD_FWD_HPP diff --git a/src/binsrv/models/binlog_file_record.hpp b/src/binsrv/models/binlog_file_record.hpp index deb3b59..273448e 100644 --- a/src/binsrv/models/binlog_file_record.hpp +++ b/src/binsrv/models/binlog_file_record.hpp @@ -23,6 +23,8 @@ #include "binsrv/gtids/gtid_set.hpp" +#include "binsrv/models/binlog_file_encryption_record.hpp" // IWYU pragma: export + #include "util/ctime_timestamp.hpp" #include "util/nv_tuple.hpp" @@ -37,7 +39,8 @@ struct [[nodiscard]] binlog_file_record util::nv<"previous_gtids", gtids::optional_gtid_set>, util::nv<"added_gtids", gtids::optional_gtid_set>, util::nv<"min_timestamp", util::ctime_timestamp>, - util::nv<"max_timestamp", util::ctime_timestamp> + util::nv<"max_timestamp", util::ctime_timestamp>, + util::nv<"encryption", optional_binlog_file_encryption_record> // clang-format on > {}; diff --git a/src/binsrv/file_data_envelope.hpp b/src/binsrv/models/file_data_envelope_record.hpp similarity index 73% rename from src/binsrv/file_data_envelope.hpp rename to src/binsrv/models/file_data_envelope_record.hpp index 9934350..7a73ec9 100644 --- a/src/binsrv/file_data_envelope.hpp +++ b/src/binsrv/models/file_data_envelope_record.hpp @@ -13,20 +13,20 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef BINSRV_FILE_DATA_ENVELOPE_HPP -#define BINSRV_FILE_DATA_ENVELOPE_HPP +#ifndef BINSRV_MODELS_FILE_DATA_ENVELOPE_RECORD_HPP +#define BINSRV_MODELS_FILE_DATA_ENVELOPE_RECORD_HPP -#include "binsrv/file_data_envelope_fwd.hpp" // IWYU pragma: export +#include "binsrv/models/file_data_envelope_record_fwd.hpp" // IWYU pragma: export #include #include "util/hex_value.hpp" #include "util/nv_tuple.hpp" -namespace binsrv { +namespace binsrv::models { -class [[nodiscard]] file_data_envelope - : public util::nv_tuple< +struct [[nodiscard]] file_data_envelope_record + : util::nv_tuple< // clang-format off util::nv<"cipher", std::string>, util::nv<"iv_hex", util::hex_value>, @@ -34,6 +34,6 @@ class [[nodiscard]] file_data_envelope // clang-format on > {}; -} // namespace binsrv +} // namespace binsrv::models -#endif // BINSRV_FILE_DATA_ENVELOPE_HPP +#endif // BINSRV_MODELS_FILE_DATA_ENVELOPE_RECORD_HPP diff --git a/src/binsrv/file_data_envelope_fwd.hpp b/src/binsrv/models/file_data_envelope_record_fwd.hpp similarity index 73% rename from src/binsrv/file_data_envelope_fwd.hpp rename to src/binsrv/models/file_data_envelope_record_fwd.hpp index 648e58f..c0762ff 100644 --- a/src/binsrv/file_data_envelope_fwd.hpp +++ b/src/binsrv/models/file_data_envelope_record_fwd.hpp @@ -13,13 +13,13 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef BINSRV_FILE_DATA_ENVELOPE_FWD_HPP -#define BINSRV_FILE_DATA_ENVELOPE_FWD_HPP +#ifndef BINSRV_MODELS_FILE_DATA_ENVELOPE_RECORD_FWD_HPP +#define BINSRV_MODELS_FILE_DATA_ENVELOPE_RECORD_FWD_HPP -namespace binsrv { +namespace binsrv::models { -class file_data_envelope; +struct file_data_envelope_record; -} // namespace binsrv +} // namespace binsrv::models -#endif // BINSRV_FILE_DATA_ENVELOPE_FWD_HPP +#endif // BINSRV_MODELS_FILE_DATA_ENVELOPE_RECORD_FWD_HPP diff --git a/src/binsrv/file_key_envelope.hpp b/src/binsrv/models/file_key_envelope_record.hpp similarity index 75% rename from src/binsrv/file_key_envelope.hpp rename to src/binsrv/models/file_key_envelope_record.hpp index 88a35cb..6c14724 100644 --- a/src/binsrv/file_key_envelope.hpp +++ b/src/binsrv/models/file_key_envelope_record.hpp @@ -13,20 +13,20 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef BINSRV_FILE_KEY_ENVELOPE_HPP -#define BINSRV_FILE_KEY_ENVELOPE_HPP +#ifndef BINSRV_MODELS_FILE_KEY_ENVELOPE_RECORD_HPP +#define BINSRV_MODELS_FILE_KEY_ENVELOPE_RECORD_HPP -#include "binsrv/file_key_envelope_fwd.hpp" // IWYU pragma: export +#include "binsrv/models/file_key_envelope_record_fwd.hpp" // IWYU pragma: export #include #include "util/hex_value.hpp" #include "util/nv_tuple.hpp" -namespace binsrv { +namespace binsrv::models { -class [[nodiscard]] file_key_envelope - : public util::nv_tuple< +struct [[nodiscard]] file_key_envelope_record + : util::nv_tuple< // clang-format off util::nv<"kek_id", std::string>, util::nv<"data_hex", util::hex_value>, @@ -35,6 +35,6 @@ class [[nodiscard]] file_key_envelope // clang-format on > {}; -} // namespace binsrv +} // namespace binsrv::models -#endif // BINSRV_FILE_KEY_ENVELOPE_HPP +#endif // BINSRV_MODELS_FILE_KEY_ENVELOPE_RECORD_HPP diff --git a/src/binsrv/file_key_envelope_fwd.hpp b/src/binsrv/models/file_key_envelope_record_fwd.hpp similarity index 74% rename from src/binsrv/file_key_envelope_fwd.hpp rename to src/binsrv/models/file_key_envelope_record_fwd.hpp index ed0a9e5..2486dd6 100644 --- a/src/binsrv/file_key_envelope_fwd.hpp +++ b/src/binsrv/models/file_key_envelope_record_fwd.hpp @@ -13,13 +13,13 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#ifndef BINSRV_FILE_KEY_ENVELOPE_FWD_HPP -#define BINSRV_FILE_KEY_ENVELOPE_FWD_HPP +#ifndef BINSRV_MODELS_FILE_KEY_ENVELOPE_RECORD_FWD_HPP +#define BINSRV_MODELS_FILE_KEY_ENVELOPE_RECORD_FWD_HPP -namespace binsrv { +namespace binsrv::models { -class file_key_envelope; +struct file_key_envelope_record; -} // namespace binsrv +} // namespace binsrv::models -#endif // BINSRV_FILE_KEY_ENVELOPE_FWD_HPP +#endif // BINSRV_MODELS_FILE_KEY_ENVELOPE_RECORD_FWD_HPP diff --git a/src/binsrv/models/search_response.cpp b/src/binsrv/models/search_response.cpp index 9b5304e..151c4b0 100644 --- a/src/binsrv/models/search_response.cpp +++ b/src/binsrv/models/search_response.cpp @@ -15,7 +15,6 @@ #include "binsrv/models/search_response.hpp" -#include #include #include #include @@ -24,8 +23,6 @@ #include #include -#include "binsrv/gtids/gtid_set.hpp" - #include "binsrv/models/binlog_file_record.hpp" #include "binsrv/models/response_status_type.hpp" @@ -60,19 +57,7 @@ search_response::~search_response() = default; return boost::json::serialize(json_value); } -void search_response::add_record(std::string_view name, std::uint64_t size, - std::string_view uri, - gtids::optional_gtid_set previous_gtids, - gtids::optional_gtid_set added_gtids, - std::time_t min_timestamp, - std::time_t max_timestamp) { - binlog_file_record record{{{std::string{name}}, - {size}, - {std::string{uri}}, - {std::move(previous_gtids)}, - {std::move(added_gtids)}, - {util::ctime_timestamp{min_timestamp}}, - {util::ctime_timestamp{max_timestamp}}}}; +void search_response::add_record(binlog_file_record record) { impl_.template get<"result">().emplace_back(std::move(record)); } diff --git a/src/binsrv/models/search_response.hpp b/src/binsrv/models/search_response.hpp index 729dcb1..af4523c 100644 --- a/src/binsrv/models/search_response.hpp +++ b/src/binsrv/models/search_response.hpp @@ -62,12 +62,7 @@ class [[nodiscard]] search_response { [[nodiscard]] auto &root() noexcept { return impl_; } - // 'previous_gtids' and 'added_gtids' are deliberately taken by value as we - // are going to move from them - void add_record(std::string_view name, std::uint64_t size, - std::string_view uri, gtids::optional_gtid_set previous_gtids, - gtids::optional_gtid_set added_gtids, - std::time_t min_timestamp, std::time_t max_timestamp); + void add_record(binlog_file_record record); private: impl_type impl_; diff --git a/src/binsrv/storage.cpp b/src/binsrv/storage.cpp index 3d29d91..768f5cf 100644 --- a/src/binsrv/storage.cpp +++ b/src/binsrv/storage.cpp @@ -52,6 +52,8 @@ #include "binsrv/gtids/gtid.hpp" #include "binsrv/gtids/gtid_set.hpp" +#include "binsrv/models/binlog_file_encryption_record.hpp" + #include "util/byte_span.hpp" #include "util/conversion_helpers.hpp" #include "util/ctime_timestamp.hpp" @@ -59,6 +61,65 @@ namespace binsrv { +[[nodiscard]] models::binlog_file_encryption_record +storage::binlog_encryption_record::to_model( + const storage::binlog_encryption_record &record) { + models::binlog_file_encryption_record model{}; + + auto &file_key_envelope{model.get<"file_key_envelope">()}; + file_key_envelope.get<"kek_id">() = record.kek_id; + file_key_envelope.get<"data_hex">() = record.file_key_encrypted_with_kek; + if (record.iv_for_file_key_encryption.has_value()) { + file_key_envelope.get<"iv_hex">() = *record.iv_for_file_key_encryption; + } + if (record.tag_of_file_key_encryption.has_value()) { + file_key_envelope.get<"tag_hex">() = *record.tag_of_file_key_encryption; + } + + auto &file_data_envelope{model.get<"file_data_envelope">()}; + file_data_envelope.get<"cipher">() = record.data_cipher; + file_data_envelope.get<"iv_hex">() = record.iv_for_data_encryption; + if (record.tag_of_data_encryption.has_value()) { + file_data_envelope.get<"tag_hex">() = *record.tag_of_data_encryption; + } + return model; +} + +[[nodiscard]] storage::binlog_encryption_record +storage::binlog_encryption_record::from_model( + const models::binlog_file_encryption_record &model) { + binlog_encryption_record record{}; + + const auto &file_key_envelope{model.get<"file_key_envelope">()}; + record.kek_id = file_key_envelope.get<"kek_id">(); + const auto file_key_raw{file_key_envelope.get<"data_hex">().get_data()}; + record.file_key_encrypted_with_kek.assign(std::cbegin(file_key_raw), + std::cend(file_key_raw)); + if (file_key_envelope.get<"iv_hex">().has_value()) { + const auto file_key_iv_raw{file_key_envelope.get<"iv_hex">()->get_data()}; + record.iv_for_file_key_encryption.emplace(std::cbegin(file_key_iv_raw), + std::cend(file_key_iv_raw)); + } + if (file_key_envelope.get<"tag_hex">().has_value()) { + const auto file_key_tag_raw{file_key_envelope.get<"tag_hex">()->get_data()}; + record.tag_of_file_key_encryption.emplace(std::cbegin(file_key_tag_raw), + std::cend(file_key_tag_raw)); + } + + const auto &file_data_envelope{model.get<"file_data_envelope">()}; + record.data_cipher = file_data_envelope.get<"cipher">(); + const auto file_data_iv_raw{file_data_envelope.get<"iv_hex">().get_data()}; + record.iv_for_data_encryption.assign(std::cbegin(file_data_iv_raw), + std::cend(file_data_iv_raw)); + if (file_data_envelope.get<"tag_hex">().has_value()) { + const auto file_data_tag_raw{ + file_data_envelope.get<"tag_hex">()->get_data()}; + record.tag_of_data_encryption.emplace(std::cbegin(file_data_tag_raw), + std::cend(file_data_tag_raw)); + } + return record; +} + storage::storage(const storage_config &config, storage_construction_mode_type construction_mode, replication_mode_type replication_mode) @@ -662,48 +723,7 @@ void storage::save_metadata() const { backend_->get_object(generate_binlog_metadata_name(binlog_name))}; binlog_file_metadata metadata{content}; - const auto encryption_info_extractor{ - [](const optional_binlog_file_encryption_metadata &encryption_metadata) - -> optional_binlog_encryption_record { - if (!encryption_metadata.has_value()) { - return std::nullopt; - } - binlog_encryption_record encryption_record{}; - - const auto &file_key_envelope{ - encryption_metadata->get<"file_key_envelope">()}; - encryption_record.kek_id = file_key_envelope.get<"kek_id">(); - const auto file_key_raw{file_key_envelope.get<"data_hex">().get_data()}; - encryption_record.file_key_encrypted_with_kek.assign( - std::cbegin(file_key_raw), std::cend(file_key_raw)); - if (file_key_envelope.get<"iv_hex">().has_value()) { - const auto file_key_iv_raw{ - file_key_envelope.get<"iv_hex">()->get_data()}; - encryption_record.iv_for_file_key_encryption.emplace( - std::cbegin(file_key_iv_raw), std::cend(file_key_iv_raw)); - } - if (file_key_envelope.get<"tag_hex">().has_value()) { - const auto file_key_tag_raw{ - file_key_envelope.get<"tag_hex">()->get_data()}; - encryption_record.tag_of_file_key_encryption.emplace( - std::cbegin(file_key_tag_raw), std::cend(file_key_tag_raw)); - } - - const auto &file_data_envelope{ - encryption_metadata->get<"file_data_envelope">()}; - encryption_record.data_cipher = file_data_envelope.get<"cipher">(); - const auto file_data_iv_raw{ - file_data_envelope.get<"iv_hex">().get_data()}; - encryption_record.iv_for_data_encryption.assign( - std::cbegin(file_data_iv_raw), std::cend(file_data_iv_raw)); - if (file_data_envelope.get<"tag_hex">().has_value()) { - const auto file_data_tag_raw{ - file_data_envelope.get<"tag_hex">()->get_data()}; - encryption_record.tag_of_data_encryption.emplace( - std::cbegin(file_data_tag_raw), std::cend(file_data_tag_raw)); - } - return encryption_record; - }}; + const auto &optional_encryption_metadata{metadata.root().get<"encryption">()}; return binlog_record{ .name = binlog_name, .size = metadata.root().get<"size">(), @@ -712,8 +732,10 @@ void storage::save_metadata() const { .timestamps = {metadata.root().get<"min_timestamp">(), metadata.root().get<"max_timestamp">()}, .last_sequence_number = metadata.root().get<"last_sequence_number">(), - .encryption = - encryption_info_extractor(metadata.root().get<"encryption">())}; + .encryption = optional_encryption_metadata.has_value() + ? binlog_encryption_record::from_model( + *optional_encryption_metadata) + : optional_binlog_encryption_record{}}; } void storage::validate_binlog_metadata(const binlog_record &record) const { @@ -756,31 +778,8 @@ void storage::save_binlog_metadata(const binlog_record &record) const { metadata.root().get<"last_sequence_number">() = record.last_sequence_number; const auto &record_encryption{record.encryption}; if (record_encryption.has_value()) { - binlog_file_encryption_metadata encryption_metadata{}; - - auto &file_key_envelope{encryption_metadata.get<"file_key_envelope">()}; - file_key_envelope.get<"kek_id">() = record_encryption->kek_id; - file_key_envelope.get<"data_hex">() = - record_encryption->file_key_encrypted_with_kek; - if (record_encryption->iv_for_file_key_encryption.has_value()) { - file_key_envelope.get<"iv_hex">() = - *record_encryption->iv_for_file_key_encryption; - } - if (record_encryption->tag_of_file_key_encryption.has_value()) { - file_key_envelope.get<"tag_hex">() = - *record_encryption->tag_of_file_key_encryption; - } - - auto &file_data_envelope{encryption_metadata.get<"file_data_envelope">()}; - file_data_envelope.get<"cipher">() = record_encryption->data_cipher; - file_data_envelope.get<"iv_hex">() = - record_encryption->iv_for_data_encryption; - if (record_encryption->tag_of_data_encryption.has_value()) { - file_data_envelope.get<"tag_hex">() = - *record_encryption->tag_of_data_encryption; - } - - metadata.root().get<"encryption">() = std::move(encryption_metadata); + metadata.root().get<"encryption">() = + binlog_encryption_record::to_model(*record_encryption); } const auto content{metadata.str()}; backend_->put_object(generate_binlog_metadata_name(record.name), diff --git a/src/binsrv/storage.hpp b/src/binsrv/storage.hpp index 38ca530..1939ea3 100644 --- a/src/binsrv/storage.hpp +++ b/src/binsrv/storage.hpp @@ -35,6 +35,8 @@ #include "binsrv/gtids/gtid_fwd.hpp" #include "binsrv/gtids/gtid_set.hpp" +#include "binsrv/models/binlog_file_encryption_record_fwd.hpp" + #include "binsrv/events/common_types.hpp" #include "util/byte_span_fwd.hpp" @@ -45,7 +47,7 @@ namespace binsrv { class [[nodiscard]] storage { -private: +public: struct binlog_encryption_record { std::string kek_id; util::hex_value_storage file_key_encrypted_with_kek; @@ -54,6 +56,11 @@ class [[nodiscard]] storage { std::string data_cipher; util::hex_value_storage iv_for_data_encryption; util::optional_hex_value_storage tag_of_data_encryption; + + [[nodiscard]] static models::binlog_file_encryption_record + to_model(const binlog_encryption_record &record); + [[nodiscard]] static binlog_encryption_record + from_model(const models::binlog_file_encryption_record &model); }; using optional_binlog_encryption_record = std::optional; @@ -76,7 +83,6 @@ class [[nodiscard]] storage { }; using binlog_record_container = std::vector; -public: static constexpr std::string_view default_binlog_index_name{"binlog.index"}; static constexpr std::string_view default_binlog_index_entry_path{"."}; static constexpr std::string_view metadata_name{"metadata.json"};