xref: /aosp_15_r20/external/tink/cc/internal/keyset_handle_builder_entry_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/keyset_handle_builder_entry.h"
18 
19 #include <string>
20 
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "absl/memory/memory.h"
24 #include "absl/status/status.h"
25 #include "absl/types/optional.h"
26 #include "tink/config/tink_config.h"
27 #include "tink/insecure_secret_key_access.h"
28 #include "tink/internal/legacy_proto_key.h"
29 #include "tink/internal/legacy_proto_parameters.h"
30 #include "tink/internal/proto_key_serialization.h"
31 #include "tink/internal/proto_parameters_serialization.h"
32 #include "tink/key.h"
33 #include "tink/key_status.h"
34 #include "tink/keyset_handle.h"
35 #include "tink/keyset_handle_builder.h"
36 #include "tink/mac/aes_cmac_key.h"
37 #include "tink/mac/aes_cmac_parameters.h"
38 #include "tink/mac/mac_key_templates.h"
39 #include "tink/parameters.h"
40 #include "tink/partial_key_access.h"
41 #include "tink/restricted_data.h"
42 #include "tink/secret_key_access_token.h"
43 #include "tink/util/status.h"
44 #include "tink/util/statusor.h"
45 #include "tink/util/test_matchers.h"
46 #include "proto/tink.pb.h"
47 
48 namespace crypto {
49 namespace tink {
50 namespace internal {
51 namespace {
52 
53 using ::crypto::tink::test::IsOk;
54 using ::crypto::tink::test::StatusIs;
55 using ::google::crypto::tink::KeyData;
56 using ::google::crypto::tink::Keyset;
57 using ::google::crypto::tink::KeyStatusType;
58 using ::google::crypto::tink::OutputPrefixType;
59 using ::testing::Eq;
60 using ::testing::IsFalse;
61 using ::testing::IsTrue;
62 using ::testing::Test;
63 
CreateLegacyProtoParameters()64 util::StatusOr<LegacyProtoParameters> CreateLegacyProtoParameters() {
65   util::StatusOr<ProtoParametersSerialization> serialization =
66       ProtoParametersSerialization::Create(MacKeyTemplates::AesCmac());
67   if (!serialization.ok()) return serialization.status();
68 
69   return LegacyProtoParameters(*serialization);
70 }
71 
TEST(KeysetHandleBuilderEntryTest,Status)72 TEST(KeysetHandleBuilderEntryTest, Status) {
73   util::StatusOr<LegacyProtoParameters> parameters =
74       CreateLegacyProtoParameters();
75   ASSERT_THAT(parameters, IsOk());
76 
77   ParametersEntry entry =
78       ParametersEntry(absl::make_unique<LegacyProtoParameters>(*parameters));
79 
80   entry.SetStatus(KeyStatus::kEnabled);
81   EXPECT_THAT(entry.GetStatus(), KeyStatus::kEnabled);
82 
83   entry.SetStatus(KeyStatus::kDisabled);
84   EXPECT_THAT(entry.GetStatus(), KeyStatus::kDisabled);
85 
86   entry.SetStatus(KeyStatus::kDestroyed);
87   EXPECT_THAT(entry.GetStatus(), KeyStatus::kDestroyed);
88 }
89 
TEST(KeysetHandleBuilderEntryTest,IdStrategy)90 TEST(KeysetHandleBuilderEntryTest, IdStrategy) {
91   util::StatusOr<LegacyProtoParameters> parameters =
92       CreateLegacyProtoParameters();
93   ASSERT_THAT(parameters, IsOk());
94 
95   ParametersEntry entry =
96       ParametersEntry(absl::make_unique<LegacyProtoParameters>(*parameters));
97 
98   entry.SetFixedId(123);
99   EXPECT_THAT(entry.GetKeyIdStrategyEnum(), KeyIdStrategyEnum::kFixedId);
100   EXPECT_THAT(entry.GetKeyIdStrategy().strategy, KeyIdStrategyEnum::kFixedId);
101   EXPECT_THAT(entry.GetKeyIdStrategy().id_requirement, 123);
102   EXPECT_THAT(entry.GetKeyIdRequirement(), 123);
103 
104   entry.SetRandomId();
105   EXPECT_THAT(entry.GetKeyIdStrategyEnum(), KeyIdStrategyEnum::kRandomId);
106   EXPECT_THAT(entry.GetKeyIdStrategy().strategy, KeyIdStrategyEnum::kRandomId);
107   EXPECT_THAT(entry.GetKeyIdStrategy().id_requirement, absl::nullopt);
108   EXPECT_THAT(entry.GetKeyIdRequirement(), absl::nullopt);
109 }
110 
TEST(KeysetHandleBuilderEntryTest,Primary)111 TEST(KeysetHandleBuilderEntryTest, Primary) {
112   util::StatusOr<LegacyProtoParameters> parameters =
113       CreateLegacyProtoParameters();
114   ASSERT_THAT(parameters, IsOk());
115 
116   ParametersEntry entry =
117       ParametersEntry(absl::make_unique<LegacyProtoParameters>(*parameters));
118 
119   entry.SetPrimary();
120   EXPECT_THAT(entry.IsPrimary(), IsTrue());
121 
122   entry.UnsetPrimary();
123   EXPECT_THAT(entry.IsPrimary(), IsFalse());
124 }
125 
126 class CreateKeysetKeyTest : public Test {
127  protected:
SetUp()128   void SetUp() override { ASSERT_THAT(TinkConfig::Register(), IsOk()); }
129 };
130 
TEST_F(CreateKeysetKeyTest,CreateKeysetKeyFromParameters)131 TEST_F(CreateKeysetKeyTest, CreateKeysetKeyFromParameters) {
132   util::StatusOr<LegacyProtoParameters> parameters =
133       CreateLegacyProtoParameters();
134   ASSERT_THAT(parameters, IsOk());
135 
136   ParametersEntry entry =
137       ParametersEntry(absl::make_unique<LegacyProtoParameters>(*parameters));
138   entry.SetStatus(KeyStatus::kEnabled);
139   entry.SetFixedId(123);
140   util::StatusOr<Keyset::Key> keyset_key = entry.CreateKeysetKey(/*id=*/123);
141   ASSERT_THAT(keyset_key, IsOk());
142 
143   EXPECT_THAT(keyset_key->status(), Eq(KeyStatusType::ENABLED));
144   EXPECT_THAT(keyset_key->key_id(), Eq(123));
145   EXPECT_THAT(
146       keyset_key->output_prefix_type(),
147       Eq(parameters->Serialization().GetKeyTemplate().output_prefix_type()));
148   EXPECT_THAT(keyset_key->key_data().type_url(),
149               Eq(parameters->Serialization().GetKeyTemplate().type_url()));
150 }
151 
TEST_F(CreateKeysetKeyTest,CreateKeysetKeyFromParametersWithDifferentKeyId)152 TEST_F(CreateKeysetKeyTest, CreateKeysetKeyFromParametersWithDifferentKeyId) {
153   util::StatusOr<LegacyProtoParameters> parameters =
154       CreateLegacyProtoParameters();
155   ASSERT_THAT(parameters, IsOk());
156 
157   ParametersEntry entry =
158       ParametersEntry(absl::make_unique<LegacyProtoParameters>(*parameters));
159   entry.SetStatus(KeyStatus::kEnabled);
160   entry.SetFixedId(123);
161   util::StatusOr<Keyset::Key> keyset_key = entry.CreateKeysetKey(/*id=*/456);
162   EXPECT_THAT(keyset_key.status(),
163               StatusIs(absl::StatusCode::kInvalidArgument));
164 }
165 
TEST_F(CreateKeysetKeyTest,CreateKeysetKeyFromKey)166 TEST_F(CreateKeysetKeyTest, CreateKeysetKeyFromKey) {
167   RestrictedData serialized_key =
168       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
169   util::StatusOr<ProtoKeySerialization> serialization =
170       ProtoKeySerialization::Create("type_url", serialized_key,
171                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
172                                     /*id_requirement=*/123);
173   ASSERT_THAT(serialization.status(), IsOk());
174 
175   util::StatusOr<LegacyProtoKey> key =
176       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
177   ASSERT_THAT(key.status(), IsOk());
178 
179   KeyEntry entry = KeyEntry(absl::make_unique<LegacyProtoKey>(*key));
180   entry.SetStatus(KeyStatus::kEnabled);
181   entry.SetFixedId(123);
182   util::StatusOr<Keyset::Key> keyset_key = entry.CreateKeysetKey(/*id=*/123);
183   ASSERT_THAT(keyset_key, IsOk());
184 
185   EXPECT_THAT(keyset_key->status(), Eq(KeyStatusType::ENABLED));
186   EXPECT_THAT(keyset_key->key_id(), Eq(123));
187   EXPECT_THAT(keyset_key->output_prefix_type(), OutputPrefixType::TINK);
188   EXPECT_THAT(keyset_key->key_data().type_url(), Eq("type_url"));
189   EXPECT_THAT(keyset_key->key_data().key_material_type(),
190               Eq(KeyData::SYMMETRIC));
191   EXPECT_THAT(keyset_key->key_data().value(), Eq("serialized_key"));
192 }
193 
TEST_F(CreateKeysetKeyTest,CreateKeysetKeyFromKeyWithDifferentEntryKeyId)194 TEST_F(CreateKeysetKeyTest, CreateKeysetKeyFromKeyWithDifferentEntryKeyId) {
195   RestrictedData serialized_key =
196       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
197   util::StatusOr<ProtoKeySerialization> serialization =
198       ProtoKeySerialization::Create("type_url", serialized_key,
199                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
200                                     /*id_requirement=*/123);
201   ASSERT_THAT(serialization.status(), IsOk());
202 
203   util::StatusOr<LegacyProtoKey> key =
204       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
205   ASSERT_THAT(key.status(), IsOk());
206 
207   KeyEntry entry = KeyEntry(absl::make_unique<LegacyProtoKey>(*key));
208   entry.SetStatus(KeyStatus::kEnabled);
209   entry.SetFixedId(123);
210   util::StatusOr<Keyset::Key> keyset_key = entry.CreateKeysetKey(/*id=*/456);
211   EXPECT_THAT(keyset_key.status(),
212               StatusIs(absl::StatusCode::kInvalidArgument));
213 }
214 
TEST_F(CreateKeysetKeyTest,CreateKeysetKeyFromKeyWithDifferentSerializationKeyId)215 TEST_F(CreateKeysetKeyTest,
216        CreateKeysetKeyFromKeyWithDifferentSerializationKeyId) {
217   RestrictedData serialized_key =
218       RestrictedData("serialized_key", InsecureSecretKeyAccess::Get());
219   util::StatusOr<ProtoKeySerialization> serialization =
220       ProtoKeySerialization::Create("type_url", serialized_key,
221                                     KeyData::SYMMETRIC, OutputPrefixType::TINK,
222                                     /*id_requirement=*/123);
223   ASSERT_THAT(serialization.status(), IsOk());
224 
225   util::StatusOr<LegacyProtoKey> key =
226       LegacyProtoKey::Create(*serialization, InsecureSecretKeyAccess::Get());
227   ASSERT_THAT(key.status(), IsOk());
228 
229   KeyEntry entry = KeyEntry(absl::make_unique<LegacyProtoKey>(*key));
230   entry.SetStatus(KeyStatus::kEnabled);
231   util::StatusOr<Keyset::Key> keyset_key = entry.CreateKeysetKey(/*id=*/456);
232   EXPECT_THAT(keyset_key.status(),
233               StatusIs(absl::StatusCode::kInvalidArgument));
234 }
235 
TEST_F(CreateKeysetKeyTest,CreateKeysetFromNonLegacyParameters)236 TEST_F(CreateKeysetKeyTest, CreateKeysetFromNonLegacyParameters) {
237   util::StatusOr<AesCmacParameters> aes_cmac_parameters =
238       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
239                                 /*cryptographic_tag_size_in_bytes=*/10,
240                                 AesCmacParameters::Variant::kTink);
241   ASSERT_THAT(aes_cmac_parameters, IsOk());
242 
243   util::StatusOr<KeysetHandle> handle =
244       KeysetHandleBuilder()
245           .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
246               *aes_cmac_parameters, KeyStatus::kEnabled, /*is_primary=*/true,
247               /*id=*/123))
248           .Build();
249   ASSERT_THAT(handle, IsOk());
250 }
251 
TEST_F(CreateKeysetKeyTest,CreateKeysetWithAllowedParametersProhibitedByKeyManager)252 TEST_F(CreateKeysetKeyTest,
253        CreateKeysetWithAllowedParametersProhibitedByKeyManager) {
254   util::StatusOr<AesCmacParameters> aes_cmac_parameters =
255       AesCmacParameters::Create(/*key_size_in_bytes=*/16,
256                                 /*cryptographic_tag_size_in_bytes=*/10,
257                                 AesCmacParameters::Variant::kTink);
258   ASSERT_THAT(aes_cmac_parameters, IsOk());
259 
260   util::StatusOr<KeysetHandle> handle =
261       KeysetHandleBuilder()
262           .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
263               *aes_cmac_parameters, KeyStatus::kEnabled, /*is_primary=*/true,
264               /*id=*/123))
265           .Build();
266   ASSERT_THAT(handle.status(), StatusIs(absl::StatusCode::kInvalidArgument));
267 }
268 
TEST_F(CreateKeysetKeyTest,CreateKeysetFromNonLegacyKey)269 TEST_F(CreateKeysetKeyTest, CreateKeysetFromNonLegacyKey) {
270   util::StatusOr<AesCmacParameters> aes_cmac_parameters =
271       AesCmacParameters::Create(/*key_size_in_bytes=*/32,
272                                 /*cryptographic_tag_size_in_bytes=*/10,
273                                 AesCmacParameters::Variant::kTink);
274   ASSERT_THAT(aes_cmac_parameters, IsOk());
275   util::StatusOr<AesCmacKey> aes_cmac_key = AesCmacKey::Create(
276       *aes_cmac_parameters, RestrictedData(32), 123, GetPartialKeyAccess());
277   ASSERT_THAT(aes_cmac_key.status(), IsOk());
278 
279   util::StatusOr<KeysetHandle> handle =
280       KeysetHandleBuilder()
281           .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableKey(
282               *aes_cmac_key, KeyStatus::kEnabled, /*is_primary=*/true))
283           .Build();
284   ASSERT_THAT(handle, IsOk());
285 }
286 
287 }  // namespace
288 }  // namespace internal
289 }  // namespace tink
290 }  // namespace crypto
291