summaryrefslogtreecommitdiff
path: root/plugin/file_key_management_plugin/EncKeys.cc
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2014-12-20 15:44:23 +0200
committerMichael Widenius <monty@mariadb.org>2014-12-20 15:44:23 +0200
commit406b31e628145f6af0fa567c0e42b8391e5173bb (patch)
treeaff311e03c5bb078fe67b090bd8a0e602beed547 /plugin/file_key_management_plugin/EncKeys.cc
parent634428b37fd039b862c8277a0c7b0b5f56e765fc (diff)
downloadmariadb-git-bb-10.1-eperi.tar.gz
Fixes for encryption from eperibb-10.1-eperi
Diffstat (limited to 'plugin/file_key_management_plugin/EncKeys.cc')
-rw-r--r--plugin/file_key_management_plugin/EncKeys.cc137
1 files changed, 60 insertions, 77 deletions
diff --git a/plugin/file_key_management_plugin/EncKeys.cc b/plugin/file_key_management_plugin/EncKeys.cc
index cabdf7911a0..c43d261926a 100644
--- a/plugin/file_key_management_plugin/EncKeys.cc
+++ b/plugin/file_key_management_plugin/EncKeys.cc
@@ -23,37 +23,43 @@ Example
[mysqld]
...
-innodb_data_encryption_providertype = 1
-innodb_data_encryption_providername = keys.enc
-innodb_data_encryption_providerurl = /home/mdb/
-innodb_data_encryption_filekey = secret
+file_key_management_plugin_filename = /home/mdb/keys.enc
+file_key_management_plugin_filekey = secret
+file_key_management_plugin_encryption_method = aes_cbc
+
...
+Optional configuration value file_key_management_plugin_encryption_method determines the method used for encryption.
+Supported are aes_cbc, aes_ecb or aes_ctr. aes_cbc is default.
+The plug-in sets the default aes encryption/decryption method to the given method.
+
+The keys are read from a file.
+The filename is set up via the file_key_management_plugin_filename configuration value.
+file_key_management_plugin_filename is used to configure the absolute path to this file.
-As provider type currently only value 1 is supported, which means, the keys are read from a file.
-The filename is set up via the innodb_data_encryption_providername configuration value.
-innodb_data_encryption_providerurl is used to configure the path to this file. This is usually
-a folder name.
Examples:
-innodb_data_encryption_providerurl = \\\\unc (windows share)
-innodb_data_encryption_providerurl = e:/tmp/ (windows path)
-innodb_data_encryption_providerurl = /tmp (linux path)
+file_key_management_plugin_filename = \\\\unc\\keys.enc (windows share)
+file_key_management_plugin_filename = e:/tmp/keys.enc (windows path)
+file_key_management_plugin_filename = /tmp/keys.enc (linux path)
The key file contains AES keys and initialization vectors as hex-encoded Strings.
Supported are keys of size 128, 192 or 256 bits. IV consists of 16 bytes.
+Example:
+1;F5502320F8429037B8DAEF761B189D12;770A8A65DA156D24EE2A093277530142
+
+1 is the key identifier which can be used for table creation, a 16 byte IV follows, and finally a 16 byte AES key.
+255 entries are supported.
The key file should be encrypted and the key to decrypt the file can be given with the
-innodb_data_encryption_filekey parameter.
+optional file_key_management_plugin_filekey parameter.
The file key can also be located if FILE: is prepended to the key. Then the following part is interpreted
-as absolut to the file containing the file key. This file can optionally be encrypted, currently with a fix key.
+as absolute path to the file containing the file key. This file can optionally be encrypted, currently with a fix key.
Example:
-innodb_data_encryption_filekey = FILE:y:/secret256.enc
+file_key_management_plugin_filekey = FILE:y:/secret256.enc
If the key file can not be read at server startup, for example if the file key is not present,
page_encryption feature is not availabe and access to page_encryption tables is not possible.
-Example files can be found inside the unittest/eperi folder.
-
Open SSL command line utility can be used to create an encrypted key file.
Examples:
openssl enc –aes-256-cbc –md sha1 –k secret –in keys.txt –out keys.enc
@@ -67,6 +73,7 @@ openssl enc –aes-256-cbc –md sha1 –k <initialPwd> –in secret –out secr
#include "EncKeys.h"
#include <my_global.h>
+
#include <my_aes.h>
#include <memory.h>
#include <my_sys.h>
@@ -119,59 +126,34 @@ EncKeys::~EncKeys() {
}
}
-bool EncKeys::initKeys(const char *name, const char *url, const int initType, const char *filekey) {
- if (KEYINITTYPE_FILE == initType)
- {
- int result = initKeysThroughFile(name, url, filekey);
- return ERROR_FALSE_FILE_KEY != result && ERROR_OPEN_FILE != result && ERROR_READING_FILE != result;
- }
- else if (KEYINITTYPE_SERVER == initType)
- {
- return NO_ERROR_KEY_FILE_PARSE_OK == initKeysThroughServer(name, url, filekey);
- }
- return false;
-}
+bool EncKeys::initKeys(const char *filename, const char *filekey) {
+ if (filename==NULL)
+ return ERROR_OPEN_FILE;
-int EncKeys::initKeysThroughFile(const char *name, const char *path, const char *filekey) {
- if (path==NULL || name==NULL) return ERROR_OPEN_FILE;
- size_t len1 = strlen(path);
- size_t len2 = strlen(name);
const char *MAGIC = "FILE:";
const short MAGIC_LEN = 5;
- int ret = NO_ERROR_KEY_FILE_PARSE_OK;
- bool isUncPath= (len1>2) ? ((strncmp("\\\\", path, 2)==0) ? TRUE : FALSE) : FALSE;
- bool isSlash = ((isUncPath? '\\':'/') == path[len1 - 1]);
- char *secret = (char*) malloc(MAX_SECRET_SIZE +1 * sizeof(char));
- char *filename = (char*) malloc((len1 + len2 + (isSlash ? 1 : 2)) * sizeof(char));
- if(filekey != NULL)
+
+ char *secret = (char*) malloc(MAX_SECRET_SIZE +1 * sizeof(char));
+
+ if(filekey != NULL)
+ {
+ //If secret starts with FILE: interpret the secret as filename.
+ if(memcmp(MAGIC, filekey, MAGIC_LEN) == 0) {
+ int fk_len = strlen(filekey);
+ char *secretfile = (char*)malloc( (1 + fk_len - MAGIC_LEN)* sizeof(char));
+ memcpy(secretfile, filekey+MAGIC_LEN, fk_len - MAGIC_LEN);
+ secretfile[fk_len-MAGIC_LEN] = '\0';
+ parseSecret(secretfile, secret);
+ free(secretfile);
+ } else
{
- //If secret starts with FILE: interpret the secret as filename.
- if(memcmp(MAGIC, filekey, MAGIC_LEN) == 0) {
- int fk_len = strlen(filekey);
- char *secretfile = (char*)malloc( (1 + fk_len - MAGIC_LEN)* sizeof(char));
- memcpy(secretfile, filekey+MAGIC_LEN, fk_len - MAGIC_LEN);
- secretfile[fk_len-MAGIC_LEN] = '\0';
- parseSecret(secretfile, secret);
- free(secretfile);
- } else
- {
- sprintf(secret, "%s", filekey);
- }
+ sprintf(secret, "%s", filekey);
}
- sprintf(filename, "%s%s%s", path, isSlash ? "" : (isUncPath ? "\\":"/"), name);
- ret = parseFile((const char *)filename, 254, secret);
- free(filename);
- free(secret);
- return ret;
-}
+ }
-int EncKeys::initKeysThroughServer( const char *name, const char *path, const char *filekey)
-{
- //TODO
-#ifdef UNIV_DEBUG
- fprintf(stderr, errorNotImplemented);
-#endif //UNIV_DEBUG
- return ERROR_KEYINITTYPE_SERVER_NOT_IMPLEMENTED;
+ int ret = parseFile((const char *)filename, 254, secret);
+ free(secret);
+ return (ret==NO_ERROR_KEY_FILE_PARSE_OK);
}
/*
@@ -181,7 +163,6 @@ void EncKeys::parseSecret( const char *secretfile, char *secret ) {
int maxSize = (MAX_SECRET_SIZE +16 + magicSize*2) ;
char* buf = (char*)malloc((maxSize) * sizeof(char));
char* _initPwd = (char*)malloc((strlen(initialPwd)+1) * sizeof(char));
-
FILE *fp = fopen(secretfile, "rb");
fseek(fp, 0L, SEEK_END);
long file_size = ftell(fp);
@@ -201,8 +182,9 @@ void EncKeys::parseSecret( const char *secretfile, char *secret ) {
_initPwd[strlen(initialPwd)]= '\0';
my_bytes_to_key((unsigned char *) salt, _initPwd, key, iv);
uint32 d_size = 0;
- int res = my_aes_decrypt_cbc((const char*)buf + 2 * magicSize, bytes_to_read - 2 * magicSize,
- secret, &d_size, key, keySize32, iv, ivSize16, 0);
+ my_aes_decrypt_dynamic_type func = get_aes_decrypt_func(MY_AES_ALGORITHM_CBC);
+ int res = (* func)((const uchar*)buf + 2 * magicSize, bytes_to_read - 2 * magicSize,
+ (uchar*)secret, &d_size, (const uchar*)key, keySize32, iv, ivSize16, 0);
if (d_size>EncKeys::MAX_SECRET_SIZE) {
d_size = EncKeys::MAX_SECRET_SIZE;
}
@@ -237,10 +219,10 @@ keyentry *EncKeys::getKeys(int id) {
* Store the keys with id smaller then <maxKeyId> in an array of structs keyentry.
* Returns NO_ERROR_PARSE_OK or an appropriate error code.
*/
-int EncKeys::parseFile(const char* filename, const ulint maxKeyId, const char *secret) {
+int EncKeys::parseFile(const char* filename, const uint32 maxKeyId, const char *secret) {
int errorCode = 0;
char *buffer = decryptFile(filename, secret, &errorCode);
- ulint id = 0;
+ uint32 id = 0;
if (NO_ERROR_PARSE_OK != errorCode) return errorCode;
else errorCode = NO_ERROR_KEY_FILE_PARSE_OK;
@@ -258,17 +240,17 @@ int EncKeys::parseFile(const char* filename, const ulint maxKeyId, const char *s
break;
case ERROR_ID_TOO_BIG:
fprintf(stderr, errorExceedKeySize, KEY_MAX, keyLineInKeyFile);
- fprintf(stderr, " --> %s\n", line);
+ fprintf(stderr, " ---> %s\n", line);
errorCode = ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS;
break;
case ERROR_NOINITIALIZEDKEY:
fprintf(stderr, errorNoInitializedKey);
- fprintf(stderr, " --> %s\n", line);
+ fprintf(stderr, " ----> %s\n", line);
errorCode = ERROR_KEY_FILE_PARSE_NULL;
break;
case ERROR_WRONG_NUMBER_OF_MATCHES:
fprintf(stderr, errorInMatches, keyLineInKeyFile);
- fprintf(stderr, " --> %s\n", line);
+ fprintf(stderr, " -----> %s\n", line);
errorCode = ERROR_KEY_FILE_PARSE_NULL;
break;
case NO_ERROR_KEY_GREATER_THAN_ASKED:
@@ -287,7 +269,7 @@ int EncKeys::parseFile(const char* filename, const ulint maxKeyId, const char *s
return errorCode;
}
-int EncKeys::parseLine(const char *line, const ulint maxKeyId) {
+int EncKeys::parseLine(const char *line, const uint32 maxKeyId) {
int ret = NO_ERROR_PARSE_OK;
if (isComment(line))
ret = NO_ERROR_ISCOMMENT;
@@ -314,7 +296,7 @@ int EncKeys::parseLine(const char *line, const ulint maxKeyId) {
else {
char buffer[4];
sprintf(buffer, "%.*s", substr_length, substring_start);
- ulint id = atoi(buffer);
+ uint32 id = atoi(buffer);
if (0 == id) ret = ERROR_NOINITIALIZEDKEY;
else if (KEY_MAX < id) ret = ERROR_ID_TOO_BIG;
else if (maxKeyId < id) ret = NO_ERROR_KEY_GREATER_THAN_ASKED;
@@ -381,12 +363,13 @@ char* EncKeys::decryptFile(const char* filename, const char *secret, int *errorC
unsigned char salt[magicSize];
unsigned char *key = new unsigned char[keySize32];
unsigned char *iv = new unsigned char[ivSize16];
- char *decrypted = new char[file_size];
+ uchar *decrypted = new uchar[file_size];
memcpy(&salt, buffer + magicSize, magicSize);
my_bytes_to_key((unsigned char *) salt, secret, key, iv);
uint32 d_size = 0;
- int res = my_aes_decrypt_cbc((const char*)buffer + 2 * magicSize, file_size - 2 * magicSize,
- decrypted, &d_size, key, keySize32, iv, ivSize16, 0);
+ my_aes_decrypt_dynamic_type func = get_aes_decrypt_func(MY_AES_ALGORITHM_CBC);
+ int res = (* func)((const uchar*)buffer + 2 * magicSize, file_size - 2 * magicSize,
+ decrypted, &d_size, (const uchar*) key, keySize32, iv, ivSize16, 0);
if(0 != res) {
*errorCode = ERROR_FALSE_FILE_KEY;
delete[] buffer; buffer = NULL;
@@ -415,7 +398,7 @@ bool EncKeys::isComment(const char *line) {
}
-void EncKeys::printKeyEntry( ulint id)
+void EncKeys::printKeyEntry( uint32 id)
{
#ifdef UNIV_DEBUG
keyentry *entry = getKeys(id);