xref: /aosp_15_r20/external/tink/cc/internal/serialization_registry.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 #include "tink/internal/serialization_registry.h"
18 
19 #include <memory>
20 #include <string>
21 #include <typeinfo>
22 
23 #include "absl/container/flat_hash_map.h"
24 #include "absl/status/status.h"
25 #include "absl/strings/str_format.h"
26 #include "tink/internal/key_parser.h"
27 #include "tink/internal/key_serializer.h"
28 #include "tink/internal/parameters_parser.h"
29 #include "tink/internal/parameters_serializer.h"
30 #include "tink/internal/parser_index.h"
31 #include "tink/internal/serialization.h"
32 #include "tink/internal/serializer_index.h"
33 #include "tink/key.h"
34 #include "tink/parameters.h"
35 #include "tink/util/status.h"
36 #include "tink/util/statusor.h"
37 
38 namespace crypto {
39 namespace tink {
40 namespace internal {
41 
Builder(const SerializationRegistry & registry)42 SerializationRegistry::Builder::Builder(const SerializationRegistry& registry)
43     : Builder(registry.parameters_parsers_, registry.parameters_serializers_,
44               registry.key_parsers_, registry.key_serializers_) {}
45 
RegisterParametersParser(ParametersParser * parser)46 util::Status SerializationRegistry::Builder::RegisterParametersParser(
47     ParametersParser* parser) {
48   ParserIndex index = parser->Index();
49   auto it = parameters_parsers_.find(index);
50   if (it != parameters_parsers_.end()) {
51     if (parameters_parsers_[index] != parser) {
52       return util::Status(absl::StatusCode::kAlreadyExists,
53                           "Attempted to update existing parameters parser.");
54     }
55   }
56   parameters_parsers_.insert({parser->Index(), parser});
57   return util::OkStatus();
58 }
59 
RegisterParametersSerializer(ParametersSerializer * serializer)60 util::Status SerializationRegistry::Builder::RegisterParametersSerializer(
61     ParametersSerializer* serializer) {
62   SerializerIndex index = serializer->Index();
63   auto it = parameters_serializers_.find(index);
64   if (it != parameters_serializers_.end()) {
65     if (parameters_serializers_[index] != serializer) {
66       return util::Status(
67           absl::StatusCode::kAlreadyExists,
68           "Attempted to update existing parameters serializer.");
69     }
70   }
71   parameters_serializers_.insert({serializer->Index(), serializer});
72   return util::OkStatus();
73 }
74 
RegisterKeyParser(KeyParser * parser)75 util::Status SerializationRegistry::Builder::RegisterKeyParser(
76     KeyParser* parser) {
77   ParserIndex index = parser->Index();
78   auto it = key_parsers_.find(index);
79   if (it != key_parsers_.end()) {
80     if (key_parsers_[index] != parser) {
81       return util::Status(absl::StatusCode::kAlreadyExists,
82                           "Attempted to update existing key parser.");
83     }
84   }
85   key_parsers_.insert({parser->Index(), parser});
86   return util::OkStatus();
87 }
88 
RegisterKeySerializer(KeySerializer * serializer)89 util::Status SerializationRegistry::Builder::RegisterKeySerializer(
90     KeySerializer* serializer) {
91   SerializerIndex index = serializer->Index();
92   auto it = key_serializers_.find(index);
93   if (it != key_serializers_.end()) {
94     if (key_serializers_[index] != serializer) {
95       return util::Status(absl::StatusCode::kAlreadyExists,
96                           "Attempted to update existing key serializer.");
97     }
98   }
99   key_serializers_.insert({serializer->Index(), serializer});
100   return util::OkStatus();
101 }
102 
Build()103 SerializationRegistry SerializationRegistry::Builder::Build() {
104   return SerializationRegistry(parameters_parsers_, parameters_serializers_,
105                                key_parsers_, key_serializers_);
106 }
107 
108 util::StatusOr<std::unique_ptr<Parameters>>
ParseParameters(const Serialization & serialization) const109 SerializationRegistry::ParseParameters(
110     const Serialization& serialization) const {
111   ParserIndex index = ParserIndex::Create(serialization);
112   auto it = parameters_parsers_.find(index);
113   if (it == parameters_parsers_.end()) {
114     return util::Status(
115         absl::StatusCode::kNotFound,
116         absl::StrFormat("No parameters parser found for parameters type %s",
117                         typeid(serialization).name()));
118   }
119 
120   return parameters_parsers_.at(index)->ParseParameters(serialization);
121 }
122 
ParseKey(const Serialization & serialization,absl::optional<SecretKeyAccessToken> token) const123 util::StatusOr<std::unique_ptr<Key>> SerializationRegistry::ParseKey(
124     const Serialization& serialization,
125     absl::optional<SecretKeyAccessToken> token) const {
126   ParserIndex index = ParserIndex::Create(serialization);
127   auto it = key_parsers_.find(index);
128   if (it == key_parsers_.end()) {
129     return util::Status(
130         absl::StatusCode::kNotFound,
131         absl::StrFormat("No key parser found for serialization type %s",
132                         typeid(serialization).name()));
133   }
134 
135   return key_parsers_.at(index)->ParseKey(serialization, token);
136 }
137 
138 }  // namespace internal
139 }  // namespace tink
140 }  // namespace crypto
141