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/mutable_serialization_registry.h"
18
19 #include <memory>
20 #include <string_view>
21 #include <typeindex>
22
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/status/status.h"
26 #include "absl/types/optional.h"
27 #include "tink/insecure_secret_key_access.h"
28 #include "tink/internal/key_parser.h"
29 #include "tink/internal/key_serializer.h"
30 #include "tink/internal/parameters_parser.h"
31 #include "tink/internal/parameters_serializer.h"
32 #include "tink/internal/proto_key_serialization.h"
33 #include "tink/internal/serialization.h"
34 #include "tink/internal/serialization_test_util.h"
35 #include "tink/key.h"
36 #include "tink/parameters.h"
37 #include "tink/restricted_data.h"
38 #include "tink/secret_key_access_token.h"
39 #include "tink/util/status.h"
40 #include "tink/util/statusor.h"
41 #include "tink/util/test_matchers.h"
42 #include "proto/tink.pb.h"
43
44 namespace crypto {
45 namespace tink {
46 namespace internal {
47
48 using ::crypto::tink::test::IsOk;
49 using ::crypto::tink::test::StatusIs;
50 using ::google::crypto::tink::KeyData;
51 using ::google::crypto::tink::OutputPrefixType;
52 using ::testing::Eq;
53 using ::testing::IsFalse;
54 using ::testing::IsTrue;
55
TEST(MutableSerializationRegistryTest,ParseParameters)56 TEST(MutableSerializationRegistryTest, ParseParameters) {
57 MutableSerializationRegistry registry;
58 ParametersParserImpl<NoIdSerialization, NoIdParams> parser1(kNoIdTypeUrl,
59 ParseNoIdParams);
60 ParametersParserImpl<IdParamsSerialization, IdParams> parser2(kIdTypeUrl,
61 ParseIdParams);
62 ASSERT_THAT(registry.RegisterParametersParser(&parser1), IsOk());
63 ASSERT_THAT(registry.RegisterParametersParser(&parser2), IsOk());
64
65 util::StatusOr<std::unique_ptr<Parameters>> no_id_params =
66 registry.ParseParameters(NoIdSerialization());
67 ASSERT_THAT(no_id_params, IsOk());
68 EXPECT_THAT((*no_id_params)->HasIdRequirement(), IsFalse());
69 EXPECT_THAT(std::type_index(typeid(**no_id_params)),
70 std::type_index(typeid(NoIdParams)));
71
72 util::StatusOr<std::unique_ptr<Parameters>> id_params =
73 registry.ParseParameters(IdParamsSerialization());
74 ASSERT_THAT(id_params, IsOk());
75 EXPECT_THAT((*id_params)->HasIdRequirement(), IsTrue());
76 EXPECT_THAT(std::type_index(typeid(**id_params)),
77 std::type_index(typeid(IdParams)));
78 }
79
TEST(MutableSerializationRegistryTest,ParseParametersWithoutRegistration)80 TEST(MutableSerializationRegistryTest, ParseParametersWithoutRegistration) {
81 MutableSerializationRegistry registry;
82
83 ASSERT_THAT(registry.ParseParameters(NoIdSerialization()).status(),
84 StatusIs(absl::StatusCode::kNotFound));
85 }
86
TEST(MutableSerializationRegistryTest,RegisterSameParametersParser)87 TEST(MutableSerializationRegistryTest, RegisterSameParametersParser) {
88 MutableSerializationRegistry registry;
89 ParametersParserImpl<NoIdSerialization, NoIdParams> parser(kNoIdTypeUrl,
90 ParseNoIdParams);
91
92 EXPECT_THAT(registry.RegisterParametersParser(&parser), IsOk());
93 EXPECT_THAT(registry.RegisterParametersParser(&parser), IsOk());
94 }
95
TEST(MutableSerializationRegistryTest,RegisterDifferentParametersParserWithSameIndex)96 TEST(MutableSerializationRegistryTest,
97 RegisterDifferentParametersParserWithSameIndex) {
98 MutableSerializationRegistry registry;
99 ParametersParserImpl<NoIdSerialization, NoIdParams> parser1(kNoIdTypeUrl,
100 ParseNoIdParams);
101 ParametersParserImpl<NoIdSerialization, NoIdParams> parser2(kNoIdTypeUrl,
102 ParseNoIdParams);
103
104 EXPECT_THAT(registry.RegisterParametersParser(&parser1), IsOk());
105 EXPECT_THAT(registry.RegisterParametersParser(&parser2),
106 StatusIs(absl::StatusCode::kAlreadyExists));
107 }
108
TEST(MutableSerializationRegistryTest,SerializeParameters)109 TEST(MutableSerializationRegistryTest, SerializeParameters) {
110 MutableSerializationRegistry registry;
111 ParametersSerializerImpl<NoIdParams, NoIdSerialization> serializer1(
112 kNoIdTypeUrl, SerializeNoIdParams);
113 ParametersSerializerImpl<IdParams, IdParamsSerialization> serializer2(
114 kIdTypeUrl, SerializeIdParams);
115 ASSERT_THAT(registry.RegisterParametersSerializer(&serializer1), IsOk());
116 ASSERT_THAT(registry.RegisterParametersSerializer(&serializer2), IsOk());
117
118 util::StatusOr<std::unique_ptr<Serialization>> serialization1 =
119 registry.SerializeParameters<NoIdSerialization>(NoIdParams());
120 ASSERT_THAT(serialization1, IsOk());
121 EXPECT_THAT((*serialization1)->ObjectIdentifier(), Eq(kNoIdTypeUrl));
122
123 util::StatusOr<std::unique_ptr<Serialization>> serialization2 =
124 registry.SerializeParameters<IdParamsSerialization>(IdParams());
125 ASSERT_THAT(serialization2, IsOk());
126 EXPECT_THAT((*serialization2)->ObjectIdentifier(), Eq(kIdTypeUrl));
127 }
128
TEST(MutableSerializationRegistryTest,SerializeParametersWithoutRegistration)129 TEST(MutableSerializationRegistryTest, SerializeParametersWithoutRegistration) {
130 MutableSerializationRegistry registry;
131
132 ASSERT_THAT(
133 registry.SerializeParameters<NoIdSerialization>(NoIdParams()).status(),
134 StatusIs(absl::StatusCode::kNotFound));
135 }
136
TEST(MutableSerializationRegistryTest,RegisterSameParametersSerializer)137 TEST(MutableSerializationRegistryTest, RegisterSameParametersSerializer) {
138 MutableSerializationRegistry registry;
139 ParametersSerializerImpl<NoIdParams, NoIdSerialization> serializer(
140 kNoIdTypeUrl, SerializeNoIdParams);
141
142 EXPECT_THAT(registry.RegisterParametersSerializer(&serializer), IsOk());
143 EXPECT_THAT(registry.RegisterParametersSerializer(&serializer), IsOk());
144 }
145
TEST(MutableSerializationRegistryTest,RegisterDifferentParametersSerializerWithSameIndex)146 TEST(MutableSerializationRegistryTest,
147 RegisterDifferentParametersSerializerWithSameIndex) {
148 MutableSerializationRegistry registry;
149 ParametersSerializerImpl<NoIdParams, NoIdSerialization> serializer1(
150 kNoIdTypeUrl, SerializeNoIdParams);
151 ParametersSerializerImpl<NoIdParams, NoIdSerialization> serializer2(
152 kNoIdTypeUrl, SerializeNoIdParams);
153
154 EXPECT_THAT(registry.RegisterParametersSerializer(&serializer1), IsOk());
155 EXPECT_THAT(registry.RegisterParametersSerializer(&serializer2),
156 StatusIs(absl::StatusCode::kAlreadyExists));
157 }
158
TEST(MutableSerializationRegistryTest,ParseKey)159 TEST(MutableSerializationRegistryTest, ParseKey) {
160 MutableSerializationRegistry registry;
161 KeyParserImpl<NoIdSerialization, NoIdKey> parser1(kNoIdTypeUrl, ParseNoIdKey);
162 KeyParserImpl<IdKeySerialization, IdKey> parser2(kIdTypeUrl, ParseIdKey);
163 ASSERT_THAT(registry.RegisterKeyParser(&parser1), IsOk());
164 ASSERT_THAT(registry.RegisterKeyParser(&parser2), IsOk());
165
166 util::StatusOr<std::unique_ptr<Key>> no_id_key =
167 registry.ParseKey(NoIdSerialization(), InsecureSecretKeyAccess::Get());
168 ASSERT_THAT(no_id_key, IsOk());
169 EXPECT_THAT(std::type_index(typeid(**no_id_key)),
170 std::type_index(typeid(NoIdKey)));
171
172 util::StatusOr<std::unique_ptr<Key>> id_key = registry.ParseKey(
173 IdKeySerialization(/*id=*/123), InsecureSecretKeyAccess::Get());
174 ASSERT_THAT(id_key, IsOk());
175 EXPECT_THAT(std::type_index(typeid(**id_key)),
176 std::type_index(typeid(IdKey)));
177 EXPECT_THAT((*id_key)->GetIdRequirement(), Eq(123));
178 }
179
TEST(MutableSerializationRegistryTest,ParseKeyNoSecretAccess)180 TEST(MutableSerializationRegistryTest, ParseKeyNoSecretAccess) {
181 MutableSerializationRegistry registry;
182 KeyParserImpl<NoIdSerialization, NoIdKey> parser(kNoIdTypeUrl, ParseNoIdKey);
183 ASSERT_THAT(registry.RegisterKeyParser(&parser), IsOk());
184
185 util::StatusOr<std::unique_ptr<Key>> no_id_public_key =
186 registry.ParseKey(NoIdSerialization(), absl::nullopt);
187 ASSERT_THAT(no_id_public_key, IsOk());
188 EXPECT_THAT(std::type_index(typeid(**no_id_public_key)),
189 std::type_index(typeid(NoIdKey)));
190 }
191
TEST(MutableSerializationRegistryTest,ParseKeyWithLegacyFallback)192 TEST(MutableSerializationRegistryTest, ParseKeyWithLegacyFallback) {
193 MutableSerializationRegistry registry;
194 KeyParserImpl<IdKeySerialization, IdKey> parser(kIdTypeUrl, ParseIdKey);
195 ASSERT_THAT(registry.RegisterKeyParser(&parser), IsOk());
196
197 // Parse key with registered key parser.
198 util::StatusOr<std::unique_ptr<Key>> id_key =
199 registry.ParseKeyWithLegacyFallback(IdKeySerialization(/*id=*/123),
200 InsecureSecretKeyAccess::Get());
201 ASSERT_THAT(id_key, IsOk());
202 EXPECT_THAT(std::type_index(typeid(**id_key)),
203 std::type_index(typeid(IdKey)));
204 EXPECT_THAT((*id_key)->GetIdRequirement(), Eq(123));
205
206 RestrictedData serialized_key =
207 RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
208 util::StatusOr<ProtoKeySerialization> serialization =
209 ProtoKeySerialization::Create("type_url", serialized_key,
210 KeyData::SYMMETRIC, OutputPrefixType::TINK,
211 /*id_requirement=*/456);
212 ASSERT_THAT(serialization.status(), IsOk());
213
214 // Fall back to legacy proto key.
215 util::StatusOr<std::unique_ptr<Key>> proto_key =
216 registry.ParseKeyWithLegacyFallback(*serialization,
217 InsecureSecretKeyAccess::Get());
218 ASSERT_THAT(proto_key, IsOk());
219 EXPECT_THAT((*proto_key)->GetIdRequirement(), Eq(456));
220 }
221
TEST(MutableSerializationRegistryTest,ParseKeyWithoutRegistration)222 TEST(MutableSerializationRegistryTest, ParseKeyWithoutRegistration) {
223 MutableSerializationRegistry registry;
224
225 ASSERT_THAT(
226 registry.ParseKey(NoIdSerialization(), InsecureSecretKeyAccess::Get())
227 .status(),
228 StatusIs(absl::StatusCode::kNotFound));
229 }
230
TEST(MutableSerializationRegistryTest,RegisterSameKeyParser)231 TEST(MutableSerializationRegistryTest, RegisterSameKeyParser) {
232 MutableSerializationRegistry registry;
233 KeyParserImpl<NoIdSerialization, NoIdKey> parser(kNoIdTypeUrl, ParseNoIdKey);
234
235 EXPECT_THAT(registry.RegisterKeyParser(&parser), IsOk());
236 EXPECT_THAT(registry.RegisterKeyParser(&parser), IsOk());
237 }
238
TEST(MutableSerializationRegistryTest,RegisterDifferentKeyParserWithSameIndex)239 TEST(MutableSerializationRegistryTest,
240 RegisterDifferentKeyParserWithSameIndex) {
241 MutableSerializationRegistry registry;
242 KeyParserImpl<NoIdSerialization, NoIdKey> parser1(kNoIdTypeUrl, ParseNoIdKey);
243 KeyParserImpl<NoIdSerialization, NoIdKey> parser2(kNoIdTypeUrl, ParseNoIdKey);
244
245 EXPECT_THAT(registry.RegisterKeyParser(&parser1), IsOk());
246 EXPECT_THAT(registry.RegisterKeyParser(&parser2),
247 StatusIs(absl::StatusCode::kAlreadyExists));
248 }
249
TEST(MutableSerializationRegistryTest,SerializeKey)250 TEST(MutableSerializationRegistryTest, SerializeKey) {
251 MutableSerializationRegistry registry;
252 KeySerializerImpl<NoIdKey, NoIdSerialization> serializer1(SerializeNoIdKey);
253 KeySerializerImpl<IdKey, IdKeySerialization> serializer2(SerializeIdKey);
254 ASSERT_THAT(registry.RegisterKeySerializer(&serializer1), IsOk());
255 ASSERT_THAT(registry.RegisterKeySerializer(&serializer2), IsOk());
256
257 util::StatusOr<std::unique_ptr<Serialization>> serialization1 =
258 registry.SerializeKey<NoIdSerialization>(NoIdKey(),
259 InsecureSecretKeyAccess::Get());
260 ASSERT_THAT(serialization1, IsOk());
261 EXPECT_THAT((*serialization1)->ObjectIdentifier(), Eq(kNoIdTypeUrl));
262
263 util::StatusOr<std::unique_ptr<Serialization>> serialization2 =
264 registry.SerializeKey<IdKeySerialization>(IdKey(123),
265 InsecureSecretKeyAccess::Get());
266 ASSERT_THAT(serialization2, IsOk());
267 EXPECT_THAT((*serialization2)->ObjectIdentifier(), Eq(kIdTypeUrl));
268 }
269
TEST(MutableSerializationRegistryTest,SerializeKeyNoSecretAccess)270 TEST(MutableSerializationRegistryTest, SerializeKeyNoSecretAccess) {
271 MutableSerializationRegistry registry;
272 KeySerializerImpl<NoIdKey, NoIdSerialization> serializer(SerializeNoIdKey);
273 ASSERT_THAT(registry.RegisterKeySerializer(&serializer), IsOk());
274
275 util::StatusOr<std::unique_ptr<Serialization>> serialization =
276 registry.SerializeKey<NoIdSerialization>(NoIdKey(), absl::nullopt);
277 ASSERT_THAT(serialization, IsOk());
278 EXPECT_THAT((*serialization)->ObjectIdentifier(), Eq(kNoIdTypeUrl));
279 }
280
TEST(MutableSerializationRegistryTest,SerializeKeyWithoutRegistration)281 TEST(MutableSerializationRegistryTest, SerializeKeyWithoutRegistration) {
282 MutableSerializationRegistry registry;
283
284 ASSERT_THAT(registry
285 .SerializeKey<NoIdSerialization>(
286 NoIdKey(), InsecureSecretKeyAccess::Get())
287 .status(),
288 StatusIs(absl::StatusCode::kNotFound));
289 }
290
TEST(MutableSerializationRegistryTest,RegisterSameKeySerializer)291 TEST(MutableSerializationRegistryTest, RegisterSameKeySerializer) {
292 MutableSerializationRegistry registry;
293 KeySerializerImpl<NoIdKey, NoIdSerialization> serializer(SerializeNoIdKey);
294
295 EXPECT_THAT(registry.RegisterKeySerializer(&serializer), IsOk());
296 EXPECT_THAT(registry.RegisterKeySerializer(&serializer), IsOk());
297 }
298
TEST(MutableSerializationRegistryTest,RegisterDifferentKeySerializerWithSameIndex)299 TEST(MutableSerializationRegistryTest,
300 RegisterDifferentKeySerializerWithSameIndex) {
301 MutableSerializationRegistry registry;
302 KeySerializerImpl<NoIdKey, NoIdSerialization> serializer1(SerializeNoIdKey);
303 KeySerializerImpl<NoIdKey, NoIdSerialization> serializer2(SerializeNoIdKey);
304
305 EXPECT_THAT(registry.RegisterKeySerializer(&serializer1), IsOk());
306 EXPECT_THAT(registry.RegisterKeySerializer(&serializer2),
307 StatusIs(absl::StatusCode::kAlreadyExists));
308 }
309
TEST(MutableSerializationRegistryTest,Reset)310 TEST(MutableSerializationRegistryTest, Reset) {
311 MutableSerializationRegistry registry;
312 ParametersParserImpl<NoIdSerialization, NoIdParams> params_parser(
313 kNoIdTypeUrl, ParseNoIdParams);
314 ParametersSerializerImpl<NoIdParams, NoIdSerialization> params_serializer(
315 kNoIdTypeUrl, SerializeNoIdParams);
316 KeyParserImpl<NoIdSerialization, NoIdKey> key_parser(kNoIdTypeUrl,
317 ParseNoIdKey);
318 KeySerializerImpl<NoIdKey, NoIdSerialization> key_serializer(
319 SerializeNoIdKey);
320
321 ASSERT_THAT(registry.RegisterParametersParser(¶ms_parser), IsOk());
322 ASSERT_THAT(registry.RegisterParametersSerializer(¶ms_serializer),
323 IsOk());
324 ASSERT_THAT(registry.RegisterKeyParser(&key_parser), IsOk());
325 ASSERT_THAT(registry.RegisterKeySerializer(&key_serializer), IsOk());
326
327 util::StatusOr<std::unique_ptr<Parameters>> params =
328 registry.ParseParameters(NoIdSerialization());
329 ASSERT_THAT(params, IsOk());
330 util::StatusOr<std::unique_ptr<Serialization>> serialization1 =
331 registry.SerializeParameters<NoIdSerialization>(NoIdParams());
332 ASSERT_THAT(serialization1, IsOk());
333 util::StatusOr<std::unique_ptr<Key>> key =
334 registry.ParseKey(NoIdSerialization(), InsecureSecretKeyAccess::Get());
335 ASSERT_THAT(key, IsOk());
336 util::StatusOr<std::unique_ptr<Serialization>> serialization2 =
337 registry.SerializeKey<NoIdSerialization>(NoIdKey(),
338 InsecureSecretKeyAccess::Get());
339 ASSERT_THAT(serialization2, IsOk());
340
341 registry.Reset();
342
343 ASSERT_THAT(registry.ParseParameters(NoIdSerialization()).status(),
344 StatusIs(absl::StatusCode::kNotFound));
345 ASSERT_THAT(
346 registry.SerializeParameters<NoIdSerialization>(NoIdParams()).status(),
347 StatusIs(absl::StatusCode::kNotFound));
348 ASSERT_THAT(
349 registry.ParseKey(NoIdSerialization(), InsecureSecretKeyAccess::Get())
350 .status(),
351 StatusIs(absl::StatusCode::kNotFound));
352 ASSERT_THAT(registry
353 .SerializeKey<NoIdSerialization>(
354 NoIdKey(), InsecureSecretKeyAccess::Get())
355 .status(),
356 StatusIs(absl::StatusCode::kNotFound));
357 }
358
TEST(MutableSerializationRegistryTest,GlobalInstance)359 TEST(MutableSerializationRegistryTest, GlobalInstance) {
360 MutableSerializationRegistry::GlobalInstance().Reset();
361 ParametersParserImpl<NoIdSerialization, NoIdParams> parser(kNoIdTypeUrl,
362 ParseNoIdParams);
363 ASSERT_THAT(
364 MutableSerializationRegistry::GlobalInstance().RegisterParametersParser(
365 &parser),
366 IsOk());
367
368 util::StatusOr<std::unique_ptr<Parameters>> params =
369 MutableSerializationRegistry::GlobalInstance().ParseParameters(
370 NoIdSerialization());
371 ASSERT_THAT(params, IsOk());
372 EXPECT_THAT((*params)->HasIdRequirement(), IsFalse());
373 EXPECT_THAT(std::type_index(typeid(**params)),
374 std::type_index(typeid(NoIdParams)));
375 }
376
377 } // namespace internal
378 } // namespace tink
379 } // namespace crypto
380