diff --git a/dbsim/db_server_service.cpp b/dbsim/db_server_service.cpp index 58ffdf3..be6e831 100644 --- a/dbsim/db_server_service.cpp +++ b/dbsim/db_server_service.cpp @@ -150,3 +150,14 @@ void db::server_service::debug_sync(const char*) { } + +int db::server_service::do_crypt(void** ctx WSREP_UNUSED, + wsrep::const_buffer& key WSREP_UNUSED, + const char (*iv)[32] WSREP_UNUSED, + wsrep::const_buffer& input WSREP_UNUSED, + void* output WSREP_UNUSED, + bool encrypt WSREP_UNUSED, + bool last WSREP_UNUSED) +{ + return -1; +} diff --git a/dbsim/db_server_service.hpp b/dbsim/db_server_service.hpp index a21c245..7c137e3 100644 --- a/dbsim/db_server_service.hpp +++ b/dbsim/db_server_service.hpp @@ -55,6 +55,15 @@ namespace db enum wsrep::server_state::state) override; int wait_committing_transactions(int) override; void debug_sync(const char*) override; + + int do_crypt(void** ctx, + wsrep::const_buffer& key, + const char (*iv)[32], + wsrep::const_buffer& input, + void* output, + bool encrypt, + bool last) override; + private: db::server& server_; wsrep::view logged_view_; diff --git a/include/wsrep/provider.hpp b/include/wsrep/provider.hpp index 38bf631..5d50a38 100644 --- a/include/wsrep/provider.hpp +++ b/include/wsrep/provider.hpp @@ -342,6 +342,8 @@ namespace wsrep virtual int sst_sent(const wsrep::gtid&, int) = 0; virtual int sst_received(const wsrep::gtid&, int) = 0; + virtual int enc_set_key(const wsrep::const_buffer& key) = 0; + virtual std::vector status() const = 0; virtual void reset_status() = 0; diff --git a/include/wsrep/server_service.hpp b/include/wsrep/server_service.hpp index 8c513b5..03b5a98 100644 --- a/include/wsrep/server_service.hpp +++ b/include/wsrep/server_service.hpp @@ -197,7 +197,6 @@ namespace wsrep const wsrep::gtid& gtid, bool bypass) = 0; - /** * Wait until committing transactions have completed. * Prior calling this method the server should have been @@ -211,6 +210,16 @@ namespace wsrep */ virtual void debug_sync(const char* sync_point) = 0; + /* + * Encrypt/decrypt data + */ + virtual int do_crypt(void** ctx, + wsrep::const_buffer& key, + const char (*iv)[32], + wsrep::const_buffer& input, + void* output, + bool encrypt, + bool last) = 0; }; } diff --git a/include/wsrep/server_state.hpp b/include/wsrep/server_state.hpp index 46f686a..9dda7d5 100644 --- a/include/wsrep/server_state.hpp +++ b/include/wsrep/server_state.hpp @@ -369,6 +369,21 @@ namespace wsrep enum wsrep::provider::status wait_for_gtid(const wsrep::gtid&, int timeout) const; + /** + * Set encryption key + * + * @param key Encryption key + * + * @return Zero on success, non-zero on failure. + */ + int set_encryption_key(std::vector& key); + + /** + * Return encryption key. + */ + const std::vector& get_encryption_key() const + { return encryption_key_; } + /** * Perform a causal read in the cluster. After the call returns, * all the causally preceding write sets have been committed @@ -583,6 +598,7 @@ namespace wsrep , incoming_address_(incoming_address) , address_(address) , working_dir_(working_dir) + , encryption_key_() , max_protocol_version_(max_protocol_version) , rollback_mode_(rollback_mode) , connected_gtid_() @@ -664,6 +680,7 @@ namespace wsrep std::string incoming_address_; std::string address_; std::string working_dir_; + std::vector encryption_key_; int max_protocol_version_; enum rollback_mode rollback_mode_; wsrep::gtid connected_gtid_; diff --git a/src/server_state.cpp b/src/server_state.cpp index cdc9a26..2cef657 100644 --- a/src/server_state.cpp +++ b/src/server_state.cpp @@ -626,6 +626,18 @@ wsrep::server_state::wait_for_gtid(const wsrep::gtid& gtid, int timeout) return provider().wait_for_gtid(gtid, timeout); } +int +wsrep::server_state::set_encryption_key(std::vector& key) +{ + encryption_key_ = key; + if (state_ != s_disconnected) + { + return provider_->enc_set_key(wsrep::const_buffer(encryption_key_.data(), + encryption_key_.size())); + } + return 0; +} + std::pair wsrep::server_state::causal_read(int timeout) const { diff --git a/src/wsrep_provider_v26.cpp b/src/wsrep_provider_v26.cpp index 981004a..8577c31 100644 --- a/src/wsrep_provider_v26.cpp +++ b/src/wsrep_provider_v26.cpp @@ -20,6 +20,7 @@ #include "wsrep_provider_v26.hpp" #include "wsrep/server_state.hpp" +#include "wsrep/server_service.hpp" #include "wsrep/high_priority_service.hpp" #include "wsrep/view.hpp" #include "wsrep/exception.hpp" @@ -421,14 +422,36 @@ namespace } } - wsrep_cb_status_t encrypt_cb(void* /* app ctx */, - wsrep_enc_ctx_t* /*ctx*/, - const wsrep_buf_t* /*input*/, - void* /*output*/, - wsrep_enc_direction_t /*direction*/, - bool /*final*/) + int encrypt_cb(void* app_ctx, + wsrep_enc_ctx_t* enc_ctx, + const wsrep_buf_t* input, + void* output, + wsrep_enc_direction_t direction, + bool last) { - return WSREP_CB_SUCCESS; + assert(app_ctx); + wsrep::server_state& server_state( + *static_cast(app_ctx)); + + + wsrep::const_buffer key(enc_ctx->key->ptr, enc_ctx->key->len); + wsrep::const_buffer in(input->ptr, input->len); + try + { + return server_state.server_service().do_crypt(&enc_ctx->ctx, + key, + enc_ctx->iv, + in, + output, + direction == WSREP_ENC, + last); + } + catch (const wsrep::runtime_error& e) + { + free(enc_ctx->ctx); + // Return negative value in case of callback error + return -1; + } } wsrep_cb_status_t apply_cb(void* ctx, @@ -582,6 +605,16 @@ wsrep::wsrep_provider_v26::wsrep_provider_v26( { throw wsrep::runtime_error("Failed to initialize wsrep provider"); } + + const std::vector& key = server_state.get_encryption_key(); + if (key.size()) + { + wsrep::const_buffer const_key(key.data(), key.size()); + if(enc_set_key(const_key)) + { + throw wsrep::runtime_error("Failed to set encryption key"); + } + } } wsrep::wsrep_provider_v26::~wsrep_provider_v26() @@ -856,6 +889,16 @@ int wsrep::wsrep_provider_v26::sst_received(const wsrep::gtid& gtid, int err) return 0; } +int wsrep::wsrep_provider_v26::enc_set_key(const wsrep::const_buffer& key) +{ + wsrep_enc_key_t enc_key = {key.data(), key.size()}; + if (wsrep_->enc_set_key(wsrep_, &enc_key) != WSREP_OK) + { + return 1; + } + return 0; +} + std::vector wsrep::wsrep_provider_v26::status() const { diff --git a/src/wsrep_provider_v26.hpp b/src/wsrep_provider_v26.hpp index c2a706b..695cd40 100644 --- a/src/wsrep_provider_v26.hpp +++ b/src/wsrep_provider_v26.hpp @@ -78,7 +78,7 @@ namespace wsrep wsrep::gtid last_committed_gtid() const; int sst_sent(const wsrep::gtid&,int); int sst_received(const wsrep::gtid& gtid, int); - + int enc_set_key(const wsrep::const_buffer& key); std::vector status() const; void reset_status(); std::string options() const; diff --git a/test/mock_provider.hpp b/test/mock_provider.hpp index 9c4d94b..7a27671 100644 --- a/test/mock_provider.hpp +++ b/test/mock_provider.hpp @@ -252,6 +252,9 @@ namespace wsrep int sst_sent(const wsrep::gtid&, int) WSREP_OVERRIDE { return 0; } int sst_received(const wsrep::gtid&, int) WSREP_OVERRIDE { return 0; } + int enc_set_key(const wsrep::const_buffer&) WSREP_OVERRIDE + { return 0; } + std::vector status() const WSREP_OVERRIDE { return std::vector(); diff --git a/test/mock_server_state.hpp b/test/mock_server_state.hpp index 11396fe..5251b6f 100644 --- a/test/mock_server_state.hpp +++ b/test/mock_server_state.hpp @@ -190,6 +190,18 @@ namespace wsrep } } + int do_crypt(void** ctx WSREP_UNUSED, + wsrep::const_buffer& key WSREP_UNUSED, + const char (*iv)[32] WSREP_UNUSED, + wsrep::const_buffer& input WSREP_UNUSED, + void* output WSREP_UNUSED, + bool encrypt WSREP_UNUSED, + bool last WSREP_UNUSED) + WSREP_OVERRIDE + { + return -1; + } + std::string sync_point_enabled_; enum sync_point_action { diff --git a/wsrep-API/v26 b/wsrep-API/v26 index f023937..75a5f45 160000 --- a/wsrep-API/v26 +++ b/wsrep-API/v26 @@ -1 +1 @@ -Subproject commit f0239371ca91af2a3638b3ed4f4f362903e15efc +Subproject commit 75a5f452f2ba07b0f4a3a9a94825fccc71b27398