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