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