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