MySQL 8.4.0
Source Code Documentation
operations.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef OPERATIONS_INCLUDED
25#define OPERATIONS_INCLUDED
26
27#include <memory> /* std::unique_ptr */
28
33
34/* clang-format off */
35/**
36 @page PAGE_COMPONENT_KEYRING_COMMON Common Keyring Implementation Infrastructure
37
38 keyring_common library includes modules that can be used in various keyring
39 implementation. This library provides implementation of following:
40
41 1. A JSON configuration file reader and parser
42 2. A data reader/writer using JSON as format
43 3. A backup file based file reader/writer
44 4. Sensitive data container
45 5. Metadata - Used to uniquely identify sensitive data
46 6. A wrapper to define extension over sensitive data
47 E.g. ID as provided by key management server
48 7. An in-memory cache to store Metadata OR {Metadata, Data}
49 8. An iterator over cache
50 9. Operations class to interface services APIs with implementation
51 10. AES encryption/decryption operations
52 11. Set of utility functions such as random data generator, hex converter etc.
53
54 Following diagram shows interactions between various parts of keyring_common
55 library and how they can be used to implement a keyring component.
56
57 The diagram uses a file based backend as example and how it can use
58 various modules provided by keyring_common library.
59
60 @startuml
61 package Error_logging {
62 object LogErr
63
64 LogErr -[#red]-> Service_implementation_templates
65 LogErr -[#red]-> Component_implementation
66 }
67
68 package Component_implementation {
69 object Service_implementation
70 object Backend
71 object Component_specific_constraints
72
73 Service_implementation <-[#red]- Backend
74 Backend <.[#red]. Json_data
75 Backend <.[#red]. Backup_aware_file_ops
76 Service_implementation -[#red]-> Operations
77 Backend <.[#red]. Encryption
78 Service_implementation <-[#red]- Config_reader
79 Component_specific_constraints -[#red]-> Service_implementation_templates
80 Service_implementation <-[#red]- service_definition_headers
81
82 Component_specific_constraints -[hidden]left- LogErr
83 }
84
85 package Library_mysys {
86 object Hex_tools
87
88 Backend -[hidden]right- Hex_tools
89 }
90
91 package Keyring_common {
92 package service_definition_headers {
93 object Writer_definition
94 object Load_definition
95 object Reader_definition
96 object Metadata_query_definition
97 object Keys_metadata_iterator_definition
98 object Generator_definition
99 object Encryption_definition
100
101 Load_definition -[hidden]up- Writer_definition
102 Writer_definition -[hidden]up- Reader_definition
103 Reader_definition -[hidden]up- Metadata_query_definition
104 Metadata_query_definition -[hidden]up- Keys_metadata_iterator_definition
105 Keys_metadata_iterator_definition -[hidden]up- Generator_definition
106 Generator_definition -[hidden]up- Encryption_definition
107 }
108
109 package Config_reader {
110 object Json_config_reader
111 }
112
113 package Backup_aware_file_ops {
114 object File_writer
115 object File_reader
116
117 File_reader <-[#red]left- File_writer
118 }
119
120 package Json_data {
121 object Json_writer
122 object Json_reader
123
124 Hex_tools -[#red]-> Json_reader
125 Hex_tools -[#red]-> Json_writer
126 }
127
128 package Data_representation {
129 object Data
130 object Metadata
131 }
132
133 package Memstore {
134 object Iterator
135 object Cache
136
137 Cache <-[#red]- Data_representation
138 Cache <-[#red]- Iterator
139 }
140
141 package Operations {
142 object Operation_manager
143
144 Operation_manager <-[#red]- Memstore
145 Operation_manager -[#red]-> Service_implementation_templates
146 }
147
148 package Utils {
149 object PRNG
150 }
151
152 package Encryption {
153 object AES
154 }
155
156 PRNG -[hidden]up- AES
157
158 package Internal_error_logging {
159 object Internal_LogErr
160
161 Internal_LogErr .[#red].> LogErr
162 }
163
164 package Service_implementation_templates {
165 object Writer_template
166 object Reader_template
167 object Metadata_query_template
168 object Keys_metadata_iterator_template
169 object Generator_template
170 object Encryption_template
171
172 Writer_template -[hidden]up- Reader_template
173 Reader_template -[hidden]up- Metadata_query_template
174 Metadata_query_template -[hidden]up- Keys_metadata_iterator_template
175 Keys_metadata_iterator_template -[hidden]up- Generator_template
176 Generator_template -[hidden]up- Encryption_template
177
178 Encryption -[#red]right-> Encryption_template
179 PRNG -[#red]-> Generator_template
180 }
181
182 Service_implementation -[hidden]down- Operations
183 }
184 @enduml
185*/
186
187/**
188 @page PAGE_COMPONENT_KEYRING_WRITE_NEW "How to write a new keyring component"
189
190 Common keyring implementation infrastructure provides useful parts to minimize
191 efforts involved in writing a new component. This page will provide details about
192 how a new keyring component can be implemented using the common infrastructure
193
194 Any keyring component can be divided in 3 parts:
195
196 1. Configuration Management
197 1. Service Implementation
198 3. Backend Management
199
200 @section configuration_management Configuration Management
201 A binary must be able to load a keyring component on top of minimal chassis.
202 Hence, the component cannot use option management provided by underlying binary
203 to read configuration for the keyring.
204
205 One way to read configuration is to accept it as a JSON file.
206 A sample configuration file may look like following:
207 @code
208 {
209 "version" : "1.0.0"
210 "config_key_1" : "config_data_1",
211 "config_key_2" : "config_data_2",
212 "config_key_3" : "config_data_3"
213 }
214 @endcode
215
216 Various (key, value) pair would help component get details required
217 to communicate with backend and initialize keyring.
218
219 You can use @ref keyring_common::config::Config_reader
220 to read a JSON file and extract value of individual configuration parameters.
221
222 Depending upon the services implemented by the component, it is possible that:
223
224 A> Configuration data can be queried at runtime
225
226 B> Configuration can be changed at runtime
227
228 @section service_implementation Service Implementation
229 Please refer to @ref PAGE_KEYRING_COMPONENT for description of various services
230 that a keyring component should implement. You may take a look at
231 @ref group_keyring_component_services_inventory for details about specific services
232 and various APIs.
233
234 If you are writing a keyring component that should work with MySQL server,
235 the component must implement following services.
236 1. Keyring reader service: @ref s_mysql_keyring_reader_with_status
237 Use @ref keyring_common::service_definition::Keyring_reader_service_impl
238 for service class declaration.
239 Use @ref KEYRING_READER_IMPLEMENTOR to add service implementation details
240 required by component infrastructure.
241 2. Keyring writer service: @ref s_mysql_keyring_writer
242 Use @ref keyring_common::service_definition::Keyring_writer_service_impl
243 for service class declaration.
244 Use @ref KEYRING_WRITER_IMPLEMENTOR to add service implementation details
245 required by component infrastructure.
246 3. Keyring generator service: @ref s_mysql_keyring_generator
247 Use @ref keyring_common::service_definition::Keyring_generator_service_impl
248 for service class declaration.
249 Use @ref KEYRING_GENERATOR_IMPLEMENTOR to add service implementation details
250 required by component infrastructure.
251 4. Keyring keys metadata iterator service: @ref s_mysql_keyring_keys_metadata_iterator
252 Use @ref keyring_common::service_definition::Keyring_keys_metadata_iterator_service_impl
253 for service class declaration.
254 Use @ref KEYRING_KEYS_METADATA_FORWARD_ITERATOR_IMPLEMENTOR to add service implementation details
255 required by component infrastructure.
256 5. Keyring component metadata query service: @ref s_mysql_keyring_component_metadata_query
257 Use @ref keyring_common::service_definition::Keyring_metadata_query_service_impl
258 for service class declaration.
259 Use @ref KEYRING_COMPONENT_METADATA_QUERY_IMPLEMENTOR to add service implementation details
260 required by component infrastructure.
261 6. Keyring load service: @ref s_mysql_keyring_load
262 Use @ref keyring_common::service_definition::Keyring_load_service_impl
263 for service class declaration.
264 Use @ref KEYRING_LOAD_IMPLEMENTOR to add service implementation details
265 required by component infrastructure.
266 7. Keyring AES service: @ref s_mysql_keyring_aes
267 Use @ref keyring_common::service_definition::Keyring_aes_service_impl
268 for service class declaration.
269 Use @ref KEYRING_AES_IMPLEMENTOR to add service implementation details
270 required by component infrastructure.
271 8. Keyring status service: @ref s_mysql_keyring_component_status
272 Use @ref keyring_common::service_definition::Keyring_metadata_query_service_impl
273 for service class declaration.
274 Use @ref KEYRING_COMPONENT_STATUS_IMPLEMENTOR to add service implementation details
275 required by component infrastructure.
276
277 Please note that key of type AES and SECRET must be supported.
278
279 In addition, you will also need to implement log_builtins and log_builtins_string
280 services if you are planning to use keyring common's implementation templates.
281 The common keyring infrastrcture has a bare-minimum implementation of these
282 services. You can use @ref keyring_common::service_definition::Log_builtins_keyring
283 for service class declaration. Use @ref KEYRING_LOG_BUILTINS_IMPLEMENTOR and
284 @ref KEYRING_LOG_BUILTINS_STRING_IMPLEMENTOR to add service implementation details
285 required by component infrastrcture.
286
287 Common keyring infrastructure also provides implementation for some of the above
288 mentioned services. This will allow implementor to create a minimal definition of
289 service APIs and use templates provided by common infra.
290
291 In order to do that, common keyring infrastrcture requires following:
292
293 1. A handle to @ref keyring_common::operations::Keyring_operations object
294 This class provides a wrapper over keyring backend and expect that implementor provides
295 handle to a backend class with set of APIs required to manage keys. Please see
296 @ref backend_management for more details.
297 2. A handle to @ref keyring_common::service_implementation::Component_callbacks object
298 This class provides callback methods which are implemented by individual component.
299 For example: Keyring state, Maximum supported data length, metadata vector creation etc.
300
301 Assumping that above mentioned dependencies are satisfied, following are some inputs
302 on how various services can be implemented.
303 1. Keyring reader service: @ref s_mysql_keyring_reader_with_status
304 See @ref keyring_common::service_implementation::init_reader_template
305 See @ref keyring_common::service_implementation::deinit_reader_template
306 See @ref keyring_common::service_implementation::fetch_length_template
307 See @ref keyring_common::service_implementation::fetch_template
308 2. Keyring writer service: @ref s_mysql_keyring_writer
309 See @ref keyring_common::service_implementation::store_template
310 See @ref keyring_common::service_implementation::remove_template
311 3. Keyring generator service: @ref s_mysql_keyring_generator
312 See @ref keyring_common::service_implementation::generate_template
313 4. Keyring keys metadata iterator service: @ref s_mysql_keyring_keys_metadata_iterator
314 See @ref keyring_common::service_implementation::init_keys_metadata_iterator_template
315 See @ref keyring_common::service_implementation::deinit_keys_metadata_iterator_template
316 See @ref keyring_common::service_implementation::keys_metadata_iterator_is_valid
317 See @ref keyring_common::service_implementation::keys_metadata_iterator_next
318 See @ref keyring_common::service_implementation::keys_metadata_get_length_template
319 See @ref keyring_common::service_implementation::keys_metadata_get_template
320 5. Keyring component metadata query service: @ref s_mysql_keyring_component_metadata_query
321 See @ref keyring_common::service_implementation::keyring_metadata_query_init_template
322 See @ref keyring_common::service_implementation::keyring_metadata_query_deinit_template
323 See @ref keyring_common::service_implementation::keyring_metadata_query_is_valid_template
324 See @ref keyring_common::service_implementation::keyring_metadata_query_next_template
325 See @ref keyring_common::service_implementation::keyring_metadata_query_get_length_template
326 See @ref keyring_common::service_implementation::keyring_metadata_query_get_template
327 6. Keyring load service: @ref s_mysql_keyring_load
328 This service is specific to individual keyring component because it has strong
329 dependency on component specific configuration details. The component should implement
330 it as per its own requirement.
331 7. Keyring AES service: @ref s_mysql_keyring_aes
332 See @ref keyring_common::service_implementation::aes_get_encrypted_size_template
333 See @ref keyring_common::service_implementation::aes_encrypt_template
334 See @ref keyring_common::service_implementation::aes_decrypt_template
335 8. Keyring status service: @ref s_mysql_keyring_component_status
336 See @ref keyring_common::service_implementation::keyring_metadata_query_keyring_initialized_template
337
338 @section backend_management Backend Management
339 This part would be different for each keyring component. Backend can be a remote server,
340 something that stored locally or a combination of both. Regardless of the backend, if
341 @ref keyring_common::operations::Keyring_operations is to be used, component must implement
342 a class similar to following:
343
344 @code
345 template <typename Data_extension>
346 class Backend {
347 public:
348 // Fetch data
349
350 // @param [in] metadata Key
351 // @param [out] data Value
352
353 // @returns Status of find operation
354 // @retval false Entry found. Check data.
355 // @retval true Entry missing.
356 bool get(const keyring_common::meta::Metadata &metadata,
357 keyring_common::data::Data &data) const;
358
359 // Store data
360
361 // @param [in] metadata Key
362 // @param [in, out] data Value
363
364 // @returns Status of store operation
365 // @retval false Entry stored successfully
366 // @retval true Failure
367 bool store(const keyring_common::meta::Metadata &metadata,
368 keyring_common::data::Data &data);
369
370 // Erase data located at given key
371
372 // @param [in] metadata Key
373 // @param [in] data Value - not used.
374
375 // @returns Status of erase operation
376 // @retval false Data deleted
377 // @retval true Could not find or delete data
378 bool erase(const keyring_common::meta::Metadata &metadata,
379 keyring_common::data::Data &data);
380
381 // Generate random data and store it
382
383 // @param [in] metadata Key
384 // @param [out] data Generated value
385 // @param [in] length Length of data to be generated
386
387 // @returns Status of generate + store operation
388 // @retval false Data generated and stored successfully
389 // @retval true Error
390 bool generate(const keyring_common::meta::Metadata &metadata,
391 keyring_common::data::Data &data, size_t length);
392
393 // Populate cache
394
395 // @param [in] operations Handle to operations class
396
397 // @returns status of cache insertion
398 // @retval false Success
399 // @retval true Failure
400 bool load_cache(
401 keyring_common::operations::Keyring_operations<Keyring_file_backend>
402 &operations);
403
404 // Maximum data length supported
405 size_t maximum_data_length() const;
406
407 // Get number of elements stored in backend
408 size_t size() const;
409 };
410 @endcode
411
412 Common keyring infrastructure includes implementation that may help file management.
413 It provides a content agnostic, backup aware file reader and writer.
414
415 Writer works in following manner:
416 - Write content to backup file
417 - If backup file exists, copy its content to main file
418 - Remove backup file
419
420 Reader works in following manner:
421 - Invoke writer to process backup file, if it exists
422 - Read from main file
423
424 Please see @ref keyring_common::data_file::File_writer for writer details and
425 @ref keyring_common::data_file::File_reader for reader details.
426
427 @section in_member_data_management In-memory Data Management
428
429 Common keyring infrastructure also provides useful classes to manage data in memory.
430
431 1. To cache metadata related to data, use @ref keyring_common::meta::Metadata
432 2. To cache data in memory, use @ref keyring_common::data::Data
433 3. To cache backend specific details for data (e.g. ID generated by backend),
434 use @ref keyring_common::data::Data_extension
435 4. A reader/writer pair for JSON data that can be used to store data, related metadata
436 and data extension if any. See @ref keyring_common::json_data::Json_reader
437 and @ref keyring_common::json_data::Json_writer.
438
439 Expected JSON format is specified below:
440
441 @code
442
443 {
444 "version": "1.0",
445 "elements": [
446 {
447 "user": "<user_name>",
448 "data_id": "<name>",
449 "data_type": "<data_type>",
450 "data": "<hex_of_data>",
451 "extension": [
452 ]
453 },
454 ...
455 ...
456 ]
457 }
458
459 @endcode
460*/
461
462/* clang-format on */
463
464namespace keyring_common {
465
466namespace operations {
467
468/**
469 Keyring operations
470 A class to perform operations on keyring.
471 If cache is enabled, operations uses it. Otherwise,
472 backend is used.
473
474 Assumptions:
475 1. Backend implements interface to keyring backend.
476 2. Backend is required to support same Data_extension as Keyring_operations
477
478 Please see @ref PAGE_COMPONENT_KEYRING_WRITE_NEW for details about
479 Backend class.
480*/
481
482template <typename Backend, typename Data_extension = data::Data>
484 public:
485 /**
486 Constructor
487
488 @param [in] cache_data Whether to cache data or not
489 @param [in] backend Pointer to keyring backend
490
491 Populates the cache from backend
492 */
493 explicit Keyring_operations(bool cache_data, Backend *backend)
494 : cache_(), cache_data_(cache_data), backend_(backend), valid_(false) {
495 load_cache();
496 }
497
499
500 /**
501 Insert API to populate cache
502
503 @param [in] metadata Key to the data
504 @param [in] secret_data Actual data
505
506 @returns status of insertion
507 @retval false Success
508 @retval true Failure
509 */
510 bool insert(const meta::Metadata &metadata, Data_extension secret_data) {
511 /* valid_ = true implies cache is operational. Do not permit bulk insert */
512 if (valid_ == true) return true;
513 if (!cache_data_) secret_data.set_data(data::Data{});
514 return !cache_.store(metadata, secret_data);
515 }
516
517 public:
518 /**
519 Search API
520
521 @param [in] metadata Key to the data
522 @param [out] data Fetched data
523
524 @returns status of search operation
525 @retval false Success - data contains required information
526 @retval true Failure - data is not valid
527 */
528 bool get(const meta::Metadata &metadata, data::Data &data) {
529 Data_extension fetched_data;
530 if (!metadata.valid()) return true;
531 if (!cache_.get(metadata, fetched_data)) return true;
532 if (!cache_data_) {
533 /* Fetch data from backend */
534 if ((*backend_).get(metadata, fetched_data)) return true;
535 }
536 data = fetched_data.get_data();
537 return false;
538 }
539
540 /**
541 Get Backend-specific data extension
542
543 @param [in] metadata Key to the data
544 @param [out] data Fetched data extension
545
546 @returns status of search operation
547 @retval false Success - data contains required information
548 @retval true Failure - data is not valid
549
550 NOTE: get_data_extension NEVER returns data.
551 It only returns Data extension information.
552 */
553 bool get_data_extension(const meta::Metadata &metadata,
554 Data_extension &data) {
555 if (!metadata.valid()) return true;
556 if (!cache_.get(metadata, data)) return true;
557 if (cache_data_) data.set_data(data::Data{});
558 return false;
559 }
560
561 /**
562 Store API
563
564 @param [in] metadata Key to the data
565 @param [in] data Data to be stored
566
567 @returns status of store operation
568 @retval false Success - data stored
569 @retval true Failure
570 */
571 bool store(const meta::Metadata &metadata, const data::Data &data) {
572 Data_extension stored_data(data);
573 if (!metadata.valid()) return true;
574 Data_extension fetched_data;
575 if (cache_.get(metadata, fetched_data)) return true;
576 if ((*backend_).store(metadata, stored_data)) return true;
577 /*
578 Note: We always cache metadata.
579 So we always consult the operation's cache first
580 to see if valid (data_id, auth_id) pair exists.
581
582 This would also retrieve backend specific metadata
583 if any.
584
585 Once we confirm that key is present, we then fetch
586 the data either from the cache(if caching is ON)
587 or from the backend(if caching is OFF).
588 */
589 if (!cache_data_) {
590 /* Just store the metadata */
591 stored_data.set_data(data::Data{});
592 }
593 if (!cache_.store(metadata, stored_data)) {
594 /* Failed caching the data. Remove it from backend too. */
595 (void)(*backend_).erase(metadata, stored_data);
596 return true;
597 }
598 return false;
599 }
600
601 /**
602 Remove API
603
604 @param [in] metadata Key to the data
605
606 @returns status of remove operation
607 @retval false Success - data removed OR does not exist
608 @retval true Failure
609 */
610 bool erase(const meta::Metadata &metadata) {
611 if (!metadata.valid()) return true;
612 Data_extension fetched_data;
613 /* Get backend specific extension from cache */
614 if (!cache_.get(metadata, fetched_data)) return true;
615 /* Remove it from backend */
616 if ((*backend_).erase(metadata, fetched_data)) return true;
617 /* Remove it from the cache */
618 cache_.erase(metadata);
619 return false;
620 }
621
622 /**
623 Generate API
624
625 @param [in] metadata Key for the data
626 @param [in] type Type of data
627 @param [in] length Length of data to be generated
628
629 @returns status of data generation
630 @retval false Success - data generated and stored in backend
631 @retval true Failure
632 */
633 bool generate(const meta::Metadata &metadata, const data::Type type,
634 size_t length) {
635 if (!metadata.valid()) return true;
636 data::Data g_data(type);
637 Data_extension generated_data(g_data);
638 if (cache_.get(metadata, generated_data)) return true;
639 if ((*backend_).generate(metadata, generated_data, length)) return true;
640 if (!cache_data_) generated_data.set_data(data::Data{});
641 if (!cache_.store(metadata, generated_data)) {
642 /* Failed to cache the data, remove it from backend too */
643 (void)(*backend_).erase(metadata, generated_data);
644 return true;
645 }
646 return false;
647 }
648
649 /**
650 Iterator creation for read
651
652 If data is cached, iterator on cached data is returned.
653 Otherwise iterator created by backend is returned.
654
655 @param [out] it Forward iterator to metadata
656 @param [in] metadata Metadata for the record to be searched
657
658 @returns Status
659 @retval false Success
660 @retval true Failure
661 */
664 const meta::Metadata &metadata) {
665 if (!valid()) return true;
666 if (!metadata.valid()) return true;
667 it = std::make_unique<iterator::Iterator<Data_extension>>(cache_, metadata);
668 return (it.get() == nullptr);
669 }
670
671 /**
672 Iterator creation
673
674 @param [out] it Forward iterator to metadata
675 @param [in] cached Iterator type
676
677 @returns Status
678 @retval false Success
679 @retval true Failure
680 */
683 if (!valid()) return true;
684 it = std::make_unique<iterator::Iterator<Data_extension>>(cache_, cached);
685 return (it.get() == nullptr);
686 }
687
688 /**
689 Iterator destruction
690
691 @param [in, out] it Forward iterator to metadata
692
693 */
696 it.reset(nullptr);
697 }
698
699 /**
700 Check iterator validity
701
702 @param [in] it Forward iterator to metadata
703
704 @returns Status
705 @retval true Valid
706 @retval false Invalid
707 */
709 return (valid() && it.get() != nullptr && (*it).valid(cache_.version()));
710 }
711
712 /**
713 Move iterator forward
714
715 @param [in] it Forward iterator to metadata
716
717 @returns Status
718 @retval false Success
719 @retval true Failure
720 */
722 if (valid() && it.get() != nullptr) return !((*it).next(cache_.version()));
723 return true;
724 }
725
726 /**
727 Get data from iterator
728
729 @param [in] it Forward iterator to metadata
730 @param [out] metadata Metadata for given key
731 @param [out] data Data for given key (Including extension)
732
733 @returns Status
734 @retval false Success
735 @retval true Failure
736 */
739 meta::Metadata &metadata, Data_extension &data) {
740 if (!valid() || it.get() == nullptr || !(*it).valid(cache_.version()))
741 return true;
742 if (!(*it).metadata(cache_.version(), metadata)) return true;
743 if (cache_data_) {
744 if (!(*it).data(cache_.version(), data)) return true;
745 } else {
746 cache_.get(metadata, data);
747 if ((*backend_).get(metadata, data)) return true;
748 }
749 return !metadata.valid();
750 }
751
752 /**
753 Get metadata from iterator
754
755 @param [in] it Forward iterator to metadata
756 @param [out] metadata Metadata for given key
757 @param [out] data Extension for given key
758
759 @returns Status
760 @retval false Success
761 @retval true Failure
762 */
765 meta::Metadata &metadata, Data_extension &data) {
766 if (!valid() || it.get() == nullptr || !(*it).valid(cache_.version()))
767 return true;
768 if (!(*it).metadata(cache_.version(), metadata)) return true;
769 if (!(*it).data(cache_.version(), data)) return true;
770 if (cache_data_) data.set_data(data::Data{});
771 return !metadata.valid();
772 }
773
774 /**
775 Maximum data length supported
776
777 @returns Maximum length supported
778 */
779 size_t maximum_data_length() const {
780 return (*backend_).maximum_data_length();
781 }
782
783 /** Keyring size */
784 size_t keyring_size() { return cache_.size(); }
785
786 /** Validity */
787 bool valid() { return valid_; }
788
789 private:
790 void load_cache() {
791 Backend *backend = backend_.get();
792 /* Clear the cache */
793 cache_.clear();
794
795 valid_ = false;
796 if (backend == nullptr || backend->size() == 0) {
797 valid_ = true;
798 return;
799 }
800
801 if (backend->load_cache(*this) == true) return;
802
803 /*
804 If we fail to load metadata (and data) for all keys,
805 wipe the cache clean.
806 */
807 if (backend->size() != cache_.size()) {
808 cache_.clear();
809 } else {
810 valid_ = true;
811 }
812 }
813
814 /** Metadata cache */
816 /** Flag to cache data */
818 /** Keyring backend */
819 std::unique_ptr<Backend> backend_;
820 /** Validity */
821 bool valid_;
822};
823
824} // namespace operations
825
826} // namespace keyring_common
827
828#endif // !OPERATIONS_INCLUDED
Definition: cache.h:41
Sensitive data storage.
Definition: data.h:40
virtual const Data get_data() const
Return self.
Definition: data.cc:65
Definition: iterator.h:33
Common metadata.
Definition: meta.h:39
bool valid() const
Validity of metadata object.
Definition: meta.cc:76
Keyring operations A class to perform operations on keyring.
Definition: operations.h:483
bool erase(const meta::Metadata &metadata)
Remove API.
Definition: operations.h:610
bool next(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Move iterator forward.
Definition: operations.h:721
bool generate(const meta::Metadata &metadata, const data::Type type, size_t length)
Generate API.
Definition: operations.h:633
Keyring_operations(bool cache_data, Backend *backend)
Constructor.
Definition: operations.h:493
bool get_data_extension(const meta::Metadata &metadata, Data_extension &data)
Get Backend-specific data extension.
Definition: operations.h:553
bool store(const meta::Metadata &metadata, const data::Data &data)
Store API.
Definition: operations.h:571
bool get_iterator_data(std::unique_ptr< iterator::Iterator< Data_extension > > &it, meta::Metadata &metadata, Data_extension &data)
Get data from iterator.
Definition: operations.h:737
size_t maximum_data_length() const
Maximum data length supported.
Definition: operations.h:779
bool init_forward_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it, bool cached)
Iterator creation.
Definition: operations.h:681
bool cache_data_
Flag to cache data.
Definition: operations.h:817
void deinit_forward_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Iterator destruction.
Definition: operations.h:694
bool valid()
Validity.
Definition: operations.h:787
bool insert(const meta::Metadata &metadata, Data_extension secret_data)
Insert API to populate cache.
Definition: operations.h:510
bool is_valid(std::unique_ptr< iterator::Iterator< Data_extension > > &it)
Check iterator validity.
Definition: operations.h:708
void load_cache()
Definition: operations.h:790
bool init_read_iterator(std::unique_ptr< iterator::Iterator< Data_extension > > &it, const meta::Metadata &metadata)
Iterator creation for read.
Definition: operations.h:662
cache::Datacache< Data_extension > cache_
Metadata cache.
Definition: operations.h:815
std::unique_ptr< Backend > backend_
Keyring backend.
Definition: operations.h:819
size_t keyring_size()
Keyring size.
Definition: operations.h:784
bool get_iterator_metadata(std::unique_ptr< iterator::Iterator< Data_extension > > &it, meta::Metadata &metadata, Data_extension &data)
Get metadata from iterator.
Definition: operations.h:763
bool get(const meta::Metadata &metadata, data::Data &data)
Search API.
Definition: operations.h:528
bool valid_
Validity.
Definition: operations.h:821
operations
Definition: mysqlcheck.h:39
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
std::string Type
Data types.
Definition: data.h:33
Definition: keyring_encryption_service_definition.h:32
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2438
required string type
Definition: replication_group_member_actions.proto:34
static double cached
Definition: xcom_statistics.cc:101