Skip to content

Commit 4b4dd7a

Browse files
author
Bharathy Satish
committed
WL#9769: Keyring migration tool and new commercial keyring_encrypted_file plugin.
New Keyring plugin called keyring_encrypted_file plugin is introduced which will store keyring data in file local to server host which is encrypted using a password. This plugin when installed must be provided with a password which will be used to decrypt the file to read the contents of file. Similarly this password will be used to encrypt the data which needs to be stored in the data file. This WL also introduces keyring migration tool which is used to migrate keys from one keyring plugin to another. This tool is embedded in mysql server, this when mysqld is invoked with migration specific options, mysql server will ast like a migration tool.
1 parent b9ac987 commit 4b4dd7a

35 files changed

+1456
-78
lines changed

include/mysql/plugin_keyring.h

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
2121
*/
2222

2323
#include "plugin.h"
24-
#define MYSQL_KEYRING_INTERFACE_VERSION 0x0100
24+
#define MYSQL_KEYRING_INTERFACE_VERSION 0x0101
2525

2626
/**
2727
The descriptor structure for the plugin, that is referred from
@@ -105,5 +105,80 @@ struct st_mysql_keyring
105105
*/
106106
my_bool (*mysql_key_generate)(const char *key_id, const char *key_type,
107107
const char *user_id, size_t key_len);
108+
109+
/**
110+
Keys_iterator object refers to an iterator which is used to iterate
111+
on a list which refers to Key_metadata. Key_metadata hold information
112+
about individual keys keyd_id and user_id. Keys_iterator should be used
113+
in following sequence only.
114+
115+
void* iterator_ptr;
116+
char key_id[64]= { 0 };
117+
char user_id[64]= { 0 };
118+
119+
plugin_handle->mysql_key_iterator_init(&iterator_ptr);
120+
121+
if (iterator_ptr == NULL)
122+
report error;
123+
124+
while (!(plugin_handle->mysql_key_iterator_get_key(iterator_ptr,
125+
key_id, user_id)))
126+
{
127+
Fetch the keys.
128+
Perform operations on the fetched keys.
129+
..
130+
}
131+
plugin_handle->mysql_key_iterator_deinit(iterator_ptr);
132+
133+
init() method accepts a void pointer which is the made to point to
134+
Keys_iterator instance. Keys_iterator instance internal pointer points
135+
to Key_metadata list. This list holds information about all keys stored
136+
in the backed end data store of keyring plugin. After call to init()
137+
please check iterator_ptr.
138+
139+
get_key() method accepts the above iterator_ptr as IN param and then
140+
fills the passes in key_id and user_id with valid values. This can be
141+
used to fetch actual key information. Every call to this method will
142+
change internal pointers to advance to next position, so that the next
143+
call will fetch the next key.
144+
145+
deinit() method frees all internal pointers along with iterator_ptr.
146+
*/
147+
/**
148+
Initialize an iterator.
149+
150+
@param[out] key_iterator Iterator used to fetch individual keys
151+
from key_container.
152+
153+
@return VOID
154+
*/
155+
void (*mysql_key_iterator_init)(void** key_iterator);
156+
157+
/**
158+
Deinitialize an iterator.
159+
160+
@param[in] key_iterator Iterator used to fetch individual keys
161+
from key_container.
162+
163+
@return VOID
164+
*/
165+
void (*mysql_key_iterator_deinit)(void* key_iterator);
166+
167+
/**
168+
Get details of key. Every call to this service will change
169+
internal pointers to advance to next position, so that the next call
170+
will fetch the next key. In case iterator moves to the end, this service
171+
will return error.
172+
173+
@param[in] key_iterator Iterator used to fetch individual keys
174+
from key_container.
175+
@param[out] key_id id of the key
176+
@param[out] user_id id of the owner
177+
178+
@return Operation status
179+
@retval 0 OK
180+
@retval 1 ERROR
181+
*/
182+
bool (*mysql_key_iterator_get_key)(void* key_iterator, char *key_id, char *user_id);
108183
};
109184
#endif

include/mysql/plugin_keyring.h.pp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,7 @@
121121
my_bool (*mysql_key_remove)(const char *key_id, const char *user_id);
122122
my_bool (*mysql_key_generate)(const char *key_id, const char *key_type,
123123
const char *user_id, size_t key_len);
124+
void (*mysql_key_iterator_init)(void** key_iterator);
125+
void (*mysql_key_iterator_deinit)(void* key_iterator);
126+
bool (*mysql_key_iterator_get_key)(void* key_iterator, char *key_id, char *user_id);
124127
};

libmysql/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,13 @@ SET(CLIENT_API_FUNCTIONS_UNDOCUMENTED
178178
)
179179

180180
SET(CLIENT_SOURCES
181-
get_password.c
182181
libmysql.c
183182
errmsg.c
184183
../sql-common/client.c
185184
../sql-common/my_time.c
186185
../sql-common/client_plugin.c
187186
../sql-common/client_authentication.cc
187+
../sql-common/get_password.c
188188
../sql/net_serv.cc
189189
../sql-common/pack.c
190190
../sql/auth/password.c
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--echo # now master key is migrated
2+
--echo # access to this table should pass
3+
SELECT * FROM T;
4+
5+
let $wl9769_destination_key1 = `SELECT hex(keyring_key_fetch('$key_name1'))`;
6+
let $wl9769_destination_key2 = `SELECT hex(keyring_key_fetch('$key_name2'))`;
7+
let $wl9769_destination_key3 = `SELECT hex(keyring_key_fetch('$key_name3'))`;
8+
9+
let $wl9769_destination_key1_type = `SELECT keyring_key_type_fetch('$key_name1')`;
10+
let $wl9769_destination_key2_type = `SELECT keyring_key_type_fetch('$key_name2')`;
11+
let $wl9769_destination_key3_type = `SELECT keyring_key_type_fetch('$key_name3')`;
12+
13+
let $wl9769_destination_key1_len = `SELECT keyring_key_length_fetch('$key_name1')`;
14+
let $wl9769_destination_key2_len = `SELECT keyring_key_length_fetch('$key_name2')`;
15+
let $wl9769_destination_key3_len = `SELECT keyring_key_length_fetch('$key_name3')`;
16+
17+
--echo check if migration took place correctly
18+
--replace_result $wl9769_destination_key1 <wl9769_destination_key1> $wl9769_source_key1 <wl9769_source_key1>
19+
eval SELECT '$wl9769_destination_key1' = '$wl9769_source_key1';
20+
--replace_result $wl9769_destination_key2 <wl9769_destination_key2> $wl9769_source_key2 <wl9769_source_key2>
21+
eval SELECT '$wl9769_destination_key2' = '$wl9769_source_key2';
22+
--replace_result $wl9769_destination_key3 <wl9769_destination_key3> $wl9769_source_key3 <wl9769_source_key3>
23+
eval SELECT '$wl9769_destination_key3' = '$wl9769_source_key3';
24+
25+
eval SELECT '$wl9769_destination_key1_type' = '$wl9769_source_key1_type';
26+
eval SELECT '$wl9769_destination_key2_type' = '$wl9769_source_key2_type';
27+
eval SELECT '$wl9769_destination_key3_type' = '$wl9769_source_key3_type';
28+
29+
eval SELECT '$wl9769_destination_key1_len' = '$wl9769_source_key1_len';
30+
eval SELECT '$wl9769_destination_key2_len' = '$wl9769_source_key2_len';
31+
eval SELECT '$wl9769_destination_key3_len' = '$wl9769_source_key3_len';
32+
33+
--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*.[0-9]*/key1_timestamp/
34+
eval SELECT keyring_key_remove('$key_name1');
35+
--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*.[0-9]*/key2_timestamp/
36+
eval SELECT keyring_key_remove('$key_name2');
37+
--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*.[0-9]*/key3_timestamp/
38+
eval SELECT keyring_key_remove('$key_name3');
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
--echo # create encrypted table with master key generated from source keyring plugin
3+
CREATE TABLE T(i INT) ENCRYPTION='Y';
4+
INSERT INTO T VALUES (9769);
5+
SELECT * FROM T;
6+
7+
--replace_regex /\.dll/.so/
8+
eval INSTALL PLUGIN keyring_udf SONAME '$KEYRING_UDF';
9+
--replace_regex /\.dll/.so/
10+
eval CREATE FUNCTION keyring_key_generate RETURNS INTEGER SONAME '$KEYRING_UDF';
11+
--replace_regex /\.dll/.so/
12+
eval CREATE FUNCTION keyring_key_store RETURNS INTEGER SONAME '$KEYRING_UDF';
13+
--replace_regex /\.dll/.so/
14+
eval CREATE FUNCTION keyring_key_fetch RETURNS STRING SONAME '$KEYRING_UDF';
15+
--replace_regex /\.dll/.so/
16+
eval CREATE FUNCTION keyring_key_type_fetch RETURNS STRING SONAME '$KEYRING_UDF';
17+
--replace_regex /\.dll/.so/
18+
eval CREATE FUNCTION keyring_key_length_fetch RETURNS INTEGER SONAME '$KEYRING_UDF';
19+
--replace_regex /\.dll/.so/
20+
eval CREATE FUNCTION keyring_key_remove RETURNS INTEGER SONAME '$KEYRING_UDF';
21+
22+
--let $key_name1=`select concat("key_", current_timestamp(6))`
23+
--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*.[0-9]*/key1_timestamp/
24+
--eval SELECT keyring_key_generate('$key_name1','AES',16)
25+
--let $key_name2=`select concat("key_", current_timestamp(6))`
26+
--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*.[0-9]*/key2_timestamp/
27+
--eval SELECT keyring_key_generate('$key_name2','AES',24)
28+
--let $key_name3=`select concat("key_", current_timestamp(6))`
29+
--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*.[0-9]*/key3_timestamp/
30+
--eval SELECT keyring_key_generate('$key_name3','AES',32)
31+
32+
let $wl9769_source_key1 = `SELECT hex(keyring_key_fetch('$key_name1'))`;
33+
let $wl9769_source_key2 = `SELECT hex(keyring_key_fetch('$key_name2'))`;
34+
let $wl9769_source_key3 = `SELECT hex(keyring_key_fetch('$key_name3'))`;
35+
36+
let $wl9769_source_key1_type = `SELECT keyring_key_type_fetch('$key_name1')`;
37+
let $wl9769_source_key2_type = `SELECT keyring_key_type_fetch('$key_name2')`;
38+
let $wl9769_source_key3_type = `SELECT keyring_key_type_fetch('$key_name3')`;
39+
40+
let $wl9769_source_key1_len = `SELECT keyring_key_length_fetch('$key_name1')`;
41+
let $wl9769_source_key2_len = `SELECT keyring_key_length_fetch('$key_name2')`;
42+
let $wl9769_source_key3_len = `SELECT keyring_key_length_fetch('$key_name3')`;

mysql-test/r/mysqld--help-notwin.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,26 @@ The following options may be given as the first argument:
361361
The default size of key cache blocks
362362
--key-cache-division-limit=#
363363
The minimum percentage of warm blocks in key cache
364+
--keyring-migration-destination=name
365+
Keyring plugin to which the keys are migrated to. This
366+
option must be specified along with
367+
--keyring-migration-source.
368+
--keyring-migration-host=name
369+
Connect to host.
370+
--keyring-migration-password[=name]
371+
Password to use when connecting to server during keyring
372+
migration. If password value is not specified then it
373+
will be asked from the tty.
374+
--keyring-migration-port=#
375+
Port number to use for connection.
376+
--keyring-migration-socket=name
377+
The socket file to use for connection.
378+
--keyring-migration-source=name
379+
Keyring plugin from where the keys needs to be migrated
380+
to. This option must be specified along with
381+
--keyring-migration-destination.
382+
--keyring-migration-user=name
383+
User to login to server.
364384
-L, --language=name Client error messages in given language. May be given as
365385
a full path. Deprecated. Use --lc-messages-dir instead.
366386
--large-pages Enable support for large pages
@@ -1335,6 +1355,12 @@ key-buffer-size 8388608
13351355
key-cache-age-threshold 300
13361356
key-cache-block-size 1024
13371357
key-cache-division-limit 100
1358+
keyring-migration-destination (No default value)
1359+
keyring-migration-host (No default value)
1360+
keyring-migration-port 0
1361+
keyring-migration-socket (No default value)
1362+
keyring-migration-source (No default value)
1363+
keyring-migration-user (No default value)
13381364
language MYSQL_SHAREDIR/
13391365
large-pages FALSE
13401366
lc-messages en_US

mysql-test/r/mysqld--help-win.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,26 @@ The following options may be given as the first argument:
360360
The default size of key cache blocks
361361
--key-cache-division-limit=#
362362
The minimum percentage of warm blocks in key cache
363+
--keyring-migration-destination=name
364+
Keyring plugin to which the keys are migrated to. This
365+
option must be specified along with
366+
--keyring-migration-source.
367+
--keyring-migration-host=name
368+
Connect to host.
369+
--keyring-migration-password[=name]
370+
Password to use when connecting to server during keyring
371+
migration. If password value is not specified then it
372+
will be asked from the tty.
373+
--keyring-migration-port=#
374+
Port number to use for connection.
375+
--keyring-migration-socket=name
376+
The socket file to use for connection.
377+
--keyring-migration-source=name
378+
Keyring plugin from where the keys needs to be migrated
379+
to. This option must be specified along with
380+
--keyring-migration-destination.
381+
--keyring-migration-user=name
382+
User to login to server.
363383
-L, --language=name Client error messages in given language. May be given as
364384
a full path. Deprecated. Use --lc-messages-dir instead.
365385
--lc-messages=name Set the language used for the error messages.
@@ -1333,6 +1353,12 @@ key-buffer-size 8388608
13331353
key-cache-age-threshold 300
13341354
key-cache-block-size 1024
13351355
key-cache-division-limit 100
1356+
keyring-migration-destination (No default value)
1357+
keyring-migration-host (No default value)
1358+
keyring-migration-port 0
1359+
keyring-migration-socket (No default value)
1360+
keyring-migration-source (No default value)
1361+
keyring-migration-user (No default value)
13361362
language MYSQL_SHAREDIR/
13371363
lc-messages en_US
13381364
lc-messages-dir MYSQL_SHAREDIR/

mysql-test/suite/perfschema/r/show_sanity.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ SHOW_MODE SOURCE VARIABLE_NAME
410410
5.6 I_S.SESSION_VARIABLES GTID_EXECUTED
411411
5.6 I_S.SESSION_VARIABLES INNODB_DEADLOCK_DETECT
412412
5.6 I_S.SESSION_VARIABLES INNODB_STATS_INCLUDE_DELETE_MARKED
413+
5.6 I_S.SESSION_VARIABLES KEYRING_OPERATIONS
413414
5.6 I_S.SESSION_VARIABLES LOG_STATEMENTS_UNSAFE_FOR_BINLOG
414415
5.6 I_S.SESSION_VARIABLES TLS_VERSION
415416

@@ -435,6 +436,7 @@ SHOW_MODE SOURCE VARIABLE_NAME
435436
5.6 I_S.SESSION_VARIABLES GTID_EXECUTED
436437
5.6 I_S.SESSION_VARIABLES INNODB_DEADLOCK_DETECT
437438
5.6 I_S.SESSION_VARIABLES INNODB_STATS_INCLUDE_DELETE_MARKED
439+
5.6 I_S.SESSION_VARIABLES KEYRING_OPERATIONS
438440
5.6 I_S.SESSION_VARIABLES LOG_STATEMENTS_UNSAFE_FOR_BINLOG
439441
5.6 I_S.SESSION_VARIABLES TLS_VERSION
440442

mysql-test/suite/sys_vars/r/all_vars.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ left join t1 on variable_name=test_name where test_name is null ORDER BY variabl
1515
There should be *no* variables listed below:
1616
DISABLED_STORAGE_ENGINES
1717
DISABLED_STORAGE_ENGINES
18+
KEYRING_OPERATIONS
19+
KEYRING_OPERATIONS
1820
TLS_VERSION
1921
TLS_VERSION
2022
drop table t1;

packaging/deb-in/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ debian/extra/authentication_ldap_sasl-plugin
6565
debian/extra/authentication_ldap_simple-plugin
6666
debian/extra/firewall-plugin
6767
debian/extra/keyring_okv-plugin
68+
debian/extra/keyring_encrypted_file-plugin
6869
debian/extra/openssl_udf-plugin
6970
debian/extra/thread_pool-plugin
7071
")
@@ -75,6 +76,7 @@ usr/lib/mysql/plugin/authentication_pam.so
7576
usr/lib/mysql/plugin/authentication_ldap_sasl.so
7677
usr/lib/mysql/plugin/authentication_ldap_simple.so
7778
usr/lib/mysql/plugin/keyring_okv.so
79+
usr/lib/mysql/plugin/keyring_encrypted_file.so
7880
usr/lib/mysql/plugin/openssl_udf.so
7981
usr/lib/mysql/plugin/thread_pool.so
8082
usr/lib/mysql/plugin/firewall.so
@@ -87,6 +89,7 @@ usr/lib/mysql/plugin/debug/authentication_pam.so
8789
usr/lib/mysql/plugin/debug/authentication_ldap_sasl.so
8890
usr/lib/mysql/plugin/debug/authentication_ldap_simple.so
8991
usr/lib/mysql/plugin/debug/keyring_okv.so
92+
usr/lib/mysql/plugin/debug/keyring_encrypted_file.so
9093
usr/lib/mysql/plugin/debug/openssl_udf.so
9194
usr/lib/mysql/plugin/debug/thread_pool.so
9295
usr/lib/mysql/plugin/debug/firewall.so

packaging/rpm-oel/mysql.spec.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ fi
10161016
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_sasl.so
10171017
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_simple.so
10181018
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_okv.so
1019+
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_encrypted_file.so
10191020
%attr(755, root, root) %{_libdir}/mysql/plugin/thread_pool.so
10201021
%attr(755, root, root) %{_libdir}/mysql/plugin/openssl_udf.so
10211022
%attr(755, root, root) %{_libdir}/mysql/plugin/firewall.so
@@ -1025,6 +1026,7 @@ fi
10251026
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_sasl.so
10261027
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_simple.so
10271028
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_okv.so
1029+
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_encrypted_file.so
10281030
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/thread_pool.so
10291031
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/openssl_udf.so
10301032
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/firewall.so
@@ -1360,6 +1362,9 @@ fi
13601362
%endif # cluster
13611363

13621364
%changelog
1365+
* Wed Nov 08 2017 Bharathy Satish <bharathy.x.satish. - 5.7.21-1
1366+
- Add keyring_encrypted_file.so plugin
1367+
13631368
* Tue Oct 31 2017 Bjorn Munch <[email protected]> - 5.7.21-1
13641369
- Remove obsoleted mysqltest man pages
13651370

packaging/rpm-sles/mysql.spec.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ fi
838838
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_sasl.so
839839
%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_ldap_simple.so
840840
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_okv.so
841+
%attr(755, root, root) %{_libdir}/mysql/plugin/keyring_encrypted_file.so
841842
%attr(755, root, root) %{_libdir}/mysql/plugin/thread_pool.so
842843
%attr(755, root, root) %{_libdir}/mysql/plugin/openssl_udf.so
843844
%attr(755, root, root) %{_libdir}/mysql/plugin/firewall.so
@@ -847,6 +848,7 @@ fi
847848
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_sasl.so
848849
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_ldap_simple.so
849850
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_okv.so
851+
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/keyring_encrypted_file.so
850852
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/thread_pool.so
851853
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/openssl_udf.so
852854
%attr(755, root, root) %{_libdir}/mysql/plugin/debug/firewall.so
@@ -1165,6 +1167,9 @@ fi
11651167
%endif # cluster
11661168

11671169
%changelog
1170+
* Wed 08 2017 Bharathy Satish <[email protected]> - 5.7.21-1
1171+
- Add keyring_encrypted_file.so plugin
1172+
11681173
* Tue Oct 31 2017 Bjorn Munch <[email protected]> - 5.7.21-1
11691174
- Remove obsoleted mysqltest man pages
11701175

plugin/keyring/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SET(
2222
KEYRING_FILE_SOURCES
2323
common/keyring_key.cc
2424
common/keys_container.cc
25+
common/keys_iterator.cc
2526
common/keyring_impl.cc
2627
keyring.cc
2728
hash_to_buffer_serializer.cc

0 commit comments

Comments
 (0)