Browse Source
Cleanup to be able to compile with YASSL.
Cleanup to be able to compile with YASSL.
Temporary push as some tests still fails.replace/d7d589dc01f6d70d1518b74d46fd3b75e76267f5
committed by
Sergei Golubchik
9 changed files with 1175 additions and 0 deletions
-
370mysys_ssl/my_crypt.cc
-
85mysys_ssl/my_crypt_key_management.cc
-
13mysys_ssl/my_crypt_key_management_impl.cc
-
3plugin/file_key_management_plugin/CMakeLists.txt
-
429plugin/file_key_management_plugin/EncKeys.cc
-
88plugin/file_key_management_plugin/EncKeys.h
-
65plugin/file_key_management_plugin/KeySingleton.cc
-
59plugin/file_key_management_plugin/KeySingleton.h
-
63plugin/file_key_management_plugin/file_key_management_plugin.cc
@ -0,0 +1,370 @@ |
|||
/*
|
|||
TODO: add support for YASSL |
|||
*/ |
|||
|
|||
#include <my_global.h>
|
|||
#include <my_crypt.h>
|
|||
|
|||
/* YASSL doesn't support EVP_CIPHER_CTX */ |
|||
#ifdef HAVE_EncryptAes128Ctr
|
|||
|
|||
#include "mysql.h"
|
|||
#include <openssl/evp.h>
|
|||
#include <openssl/aes.h>
|
|||
#include <openssl/rand.h>
|
|||
|
|||
static const int CRYPT_ENCRYPT = 1; |
|||
static const int CRYPT_DECRYPT = 0; |
|||
|
|||
class Encrypter { |
|||
public: |
|||
virtual ~Encrypter() {} |
|||
|
|||
virtual Crypt_result Encrypt(const uchar* plaintext, |
|||
int plaintext_size, |
|||
uchar* ciphertext, |
|||
int* ciphertext_used) = 0; |
|||
virtual Crypt_result GetTag(uchar* tag, int tag_size) = 0; |
|||
}; |
|||
|
|||
class Decrypter { |
|||
public: |
|||
virtual ~Decrypter() {} |
|||
|
|||
virtual Crypt_result SetTag(const uchar* tag, int tag_size) = 0; |
|||
virtual Crypt_result Decrypt(const uchar* ciphertext, |
|||
int ciphertext_size, |
|||
uchar* plaintext, |
|||
int* plaintext_used) = 0; |
|||
virtual Crypt_result CheckTag() = 0; |
|||
}; |
|||
|
|||
class Crypto { |
|||
public: |
|||
virtual ~Crypto(); |
|||
|
|||
Crypt_result Crypt(const uchar* input, int input_size, |
|||
uchar* output, int* output_used); |
|||
|
|||
protected: |
|||
Crypto(); |
|||
|
|||
EVP_CIPHER_CTX ctx; |
|||
}; |
|||
|
|||
|
|||
/* Various crypto implementations */ |
|||
|
|||
class Aes128CtrCrypto : public Crypto { |
|||
public: |
|||
virtual Crypt_result Init(const uchar* key, const uchar* iv, |
|||
int iv_size); |
|||
|
|||
protected: |
|||
Aes128CtrCrypto() {} |
|||
|
|||
virtual int mode() = 0; |
|||
}; |
|||
|
|||
class Aes128CtrEncrypter : public Aes128CtrCrypto, public Encrypter { |
|||
public: |
|||
Aes128CtrEncrypter() {} |
|||
virtual Crypt_result Encrypt(const uchar* plaintext, |
|||
int plaintext_size, |
|||
uchar* ciphertext, |
|||
int* ciphertext_used); |
|||
|
|||
virtual Crypt_result GetTag(uchar* tag, int tag_size) { |
|||
DBUG_ASSERT(false); |
|||
return AES_INVALID; |
|||
} |
|||
|
|||
protected: |
|||
virtual int mode() { |
|||
return CRYPT_ENCRYPT; |
|||
} |
|||
|
|||
private: |
|||
Aes128CtrEncrypter(const Aes128CtrEncrypter& o); |
|||
Aes128CtrEncrypter& operator=(const Aes128CtrEncrypter& o); |
|||
}; |
|||
|
|||
class Aes128CtrDecrypter : public Aes128CtrCrypto, public Decrypter { |
|||
public: |
|||
Aes128CtrDecrypter() {} |
|||
virtual Crypt_result Decrypt(const uchar* ciphertext, |
|||
int ciphertext_size, |
|||
uchar* plaintext, |
|||
int* plaintext_used); |
|||
|
|||
virtual Crypt_result SetTag(const uchar* tag, int tag_size) { |
|||
DBUG_ASSERT(false); |
|||
return AES_INVALID; |
|||
} |
|||
|
|||
virtual Crypt_result CheckTag() { |
|||
DBUG_ASSERT(false); |
|||
return AES_INVALID; |
|||
} |
|||
|
|||
protected: |
|||
virtual int mode() { |
|||
return CRYPT_DECRYPT; |
|||
} |
|||
|
|||
private: |
|||
Aes128CtrDecrypter(const Aes128CtrDecrypter& o); |
|||
Aes128CtrDecrypter& operator=(const Aes128CtrDecrypter& o); |
|||
}; |
|||
|
|||
class Aes128EcbCrypto : public Crypto { |
|||
public: |
|||
virtual Crypt_result Init(const unsigned char* key); |
|||
|
|||
protected: |
|||
Aes128EcbCrypto() {} |
|||
|
|||
virtual int mode() = 0; |
|||
}; |
|||
|
|||
class Aes128EcbEncrypter : public Aes128EcbCrypto, public Encrypter { |
|||
public: |
|||
Aes128EcbEncrypter() {} |
|||
virtual Crypt_result Encrypt(const unsigned char* plaintext, |
|||
int plaintext_size, |
|||
unsigned char* ciphertext, |
|||
int* ciphertext_used); |
|||
|
|||
virtual Crypt_result GetTag(unsigned char* tag, int tag_size) { |
|||
DBUG_ASSERT(false); |
|||
return AES_INVALID; |
|||
} |
|||
|
|||
protected: |
|||
virtual int mode() { |
|||
return CRYPT_ENCRYPT; |
|||
} |
|||
|
|||
private: |
|||
Aes128EcbEncrypter(const Aes128EcbEncrypter& o); |
|||
Aes128EcbEncrypter& operator=(const Aes128EcbEncrypter& o); |
|||
}; |
|||
|
|||
class Aes128EcbDecrypter : public Aes128EcbCrypto, public Decrypter { |
|||
public: |
|||
Aes128EcbDecrypter() {} |
|||
virtual Crypt_result Decrypt(const unsigned char* ciphertext, |
|||
int ciphertext_size, |
|||
unsigned char* plaintext, |
|||
int* plaintext_used); |
|||
|
|||
virtual Crypt_result SetTag(const unsigned char* tag, int tag_size) { |
|||
DBUG_ASSERT(false); |
|||
return AES_INVALID; |
|||
} |
|||
|
|||
virtual Crypt_result CheckTag() { |
|||
DBUG_ASSERT(false); |
|||
return AES_INVALID; |
|||
} |
|||
|
|||
protected: |
|||
virtual int mode() { |
|||
return CRYPT_DECRYPT; |
|||
} |
|||
|
|||
private: |
|||
Aes128EcbDecrypter(const Aes128EcbDecrypter& o); |
|||
Aes128EcbDecrypter& operator=(const Aes128EcbDecrypter& o); |
|||
}; |
|||
|
|||
|
|||
Crypto::~Crypto() { |
|||
EVP_CIPHER_CTX_cleanup(&ctx); |
|||
} |
|||
|
|||
Crypto::Crypto() { |
|||
EVP_CIPHER_CTX_init(&ctx); |
|||
} |
|||
|
|||
/*
|
|||
WARNING: It is allowed to have output == NULL, for special cases like AAD |
|||
support in AES GCM. output_used however must never be NULL. |
|||
*/ |
|||
|
|||
Crypt_result Crypto::Crypt(const uchar* input, int input_size, |
|||
uchar* output, int* output_used) { |
|||
DBUG_ASSERT(input != NULL); |
|||
DBUG_ASSERT(output_used != NULL); |
|||
if (!EVP_CipherUpdate(&ctx, output, output_used, input, input_size)) { |
|||
return AES_OPENSSL_ERROR; |
|||
} |
|||
|
|||
return AES_OK; |
|||
} |
|||
|
|||
Crypt_result Aes128CtrCrypto::Init(const uchar* key, |
|||
const uchar* iv, |
|||
int iv_size) { |
|||
if (iv_size != 16) { |
|||
DBUG_ASSERT(false); |
|||
return AES_BAD_IV; |
|||
} |
|||
|
|||
if (!EVP_CipherInit_ex(&ctx, EVP_aes_128_ctr(), NULL, key, iv, mode())) { |
|||
return AES_OPENSSL_ERROR; |
|||
} |
|||
|
|||
return AES_OK; |
|||
} |
|||
|
|||
Crypt_result Aes128CtrEncrypter::Encrypt(const uchar* plaintext, |
|||
int plaintext_size, |
|||
uchar* ciphertext, |
|||
int* ciphertext_used) { |
|||
Crypt_result res = Crypt(plaintext, plaintext_size, ciphertext, |
|||
ciphertext_used); |
|||
DBUG_ASSERT(*ciphertext_used == plaintext_size); |
|||
return res; |
|||
} |
|||
|
|||
Crypt_result Aes128CtrDecrypter::Decrypt(const uchar* ciphertext, |
|||
int ciphertext_size, |
|||
uchar* plaintext, |
|||
int* plaintext_used) { |
|||
Crypt_result res = Crypt(ciphertext, ciphertext_size, plaintext, |
|||
plaintext_used); |
|||
DBUG_ASSERT(*plaintext_used == ciphertext_size); |
|||
return res; |
|||
} |
|||
|
|||
|
|||
Crypt_result Aes128EcbCrypto::Init(const unsigned char* key) { |
|||
if (!EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, mode())) { |
|||
return AES_OPENSSL_ERROR; |
|||
} |
|||
|
|||
return AES_OK; |
|||
} |
|||
|
|||
Crypt_result Aes128EcbEncrypter::Encrypt(const unsigned char* plaintext, |
|||
int plaintext_size, |
|||
unsigned char* ciphertext, |
|||
int* ciphertext_used) { |
|||
Crypt_result res = Crypt(plaintext, plaintext_size, |
|||
ciphertext, ciphertext_used); |
|||
DBUG_ASSERT(*ciphertext_used == plaintext_size); |
|||
return res; |
|||
} |
|||
|
|||
Crypt_result Aes128EcbDecrypter::Decrypt(const unsigned char* ciphertext, |
|||
int ciphertext_size, |
|||
unsigned char* plaintext, |
|||
int* plaintext_used) { |
|||
Crypt_result res = Crypt(ciphertext, ciphertext_size, |
|||
plaintext, plaintext_used); |
|||
DBUG_ASSERT(*plaintext_used == ciphertext_size); |
|||
return res; |
|||
} |
|||
|
|||
C_MODE_START |
|||
|
|||
|
|||
/* Encrypt and decrypt according to Aes128Ctr */ |
|||
|
|||
Crypt_result my_aes_encrypt_ctr(const uchar* source, uint32 source_length, |
|||
uchar* dest, uint32* dest_length, |
|||
const unsigned char* key, uint8 key_length, |
|||
const unsigned char* iv, uint8 iv_length, |
|||
uint noPadding) |
|||
{ |
|||
Aes128CtrEncrypter encrypter; |
|||
Crypt_result res = encrypter.Init(key, iv, iv_length); |
|||
if (res != AES_OK) |
|||
return res; |
|||
return encrypter.Encrypt(source, source_length, dest, (int*)dest_length); |
|||
} |
|||
|
|||
|
|||
Crypt_result my_aes_decrypt_ctr(const uchar* source, uint32 source_length, |
|||
uchar* dest, uint32* dest_length, |
|||
const unsigned char* key, uint8 key_length, |
|||
const unsigned char* iv, uint8 iv_length, |
|||
uint noPadding) |
|||
{ |
|||
Aes128CtrDecrypter decrypter; |
|||
|
|||
Crypt_result res = decrypter.Init(key, iv, iv_length); |
|||
if (res != AES_OK) |
|||
return res; |
|||
return decrypter.Decrypt(source, source_length, dest, (int*)dest_length); |
|||
} |
|||
|
|||
|
|||
Crypt_result my_aes_encrypt_ecb(const uchar* source, uint32 source_length, |
|||
uchar* dest, uint32* dest_length, |
|||
const unsigned char* key, uint8 key_length, |
|||
const unsigned char* iv, uint8 iv_length, |
|||
uint noPadding) |
|||
{ |
|||
Aes128EcbEncrypter encrypter; |
|||
Crypt_result res = encrypter.Init(key); |
|||
if (res != AES_OK) |
|||
return res; |
|||
return encrypter.Encrypt(source, source_length, dest, (int*)dest_length); |
|||
} |
|||
|
|||
Crypt_result my_aes_decrypt_ecb(const uchar* source, uint32 source_length, |
|||
uchar* dest, uint32* dest_length, |
|||
const unsigned char* key, uint8 key_length, |
|||
const unsigned char* iv, uint8 iv_length, |
|||
uint noPadding) |
|||
{ |
|||
Aes128EcbDecrypter decrypter; |
|||
|
|||
Crypt_result res = decrypter.Init(key); |
|||
|
|||
if (res != AES_OK) |
|||
return res; |
|||
return decrypter.Decrypt(source, source_length, dest, (int*)dest_length); |
|||
} |
|||
|
|||
C_MODE_END |
|||
|
|||
#endif /* HAVE_EncryptAes128Ctr */
|
|||
|
|||
#if defined(HAVE_YASSL)
|
|||
|
|||
#include <random.hpp>
|
|||
|
|||
C_MODE_START |
|||
|
|||
Crypt_result RandomBytes(uchar* buf, int num) |
|||
{ |
|||
TaoCrypt::RandomNumberGenerator rand; |
|||
rand.GenerateBlock((TaoCrypt::byte*) buf, num); |
|||
return AES_OK; |
|||
} |
|||
|
|||
C_MODE_END |
|||
|
|||
#else /* OpenSSL */
|
|||
|
|||
C_MODE_START |
|||
|
|||
Crypt_result RandomBytes(uchar* buf, int num) |
|||
{ |
|||
/*
|
|||
Unfortunately RAND_bytes manual page does not provide any guarantees |
|||
in relation to blocking behavior. Here we explicitly use SSLeay random |
|||
instead of whatever random engine is currently set in OpenSSL. That way |
|||
we are guaranteed to have a non-blocking random. |
|||
*/ |
|||
RAND_METHOD* rand = RAND_SSLeay(); |
|||
if (rand == NULL || rand->bytes(buf, num) != 1) |
|||
return AES_OPENSSL_ERROR; |
|||
return AES_OK; |
|||
} |
|||
|
|||
C_MODE_END |
|||
#endif /* HAVE_YASSL */
|
@ -0,0 +1,85 @@ |
|||
#include <my_global.h>
|
|||
#include <my_crypt_key_management.h>
|
|||
#include <cstring>
|
|||
#ifdef __linux__
|
|||
#include <arpa/inet.h>
|
|||
#endif
|
|||
|
|||
#ifndef DBUG_OFF
|
|||
my_bool opt_danger_danger_use_dbug_keys = 0; |
|||
|
|||
#ifdef HAVE_PSI_INTERFACE
|
|||
PSI_rwlock_key key_LOCK_dbug_crypto_key_version; |
|||
#endif
|
|||
mysql_rwlock_t LOCK_dbug_crypto_key_version; |
|||
unsigned int opt_danger_danger_dbug_crypto_key_version = 0; |
|||
#endif
|
|||
|
|||
/**
|
|||
* Default functions |
|||
*/ |
|||
unsigned int GetLatestCryptoKeyVersionImpl(); |
|||
int GetCryptoKeyImpl(unsigned int version, unsigned char* key_buffer, |
|||
unsigned int size); |
|||
|
|||
/**
|
|||
* Function pointers for |
|||
* - GetLatestCryptoKeyVersion |
|||
* - GetCryptoKey |
|||
*/ |
|||
static |
|||
struct CryptoKeyFuncs_t cryptoKeyFuncs = { |
|||
GetLatestCryptoKeyVersionImpl, |
|||
GetCryptoKeyImpl |
|||
}; |
|||
|
|||
extern "C" |
|||
unsigned int GetLatestCryptoKeyVersion() { |
|||
#ifndef DBUG_OFF
|
|||
if (opt_danger_danger_use_dbug_keys) { |
|||
mysql_rwlock_rdlock(&LOCK_dbug_crypto_key_version); |
|||
unsigned int res = opt_danger_danger_dbug_crypto_key_version; |
|||
mysql_rwlock_unlock(&LOCK_dbug_crypto_key_version); |
|||
return res; |
|||
} |
|||
#endif
|
|||
|
|||
return (* cryptoKeyFuncs.getLatestCryptoKeyVersionFunc)(); |
|||
} |
|||
|
|||
extern "C" |
|||
int GetCryptoKey(unsigned int version, unsigned char* key, unsigned int size) { |
|||
#ifndef DBUG_OFF
|
|||
if (opt_danger_danger_use_dbug_keys) { |
|||
memset(key, 0, size); |
|||
// Just don't support tiny keys, no point anyway.
|
|||
if (size < sizeof(version)) { |
|||
return 1; |
|||
} |
|||
|
|||
version = htonl(version); |
|||
memcpy(key, &version, sizeof(version)); |
|||
return 0; |
|||
} |
|||
#endif
|
|||
|
|||
return (* cryptoKeyFuncs.getCryptoKeyFunc)(version, key, size); |
|||
} |
|||
|
|||
extern "C" |
|||
void |
|||
InstallCryptoKeyFunctions(const struct CryptoKeyFuncs_t* _cryptoKeyFuncs) |
|||
{ |
|||
if (_cryptoKeyFuncs == NULL) |
|||
{ |
|||
/* restore defaults when called with NULL argument */ |
|||
cryptoKeyFuncs.getLatestCryptoKeyVersionFunc = |
|||
GetLatestCryptoKeyVersionImpl; |
|||
cryptoKeyFuncs.getCryptoKeyFunc = |
|||
GetCryptoKeyImpl; |
|||
} |
|||
else |
|||
{ |
|||
cryptoKeyFuncs = *_cryptoKeyFuncs; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
#include <my_global.h>
|
|||
|
|||
// TODO Not yet implemented.
|
|||
unsigned int GetLatestCryptoKeyVersionImpl() |
|||
{ |
|||
abort(); |
|||
} |
|||
|
|||
int GetCryptoKeyImpl(unsigned int version, unsigned char* key, |
|||
unsigned int key_size) |
|||
{ |
|||
abort(); |
|||
} |
@ -0,0 +1,3 @@ |
|||
SET(FILE_KEY_MANAGEMENT_PLUGIN_SOURCES file_key_management_plugin.cc ) |
|||
|
|||
MYSQL_ADD_PLUGIN(FILE_KEY_MANAGEMENT_PLUGIN ${FILE_KEY_MANAGEMENT_PLUGIN_SOURCES} MANDATORY) |
@ -0,0 +1,429 @@ |
|||
/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
|
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; version 2 of the License. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
|||
|
|||
/******************************************************************//**
|
|||
@file EncKeys.cc |
|||
A class to keep keys for encryption/decryption. |
|||
|
|||
How it works... |
|||
The location and usage can be configured via the configuration file. |
|||
Example |
|||
|
|||
[mysqld] |
|||
... |
|||
innodb_data_encryption_providertype = 1 |
|||
innodb_data_encryption_providername = keys.enc |
|||
innodb_data_encryption_providerurl = /home/mdb/ |
|||
innodb_data_encryption_filekey = secret |
|||
... |
|||
|
|||
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) |
|||
|
|||
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. |
|||
|
|||
The key file should be encrypted and the key to decrypt the file can be given with the |
|||
innodb_data_encryption_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. |
|||
Example: |
|||
innodb_data_encryption_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 |
|||
openssl enc –aes-256-cbc –md sha1 –k <initialPwd> –in secret –out secret.enc |
|||
|
|||
Created 09/15/2014 |
|||
***********************************************************************/ |
|||
#ifdef __WIN__
|
|||
#define PCRE_STATIC 1
|
|||
#endif
|
|||
|
|||
#include "EncKeys.h"
|
|||
#include <my_global.h>
|
|||
#include <my_aes.h>
|
|||
#include <memory.h>
|
|||
#include <my_sys.h>
|
|||
#include <pcre.h>
|
|||
#include <string.h>
|
|||
#include <my_sys.h>
|
|||
|
|||
|
|||
|
|||
|
|||
const char* EncKeys::strMAGIC = "Salted__"; |
|||
const int EncKeys::magicSize = 8;//strlen(strMAGIC); // 8 byte
|
|||
const char* EncKeys::newLine = "\n"; |
|||
|
|||
const char* EncKeys::errorNoKeyId = "KeyID = %u not found or with error. Check the key and the log file.\n"; |
|||
const char* EncKeys::errorInMatches = "Wrong match of the keyID in line %u, see the template.\n"; |
|||
const char* EncKeys::errorExceedKeyFileSize = "The size of the key file %s exceeds " |
|||
"the maximum allowed of %u bytes.\n"; |
|||
const char* EncKeys::errorExceedKeySize = "The key size exceeds the maximum allowed size of %u in line %u.\n"; |
|||
const char* EncKeys::errorEqualDoubleKey = "More than one identical key with keyID = %u found" |
|||
" in lines %u and %u.\nDelete one of them in the key file.\n"; |
|||
const char* EncKeys::errorUnequalDoubleKey = "More than one not identical key with keyID = %u found" |
|||
" in lines %u and %u.\nChoose the right one and delete the other in the key file.\n" |
|||
"I'll take the key from line %u\n"; |
|||
const char* EncKeys::errorNoInitializedKey = "The key could not be initialized.\n"; |
|||
const char* EncKeys::errorNotImplemented = "Initializing keys through key server is not" |
|||
" yet implemented.\nYou can not read encrypted tables or columns\n\n"; |
|||
const char* EncKeys::errorOpenFile = "Could not open %s for reading. You can not read encrypted tables or columns.\n\n"; |
|||
const char* EncKeys::errorReadingFile = "Could not read from %s. You can not read encrypted tables or columns\n\n"; |
|||
const char* EncKeys::errorFileSize = "Could not get the file size from %s. You can not read encrypted tables or columns\n\n"; |
|||
const char* EncKeys::errorFalseFileKey = "Wrong encryption / decryption key for keyfile '%s'.\n"; |
|||
|
|||
/* read this from a secret source in some later version */ |
|||
const char* EncKeys::initialPwd = "lg28s9ac5ffa537fd8798875c98e190df289da7e047c05"; |
|||
|
|||
EncKeys::EncKeys() { |
|||
countKeys = keyLineInKeyFile = 0; |
|||
for (int ii = 0; ii < MAX_KEYS; ii++) { |
|||
keys[ii].id = 0; |
|||
keys[ii].iv = keys[ii].key = NULL; |
|||
} |
|||
oneKey = NULL; |
|||
} |
|||
|
|||
EncKeys::~EncKeys() { |
|||
for (int ii = MAX_KEYS - 1; ii >= 0 ; ii--) { |
|||
delete[] keys[ii].iv; keys[ii].iv = NULL; |
|||
delete[] keys[ii].key; keys[ii].key = NULL; |
|||
|
|||
} |
|||
} |
|||
|
|||
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; |
|||
} |
|||
|
|||
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) |
|||
{ |
|||
//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(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; |
|||
} |
|||
|
|||
/*
|
|||
* secret is limited to MAX_SECRET_SIZE characters |
|||
*/ |
|||
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); |
|||
rewind(fp); |
|||
int bytes_to_read = (maxSize >= file_size)? file_size:(maxSize); |
|||
fread(buf, 1, bytes_to_read, fp); |
|||
if (memcmp(buf, strMAGIC, magicSize)) { |
|||
bytes_to_read = (bytes_to_read>MAX_SECRET_SIZE) ? MAX_SECRET_SIZE : bytes_to_read; |
|||
memcpy(secret, buf, bytes_to_read); |
|||
secret[bytes_to_read] = '\0'; |
|||
} else { |
|||
unsigned char salt[magicSize]; |
|||
unsigned char *key = new unsigned char[keySize32]; |
|||
unsigned char *iv = new unsigned char[ivSize16]; |
|||
memcpy(&salt, buf + magicSize, magicSize); |
|||
memcpy(_initPwd, initialPwd, strlen(initialPwd)); |
|||
_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); |
|||
if (d_size>EncKeys::MAX_SECRET_SIZE) { |
|||
d_size = EncKeys::MAX_SECRET_SIZE; |
|||
} |
|||
secret[d_size] = '\0'; |
|||
delete[] key; |
|||
delete[] iv; |
|||
} |
|||
free(buf); |
|||
free(_initPwd); |
|||
fclose(fp); |
|||
} |
|||
|
|||
/**
|
|||
* Returns a struct keyentry with the asked 'id' or NULL. |
|||
*/ |
|||
keyentry *EncKeys::getKeys(int id) { |
|||
if (KEY_MIN <= id && KEY_MAX >= id && (&keys[id - 1])->iv) |
|||
{ |
|||
return &keys[id - 1]; |
|||
} |
|||
#ifdef UNIV_DEBUG
|
|||
else { |
|||
|
|||
fprintf(stderr, errorNoKeyId, id); |
|||
return NULL; |
|||
} |
|||
#endif //UNIV_DEBUG
|
|||
} |
|||
|
|||
/**
|
|||
* Get the keys from the key file <filename> and decrypt it with the key <secret>. |
|||
* 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 errorCode = 0; |
|||
char *buffer = decryptFile(filename, secret, &errorCode); |
|||
ulint id = 0; |
|||
|
|||
if (NO_ERROR_PARSE_OK != errorCode) return errorCode; |
|||
else errorCode = NO_ERROR_KEY_FILE_PARSE_OK; |
|||
|
|||
char *line = strtok(buffer, newLine); |
|||
while ( NULL != line) { |
|||
keyLineInKeyFile++; |
|||
switch (parseLine(line, maxKeyId)) { |
|||
case NO_ERROR_PARSE_OK: |
|||
id = oneKey->id; |
|||
keys[oneKey->id - 1] = *oneKey; |
|||
delete(oneKey); |
|||
countKeys++; |
|||
fprintf(stderr, "Line: %u --> ", keyLineInKeyFile); printKeyEntry(id); |
|||
break; |
|||
case ERROR_ID_TOO_BIG: |
|||
fprintf(stderr, errorExceedKeySize, KEY_MAX, keyLineInKeyFile); |
|||
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); |
|||
errorCode = ERROR_KEY_FILE_PARSE_NULL; |
|||
break; |
|||
case ERROR_WRONG_NUMBER_OF_MATCHES: |
|||
fprintf(stderr, errorInMatches, keyLineInKeyFile); |
|||
fprintf(stderr, " --> %s\n", line); |
|||
errorCode = ERROR_KEY_FILE_PARSE_NULL; |
|||
break; |
|||
case NO_ERROR_KEY_GREATER_THAN_ASKED: |
|||
fprintf(stderr, "No asked key in line %lu: %s\n", keyLineInKeyFile, line); |
|||
break; |
|||
case NO_ERROR_ISCOMMENT: |
|||
fprintf(stderr, "Is comment in line %lu: %s\n", keyLineInKeyFile, line); |
|||
default: |
|||
break; |
|||
} |
|||
line = strtok(NULL, newLine); |
|||
} |
|||
|
|||
free(line); line = NULL; |
|||
delete[] buffer; buffer = NULL; |
|||
return errorCode; |
|||
} |
|||
|
|||
int EncKeys::parseLine(const char *line, const ulint maxKeyId) { |
|||
int ret = NO_ERROR_PARSE_OK; |
|||
if (isComment(line)) |
|||
ret = NO_ERROR_ISCOMMENT; |
|||
else { |
|||
const char *error_p = NULL; |
|||
int offset; |
|||
pcre *pattern = pcre_compile( |
|||
"([0-9]+);([0-9,a-f,A-F]{32});([0-9,a-f,A-F]{64}|[0-9,a-f,A-F]{48}|[0-9,a-f,A-F]{32})", |
|||
0, &error_p, &offset, NULL); |
|||
if ( NULL != error_p) |
|||
fprintf(stderr, "Error: %s\nOffset: %d\n", error_p, offset); |
|||
|
|||
int m_len = (int) strlen(line), ovector[MAX_OFFSETS_IN_PCRE_PATTERNS]; |
|||
int rc = pcre_exec(pattern, NULL, line, m_len, 0, 0, ovector, MAX_OFFSETS_IN_PCRE_PATTERNS); |
|||
pcre_free(pattern); |
|||
if (4 == rc) { |
|||
char lin[MAX_KEY_LINE_SIZE + 1]; |
|||
strncpy( lin, line, MAX_KEY_LINE_SIZE); |
|||
lin[MAX_KEY_LINE_SIZE] = '\0'; |
|||
char *substring_start = lin + ovector[2]; |
|||
int substr_length = ovector[3] - ovector[2]; |
|||
if (3 < substr_length) |
|||
ret = ERROR_ID_TOO_BIG; |
|||
else { |
|||
char buffer[4]; |
|||
sprintf(buffer, "%.*s", substr_length, substring_start); |
|||
ulint 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; |
|||
else { |
|||
oneKey = new keyentry; |
|||
oneKey->id = id; |
|||
substring_start = lin + ovector[4]; |
|||
substr_length = ovector[5] - ovector[4]; |
|||
oneKey->iv = new char[substr_length + 1]; |
|||
sprintf(oneKey->iv, "%.*s", substr_length, substring_start); |
|||
substring_start = lin + ovector[6]; |
|||
substr_length = ovector[7] - ovector[6]; |
|||
oneKey->key = new char[substr_length + 1]; |
|||
sprintf(oneKey->key, "%.*s", substr_length, substring_start); |
|||
} |
|||
} |
|||
} |
|||
else |
|||
ret = ERROR_WRONG_NUMBER_OF_MATCHES; |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
/**
|
|||
* Decrypt the key file 'filename' if it is encrypted with the key 'secret'. |
|||
* Store the content of the decrypted file in 'buffer'. The buffer has to be freed |
|||
* in the calling function. |
|||
*/ |
|||
char* EncKeys::decryptFile(const char* filename, const char *secret, int *errorCode) { |
|||
*errorCode = NO_ERROR_PARSE_OK; |
|||
fprintf(stderr, "Reading %s\n\n", filename); |
|||
FILE *fp = fopen(filename, "rb"); |
|||
if (NULL == fp) { |
|||
fprintf(stderr, errorOpenFile, filename); |
|||
*errorCode = ERROR_OPEN_FILE; |
|||
return NULL; |
|||
} |
|||
|
|||
if (fseek(fp, 0L, SEEK_END)) { |
|||
*errorCode = ERROR_READING_FILE; |
|||
return NULL; |
|||
} |
|||
long file_size = ftell(fp); // get the file size
|
|||
if (MAX_KEY_FILE_SIZE < file_size) { |
|||
fprintf(stderr, errorExceedKeyFileSize, filename, MAX_KEY_FILE_SIZE); |
|||
*errorCode = ERROR_KEY_FILE_TOO_BIG; |
|||
fclose(fp); |
|||
return NULL; |
|||
} |
|||
else if (-1L == file_size) { |
|||
fprintf(stderr, errorFileSize, filename); |
|||
*errorCode = ERROR_READING_FILE; |
|||
return NULL; |
|||
} |
|||
|
|||
rewind(fp); |
|||
//Read file into buffer
|
|||
uchar *buffer = new uchar[file_size + 1]; |
|||
size_t read_bytes = fread(buffer, 1, file_size, fp); |
|||
buffer[file_size] = '\0'; |
|||
fclose(fp); |
|||
//Check for file encryption
|
|||
if (0 == memcmp(buffer, strMAGIC, magicSize)) { //If file is encrypted, decrypt it first.
|
|||
unsigned char salt[magicSize]; |
|||
unsigned char *key = new unsigned char[keySize32]; |
|||
unsigned char *iv = new unsigned char[ivSize16]; |
|||
char *decrypted = new char[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); |
|||
if(0 != res) { |
|||
*errorCode = ERROR_FALSE_FILE_KEY; |
|||
delete[] buffer; buffer = NULL; |
|||
fprintf(stderr, errorFalseFileKey, filename); |
|||
} |
|||
else { |
|||
memcpy(buffer, decrypted, d_size); |
|||
buffer[d_size] = '\0'; |
|||
} |
|||
|
|||
delete[] decrypted; decrypted = NULL; |
|||
delete[] key; key = NULL; |
|||
delete[] iv; iv = NULL; |
|||
} |
|||
return (char*) buffer; |
|||
} |
|||
|
|||
bool EncKeys::isComment(const char *line) { |
|||
const char *error_p; |
|||
int offset, m_len = (int) strlen(line), ovector[MAX_OFFSETS_IN_PCRE_PATTERNS]; |
|||
pcre *pattern = pcre_compile("\\s*#.*", 0, &error_p, &offset, NULL); |
|||
int rc = pcre_exec( pattern, NULL, line, m_len, 0, 0, ovector, MAX_OFFSETS_IN_PCRE_PATTERNS); |
|||
pcre_free(pattern); |
|||
if (0 > rc) return false; |
|||
else return true; |
|||
} |
|||
|
|||
|
|||
void EncKeys::printKeyEntry( ulint id) |
|||
{ |
|||
#ifdef UNIV_DEBUG
|
|||
keyentry *entry = getKeys(id); |
|||
if( NULL == entry) { |
|||
fprintf(stderr, "No such keyID=%lu\n",id); |
|||
} |
|||
else { |
|||
fprintf(stderr, "Key: id:%3lu \tiv:%lu bytes\tkey:%lu bytes\n", entry->id, strlen(entry->iv)/2, strlen(entry->key)/2); |
|||
} |
|||
#endif //UNIV_DEBUG
|
|||
} |
@ -0,0 +1,88 @@ |
|||
/* Copyright (C) 2014 eperi GmbH. All Rights Reserved. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; version 2 of the License. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
|||
|
|||
/******************************************************************//** |
|||
@file EncKeys.h |
|||
A structure and class to keep keys for encryption/decryption. |
|||
|
|||
Created 09/15/2014 |
|||
***********************************************************************/ |
|||
|
|||
#ifndef ENCKEYS_H_ |
|||
#define ENCKEYS_H_ |
|||
|
|||
#include "my_global.h" |
|||
#include <sys/types.h> |
|||
#include <stdio.h> |
|||
|
|||
|
|||
|
|||
|
|||
struct keyentry { |
|||
ulint id; |
|||
char *iv; |
|||
char *key; |
|||
}; |
|||
|
|||
|
|||
class EncKeys |
|||
{ |
|||
private: |
|||
static const char *strMAGIC, *newLine; |
|||
static const int magicSize; |
|||
|
|||
enum constants { MAX_OFFSETS_IN_PCRE_PATTERNS = 30}; |
|||
enum keyAttributes { KEY_MIN = 1, KEY_MAX = 255, MAX_KEYS = 255, |
|||
MAX_IVLEN = 256, MAX_KEYLEN = 512, ivSize16 = 16, keySize32 = 32 }; |
|||
enum keyInitType { KEYINITTYPE_FILE = 1, KEYINITTYPE_SERVER = 2 }; |
|||
enum errorAttributes { MAX_KEY_LINE_SIZE = 3 * MAX_KEYLEN, MAX_KEY_FILE_SIZE = 1048576 }; |
|||
enum errorCodesLine { NO_ERROR_PARSE_OK = 0, NO_ERROR_ISCOMMENT = 10, NO_ERROR_KEY_GREATER_THAN_ASKED = 20, |
|||
ERROR_NOINITIALIZEDKEY = 30, ERROR_ID_TOO_BIG = 40, ERROR_WRONG_NUMBER_OF_MATCHES = 50, |
|||
ERROR_EQUAL_DOUBLE_KEY = 60, ERROR_UNEQUAL_DOUBLE_KEY = 70 }; |
|||
|
|||
static const char *errorNoKeyId, *errorInMatches, *errorExceedKeyFileSize, |
|||
*errorExceedKeySize, *errorEqualDoubleKey, *errorUnequalDoubleKey, |
|||
*errorNoInitializedKey, *errorFalseFileKey, |
|||
*errorNotImplemented, *errorOpenFile, *errorReadingFile, *errorFileSize; |
|||
|
|||
static const char* initialPwd; |
|||
ulint countKeys, keyLineInKeyFile; |
|||
keyentry keys[MAX_KEYS], *oneKey; |
|||
|
|||
void printKeyEntry( ulint id); |
|||
int initKeysThroughFile( const char *name, const char *path, const char *filekey); |
|||
int initKeysThroughServer( const char *name, const char *path, const char *filekey); |
|||
bool isComment( const char *line); |
|||
char * decryptFile( const char* filename, const char *secret, int *errorCode); |
|||
int parseFile( const char* filename, const ulint maxKeyId, const char *secret); |
|||
int parseLine( const char *line, const ulint maxKeyId); |
|||
|
|||
public: |
|||
static const size_t MAX_SECRET_SIZE = 256; |
|||
|
|||
enum errorCodesFile { NO_ERROR_KEY_FILE_PARSE_OK = 0, ERROR_KEY_FILE_PARSE_NULL = 110, |
|||
ERROR_KEY_FILE_TOO_BIG = 120, ERROR_KEY_FILE_EXCEEDS_MAX_NUMBERS_OF_KEYS = 130, |
|||
ERROR_OPEN_FILE = 140, ERROR_READING_FILE = 150, ERROR_FALSE_FILE_KEY = 160, |
|||
ERROR_KEYINITTYPE_SERVER_NOT_IMPLEMENTED = 170, ERROR_ENCRYPTION_SECRET_NULL = 180 }; |
|||
EncKeys(); |
|||
virtual ~EncKeys(); |
|||
bool initKeys( const char *name, const char *url, const int initType, const char *filekey); |
|||
keyentry *getKeys( int id); |
|||
/* made public for unit testing */ |
|||
static void parseSecret( const char *filename, char *secret ); |
|||
|
|||
}; |
|||
|
|||
#endif /* ENCKEYS_H_ */ |
@ -0,0 +1,65 @@ |
|||
/* Copyright (C) 2014 eperi GmbH. All Rights Reserved.
|
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; version 2 of the License. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
|||
|
|||
/******************************************************************//**
|
|||
@file KeySingleton.cc |
|||
Implementation of single pattern to keep keys for encrypting/decrypting pages. |
|||
|
|||
Created 09/13/2014 |
|||
***********************************************************************/ |
|||
|
|||
|
|||
#include "KeySingleton.h"
|
|||
#include <stdlib.h>
|
|||
|
|||
|
|||
bool KeySingleton::instanceInited = false; |
|||
KeySingleton KeySingleton::theInstance; |
|||
EncKeys KeySingleton::encKeys; |
|||
|
|||
|
|||
|
|||
KeySingleton & KeySingleton::getInstance() { |
|||
#ifdef UNIV_DEBUG
|
|||
if( !instanceInited) { |
|||
fprintf(stderr, "Encryption / decryption keys were not initialized. " |
|||
"You can not read encrypted tables or columns\n"); |
|||
} |
|||
#endif UNIV_DEBUG
|
|||
return theInstance; |
|||
} |
|||
|
|||
KeySingleton & KeySingleton::getInstance(const char *name, const char *url, |
|||
const int initType, const char *filekey) { |
|||
|
|||
if(instanceInited) return theInstance; |
|||
instanceInited = encKeys.initKeys(name, url, initType, filekey); |
|||
if( !instanceInited) { |
|||
fprintf(stderr, "Could not initialize any of the encryption / decryption keys. " |
|||
"You can not read encrypted tables\n\n"); |
|||
fflush(stderr); |
|||
} |
|||
|
|||
return theInstance; |
|||
} |
|||
|
|||
keyentry *KeySingleton::getKeys(int id) { |
|||
return encKeys.getKeys(id); |
|||
} |
|||
|
|||
ibool KeySingleton::hasKey(int id) { |
|||
return encKeys.getKeys(id) != NULL; |
|||
} |
|||
|
@ -0,0 +1,59 @@ |
|||
/* Copyright (C) 2014 eperi GmbH. All Rights Reserved. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; version 2 of the License. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
|||
|
|||
/******************************************************************//** |
|||
@file KeySingletonPattern.h |
|||
Implementation of single pattern to keep keys for encrypting/decrypting pages. |
|||
|
|||
Created 09/13/2014 |
|||
***********************************************************************/ |
|||
|
|||
|
|||
#ifndef KEYSINGLETON_H_ |
|||
#define KEYSINGLETON_H_ |
|||
|
|||
#include "EncKeys.h" |
|||
|
|||
|
|||
class KeySingleton |
|||
{ |
|||
private: |
|||
static bool instanceInited; |
|||
static KeySingleton theInstance; |
|||
static EncKeys encKeys; |
|||
|
|||
// No new instance or object possible |
|||
KeySingleton() {} |
|||
|
|||
// No new instance possible through copy constructor |
|||
KeySingleton( const KeySingleton&) {} |
|||
|
|||
// No new instance possible through copy |
|||
KeySingleton & operator = (const KeySingleton&); |
|||
|
|||
public: |
|||
virtual ~KeySingleton() {encKeys.~EncKeys();} |
|||
static KeySingleton& getInstance(); |
|||
// Init the instance for only one time |
|||
static KeySingleton& getInstance(const char *name, const char *url, |
|||
const int initType, const char *filekey); |
|||
keyentry *getKeys(int id); |
|||
ibool hasKey(int id); |
|||
static bool isAvailable() { |
|||
return instanceInited; |
|||
} |
|||
}; |
|||
|
|||
#endif /* KEYSINGLETON_H_ */ |
@ -0,0 +1,63 @@ |
|||
/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; version 2 of the License. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
|||
|
|||
|
|||
#include <my_global.h>
|
|||
#include <mysql_version.h>
|
|||
#include <my_aes.h>
|
|||
|
|||
static int file_key_management_plugin_init(void *p) |
|||
{ |
|||
/* init */ |
|||
printf("TO_BE_REMOVED: Loading file_key_management_plugin_init\n"); |
|||
|
|||
/* Setting to MY_AES_METHOD_CBC for page encryption */ |
|||
my_aes_init_dynamic_encrypt(MY_AES_ALGORITHM_CBC); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static int file_key_management_plugin_deinit(void *p) |
|||
{ |
|||
/**
|
|||
* don't uninstall... |
|||
*/ |
|||
return 0; |
|||
} |
|||
|
|||
struct st_mysql_daemon file_key_management_plugin= { |
|||
MYSQL_DAEMON_INTERFACE_VERSION |
|||
}; |
|||
|
|||
/*
|
|||
Plugin library descriptor |
|||
*/ |
|||
maria_declare_plugin(file_key_management_plugin) |
|||
{ |
|||
MYSQL_DAEMON_PLUGIN, |
|||
&file_key_management_plugin, |
|||
"file_key_management_plugin", |
|||
"Denis Endro eperi GmbH", |
|||
"File key management plugin", |
|||
PLUGIN_LICENSE_GPL, |
|||
file_key_management_plugin_init, /* Plugin Init */ |
|||
file_key_management_plugin_deinit, /* Plugin Deinit */ |
|||
0x0100 /* 1.0 */, |
|||
NULL, /* status variables */ |
|||
NULL, /* system variables */ |
|||
"1.0", |
|||
MariaDB_PLUGIN_MATURITY_UNKNOWN |
|||
} |
|||
maria_declare_plugin_end; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue