MySQL 8.0.31
Source Code Documentation
keyring_reader_with_status.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
2
3This program is free software; you can redistribute it and/or modify
4it under the terms of the GNU General Public License, version 2.0,
5as published by the Free Software Foundation.
6
7This program is also distributed with certain software (including
8but not limited to OpenSSL) that is licensed under separate terms,
9as designated in a particular file or component or in included license
10documentation. The authors of MySQL hereby grant you an additional
11permission to link the program and your derivative works with the
12separately licensed software that they have included with MySQL.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License, version 2.0, for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef KEYRING_READER_WITH_STATUS_INCLUDED
24#define KEYRING_READER_WITH_STATUS_INCLUDED
25
27
29
30/**
31 @ingroup group_keyring_component_services_inventory
32
33 Keyring reader with status service provides APIs to
34 fetch sensitive data from keyring backend
35
36 It is designed to be compatible with corresponding plugin
37 method which returns state of the keyring as well.
38
39 Data stored within keyring should be uniquely identified using:
40 1. Data ID
41 An identifier associated with data - supplied by keyring APIs' callers
42 2. Auth ID
43 An identifier associated with owner of the data - suppled by keyring
44 APIs' callers. If Auth ID is not provided, key is treated as an internal
45 key. Such a key shalll not be accessible to database users using
46 SQL interface
47
48 fetch and fetch_length APIs return a value indicating
49 one of the 3 possible states.
50 1. An error in keyring component
51 2. Key is missing or there is a problem performing the operation
52 3. Key is found and returned
53
54 @code
55 bool read_key(const char *data_id, const char *auth_id, char **out_key_buffer,
56 size_t *out_key_length, char **out_key_type) {
57 *out_key_buffer = nullptr;
58 *out_key_type = nullptr;
59 *out_key_length = 0;
60 my_service<SERVICE_TYPE(keyring_reader_with_status)> keyring_reader(
61 "keyring_reader_with_status", m_reg_srv);
62 if (!keyring_reader.is_valid()) {
63 return true;
64 }
65
66 my_h_keyring_reader_object reader_object = nullptr;
67 int key_exists = 0;
68 bool retval = keyring_reader->init(data_id, auth_id, &reader_object,
69 &key_exists); if (retval) return true;
70
71 if (key_exists == 0)
72 return true;
73
74 auto cleanup_object = create_scope_guard([&]{
75 if (reader_object != nullptr) keyring_reader->deinit(reader_object);
76 reader_object = nullptr;
77 });
78 size_t key_length, key_type_length;
79 if (keyring_reader->fetch_length(data_id, auth_id, &key_length,
80 &key_type_length) == true) {
81 return true;
82 }
83
84 std::unique_ptr<char[]> key_buffer(new char[key_length]);
85 std::unique_ptr<char[]> key_type_buffer(new char[key_type_length + 1]);
86 if (key_buffer.get() == nullptr || key_type_buffer.get() == nullptr) {
87 return true;
88 }
89 memset(key_buffer.get(), 0, key_length);
90 memset(key_type_buffer.get(), 0, key_type_length + 1);
91
92 size t fetched_key_length = 0, fetched_key_type_length = 0;
93 if( keyring_reader->fetch(data_id, auth_id, key_buffer.get(),
94 key_length, &fetched_key_length,
95 key_type_buffer, key_type_length,
96 &fetched_key_type_length) == true)
97 return true;
98
99 *out_key_buffer = new char[](fetched_key_length);
100 *out_key_type = new char[](fetched_key_type_length + 1);
101 if (*out_key_buffer == nullptr || *out_key_type == nullptr) {
102 return true;
103 }
104 memset(*out_key_buffer, 0, fetched_key_length);
105 memset(*out_key_type, 0, fetched_key_type_length + 1);
106 memcpy(*out_key_buffer, key_buffer.get(), fetched_key_length);
107 memcpy(*out_key_type, key_type_buffer.get(), fetched_key_type_length);
108 *out_key_length = fetched_key_length;
109
110 return false;
111 }
112 @endcode
113
114 Implementor can choose to:
115 A. Read data from backend on each request
116 B. Cache data in memory and server read requests from the cache
117
118 In case of B, care should be taken to keep cached data
119 in sync with backend.
120
121 To go one step further, implementation may let user choose
122 behavior (cached or otherwise) for read operation through
123 configuration options.
124
125*/
126
127BEGIN_SERVICE_DEFINITION(keyring_reader_with_status)
128
129/**
130 Initialize reader
131
132 @param [in] data_id Data Identifier. Byte string.
133 @param [in] auth_id Authorization ID. Byte string.
134 @param [out] reader_object Reader object
135
136 If return value is false, here is how value of reader_object
137 is interpreted:
138 reader_object == nullptr implies key does not exist
139 reader_object != nullptr implies key exists
140
141 @returns status of the operation
142 @retval false Success - Does not mean that key is found.
143 @retval true Failure
144*/
145DECLARE_BOOL_METHOD(init, (const char *data_id, const char *auth_id,
147
148/**
149 Deinitialize reader
150
151 @param [in] reader_object Reader object
152
153 @returns status of the operation
154 @retval false Success
155 @retval true Failure
156*/
158
159/**
160 Fetch length of the data if it exists
161 data_size and data_type_size must not be nullptr.
162
163 Data_type value is implementation specific. It associates type
164 label with data which may be an important indicator for certain
165 backends.
166
167 Minimum expectation: AES, SECRET
168
169 @param [in] reader_object Reader object
170 @param [out] data_size Size of fetched data in bytes
171 @param [out] data_type_size Size of data type
172
173 @returns status of the operation
174 @retval false success
175 @retval true failure
176*/
177DECLARE_BOOL_METHOD(fetch_length, (my_h_keyring_reader_object reader_object,
178 size_t *data_size, size_t *data_type_size));
179
180/**
181 Fetches data if it exists.
182 All pointer parameters must be non-null.
183
184 Data_type value is implementation specific. It associates type
185 label with data which may be an important indicator for certain
186 backends.
187
188 Minimum expectation: AES, SECRET
189
190 data_buffer size must be enough to hold data
191 data_type size must be enough to hold datatype and
192 a null-terminating character
193
194 @sa fetch_length - To fetch length information about sensitive data
195
196 @param [in] reader_object Reader object
197 @param [out] data_buffer Out buffer for data. Byte string.
198 @param [in] data_buffer_length Length of out buffer
199 @param [out] data_size Size of fetched data
200 @param [out] data_type Type of data. ASCII. Null terminated.
201 @param [in] data_type_buffer_length Length of data type buffer
202 @param [out] data_type_size Size of fetched datatype
203
204 @returns status of the operation
205 @retval false success
206 @retval true failure
207*/
208
210 (my_h_keyring_reader_object reader_object,
211 unsigned char *data_buffer, size_t data_buffer_length,
212 size_t *data_size, char *data_type,
213 size_t data_type_buffer_length, size_t *data_type_size));
214
215END_SERVICE_DEFINITION(keyring_reader_with_status)
216
217#endif // !KEYRING_READER_WITH_STATUS_INCLUDED
static mysql_service_status_t deinit()
Component deinitialization.
Definition: audit_api_message_emit.cc:579
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
struct my_h_keyring_reader_object_imp * my_h_keyring_reader_object
Definition: keyring_reader_with_status.h:28
static mysql_service_status_t fetch(const char *service_name, reference_caching_channel *out_channel) noexcept
Definition: component.cc:76
#define END_SERVICE_DEFINITION(name)
A macro to end the last Service definition started with the BEGIN_SERVICE_DEFINITION macro.
Definition: service.h:90
#define BEGIN_SERVICE_DEFINITION(name)
Declares a new Service.
Definition: service.h:85
#define DEFINE_SERVICE_HANDLE(name)
Defines an object type that is meant for carrying handles to the implementation-specific objects used...
Definition: service.h:128
#define DECLARE_BOOL_METHOD(name, args)
Declares a method that returns bool as a part of the Service definition.
Definition: service.h:111