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