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