xref: /aosp_15_r20/external/tink/cc/internal/configuration_impl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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/configuration_impl.h"
18 
19 #include <memory>
20 #include <string>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "tink/cleartext_keyset_handle.h"
26 #include "tink/configuration.h"
27 #include "tink/internal/keyset_wrapper_store.h"
28 #include "tink/subtle/random.h"
29 #include "tink/util/test_matchers.h"
30 #include "tink/util/test_util.h"
31 #include "proto/aes_gcm.pb.h"
32 #include "proto/rsa_ssa_pss.pb.h"
33 
34 namespace crypto {
35 namespace tink {
36 namespace internal {
37 namespace {
38 
39 using ::crypto::tink::test::IsOk;
40 using ::crypto::tink::test::StatusIs;
41 using ::google::crypto::tink::AesGcmKey;
42 using ::google::crypto::tink::AesGcmKeyFormat;
43 using ::google::crypto::tink::KeyData;
44 using ::google::crypto::tink::Keyset;
45 using ::google::crypto::tink::KeyStatusType;
46 using ::google::crypto::tink::OutputPrefixType;
47 using ::google::crypto::tink::RsaSsaPssKeyFormat;
48 using ::google::crypto::tink::RsaSsaPssParams;
49 using ::google::crypto::tink::RsaSsaPssPrivateKey;
50 using ::google::crypto::tink::RsaSsaPssPublicKey;
51 
52 class FakePrimitive {
53  public:
FakePrimitive(std::string s)54   explicit FakePrimitive(std::string s) : s_(s) {}
get()55   std::string get() { return s_; }
56 
57  private:
58   std::string s_;
59 };
60 
61 class FakePrimitive2 {
62  public:
FakePrimitive2(std::string s)63   explicit FakePrimitive2(std::string s) : s_(s) {}
get()64   std::string get() { return s_ + "2"; }
65 
66  private:
67   std::string s_;
68 };
69 
70 // Transforms AesGcmKey into FakePrimitive.
71 class FakeKeyTypeManager
72     : public KeyTypeManager<AesGcmKey, AesGcmKeyFormat, List<FakePrimitive>> {
73  public:
74   class FakePrimitiveFactory : public PrimitiveFactory<FakePrimitive> {
75    public:
Create(const AesGcmKey & key) const76     util::StatusOr<std::unique_ptr<FakePrimitive>> Create(
77         const AesGcmKey& key) const override {
78       return absl::make_unique<FakePrimitive>(key.key_value());
79     }
80   };
81 
FakeKeyTypeManager()82   FakeKeyTypeManager()
83       : KeyTypeManager(absl::make_unique<FakePrimitiveFactory>()) {}
84 
key_material_type() const85   KeyData::KeyMaterialType key_material_type() const override {
86     return KeyData::SYMMETRIC;
87   }
88 
get_version() const89   uint32_t get_version() const override { return 0; }
90 
get_key_type() const91   const std::string& get_key_type() const override { return key_type_; }
92 
ValidateKey(const AesGcmKey & key) const93   util::Status ValidateKey(const AesGcmKey& key) const override {
94     return util::OkStatus();
95   }
96 
ValidateKeyFormat(const AesGcmKeyFormat & key_format) const97   util::Status ValidateKeyFormat(
98       const AesGcmKeyFormat& key_format) const override {
99     return util::OkStatus();
100   }
101 
CreateKey(const AesGcmKeyFormat & key_format) const102   util::StatusOr<AesGcmKey> CreateKey(
103       const AesGcmKeyFormat& key_format) const override {
104     return AesGcmKey();
105   }
106 
DeriveKey(const AesGcmKeyFormat & key_format,InputStream * input_stream) const107   util::StatusOr<AesGcmKey> DeriveKey(
108       const AesGcmKeyFormat& key_format,
109       InputStream* input_stream) const override {
110     return AesGcmKey();
111   }
112 
113  private:
114   const std::string key_type_ =
115       "type.googleapis.com/google.crypto.tink.AesGcmKey";
116 };
117 
118 // Transforms FakePrimitive into FakePrimitive.
119 class FakePrimitiveWrapper
120     : public PrimitiveWrapper<FakePrimitive, FakePrimitive> {
121  public:
Wrap(std::unique_ptr<PrimitiveSet<FakePrimitive>> primitive_set) const122   util::StatusOr<std::unique_ptr<FakePrimitive>> Wrap(
123       std::unique_ptr<PrimitiveSet<FakePrimitive>> primitive_set)
124       const override {
125     return absl::make_unique<FakePrimitive>(
126         primitive_set->get_primary()->get_primitive().get());
127   }
128 };
129 
130 // Transforms FakePrimitive2 into FakePrimitive.
131 class FakePrimitiveWrapper2
132     : public PrimitiveWrapper<FakePrimitive2, FakePrimitive> {
133  public:
Wrap(std::unique_ptr<PrimitiveSet<FakePrimitive2>> primitive_set) const134   util::StatusOr<std::unique_ptr<FakePrimitive>> Wrap(
135       std::unique_ptr<PrimitiveSet<FakePrimitive2>> primitive_set)
136       const override {
137     return absl::make_unique<FakePrimitive>(
138         primitive_set->get_primary()->get_primitive().get());
139   }
140 };
141 
AddAesGcmKeyToKeyset(Keyset & keyset,uint32_t key_id,OutputPrefixType output_prefix_type,KeyStatusType key_status_type)142 std::string AddAesGcmKeyToKeyset(Keyset& keyset, uint32_t key_id,
143                                  OutputPrefixType output_prefix_type,
144                                  KeyStatusType key_status_type) {
145   AesGcmKey key;
146   key.set_version(0);
147   key.set_key_value(subtle::Random::GetRandomBytes(16));
148   KeyData key_data;
149   key_data.set_value(key.SerializeAsString());
150   key_data.set_type_url("type.googleapis.com/google.crypto.tink.AesGcmKey");
151   test::AddKeyData(key_data, key_id, output_prefix_type, key_status_type,
152                    &keyset);
153   return key.key_value();
154 }
155 
TEST(ConfigurationImplTest,AddPrimitiveWrapper)156 TEST(ConfigurationImplTest, AddPrimitiveWrapper) {
157   Configuration config;
158   EXPECT_THAT((ConfigurationImpl::AddPrimitiveWrapper(
159                   absl::make_unique<FakePrimitiveWrapper>(), config)),
160               IsOk());
161 }
162 
TEST(ConfigurationImplTest,AddKeyTypeManager)163 TEST(ConfigurationImplTest, AddKeyTypeManager) {
164   Configuration config;
165   EXPECT_THAT(ConfigurationImpl::AddKeyTypeManager(
166                   absl::make_unique<FakeKeyTypeManager>(), config),
167               IsOk());
168 }
169 
TEST(ConfigurationImplTest,GetKeyTypeInfoStore)170 TEST(ConfigurationImplTest, GetKeyTypeInfoStore) {
171   Configuration config;
172   ASSERT_THAT(ConfigurationImpl::AddKeyTypeManager(
173                   absl::make_unique<FakeKeyTypeManager>(), config),
174               IsOk());
175 
176   std::string type_url = FakeKeyTypeManager().get_key_type();
177   util::StatusOr<const KeyTypeInfoStore*> store =
178       ConfigurationImpl::GetKeyTypeInfoStore(config);
179   ASSERT_THAT(store, IsOk());
180   util::StatusOr<const KeyTypeInfoStore::Info*> info = (*store)->Get(type_url);
181   ASSERT_THAT(info, IsOk());
182 
183   util::StatusOr<const KeyManager<FakePrimitive>*> key_manager =
184       (*info)->get_key_manager<FakePrimitive>(type_url);
185   ASSERT_THAT(key_manager, IsOk());
186   EXPECT_EQ((*key_manager)->get_key_type(), type_url);
187 }
188 
TEST(ConfigurationImplTest,GetKeyTypeInfoStoreMissingInfoFails)189 TEST(ConfigurationImplTest, GetKeyTypeInfoStoreMissingInfoFails) {
190   Configuration config;
191   util::StatusOr<const KeyTypeInfoStore*> store =
192       ConfigurationImpl::GetKeyTypeInfoStore(config);
193   ASSERT_THAT(store, IsOk());
194   EXPECT_THAT((*store)->Get("i.do.not.exist").status(),
195               StatusIs(absl::StatusCode::kNotFound));
196 }
197 
TEST(ConfigurationImplTest,GetKeysetWrapperStoreAndWrap)198 TEST(ConfigurationImplTest, GetKeysetWrapperStoreAndWrap) {
199   Configuration config;
200   ASSERT_THAT((ConfigurationImpl::AddPrimitiveWrapper(
201                   absl::make_unique<FakePrimitiveWrapper>(), config)),
202               IsOk());
203   ASSERT_THAT(ConfigurationImpl::AddKeyTypeManager(
204                   absl::make_unique<FakeKeyTypeManager>(), config),
205               IsOk());
206 
207   util::StatusOr<const KeysetWrapperStore*> store =
208       ConfigurationImpl::GetKeysetWrapperStore(config);
209   ASSERT_THAT(store, IsOk());
210   util::StatusOr<const KeysetWrapper<FakePrimitive>*> wrapper =
211       (*store)->Get<FakePrimitive>();
212   ASSERT_THAT(wrapper, IsOk());
213 
214   Keyset keyset;
215   std::string raw_key = AddAesGcmKeyToKeyset(
216       keyset, /*key_id=*/13, OutputPrefixType::TINK, KeyStatusType::ENABLED);
217   keyset.set_primary_key_id(13);
218 
219   util::StatusOr<std::unique_ptr<FakePrimitive>> aead =
220       (*wrapper)->Wrap(keyset, /*annotations=*/{});
221   ASSERT_THAT(aead, IsOk());
222   EXPECT_EQ((*aead)->get(), raw_key);
223 }
224 
TEST(ConfigurationImplTest,KeysetWrapperWrapMissingKeyTypeInfoFails)225 TEST(ConfigurationImplTest, KeysetWrapperWrapMissingKeyTypeInfoFails) {
226   Configuration config;
227   ASSERT_THAT(ConfigurationImpl::AddPrimitiveWrapper(
228                   absl::make_unique<FakePrimitiveWrapper>(), config),
229               IsOk());
230 
231   util::StatusOr<const KeysetWrapperStore*> store =
232       ConfigurationImpl::GetKeysetWrapperStore(config);
233   ASSERT_THAT(store, IsOk());
234   util::StatusOr<const KeysetWrapper<FakePrimitive>*> wrapper =
235       (*store)->Get<FakePrimitive>();
236   ASSERT_THAT(wrapper, IsOk());
237 
238   Keyset keyset;
239   std::string raw_key = AddAesGcmKeyToKeyset(
240       keyset, /*key_id=*/13, OutputPrefixType::TINK, KeyStatusType::ENABLED);
241   keyset.set_primary_key_id(13);
242 
243   EXPECT_THAT((*wrapper)->Wrap(keyset, /*annotations=*/{}).status(),
244               StatusIs(absl::StatusCode::kNotFound));
245 }
246 
TEST(ConfigurationImplTest,KeysetWrapperWrapMissingKeyManagerFails)247 TEST(ConfigurationImplTest, KeysetWrapperWrapMissingKeyManagerFails) {
248   Configuration config;
249   // Transforms FakePrimitive2 to FakePrimitive.
250   ASSERT_THAT((ConfigurationImpl::AddPrimitiveWrapper(
251                   absl::make_unique<FakePrimitiveWrapper2>(), config)),
252               IsOk());
253   // Transforms KeyData to FakePrimitive.
254   ASSERT_THAT(ConfigurationImpl::AddKeyTypeManager(
255                   absl::make_unique<FakeKeyTypeManager>(), config),
256               IsOk());
257 
258   // AesGcmKey KeyData -> FakePrimitive2 -> FakePrimitive is the success path,
259   // but the AesGcmKey KeyData -> FakePrimitive2 transformation is not
260   // registered.
261   util::StatusOr<const KeysetWrapperStore*> store =
262       ConfigurationImpl::GetKeysetWrapperStore(config);
263   ASSERT_THAT(store, IsOk());
264   util::StatusOr<const KeysetWrapper<FakePrimitive>*> wrapper =
265       (*store)->Get<FakePrimitive>();
266   ASSERT_THAT(wrapper, IsOk());
267 
268   Keyset keyset;
269   std::string raw_key = AddAesGcmKeyToKeyset(
270       keyset, /*key_id=*/13, OutputPrefixType::TINK, KeyStatusType::ENABLED);
271   keyset.set_primary_key_id(13);
272 
273   // FakeKeyTypeManager cannot transform AesGcmKey KeyData -> FakePrimitive2.
274   EXPECT_THAT((*wrapper)->Wrap(keyset, /*annotations=*/{}).status(),
275               StatusIs(absl::StatusCode::kInvalidArgument));
276 }
277 
278 class FakeSignKeyManager
279     : public PrivateKeyTypeManager<RsaSsaPssPrivateKey, RsaSsaPssKeyFormat,
280                                    RsaSsaPssPublicKey, List<PublicKeySign>> {
281  public:
282   class PublicKeySignFactory : public PrimitiveFactory<PublicKeySign> {
283    public:
Create(const RsaSsaPssPrivateKey & key) const284     util::StatusOr<std::unique_ptr<PublicKeySign>> Create(
285         const RsaSsaPssPrivateKey& key) const override {
286       return {absl::make_unique<test::DummyPublicKeySign>("a public key sign")};
287     }
288   };
289 
FakeSignKeyManager()290   explicit FakeSignKeyManager()
291       : PrivateKeyTypeManager(absl::make_unique<PublicKeySignFactory>()) {}
292 
key_material_type() const293   KeyData::KeyMaterialType key_material_type() const override {
294     return KeyData::ASYMMETRIC_PRIVATE;
295   }
296 
get_version() const297   uint32_t get_version() const override { return 0; }
298 
get_key_type() const299   const std::string& get_key_type() const override { return key_type_; }
300 
ValidateKey(const RsaSsaPssPrivateKey & key) const301   util::Status ValidateKey(const RsaSsaPssPrivateKey& key) const override {
302     return util::OkStatus();
303   }
304 
ValidateKeyFormat(const RsaSsaPssKeyFormat & key_format) const305   util::Status ValidateKeyFormat(
306       const RsaSsaPssKeyFormat& key_format) const override {
307     return util::OkStatus();
308   }
309 
CreateKey(const RsaSsaPssKeyFormat & key_format) const310   util::StatusOr<RsaSsaPssPrivateKey> CreateKey(
311       const RsaSsaPssKeyFormat& key_format) const override {
312     return RsaSsaPssPrivateKey();
313   }
314 
DeriveKey(const RsaSsaPssKeyFormat & key_format,InputStream * input_stream) const315   util::StatusOr<RsaSsaPssPrivateKey> DeriveKey(
316       const RsaSsaPssKeyFormat& key_format,
317       InputStream* input_stream) const override {
318     return RsaSsaPssPrivateKey();
319   }
320 
GetPublicKey(const RsaSsaPssPrivateKey & private_key) const321   util::StatusOr<RsaSsaPssPublicKey> GetPublicKey(
322       const RsaSsaPssPrivateKey& private_key) const override {
323     return private_key.public_key();
324   }
325 
326  private:
327   const std::string key_type_ = "some.sign.key.type";
328 };
329 
330 class FakeVerifyKeyManager
331     : public KeyTypeManager<RsaSsaPssPublicKey, void, List<PublicKeyVerify>> {
332  public:
333   class PublicKeyVerifyFactory : public PrimitiveFactory<PublicKeyVerify> {
334    public:
Create(const RsaSsaPssPublicKey & key) const335     util::StatusOr<std::unique_ptr<PublicKeyVerify>> Create(
336         const RsaSsaPssPublicKey& key) const override {
337       return {
338           absl::make_unique<test::DummyPublicKeyVerify>("a public key verify")};
339     }
340   };
341 
FakeVerifyKeyManager()342   explicit FakeVerifyKeyManager()
343       : KeyTypeManager(absl::make_unique<PublicKeyVerifyFactory>()) {}
344 
key_material_type() const345   KeyData::KeyMaterialType key_material_type() const override {
346     return KeyData::ASYMMETRIC_PUBLIC;
347   }
348 
get_version() const349   uint32_t get_version() const override { return 0; }
350 
get_key_type() const351   const std::string& get_key_type() const override { return key_type_; }
352 
ValidateKey(const RsaSsaPssPublicKey & key) const353   util::Status ValidateKey(const RsaSsaPssPublicKey& key) const override {
354     return util::OkStatus();
355   }
356 
ValidateParams(const RsaSsaPssParams & params) const357   util::Status ValidateParams(const RsaSsaPssParams& params) const {
358     return util::OkStatus();
359   }
360 
361  private:
362   const std::string key_type_ = "some.verify.key.type";
363 };
364 
TEST(ConfigurationImplTest,AddAsymmetricKeyManagers)365 TEST(ConfigurationImplTest, AddAsymmetricKeyManagers) {
366   Configuration config;
367   EXPECT_THAT(ConfigurationImpl::AddAsymmetricKeyManagers(
368                   absl::make_unique<FakeSignKeyManager>(),
369                   absl::make_unique<FakeVerifyKeyManager>(), config),
370               IsOk());
371 }
372 
TEST(ConfigurationImplTest,GetKeyTypeInfoStoreAsymmetric)373 TEST(ConfigurationImplTest, GetKeyTypeInfoStoreAsymmetric) {
374   Configuration config;
375   ASSERT_THAT(ConfigurationImpl::AddAsymmetricKeyManagers(
376                   absl::make_unique<FakeSignKeyManager>(),
377                   absl::make_unique<FakeVerifyKeyManager>(), config),
378               IsOk());
379 
380   {
381     std::string type_url = FakeSignKeyManager().get_key_type();
382     util::StatusOr<const KeyTypeInfoStore*> store =
383         ConfigurationImpl::GetKeyTypeInfoStore(config);
384     ASSERT_THAT(store, IsOk());
385     util::StatusOr<const KeyTypeInfoStore::Info*> info =
386         (*store)->Get(type_url);
387     ASSERT_THAT(info, IsOk());
388 
389     util::StatusOr<const KeyManager<PublicKeySign>*> key_manager =
390         (*info)->get_key_manager<PublicKeySign>(type_url);
391     ASSERT_THAT(key_manager, IsOk());
392     EXPECT_EQ((*key_manager)->get_key_type(), type_url);
393   }
394   {
395     std::string type_url = FakeVerifyKeyManager().get_key_type();
396     util::StatusOr<const KeyTypeInfoStore*> store =
397         ConfigurationImpl::GetKeyTypeInfoStore(config);
398     ASSERT_THAT(store, IsOk());
399     util::StatusOr<const KeyTypeInfoStore::Info*> info =
400         (*store)->Get(type_url);
401     ASSERT_THAT(info, IsOk());
402 
403     util::StatusOr<const KeyManager<PublicKeyVerify>*> key_manager =
404         (*info)->get_key_manager<PublicKeyVerify>(type_url);
405     ASSERT_THAT(key_manager, IsOk());
406     EXPECT_EQ((*key_manager)->get_key_type(), type_url);
407   }
408 }
409 
TEST(ConfigurationImplTest,GlobalRegistryMode)410 TEST(ConfigurationImplTest, GlobalRegistryMode) {
411   Registry::Reset();
412   Configuration config;
413   ASSERT_THAT(ConfigurationImpl::SetGlobalRegistryMode(config), IsOk());
414   EXPECT_TRUE(ConfigurationImpl::IsInGlobalRegistryMode(config));
415 
416   // Check that ConfigurationImpl functions return kFailedPrecondition.
417   EXPECT_THAT(ConfigurationImpl::AddPrimitiveWrapper(
418                   absl::make_unique<FakePrimitiveWrapper>(), config),
419               StatusIs(absl::StatusCode::kFailedPrecondition));
420   EXPECT_THAT(ConfigurationImpl::AddKeyTypeManager(
421                   absl::make_unique<FakeKeyTypeManager>(), config),
422               StatusIs(absl::StatusCode::kFailedPrecondition));
423   EXPECT_THAT(ConfigurationImpl::AddAsymmetricKeyManagers(
424                   absl::make_unique<FakeSignKeyManager>(),
425                   absl::make_unique<FakeVerifyKeyManager>(), config),
426               StatusIs(absl::StatusCode::kFailedPrecondition));
427   EXPECT_THAT(ConfigurationImpl::GetKeyTypeInfoStore(config).status(),
428               StatusIs(absl::StatusCode::kFailedPrecondition));
429   EXPECT_THAT(ConfigurationImpl::GetKeysetWrapperStore(config).status(),
430               StatusIs(absl::StatusCode::kFailedPrecondition));
431 
432   Keyset keyset;
433   std::string raw_key = AddAesGcmKeyToKeyset(
434       keyset, /*key_id=*/13, OutputPrefixType::TINK, KeyStatusType::ENABLED);
435   keyset.set_primary_key_id(13);
436   std::unique_ptr<KeysetHandle> handle =
437       CleartextKeysetHandle::GetKeysetHandle(keyset);
438   // TODO(b/265705174): Replace with GetPrimitive(config) once implemented.
439   EXPECT_THAT(handle->GetPrimitive<FakePrimitive>().status(),
440               StatusIs(absl::StatusCode::kNotFound));
441 
442   ASSERT_THAT(Registry::RegisterPrimitiveWrapper(
443                   absl::make_unique<FakePrimitiveWrapper>()),
444               IsOk());
445   ASSERT_THAT(
446       Registry::RegisterKeyTypeManager(absl::make_unique<FakeKeyTypeManager>(),
447                                        /*new_key_allowed=*/true),
448       IsOk());
449   // TODO(b/265705174): Replace with GetPrimitive(config) once implemented.
450   EXPECT_THAT(handle->GetPrimitive<FakePrimitive>(), IsOk());
451 }
452 
TEST(ConfigurationImplTest,GlobalRegistryModeWithNonEmptyConfigFails)453 TEST(ConfigurationImplTest, GlobalRegistryModeWithNonEmptyConfigFails) {
454   Configuration config;
455   ASSERT_THAT(ConfigurationImpl::AddPrimitiveWrapper(
456                   absl::make_unique<FakePrimitiveWrapper>(), config),
457               IsOk());
458   EXPECT_THAT(ConfigurationImpl::SetGlobalRegistryMode(config),
459               StatusIs(absl::StatusCode::kFailedPrecondition));
460   EXPECT_FALSE(ConfigurationImpl::IsInGlobalRegistryMode(config));
461 }
462 
463 }  // namespace
464 }  // namespace internal
465 }  // namespace tink
466 }  // namespace crypto
467