summaryrefslogtreecommitdiff
path: root/plugin/file_key_management
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2017-04-25 15:44:18 +0200
committerSergei Golubchik <serg@mariadb.org>2017-04-27 19:12:38 +0200
commit7bf409593e624deb00265e21e0d4579ce9fa7999 (patch)
tree7da6af1ff5a92126af5969a9504a82ddcf4cf263 /plugin/file_key_management
parentdb3910741347e7d741f4a854075c248e9081d722 (diff)
downloadmariadb-git-7bf409593e624deb00265e21e0d4579ce9fa7999.tar.gz
MDEV-11660 Make encryption plugins "pure"
Do not exporting mysqld entry points directly. This is needed for mariabackup, to load encryption plugins on Windows. All plugins are "pure" by default. To mark plugin "impure" it should use RECOMPILE_FOR_EMBEDDED or STORAGE_ENGINE keyword.
Diffstat (limited to 'plugin/file_key_management')
-rw-r--r--plugin/file_key_management/file_key_management_plugin.cc18
-rw-r--r--plugin/file_key_management/parser.cc106
-rw-r--r--plugin/file_key_management/parser.h6
3 files changed, 76 insertions, 54 deletions
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc
index 2c3e22c02d2..f6f7083d5f7 100644
--- a/plugin/file_key_management/file_key_management_plugin.cc
+++ b/plugin/file_key_management/file_key_management_plugin.cc
@@ -66,22 +66,14 @@ static struct st_mysql_sys_var* settings[] = {
NULL
};
-Dynamic_array<keyentry> keys(static_cast<uint>(0));
+std::map<unsigned int,keyentry> keys;
static keyentry *get_key(unsigned int key_id)
{
- keyentry *a= keys.front(), *b= keys.back() + 1, *c;
- while (b - a > 1)
- {
- c= a + (b - a)/2;
- if (c->id == key_id)
- return c;
- else if (c->id < key_id)
- a= c;
- else
- b= c;
- }
- return a->id == key_id ? a : 0;
+ keyentry &key= keys[key_id];
+ if (key.id == 0)
+ return 0;
+ return &key;
}
/* the version is always the same, no automatic key rotation */
diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc
index facea9fad25..ac78186a488 100644
--- a/plugin/file_key_management/parser.cc
+++ b/plugin/file_key_management/parser.cc
@@ -143,13 +143,13 @@ void Parser::bytes_to_key(const unsigned char *salt, const char *input,
}
-bool Parser::parse(Dynamic_array<keyentry> *keys)
+bool Parser::parse(std::map<uint,keyentry> *keys)
{
const char *secret= filekey;
char buf[MAX_SECRET_SIZE + 1];
//If secret starts with FILE: interpret the secret as a filename.
- if (is_prefix(filekey, FILE_PREFIX))
+ if (strncmp(filekey, FILE_PREFIX,sizeof(FILE_PREFIX) -1) == 0)
{
if (read_filekey(filekey + sizeof(FILE_PREFIX) - 1, buf))
return 1;
@@ -166,22 +166,26 @@ bool Parser::parse(Dynamic_array<keyentry> *keys)
bool Parser::read_filekey(const char *filekey, char *secret)
{
- int f= my_open(filekey, O_RDONLY, MYF(MY_WME));
+ int f= open(filekey, O_RDONLY|O_BINARY);
if (f == -1)
+ {
+ my_error(EE_FILENOTFOUND,ME_ERROR_LOG, filekey, errno);
return 1;
- int len= my_read(f, (uchar*)secret, MAX_SECRET_SIZE, MYF(MY_WME));
- my_close(f, MYF(MY_WME));
+ }
+
+ int len= read(f, secret, MAX_SECRET_SIZE);
if (len <= 0)
+ {
+ my_error(EE_READ,ME_ERROR_LOG, filekey, errno);
+ close(f);
return 1;
+ }
+ close(f);
while (secret[len - 1] == '\r' || secret[len - 1] == '\n') len--;
secret[len]= '\0';
return 0;
}
-static int sort_keys(const keyentry *k1, const keyentry *k2)
-{
- return k1->id < k2->id ? -1 : k1->id > k2->id;
-}
/**
Get the keys from the key file <filename> and decrypt it with the
@@ -191,7 +195,7 @@ static int sort_keys(const keyentry *k1, const keyentry *k2)
@return 0 when ok, 1 for an error
*/
-bool Parser::parse_file(Dynamic_array<keyentry> *keys, const char *secret)
+bool Parser::parse_file(std::map<uint,keyentry> *keys, const char *secret)
{
char *buffer= read_and_decrypt_file(secret);
@@ -208,19 +212,16 @@ bool Parser::parse_file(Dynamic_array<keyentry> *keys, const char *secret)
case 1: // comment
break;
case -1: // error
- my_free(buffer);
+ free(buffer);
return 1;
case 0:
- if (keys->push(key))
- return 1;
+ (*keys)[key.id] = key;
break;
}
}
- keys->sort(sort_keys);
- my_free(buffer);
-
- if (keys->elements() == 0 || keys->at(0).id != 1)
+ free(buffer);
+ if (keys->size() == 0 || (*keys)[1].id == 0)
{
report_error("System key id 1 is missing", 0);
return 1;
@@ -247,16 +248,25 @@ int Parser::parse_line(char **line_ptr, keyentry *key)
while (isspace(*p) && *p != '\n') p++;
if (*p != '#' && *p != '\n')
{
- int error;
- p+= 100; // the number will surely end here (on a non-digit or with an overflow)
- longlong id= my_strtoll10(p - 100, &p, &error);
- if (error)
+ if (!isdigit(*p))
{
report_error("Syntax error", p - *line_ptr);
return -1;
}
- if (id < 1 || id > UINT_MAX32)
+ longlong id = 0;
+ while (isdigit(*p))
+ {
+ id = id * 10 + *p - '0';
+ if (id > UINT_MAX32)
+ {
+ report_error("Invalid key id", p - *line_ptr);
+ return -1;
+ }
+ p++;
+ }
+
+ if (id < 1)
{
report_error("Invalid key id", p - *line_ptr);
return -1;
@@ -269,7 +279,7 @@ int Parser::parse_line(char **line_ptr, keyentry *key)
}
p++;
- key->id= id;
+ key->id= (unsigned int)id;
key->length=0;
while (isxdigit(p[0]) && isxdigit(p[1]) && key->length < sizeof(key->key))
{
@@ -295,9 +305,13 @@ int Parser::parse_line(char **line_ptr, keyentry *key)
'secret'. Store the content of the decrypted file in 'buffer'. The
buffer has to be freed in the calling function.
*/
+#ifdef _WIN32
+#define lseek _lseeki64
+#endif
char* Parser::read_and_decrypt_file(const char *secret)
{
+ int f;
if (!filename || !filename[0])
{
my_printf_error(EE_CANT_OPEN_STREAM, "file-key-management-filename is not set",
@@ -305,15 +319,21 @@ char* Parser::read_and_decrypt_file(const char *secret)
goto err0;
}
- int f;
- if ((f= my_open(filename, O_RDONLY, MYF(MY_WME))) < 0)
+ f= open(filename, O_RDONLY|O_BINARY, 0);
+ if (f < 0)
+ {
+ my_error(EE_FILENOTFOUND, ME_ERROR_LOG, filename, errno);
goto err0;
+ }
my_off_t file_size;
- file_size= my_seek(f, 0, SEEK_END, MYF(MY_WME));
+ file_size= lseek(f, 0, SEEK_END);
- if (file_size == MY_FILEPOS_ERROR)
+ if (file_size == MY_FILEPOS_ERROR || (my_off_t)lseek(f, 0, SEEK_SET) == MY_FILEPOS_ERROR)
+ {
+ my_error(EE_CANT_SEEK, MYF(0), filename, errno);
goto err1;
+ }
if (file_size > MAX_KEY_FILE_SIZE)
{
@@ -323,29 +343,39 @@ char* Parser::read_and_decrypt_file(const char *secret)
//Read file into buffer
uchar *buffer;
- buffer= (uchar*)my_malloc(file_size + 1, MYF(MY_WME));
+ buffer= (uchar*)malloc((size_t)file_size + 1);
if (!buffer)
+ {
+ my_error(EE_OUTOFMEMORY, ME_ERROR_LOG| ME_FATAL, file_size);
goto err1;
+ }
- if (my_pread(f, buffer, file_size, 0, MYF(MY_WME)) != file_size)
+ if (read(f, buffer, (int)file_size) != (int)file_size)
+ {
+ my_printf_error(EE_READ,
+ "read from %s failed, errno %d",
+ MYF(ME_ERROR_LOG|ME_FATAL), filename, errno);
goto err2;
+ }
// Check for file encryption
uchar *decrypted;
- if (file_size > OpenSSL_prefix_len && is_prefix((char*)buffer, OpenSSL_prefix))
+ if (file_size > OpenSSL_prefix_len && strncmp((char*)buffer, OpenSSL_prefix, OpenSSL_prefix_len) == 0)
{
uchar key[OpenSSL_key_len];
uchar iv[OpenSSL_iv_len];
- decrypted= (uchar*)my_malloc(file_size, MYF(MY_WME));
+ decrypted= (uchar*)malloc((size_t)file_size);
if (!decrypted)
+ {
+ my_error(EE_OUTOFMEMORY, ME_ERROR_LOG | ME_FATAL, file_size);
goto err2;
-
+ }
bytes_to_key(buffer + OpenSSL_prefix_len, secret, key, iv);
uint32 d_size;
if (my_aes_crypt(MY_AES_CBC, ENCRYPTION_FLAG_DECRYPT,
buffer + OpenSSL_prefix_len + OpenSSL_salt_len,
- file_size - OpenSSL_prefix_len - OpenSSL_salt_len,
+ (unsigned int)file_size - OpenSSL_prefix_len - OpenSSL_salt_len,
decrypted, &d_size, key, OpenSSL_key_len,
iv, OpenSSL_iv_len))
@@ -354,7 +384,7 @@ char* Parser::read_and_decrypt_file(const char *secret)
goto err3;
}
- my_free(buffer);
+ free(buffer);
buffer= decrypted;
file_size= d_size;
}
@@ -365,15 +395,15 @@ char* Parser::read_and_decrypt_file(const char *secret)
}
buffer[file_size]= '\0';
- my_close(f, MYF(MY_WME));
+ close(f);
return (char*) buffer;
err3:
- my_free(decrypted);
+ free(decrypted);
err2:
- my_free(buffer);
+ free(buffer);
err1:
- my_close(f, MYF(MY_WME));
+ close(f);
err0:
return NULL;
}
diff --git a/plugin/file_key_management/parser.h b/plugin/file_key_management/parser.h
index c8349db70a0..627b7fd84a6 100644
--- a/plugin/file_key_management/parser.h
+++ b/plugin/file_key_management/parser.h
@@ -22,7 +22,7 @@ Created 09/15/2014
#include <my_crypt.h>
#include <ctype.h>
-#include <sql_array.h>
+#include <map>
struct keyentry {
unsigned int id;
@@ -42,7 +42,7 @@ class Parser
void bytes_to_key(const unsigned char *salt, const char *secret,
unsigned char *key, unsigned char *iv);
bool read_filekey(const char *filekey, char *secret);
- bool parse_file(Dynamic_array<keyentry> *keys, const char *secret);
+ bool parse_file(std::map<unsigned int ,keyentry> *keys, const char *secret);
void report_error(const char *reason, unsigned int position);
int parse_line(char **line_ptr, keyentry *key);
char* read_and_decrypt_file(const char *secret);
@@ -50,5 +50,5 @@ class Parser
public:
Parser(const char* fn, const char *fk) :
filename(fn), filekey(fk), line_number(0) { }
- bool parse(Dynamic_array<keyentry> *keys);
+ bool parse(std::map<unsigned int ,keyentry> *keys);
};