1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 #ifndef TINK_INTERNAL_SERIALIZATION_REGISTRY_H_ 18 #define TINK_INTERNAL_SERIALIZATION_REGISTRY_H_ 19 20 #include <map> 21 #include <memory> 22 #include <string> 23 #include <typeindex> 24 #include <typeinfo> 25 26 #include "absl/container/flat_hash_map.h" 27 #include "absl/status/status.h" 28 #include "absl/strings/str_format.h" 29 #include "absl/types/optional.h" 30 #include "tink/internal/key_parser.h" 31 #include "tink/internal/key_serializer.h" 32 #include "tink/internal/parameters_parser.h" 33 #include "tink/internal/parameters_serializer.h" 34 #include "tink/internal/parser_index.h" 35 #include "tink/internal/serialization.h" 36 #include "tink/internal/serializer_index.h" 37 #include "tink/key.h" 38 #include "tink/parameters.h" 39 #include "tink/util/status.h" 40 #include "tink/util/statusor.h" 41 42 namespace crypto { 43 namespace tink { 44 namespace internal { 45 46 class SerializationRegistry { 47 public: 48 class Builder { 49 public: 50 // Neither movable nor copyable. 51 Builder(const Builder& other) = delete; 52 Builder& operator=(const Builder& other) = delete; 53 54 // Creates initially empty serialization registry builder. 55 Builder() = default; 56 // Creates serialization registry builder by initially copying entries from 57 // `registry`. 58 explicit Builder(const SerializationRegistry& registry); 59 60 // Registers parameters `parser`. Returns an error if a different parameters 61 // parser has already been registered. 62 util::Status RegisterParametersParser(ParametersParser* parser); 63 64 // Registers parameters `serializer`. Returns an error if a different 65 // parameters serializer has already been registered. 66 util::Status RegisterParametersSerializer(ParametersSerializer* serializer); 67 68 // Registers key `parser`. Returns an error if a different key parser has 69 // already been registered. 70 util::Status RegisterKeyParser(KeyParser* parser); 71 72 // Registers key `serializer`. Returns an error if a different key 73 // serializer has already been registered. 74 util::Status RegisterKeySerializer(KeySerializer* serializer); 75 76 // Creates serialization registry from this builder. 77 SerializationRegistry Build(); 78 79 private: Builder(const absl::flat_hash_map<ParserIndex,ParametersParser * > & parameters_parsers,const absl::flat_hash_map<SerializerIndex,ParametersSerializer * > & parameters_serializers,const absl::flat_hash_map<ParserIndex,KeyParser * > key_parsers,const absl::flat_hash_map<SerializerIndex,KeySerializer * > key_serializers)80 Builder(const absl::flat_hash_map<ParserIndex, ParametersParser*>& 81 parameters_parsers, 82 const absl::flat_hash_map<SerializerIndex, ParametersSerializer*>& 83 parameters_serializers, 84 const absl::flat_hash_map<ParserIndex, KeyParser*> key_parsers, 85 const absl::flat_hash_map<SerializerIndex, KeySerializer*> 86 key_serializers) 87 : parameters_parsers_(parameters_parsers), 88 parameters_serializers_(parameters_serializers), 89 key_parsers_(key_parsers), 90 key_serializers_(key_serializers) {} 91 92 absl::flat_hash_map<ParserIndex, ParametersParser*> parameters_parsers_; 93 absl::flat_hash_map<SerializerIndex, ParametersSerializer*> 94 parameters_serializers_; 95 absl::flat_hash_map<ParserIndex, KeyParser*> key_parsers_; 96 absl::flat_hash_map<SerializerIndex, KeySerializer*> key_serializers_; 97 }; 98 99 // Movable and copyable. 100 SerializationRegistry(SerializationRegistry&& other) = default; 101 SerializationRegistry& operator=(SerializationRegistry&& other) = default; 102 SerializationRegistry(const SerializationRegistry& other) = default; 103 SerializationRegistry& operator=(const SerializationRegistry& other) = 104 default; 105 106 // Creates empty serialization registry. 107 SerializationRegistry() = default; 108 109 // Parses `serialization` into a `Parameters` instance. 110 util::StatusOr<std::unique_ptr<Parameters>> ParseParameters( 111 const Serialization& serialization) const; 112 113 // Serializes `parameters` into a `Serialization` instance. 114 template <typename SerializationT> SerializeParameters(const Parameters & parameters)115 util::StatusOr<std::unique_ptr<Serialization>> SerializeParameters( 116 const Parameters& parameters) const { 117 SerializerIndex index = SerializerIndex::Create<SerializationT>(parameters); 118 auto it = parameters_serializers_.find(index); 119 if (it == parameters_serializers_.end()) { 120 return util::Status( 121 absl::StatusCode::kNotFound, 122 absl::StrFormat( 123 "No parameters serializer found for parameters type %s", 124 typeid(parameters).name())); 125 } 126 127 return parameters_serializers_.at(index)->SerializeParameters(parameters); 128 } 129 130 // Parses `serialization` into a `Key` instance. 131 util::StatusOr<std::unique_ptr<Key>> ParseKey( 132 const Serialization& serialization, 133 absl::optional<SecretKeyAccessToken> token) const; 134 135 // Serializes `parameters` into a `Serialization` instance. 136 template <typename SerializationT> SerializeKey(const Key & key,absl::optional<SecretKeyAccessToken> token)137 util::StatusOr<std::unique_ptr<Serialization>> SerializeKey( 138 const Key& key, absl::optional<SecretKeyAccessToken> token) const { 139 SerializerIndex index = SerializerIndex::Create<SerializationT>(key); 140 auto it = key_serializers_.find(index); 141 if (it == key_serializers_.end()) { 142 return util::Status( 143 absl::StatusCode::kNotFound, 144 absl::StrFormat("No key serializer found for key type %s", 145 typeid(key).name())); 146 } 147 148 return key_serializers_.at(index)->SerializeKey(key, token); 149 } 150 151 private: SerializationRegistry(const absl::flat_hash_map<ParserIndex,ParametersParser * > & parameters_parsers,const absl::flat_hash_map<SerializerIndex,ParametersSerializer * > & parameters_serializers,const absl::flat_hash_map<ParserIndex,KeyParser * > key_parsers,const absl::flat_hash_map<SerializerIndex,KeySerializer * > key_serializers)152 SerializationRegistry( 153 const absl::flat_hash_map<ParserIndex, ParametersParser*>& 154 parameters_parsers, 155 const absl::flat_hash_map<SerializerIndex, ParametersSerializer*>& 156 parameters_serializers, 157 const absl::flat_hash_map<ParserIndex, KeyParser*> key_parsers, 158 const absl::flat_hash_map<SerializerIndex, KeySerializer*> 159 key_serializers) 160 : parameters_parsers_(parameters_parsers), 161 parameters_serializers_(parameters_serializers), 162 key_parsers_(key_parsers), 163 key_serializers_(key_serializers) {} 164 165 absl::flat_hash_map<ParserIndex, ParametersParser*> parameters_parsers_; 166 absl::flat_hash_map<SerializerIndex, ParametersSerializer*> 167 parameters_serializers_; 168 absl::flat_hash_map<ParserIndex, KeyParser*> key_parsers_; 169 absl::flat_hash_map<SerializerIndex, KeySerializer*> key_serializers_; 170 }; 171 172 } // namespace internal 173 } // namespace tink 174 } // namespace crypto 175 176 #endif // TINK_INTERNAL_SERIALIZATION_REGISTRY_H_ 177