Last active
July 19, 2018 11:54
-
-
Save gaurav36/ced2e5d985f5691db2da21b5ee15f8f7 to your computer and use it in GitHub Desktop.
own key generation for keyring file plugin in mysql-server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/plugin/keyring/CMakeLists.txt b/plugin/keyring/CMakeLists.txt | |
index d098f27..dc24720 100644 | |
--- a/plugin/keyring/CMakeLists.txt | |
+++ b/plugin/keyring/CMakeLists.txt | |
@@ -24,6 +24,7 @@ INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/compile_flags.cmake) | |
ADD_DEFINITIONS(-DLOG_COMPONENT_TAG="keyring_file") | |
+set (CMAKE_CXX_FLAGS "-lcurl") | |
SET (KEYRING_FILE_SOURCES | |
common/keyring_key.cc | |
common/keys_container.cc | |
diff --git a/plugin/keyring/common/keyring_impl.cc b/plugin/keyring/common/keyring_impl.cc | |
index 5de31ad..b6cbdb6 100644 | |
--- a/plugin/keyring/common/keyring_impl.cc | |
+++ b/plugin/keyring/common/keyring_impl.cc | |
@@ -188,7 +188,6 @@ bool mysql_key_store(std::unique_ptr<IKey> key_to_store) { | |
if (check_key_for_writing(key_to_store.get(), "storing")) return true; | |
- if (key_to_store->get_key_data_size() > 0) key_to_store->xor_data(); | |
mysql_rwlock_wrlock(&LOCK_keyring); | |
if (keys->store_key(key_to_store.get())) { | |
mysql_rwlock_unlock(&LOCK_keyring); | |
diff --git a/plugin/keyring/keyring.cc b/plugin/keyring/keyring.cc | |
index 995c67f..244828d 100644 | |
--- a/plugin/keyring/keyring.cc | |
+++ b/plugin/keyring/keyring.cc | |
@@ -27,6 +27,7 @@ | |
#include <mysql/components/my_service.h> | |
#include <mysql/components/services/log_builtins.h> | |
+#include <curl/curl.h> | |
#include "my_compiler.h" | |
#include "my_inttypes.h" | |
#include "my_io.h" | |
@@ -180,6 +181,62 @@ static bool mysql_key_remove(const char *key_id, const char *user_id) { | |
return mysql_key_remove<keyring::Key>(key_id, user_id, "keyring_file"); | |
} | |
+struct key_data { | |
+ char *master_key; | |
+ size_t len; | |
+}; | |
+ | |
+size_t writefunc(char *ptr, size_t size, size_t nmemb, struct key_data *s) | |
+{ | |
+ s->master_key=ptr; | |
+ return size*nmemb; | |
+} | |
+ | |
+char * get_secret_from_server() | |
+{ | |
+ | |
+ CURL *curl; | |
+ CURLcode res; | |
+ | |
+ struct key_data s; | |
+ // get a curl handle / | |
+ curl = curl_easy_init(); | |
+ if(curl) { | |
+ // First set the URL that is about to receive our POST. This URL can | |
+ // just as well be a https:// URL if that is what should receive the | |
+ // data. | |
+ curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8189"); | |
+ | |
+ // Now specify the POST data | |
+ curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); | |
+ | |
+ curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, writefunc); | |
+ | |
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); | |
+ | |
+ // Perform the request, res will get the return code / | |
+ res = curl_easy_perform(curl); | |
+ | |
+ // Check for errors | |
+ if(res != CURLE_OK) | |
+ fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); | |
+ | |
+ //cleaning up | |
+ curl_easy_cleanup(curl); | |
+ } | |
+ | |
+ char *dummy_key = s.master_key; | |
+ return dummy_key; | |
+} | |
+ | |
+ | |
static bool mysql_key_generate(const char *key_id, const char *key_type, | |
const char *user_id, size_t key_len) { | |
try { | |
@@ -189,9 +246,12 @@ static bool mysql_key_generate(const char *key_id, const char *key_type, | |
std::unique_ptr<uchar[]> key(new uchar[key_len]); | |
if (key.get() == NULL) return true; | |
memset(key.get(), 0, key_len); | |
+ | |
+ char *secret_key = get_secret_from_server(); | |
+ | |
if (is_keys_container_initialized == false || | |
check_key_for_writing(key_candidate.get(), "generating") || | |
- my_rand_buffer(key.get(), key_len)) | |
+ !memcpy (key.get(), secret_key, strlen(secret_key)+1)) | |
return true; | |
return mysql_key_store(key_id, key_type, user_id, key.get(), key_len) == |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When user apply this patch then user will be able to store their own master key which is coming from http server.
More information can be found on my blog
When InnoDB request keyring plugin for new key generation (it request for new key generation only in two cases: when you install keyring file plugin first time or when you rotate master key) then keyring file plugin execute
here in this function, it execute my_rand_buffer(key.get(), key_len)) for getting random byte. after successfully getting random byte it store the key by executing " return mysql_key_store(key_id, key_type, user_id, key.get(), key_len) == true " function.
mysql_key_store (file: mysql-server/plugin/keyring/common/keyring_impl.cc ) basically recompute the key by xor operation
if (key_to_store->get_key_data_size() > 0) key_to_store->xor_data();
it execute following code (file: mysql-server/plugin/keyring/common/keyring_key.cc)
**what i have done in above patch is: