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