MySQL 8.3.0
Source Code Documentation
Keyring component services
Collaboration diagram for Keyring component services:

Classes

struct  s_mysql_keyring_aes
 Keyring aes encryption service provides APIs to perform AES encryption/decryption operation on given data. More...
 
struct  s_mysql_keyring_generator
 Key generator service provides a way to generate random data and store it in keyring backend. More...
 
struct  s_mysql_keyring_keys_metadata_iterator
 Keyring keys metadata iterator service provides APIs to create and use iterator to access metadata associated with all keys stored in keyring. More...
 
struct  s_mysql_keyring_load
 Keyring load service provides way to initialize or reiniitalize keyring component. More...
 
struct  s_mysql_keyring_component_status
 Keyring component status provides a way to check whether keyring is active or not. More...
 
struct  s_mysql_keyring_component_metadata_query
 Keyring component metadata query service provides APIs to obtain component specific metadata in string format. More...
 
struct  s_mysql_keyring_reader_with_status
 Keyring reader with status service provides APIs to fetch sensitive data from keyring backend. More...
 
struct  s_mysql_keyring_writer
 Keyring writer service provides APIs to add/remove sensitive data to/from keyring backend. More...
 

Typedefs

typedef struct s_mysql_keyring_aes mysql_service_keyring_aes_t
 Keyring aes encryption service provides APIs to perform AES encryption/decryption operation on given data. More...
 
typedef struct s_mysql_keyring_generator mysql_service_keyring_generator_t
 Key generator service provides a way to generate random data and store it in keyring backend. More...
 
typedef struct s_mysql_keyring_keys_metadata_iterator mysql_service_keyring_keys_metadata_iterator_t
 Keyring keys metadata iterator service provides APIs to create and use iterator to access metadata associated with all keys stored in keyring. More...
 
typedef struct s_mysql_keyring_load mysql_service_keyring_load_t
 Keyring load service provides way to initialize or reiniitalize keyring component. More...
 
typedef struct s_mysql_keyring_component_status mysql_service_keyring_component_status_t
 Keyring component status provides a way to check whether keyring is active or not. More...
 
typedef struct s_mysql_keyring_component_metadata_query mysql_service_keyring_component_metadata_query_t
 Keyring component metadata query service provides APIs to obtain component specific metadata in string format. More...
 
typedef struct s_mysql_keyring_reader_with_status mysql_service_keyring_reader_with_status_t
 Keyring reader with status service provides APIs to fetch sensitive data from keyring backend. More...
 
typedef struct s_mysql_keyring_writer mysql_service_keyring_writer_t
 Keyring writer service provides APIs to add/remove sensitive data to/from keyring backend. More...
 

Detailed Description

Typedef Documentation

◆ mysql_service_keyring_aes_t

Keyring aes encryption service provides APIs to perform AES encryption/decryption operation on given data.

These methods make sure that key never leaves keyring component.

my_service<SERVICE_TYPE(keyring_aes)> aes_encryption(
"keyring_aes", m_reg_srv);
if (!aes_encryption.is_valid()) {
return true;
}
std::string mode("cbc");
size_t block_size = 256;
const unsigned char plaintext[] = "Quick brown fox jumped over the lazy dog.";
size_t plaintext_length = strlen(static_cast<const char *>(plaintext));
size_t ciphertext_length = 0;
if (aes_encryption->get_size(plaintext_length, block_size, mode.c_str,
&ciphertext_length) == true) {
return true;
}
std::unique_ptr<unsigned char[]> ciphertext(
new unsigned char[ciphertext_length]);
if (ciphertext.get() == nullptr) {
return true;
}
const unsigned char iv[] = "abcefgh12345678";
size_t out_length = 0;
if (aes_encryption->encrypt(
"my_aes_key_1", "testuser@localhost", mode.c_str(), block_size,
iv, true, plaintext, plaintext_length, ciphertext.get(),
ciphertext_length, &out_length) == true) {
return true;
}
std::unique_ptr<unsigned char[]> retrieved_plaintext(
new unsigned char[plaintext_length]);
if (retrieved_plaintext.get() == nullptr) {
return true;
}
if (aes_encryption->decrypt(
"my_aes_key_1", "testuser@localhost", mode.c_str(), block_size,
iv, true, ciphertext.get(), out_length, retrieved_plaintext.get(),
plaintext_length, &out_length) == true) {
return true;
}
if (plaintext_length != out_length ||
memcmp(plaintext, retrieved_plaintext.get(), plaintext_length) != 0) {
return true;
}
return false;
Wraps my_h_service struct conforming ABI into RAII C++ object with ability to cast to desired service...
Definition: my_service.h:34
mode
Definition: file_handle.h:59
#define SERVICE_TYPE(name)
Generates the standard Service type name.
Definition: service.h:75

◆ mysql_service_keyring_component_metadata_query_t

Keyring component metadata query service provides APIs to obtain component specific metadata in string format.

Metadata would be in (key, value) pair.

Implementor can decide what metadata should be exposed through these APIs.

One of the primary consumer of this metadata is Performance schema table keyring_component_status.

bool print_component_status() {
bool next_status = false;
my_service<SERVICE_TYPE(keyring_component_metadata_query)>
metadata_query_service("keyring_component_metadata_query",
m_reg_srv);
if (!metadata_query_service.valid()) {
return false;
}
if (metadata_query_service->init(&iterator) == true) {
return false;
}
bool ok = true;
for (; metadata_query_service->is_valid(iterator) && next_status;
next_status = metadata_query_service->next(iterator)) {
size_t key_buffer_length = 0;
size_t value_buffer_length = 0;
if (metadata_query_service->get_length(iterator, &key_buffer_length,
&value_buffer_length) == true) {
ok = false;
break;
}
std::unique_ptr<char[]> key_buffer(new char[key_buffer_length]);
std::unique_ptr<char[]> value_buffer(new char[value_buffer_length]);
if (key_buffer.get() == nullptr || value_buffer.get() == nullptr) break;
memset(key_buffer.get(), 0, key_buffer_length);
memset(value_buffer.get(), 0, value_buffer_length);
if (metadata_query_service->get(
iterator, key_buffer.get(), key_buffer_length, value_buffer.get(),
value_buffer_length) == true) {
ok = false;
break;
}
std::cout << "Metadata key: " << key_buffer.get()
<< ". Metadata value: " << value_buffer.get.get() << std::endl;
}
if (metadata_query_service->deinit(iterator) {
return false;
}
return ok;
}
struct my_h_keyring_component_metadata_iterator_imp * my_h_keyring_component_metadata_iterator
Definition: keyring_metadata_query.h:28

◆ mysql_service_keyring_component_status_t

Keyring component status provides a way to check whether keyring is active or not.

my_service<SERVICE_TYPE(keyring_component_status)> component_status(
"keyring_component_status", m_reg_srv);
if (!component_status.is_valid()) {
return false;
}
return component_status->keyring_initialized();

◆ mysql_service_keyring_generator_t

Key generator service provides a way to generate random data and store it in keyring backend.

Data stored within keyring should be uniquely identified using:

  1. Data ID An identifier associated with data - supplied by keyring APIs' callers
  2. Auth ID An identifier associated with owner of the data - suppled by keyring APIs' callers. If Auth ID is not provided, key is treated as an internal key. Such a key shalll not be accessible to database users using SQL interface

This service does not return generated data back to user. For that, Keyring reader service should be used.

bool generate_key(const char *data_id, const char *auth_id,
const char *data_type, size_t data_size) {
my_service<SERVICE_TYPE(keyring_generator)> keyring_generator(
"keyring_reader_generator", m_reg_srv);
if (!keyring_generator.is_valid()) {
return true;
}
if (keyring_generator->generate(data_id, auth_id, data_type, data_size) ==
true) {
return true;
}
return false;
}
bool generate_key(const char *key_id, const char *key_type, size_t key_length)
Generate a new key.
Definition: os0enc.cc:162

◆ mysql_service_keyring_keys_metadata_iterator_t

Keyring keys metadata iterator service provides APIs to create and use iterator to access metadata associated with all keys stored in keyring.

bool print_keys_metadata() {
char data_id[KEYRING_ITEM_BUFFER_SIZE] = "\0";
char auth_id[KEYRING_ITEM_BUFFER_SIZE] = "\0";
my_h_keyring_keys_metadata_iterator forward_iterator = nullptr;
my_service<SERVICE_TYPE(keyring_keys_metadata_iterator)>
keys_metadata_iterator("keyring_keys_metadata_iterator", m_reg_srv);
if (!keys_metadata_iterator.is_valid()) {
return true;
}
if (keys_metadata_iterator->init(&forward_iterator) == true) {
return true;
}
bool ok = false;
bool move_next = false;
for (; keys_metadata_iterator->is_valid(forward_iterator) && move_next;
move_next = !keys_metadata_iterator->next(forward_iterator)) {
if (keys_metadata_iterator->get(
forward_iterator, data_id, KEYRING_ITEM_BUFFER_SIZE, auth_id,
ok = true;
break;
}
std::cout << "Key name: " << data_id << ". User name: " << auth_id << "."
<< std::endl;
memset(data_id, 0, KEYRING_ITEM_BUFFER_SIZE);
memset(auth_id, 0, KEYRING_ITEM_BUFFER_SIZE);
}
if (keys_metadata_iterator->deinit(forward_iterator)) {
return true;
}
return ok;
}
struct my_h_keyring_keys_metadata_iterator_imp * my_h_keyring_keys_metadata_iterator
Definition: keyring_keys_metadata_iterator.h:28
constexpr auto KEYRING_ITEM_BUFFER_SIZE
Definition: table_keyring_keys.cc:45

◆ mysql_service_keyring_load_t

Keyring load service provides way to initialize or reiniitalize keyring component.

This must be implemented by any component that aims at providing keyring functionality.

bool initialize_keyring() {
my_service<SERVICE_TYPE(keyring_load)> keyring_load(
"keyring_load", m_reg_srv);
if (!keyring_load.is_valid()) {
log_error("Failed to obtain handle of keyring initialize service");
return true;
}
if (keyring_load->initialize(component_path, instance_path) == true) {
return true;
}
return false;
}
#define log_error(...)
Definition: log_client.h:154

◆ mysql_service_keyring_reader_with_status_t

Keyring reader with status service provides APIs to fetch sensitive data from keyring backend.

It is designed to be compatible with corresponding plugin method which returns state of the keyring as well.

Data stored within keyring should be uniquely identified using:

  1. Data ID An identifier associated with data - supplied by keyring APIs' callers
  2. Auth ID An identifier associated with owner of the data - suppled by keyring APIs' callers. If Auth ID is not provided, key is treated as an internal key. Such a key shalll not be accessible to database users using SQL interface

fetch and fetch_length APIs return a value indicating one of the 3 possible states.

  1. An error in keyring component
  2. Key is missing or there is a problem performing the operation
  3. Key is found and returned
bool read_key(const char *data_id, const char *auth_id, char **out_key_buffer,
size_t *out_key_length, char **out_key_type) {
*out_key_buffer = nullptr;
*out_key_type = nullptr;
*out_key_length = 0;
my_service<SERVICE_TYPE(keyring_reader_with_status)> keyring_reader(
"keyring_reader_with_status", m_reg_srv);
if (!keyring_reader.is_valid()) {
return true;
}
my_h_keyring_reader_object reader_object = nullptr;
int key_exists = 0;
bool retval = keyring_reader->init(data_id, auth_id, &reader_object,
&key_exists); if (retval) return true;
if (key_exists == 0)
return true;
auto cleanup_object = create_scope_guard([&]{
if (reader_object != nullptr) keyring_reader->deinit(reader_object);
reader_object = nullptr;
});
size_t key_length, key_type_length;
if (keyring_reader->fetch_length(data_id, auth_id, &key_length,
&key_type_length) == true) {
return true;
}
std::unique_ptr<char[]> key_buffer(new char[key_length]);
std::unique_ptr<char[]> key_type_buffer(new char[key_type_length + 1]);
if (key_buffer.get() == nullptr || key_type_buffer.get() == nullptr) {
return true;
}
memset(key_buffer.get(), 0, key_length);
memset(key_type_buffer.get(), 0, key_type_length + 1);
size t fetched_key_length = 0, fetched_key_type_length = 0;
if( keyring_reader->fetch(data_id, auth_id, key_buffer.get(),
key_length, &fetched_key_length,
key_type_buffer, key_type_length,
&fetched_key_type_length) == true)
return true;
*out_key_buffer = new char[](fetched_key_length);
*out_key_type = new char[](fetched_key_type_length + 1);
if (*out_key_buffer == nullptr || *out_key_type == nullptr) {
return true;
}
memset(*out_key_buffer, 0, fetched_key_length);
memset(*out_key_type, 0, fetched_key_type_length + 1);
memcpy(*out_key_buffer, key_buffer.get(), fetched_key_length);
memcpy(*out_key_type, key_type_buffer.get(), fetched_key_type_length);
*out_key_length = fetched_key_length;
return false;
}
struct my_h_keyring_reader_object_imp * my_h_keyring_reader_object
Definition: keyring_reader_with_status.h:28
void read_key(PSI_key_reader *, PSI_plugin_key_bigint *, int) noexcept
Definition: pfs_plugin_column_bigint_v1_all_empty.cc:36
Scope_guard< TLambda > create_scope_guard(const TLambda rollback_lambda)
Definition: scope_guard.h:60

Implementor can choose to: A. Read data from backend on each request B. Cache data in memory and server read requests from the cache

In case of B, care should be taken to keep cached data in sync with backend.

To go one step further, implementation may let user choose behavior (cached or otherwise) for read operation through configuration options.

◆ mysql_service_keyring_writer_t

Keyring writer service provides APIs to add/remove sensitive data to/from keyring backend.

Data stored within keyring should be uniquely identified using:

  1. Data ID An identifier associated with data - supplied by keyring APIs' callers
  2. Auth ID An identifier associated with owner of the data - suppled by keyring APIs' callers. If Auth ID is not provided, key is treated as an internal key. Such a key shalll not be accessible to database users using SQL interface
bool write_key(const char *data_id, const char *auth_id,
const unsigned char *data_buffer, size_t data_length,
const char *data_type) {
my_service<SERVICE_TYPE(keyring_writer)> keyring_writer("keyring_writer",
m_reg_srv);
if (!keyring_writer.is_valid()) {
return true;
}
return keyring_writer->store(data_id, auth_id, data_buffer, data_length,
data_type);
}
bool remove_key(const char *data_id, const char *auth_id) {
my_service<SERVICE_TYPE(keyring_writer)> keyring_writer("keyring_writer",
m_reg_srv);
if (!keyring_writer.is_valid()) {
return true;
}
return keyring_writer->remove(data_id, auth_id);
}
static uint remove_key(MI_KEYDEF *keyinfo, uint nod_flag, uchar *keypos, uchar *lastkey, uchar *page_end, my_off_t *next_block)
Definition: mi_delete.cc:708
static int write_key(MI_SORT_PARAM *info, uchar *key, IO_CACHE *tempfile)
Definition: sort.cc:353