xref: /aosp_15_r20/external/tink/cc/internal/legacy_proto_key_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2022 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/legacy_proto_key.h"
18 
19 #include <string>
20 #include <tuple>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "absl/types/optional.h"
26 #include "tink/insecure_secret_key_access.h"
27 #include "tink/internal/proto_key_serialization.h"
28 #include "tink/key.h"
29 #include "tink/parameters.h"
30 #include "tink/restricted_data.h"
31 #include "tink/secret_key_access_token.h"
32 #include "tink/util/statusor.h"
33 #include "tink/util/test_matchers.h"
34 #include "proto/tink.pb.h"
35 
36 namespace crypto {
37 namespace tink {
38 namespace internal {
39 
40 using ::crypto::tink::test::IsOk;
41 using ::crypto::tink::test::StatusIs;
42 using ::google::crypto::tink::KeyData;
43 using ::google::crypto::tink::OutputPrefixType;
44 using ::testing::Eq;
45 using ::testing::IsTrue;
46 using ::testing::TestWithParam;
47 using ::testing::Values;
48 
49 class LegacyProtoKeyTest : public ::testing::Test {
50  protected:
51   // Although this is a friend class, this utility function is necessary to
52   // access `ProtoKeySerialization::EqualsWithPotentialFalseNegatives()`
53   // since the test fixtures are subclasses that would not have direct access.
Equals(ProtoKeySerialization serialization,ProtoKeySerialization other)54   bool Equals(ProtoKeySerialization serialization,
55               ProtoKeySerialization other) {
56     return serialization.EqualsWithPotentialFalseNegatives(other);
57   }
58 };
59 
TEST_F(LegacyProtoKeyTest,CreateAndSerialization)60 TEST_F(LegacyProtoKeyTest, CreateAndSerialization) {
61   RestrictedData serialized_key =
62       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
63   util::StatusOr<ProtoKeySerialization> serialization =
64       ProtoKeySerialization::Create("type_url", serialized_key,
65                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
66                                     /*id_requirement=*/12345);
67   ASSERT_THAT(serialization.status(), IsOk());
68 
69   util::StatusOr<LegacyProtoKey> key =
70       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
71   ASSERT_THAT(key.status(), IsOk());
72 
73   EXPECT_THAT(key->GetIdRequirement(), Eq(12345));
74   EXPECT_THAT(key->GetParameters().HasIdRequirement(), IsTrue());
75   EXPECT_THAT(key->Serialization(InsecureSecretKeyAccess::Get()), IsOk());
76 
77   util::StatusOr<const ProtoKeySerialization*> key_serialization =
78       key->Serialization(InsecureSecretKeyAccess::Get());
79   ASSERT_THAT(key_serialization.status(), IsOk());
80   EXPECT_THAT(Equals(**key_serialization, *serialization), IsTrue());
81 }
82 
TEST_F(LegacyProtoKeyTest,Equals)83 TEST_F(LegacyProtoKeyTest, Equals) {
84   RestrictedData serialized_key =
85       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
86 
87   util::StatusOr<ProtoKeySerialization> serialization =
88       ProtoKeySerialization::Create("type_url", serialized_key,
89                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
90                                     /*id_requirement=*/12345);
91   ASSERT_THAT(serialization.status(), IsOk());
92 
93   util::StatusOr<ProtoKeySerialization> other_serialization =
94       ProtoKeySerialization::Create("type_url", serialized_key,
95                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
96                                     /*id_requirement=*/12345);
97   ASSERT_THAT(other_serialization.status(), IsOk());
98 
99   util::StatusOr<LegacyProtoKey> key =
100       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
101   ASSERT_THAT(key.status(), IsOk());
102 
103   util::StatusOr<LegacyProtoKey> other_key = LegacyProtoKey::Create(
104       *other_serialization, InsecureSecretKeyAccess::Get());
105   ASSERT_THAT(other_key.status(), IsOk());
106 
107   EXPECT_TRUE(*key == *other_key);
108   EXPECT_TRUE(*other_key == *key);
109   EXPECT_FALSE(*key != *other_key);
110   EXPECT_FALSE(*other_key != *key);
111 }
112 
TEST_F(LegacyProtoKeyTest,TypeUrlNotEqual)113 TEST_F(LegacyProtoKeyTest, TypeUrlNotEqual) {
114   RestrictedData serialized_key =
115       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
116 
117   util::StatusOr<ProtoKeySerialization> serialization =
118       ProtoKeySerialization::Create("type_url", serialized_key,
119                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
120                                     /*id_requirement=*/12345);
121   ASSERT_THAT(serialization.status(), IsOk());
122 
123   util::StatusOr<ProtoKeySerialization> other_serialization =
124       ProtoKeySerialization::Create("other_type_url", serialized_key,
125                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
126                                     /*id_requirement=*/12345);
127   ASSERT_THAT(other_serialization.status(), IsOk());
128 
129   util::StatusOr<LegacyProtoKey> key =
130       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
131   ASSERT_THAT(key.status(), IsOk());
132 
133   util::StatusOr<LegacyProtoKey> other_key = LegacyProtoKey::Create(
134       *other_serialization, InsecureSecretKeyAccess::Get());
135   ASSERT_THAT(other_key.status(), IsOk());
136 
137   EXPECT_TRUE(*key != *other_key);
138   EXPECT_TRUE(*other_key != *key);
139   EXPECT_FALSE(*key == *other_key);
140   EXPECT_FALSE(*other_key == *key);
141 }
142 
TEST_F(LegacyProtoKeyTest,SerializedKeyNotEqual)143 TEST_F(LegacyProtoKeyTest, SerializedKeyNotEqual) {
144   RestrictedData serialized_key =
145       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
146   RestrictedData other_serialized_key =
147       RestrictedData("other_serialized_key", InsecureSecretKeyAccess::Get());
148 
149   util::StatusOr<ProtoKeySerialization> serialization =
150       ProtoKeySerialization::Create("type_url", serialized_key,
151                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
152                                     /*id_requirement=*/12345);
153   ASSERT_THAT(serialization.status(), IsOk());
154 
155   util::StatusOr<ProtoKeySerialization> other_serialization =
156       ProtoKeySerialization::Create("type_url", other_serialized_key,
157                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
158                                     /*id_requirement=*/12345);
159   ASSERT_THAT(other_serialization.status(), IsOk());
160 
161   util::StatusOr<LegacyProtoKey> key =
162       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
163   ASSERT_THAT(key.status(), IsOk());
164 
165   util::StatusOr<LegacyProtoKey> other_key = LegacyProtoKey::Create(
166       *other_serialization, InsecureSecretKeyAccess::Get());
167   ASSERT_THAT(other_key.status(), IsOk());
168 
169   EXPECT_TRUE(*key != *other_key);
170   EXPECT_TRUE(*other_key != *key);
171   EXPECT_FALSE(*key == *other_key);
172   EXPECT_FALSE(*other_key == *key);
173 }
174 
TEST_F(LegacyProtoKeyTest,KeyMaterialTypeNotEqual)175 TEST_F(LegacyProtoKeyTest, KeyMaterialTypeNotEqual) {
176   RestrictedData serialized_key =
177       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
178 
179   util::StatusOr<ProtoKeySerialization> serialization =
180       ProtoKeySerialization::Create("type_url", serialized_key,
181                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
182                                     /*id_requirement=*/12345);
183   ASSERT_THAT(serialization.status(), IsOk());
184 
185   util::StatusOr<ProtoKeySerialization> other_serialization =
186       ProtoKeySerialization::Create("type_url", serialized_key, KeyData::REMOTE,
187                                     OutputPrefixType::TINK,
188                                     /*id_requirement=*/12345);
189   ASSERT_THAT(other_serialization.status(), IsOk());
190 
191   util::StatusOr<LegacyProtoKey> key =
192       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
193   ASSERT_THAT(key.status(), IsOk());
194 
195   util::StatusOr<LegacyProtoKey> other_key = LegacyProtoKey::Create(
196       *other_serialization, InsecureSecretKeyAccess::Get());
197   ASSERT_THAT(other_key.status(), IsOk());
198 
199   EXPECT_TRUE(*key != *other_key);
200   EXPECT_TRUE(*other_key != *key);
201   EXPECT_FALSE(*key == *other_key);
202   EXPECT_FALSE(*other_key == *key);
203 }
204 
TEST_F(LegacyProtoKeyTest,OutputPrefixTypeNotEqual)205 TEST_F(LegacyProtoKeyTest, OutputPrefixTypeNotEqual) {
206   RestrictedData serialized_key =
207       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
208 
209   util::StatusOr<ProtoKeySerialization> serialization =
210       ProtoKeySerialization::Create("type_url", serialized_key,
211                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
212                                     /*id_requirement=*/12345);
213   ASSERT_THAT(serialization.status(), IsOk());
214 
215   util::StatusOr<ProtoKeySerialization> other_serialization =
216       ProtoKeySerialization::Create("type_url", serialized_key,
217                                     KeyData::SYMMETRIC,
218                                     OutputPrefixType::CRUNCHY,
219                                     /*id_requirement=*/12345);
220   ASSERT_THAT(other_serialization.status(), IsOk());
221 
222   util::StatusOr<LegacyProtoKey> key =
223       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
224   ASSERT_THAT(key.status(), IsOk());
225 
226   util::StatusOr<LegacyProtoKey> other_key = LegacyProtoKey::Create(
227       *other_serialization, InsecureSecretKeyAccess::Get());
228   ASSERT_THAT(other_key.status(), IsOk());
229 
230   EXPECT_TRUE(*key != *other_key);
231   EXPECT_TRUE(*other_key != *key);
232   EXPECT_FALSE(*key == *other_key);
233   EXPECT_FALSE(*other_key == *key);
234 }
235 
TEST_F(LegacyProtoKeyTest,IdRequirementNotEqual)236 TEST_F(LegacyProtoKeyTest, IdRequirementNotEqual) {
237   RestrictedData serialized_key =
238       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
239 
240   util::StatusOr<ProtoKeySerialization> serialization =
241       ProtoKeySerialization::Create("type_url", serialized_key,
242                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
243                                     /*id_requirement=*/12345);
244   ASSERT_THAT(serialization.status(), IsOk());
245 
246   util::StatusOr<ProtoKeySerialization> other_serialization =
247       ProtoKeySerialization::Create("type_url", serialized_key,
248                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
249                                     /*id_requirement=*/6789);
250   ASSERT_THAT(other_serialization.status(), IsOk());
251 
252   util::StatusOr<LegacyProtoKey> key =
253       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
254   ASSERT_THAT(key.status(), IsOk());
255 
256   util::StatusOr<LegacyProtoKey> other_key = LegacyProtoKey::Create(
257       *other_serialization, InsecureSecretKeyAccess::Get());
258   ASSERT_THAT(other_key.status(), IsOk());
259 
260   EXPECT_TRUE(*key != *other_key);
261   EXPECT_TRUE(*other_key != *key);
262   EXPECT_FALSE(*key == *other_key);
263   EXPECT_FALSE(*other_key == *key);
264 }
265 
266 using AllOutputPrefixTypesTest =
267     TestWithParam<std::tuple<OutputPrefixType, absl::optional<int>>>;
268 
269 INSTANTIATE_TEST_SUITE_P(
270     AllOutputPrefixTypesTestSuite, AllOutputPrefixTypesTest,
271     Values(std::make_tuple(OutputPrefixType::RAW, absl::nullopt),
272            std::make_tuple(OutputPrefixType::TINK, 123),
273            std::make_tuple(OutputPrefixType::CRUNCHY, 456),
274            std::make_tuple(OutputPrefixType::LEGACY, 789)));
275 
TEST_P(AllOutputPrefixTypesTest,GetIdRequirement)276 TEST_P(AllOutputPrefixTypesTest, GetIdRequirement) {
277   OutputPrefixType output_prefix_type;
278   absl::optional<int> id_requirement;
279   std::tie(output_prefix_type, id_requirement) = GetParam();
280 
281   RestrictedData serialized_key =
282       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
283   util::StatusOr<ProtoKeySerialization> serialization =
284       ProtoKeySerialization::Create("type_url", serialized_key,
285                                     KeyData::SYMMETRIC, output_prefix_type,
286                                     id_requirement);
287   ASSERT_THAT(serialization.status(), IsOk());
288 
289   util::StatusOr<LegacyProtoKey> key =
290       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
291   ASSERT_THAT(key.status(), IsOk());
292 
293   EXPECT_THAT(key->GetIdRequirement(), Eq(id_requirement));
294 }
295 
296 using AllKeyMaterialTypesTest = TestWithParam<KeyData::KeyMaterialType>;
297 
298 INSTANTIATE_TEST_SUITE_P(AllKeyMaterialTypesTestSuite, AllKeyMaterialTypesTest,
299                          Values(KeyData::SYMMETRIC, KeyData::ASYMMETRIC_PRIVATE,
300                                 KeyData::ASYMMETRIC_PUBLIC, KeyData::REMOTE));
301 
TEST_P(AllKeyMaterialTypesTest,CreateAndSerializationWithSecretAccessToken)302 TEST_P(AllKeyMaterialTypesTest, CreateAndSerializationWithSecretAccessToken) {
303   KeyData::KeyMaterialType key_material_type = GetParam();
304 
305   RestrictedData serialized_key =
306       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
307 
308   util::StatusOr<ProtoKeySerialization> serialization =
309       ProtoKeySerialization::Create("type_url", serialized_key,
310                                     key_material_type, OutputPrefixType::TINK,
311                                     /*id_requirement=*/12345);
312   ASSERT_THAT(serialization.status(), IsOk());
313 
314   util::StatusOr<LegacyProtoKey> key =
315       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
316   ASSERT_THAT(key.status(), IsOk());
317 
318   util::StatusOr<const ProtoKeySerialization*> key_serialization =
319       key->Serialization(InsecureSecretKeyAccess::Get());
320   ASSERT_THAT(key_serialization.status(), IsOk());
321 }
322 
323 using SecretKeyMaterialTypesTest = TestWithParam<KeyData::KeyMaterialType>;
324 
325 INSTANTIATE_TEST_SUITE_P(SecretKeyMaterialTypesTestSuite,
326                          SecretKeyMaterialTypesTest,
327                          Values(KeyData::SYMMETRIC,
328                                 KeyData::ASYMMETRIC_PRIVATE));
329 
TEST_P(SecretKeyMaterialTypesTest,CreateWithoutSecretAccessToken)330 TEST_P(SecretKeyMaterialTypesTest, CreateWithoutSecretAccessToken) {
331   KeyData::KeyMaterialType key_material_type = GetParam();
332 
333   RestrictedData serialized_key =
334       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
335 
336   util::StatusOr<ProtoKeySerialization> serialization =
337       ProtoKeySerialization::Create("type_url", serialized_key,
338                                     key_material_type, OutputPrefixType::TINK,
339                                     /*id_requirement=*/12345);
340   ASSERT_THAT(serialization.status(), IsOk());
341 
342   util::StatusOr<LegacyProtoKey> key =
343       LegacyProtoKey::Create(*serialization, /*token=*/absl::nullopt);
344   ASSERT_THAT(key.status(), StatusIs(absl::StatusCode::kPermissionDenied));
345 }
346 
TEST_P(SecretKeyMaterialTypesTest,SerializationWithoutSecretAccessToken)347 TEST_P(SecretKeyMaterialTypesTest, SerializationWithoutSecretAccessToken) {
348   KeyData::KeyMaterialType key_material_type = GetParam();
349 
350   RestrictedData serialized_key =
351       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
352 
353   util::StatusOr<ProtoKeySerialization> serialization =
354       ProtoKeySerialization::Create("type_url", serialized_key,
355                                     key_material_type, OutputPrefixType::TINK,
356                                     /*id_requirement=*/12345);
357   ASSERT_THAT(serialization.status(), IsOk());
358 
359   // Must use token for key creation.
360   util::StatusOr<LegacyProtoKey> key =
361       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
362   ASSERT_THAT(key.status(), IsOk());
363 
364   util::StatusOr<const ProtoKeySerialization*> key_serialization =
365       key->Serialization(/*token=*/absl::nullopt);
366   ASSERT_THAT(key_serialization.status(),
367               StatusIs(absl::StatusCode::kPermissionDenied));
368 }
369 
370 using NonSecretKeyMaterialTypesTest = TestWithParam<KeyData::KeyMaterialType>;
371 
372 INSTANTIATE_TEST_SUITE_P(NonSecretKeyMaterialTypesTestSuite,
373                          NonSecretKeyMaterialTypesTest,
374                          Values(KeyData::ASYMMETRIC_PUBLIC, KeyData::REMOTE));
375 
TEST_P(NonSecretKeyMaterialTypesTest,CreateWithoutSecretAccessToken)376 TEST_P(NonSecretKeyMaterialTypesTest, CreateWithoutSecretAccessToken) {
377   KeyData::KeyMaterialType key_material_type = GetParam();
378 
379   RestrictedData serialized_key =
380       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
381 
382   util::StatusOr<ProtoKeySerialization> serialization =
383       ProtoKeySerialization::Create("type_url", serialized_key,
384                                     key_material_type, OutputPrefixType::TINK,
385                                     /*id_requirement=*/12345);
386   ASSERT_THAT(serialization.status(), IsOk());
387 
388   util::StatusOr<LegacyProtoKey> key =
389       LegacyProtoKey::Create(*serialization, /*token=*/absl::nullopt);
390   ASSERT_THAT(key.status(), IsOk());
391 }
392 
TEST_P(NonSecretKeyMaterialTypesTest,SerializationWithoutSecretAccessToken)393 TEST_P(NonSecretKeyMaterialTypesTest, SerializationWithoutSecretAccessToken) {
394   KeyData::KeyMaterialType key_material_type = GetParam();
395 
396   RestrictedData serialized_key =
397       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
398 
399   util::StatusOr<ProtoKeySerialization> serialization =
400       ProtoKeySerialization::Create("type_url", serialized_key,
401                                     key_material_type, OutputPrefixType::TINK,
402                                     /*id_requirement=*/12345);
403   ASSERT_THAT(serialization.status(), IsOk());
404 
405   // Must use token for key creation.
406   util::StatusOr<LegacyProtoKey> key =
407       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
408   ASSERT_THAT(key.status(), IsOk());
409 
410   util::StatusOr<const ProtoKeySerialization*> key_serialization =
411       key->Serialization(/*token=*/absl::nullopt);
412   ASSERT_THAT(key_serialization.status(), IsOk());
413 }
414 
415 }  // namespace internal
416 }  // namespace tink
417 }  // namespace crypto
418