xref: /aosp_15_r20/external/tink/cc/core/keyset_handle_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2017 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/keyset_handle.h"
18 
19 #include <memory>
20 #include <ostream>
21 #include <sstream>
22 #include <string>
23 #include <utility>
24 
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "absl/memory/memory.h"
28 #include "absl/status/status.h"
29 #include "absl/strings/string_view.h"
30 #include "tink/aead/aead_key_templates.h"
31 #include "tink/aead/aead_wrapper.h"
32 #include "tink/aead/aes_gcm_key_manager.h"
33 #include "tink/aead_key_templates.h"
34 #include "tink/binary_keyset_reader.h"
35 #include "tink/binary_keyset_writer.h"
36 #include "tink/cleartext_keyset_handle.h"
37 #include "tink/config/fips_140_2.h"
38 #include "tink/config/global_registry.h"
39 #include "tink/config/key_gen_fips_140_2.h"
40 #include "tink/config/tink_config.h"
41 #include "tink/core/key_manager_impl.h"
42 #include "tink/internal/fips_utils.h"
43 #include "tink/internal/key_gen_configuration_impl.h"
44 #include "tink/json_keyset_reader.h"
45 #include "tink/json_keyset_writer.h"
46 #include "tink/key_gen_configuration.h"
47 #include "tink/key_status.h"
48 #include "tink/primitive_set.h"
49 #include "tink/primitive_wrapper.h"
50 #include "tink/signature/ecdsa_sign_key_manager.h"
51 #include "tink/signature/ecdsa_verify_key_manager.h"
52 #include "tink/signature/signature_key_templates.h"
53 #include "tink/util/status.h"
54 #include "tink/util/statusor.h"
55 #include "tink/util/test_keyset_handle.h"
56 #include "tink/util/test_matchers.h"
57 #include "tink/util/test_util.h"
58 #include "proto/aes_gcm_siv.pb.h"
59 #include "proto/tink.pb.h"
60 
61 namespace crypto {
62 namespace tink {
63 
64 using ::crypto::tink::TestKeysetHandle;
65 using ::crypto::tink::test::AddKeyData;
66 using ::crypto::tink::test::AddLegacyKey;
67 using ::crypto::tink::test::AddRawKey;
68 using ::crypto::tink::test::AddTinkKey;
69 using ::crypto::tink::test::DummyAead;
70 using ::crypto::tink::test::IsOk;
71 using ::crypto::tink::test::StatusIs;
72 using ::google::crypto::tink::AesGcmKey;
73 using ::google::crypto::tink::AesGcmKeyFormat;
74 using ::google::crypto::tink::AesGcmSivKey;
75 using ::google::crypto::tink::EcdsaKeyFormat;
76 using ::google::crypto::tink::EncryptedKeyset;
77 using ::google::crypto::tink::KeyData;
78 using ::google::crypto::tink::Keyset;
79 using ::google::crypto::tink::KeyStatusType;
80 using ::google::crypto::tink::KeyTemplate;
81 using ::google::crypto::tink::OutputPrefixType;
82 using ::testing::_;
83 using ::testing::Eq;
84 using ::testing::IsFalse;
85 using ::testing::IsTrue;
86 using ::testing::Not;
87 using ::testing::SizeIs;
88 
89 namespace {
90 
91 class KeysetHandleTest : public ::testing::Test {
92  protected:
SetUp()93   void SetUp() override {
94     Registry::Reset();
95     auto status = TinkConfig::Register();
96     ASSERT_TRUE(status.ok()) << status;
97 
98     internal::UnSetFipsRestricted();
99   }
100 };
101 
102 using KeysetHandleDeathTest = KeysetHandleTest;
103 
104 // Fake AEAD key type manager for testing.
105 class FakeAeadKeyManager
106     : public KeyTypeManager<AesGcmKey, AesGcmKeyFormat, List<Aead>> {
107  public:
108   class AeadFactory : public PrimitiveFactory<Aead> {
109    public:
AeadFactory(absl::string_view key_type)110     explicit AeadFactory(absl::string_view key_type) : key_type_(key_type) {}
111 
Create(const AesGcmKey & key) const112     util::StatusOr<std::unique_ptr<Aead>> Create(
113         const AesGcmKey& key) const override {
114       return {absl::make_unique<DummyAead>(key_type_)};
115     }
116 
117    private:
118     const std::string key_type_;
119   };
120 
FakeAeadKeyManager(absl::string_view key_type)121   explicit FakeAeadKeyManager(absl::string_view key_type)
122       : KeyTypeManager(absl::make_unique<AeadFactory>(key_type)),
123         key_type_(key_type) {}
124 
key_material_type() const125   google::crypto::tink::KeyData::KeyMaterialType key_material_type()
126       const override {
127     return google::crypto::tink::KeyData::SYMMETRIC;
128   }
129 
get_version() const130   uint32_t get_version() const override { return 0; }
131 
get_key_type() const132   const std::string& get_key_type() const override { return key_type_; }
133 
ValidateKey(const AesGcmKey & key) const134   crypto::tink::util::Status ValidateKey(const AesGcmKey& key) const override {
135     return util::OkStatus();
136   }
137 
ValidateKeyFormat(const AesGcmKeyFormat & key_format) const138   crypto::tink::util::Status ValidateKeyFormat(
139       const AesGcmKeyFormat& key_format) const override {
140     return util::OkStatus();
141   }
142 
CreateKey(const AesGcmKeyFormat & key_format) const143   crypto::tink::util::StatusOr<AesGcmKey> CreateKey(
144       const AesGcmKeyFormat& key_format) const override {
145     return AesGcmKey();
146   }
147 
DeriveKey(const AesGcmKeyFormat & key_format,InputStream * input_stream) const148   crypto::tink::util::StatusOr<AesGcmKey> DeriveKey(
149       const AesGcmKeyFormat& key_format,
150       InputStream* input_stream) const override {
151     return AesGcmKey();
152   }
153 
154  private:
155   const std::string key_type_;
156 };
157 
158 class MockAeadPrimitiveWrapper : public PrimitiveWrapper<Aead, Aead> {
159  public:
160   MOCK_METHOD(util::StatusOr<std::unique_ptr<Aead>>, Wrap,
161               (std::unique_ptr<PrimitiveSet<Aead>> primitive_set),
162               (const override));
163 };
164 
165 // Generates a keyset for testing.
GetTestKeyset()166 Keyset GetTestKeyset() {
167   Keyset keyset;
168   Keyset::Key key;
169   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
170              KeyData::SYMMETRIC, &keyset);
171   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
172             KeyData::SYMMETRIC, &keyset);
173   keyset.set_primary_key_id(42);
174   return keyset;
175 }
176 
177 // Generates a public keyset for testing.
GetPublicTestKeyset()178 Keyset GetPublicTestKeyset() {
179   Keyset keyset;
180   Keyset::Key key;
181   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
182              KeyData::ASYMMETRIC_PUBLIC, &keyset);
183   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
184             KeyData::REMOTE, &keyset);
185   keyset.set_primary_key_id(42);
186   return keyset;
187 }
188 
TEST_F(KeysetHandleTest,ReadEncryptedKeysetBinary)189 TEST_F(KeysetHandleTest, ReadEncryptedKeysetBinary) {
190   Keyset keyset;
191   Keyset::Key key;
192   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
193              KeyData::SYMMETRIC, &keyset);
194   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
195             KeyData::SYMMETRIC, &keyset);
196   keyset.set_primary_key_id(42);
197 
198   {  // Good encrypted keyset.
199     DummyAead aead("dummy aead 42");
200     std::string keyset_ciphertext =
201         aead.Encrypt(keyset.SerializeAsString(), /* associated_data= */ "")
202             .value();
203     EncryptedKeyset encrypted_keyset;
204     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
205     auto reader = std::move(
206         BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
207     auto result = KeysetHandle::Read(std::move(reader), aead);
208     EXPECT_TRUE(result.ok()) << result.status();
209     auto handle = std::move(result.value());
210     EXPECT_EQ(keyset.SerializeAsString(),
211               TestKeysetHandle::GetKeyset(*handle).SerializeAsString());
212   }
213 
214   {  // AEAD does not match the ciphertext
215     DummyAead aead("dummy aead 42");
216     std::string keyset_ciphertext =
217         aead.Encrypt(keyset.SerializeAsString(), /* associated_data= */ "")
218             .value();
219     EncryptedKeyset encrypted_keyset;
220     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
221     auto reader = std::move(
222         BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
223     DummyAead wrong_aead("wrong aead");
224     auto result = KeysetHandle::Read(std::move(reader), wrong_aead);
225     EXPECT_FALSE(result.ok());
226     EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
227   }
228 
229   {  // Ciphertext does not contain actual keyset.
230     DummyAead aead("dummy aead 42");
231     std::string keyset_ciphertext =
232         aead.Encrypt("not a serialized keyset", /* associated_data= */ "")
233             .value();
234     EncryptedKeyset encrypted_keyset;
235     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
236     auto reader = std::move(
237         BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
238     auto result = KeysetHandle::Read(std::move(reader), aead);
239     EXPECT_FALSE(result.ok());
240     EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
241   }
242 
243   {  // Wrong ciphertext of encrypted keyset.
244     DummyAead aead("dummy aead 42");
245     std::string keyset_ciphertext = "totally wrong ciphertext";
246     EncryptedKeyset encrypted_keyset;
247     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
248     auto reader = std::move(
249         BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
250     auto result = KeysetHandle::Read(std::move(reader), aead);
251     EXPECT_FALSE(result.ok());
252     EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
253   }
254 }
255 
256 // Check that the generated keyset handle correctly propagates annotations.
TEST_F(KeysetHandleTest,ReadEncryptedWithAnnotations)257 TEST_F(KeysetHandleTest, ReadEncryptedWithAnnotations) {
258   const absl::flat_hash_map<std::string, std::string> kAnnotations = {
259       {"key1", "value1"}, {"key2", "value2"}};
260   Keyset keyset = GetTestKeyset();
261   DummyAead aead("dummy aead 42");
262   std::string keyset_ciphertext =
263       *aead.Encrypt(keyset.SerializeAsString(), /*associated_data=*/"");
264   EncryptedKeyset encrypted_keyset;
265   encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
266   util::StatusOr<std::unique_ptr<KeysetReader>> reader =
267       BinaryKeysetReader::New(encrypted_keyset.SerializeAsString());
268   util::StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
269       KeysetHandle::Read(*std::move(reader), aead, kAnnotations);
270   ASSERT_THAT(keyset_handle, IsOk());
271 
272   // In order to validate annotations are set correctly, we need acceess to the
273   // generated primitive set, which is populated by KeysetWrapperImpl and passed
274   // to the primitive wrapper. We thus register a mock primitive wrapper for
275   // Aead so that we can copy the annotations and later check them.
276   auto primitive_wrapper = absl::make_unique<MockAeadPrimitiveWrapper>();
277   absl::flat_hash_map<std::string, std::string> generated_annotations;
278   EXPECT_CALL(*primitive_wrapper, Wrap(_))
279       .WillOnce(
280           [&generated_annotations](
281               std::unique_ptr<PrimitiveSet<Aead>> generated_primitive_set) {
282             generated_annotations = generated_primitive_set->get_annotations();
283             std::unique_ptr<Aead> aead = absl::make_unique<DummyAead>("");
284             return aead;
285           });
286   Registry::Reset();
287   ASSERT_THAT(Registry::RegisterPrimitiveWrapper(std::move(primitive_wrapper)),
288               IsOk());
289   ASSERT_THAT(Registry::RegisterKeyTypeManager(
290                   absl::make_unique<FakeAeadKeyManager>("some_key_type"),
291                   /*new_key_allowed=*/true),
292               IsOk());
293   ASSERT_THAT(Registry::RegisterKeyTypeManager(
294                   absl::make_unique<FakeAeadKeyManager>("some_other_key_type"),
295                   /*new_key_allowed=*/true),
296               IsOk());
297 
298   ASSERT_THAT((*keyset_handle)->GetPrimitive<Aead>(), IsOk());
299   EXPECT_EQ(generated_annotations, kAnnotations);
300   // This is needed to cleanup mocks.
301   Registry::Reset();
302 }
303 
TEST_F(KeysetHandleTest,ReadEncryptedKeysetJson)304 TEST_F(KeysetHandleTest, ReadEncryptedKeysetJson) {
305   Keyset keyset;
306   Keyset::Key key;
307   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
308              KeyData::SYMMETRIC, &keyset);
309   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
310             KeyData::SYMMETRIC, &keyset);
311   keyset.set_primary_key_id(42);
312 
313   {  // Good encrypted keyset.
314     DummyAead aead("dummy aead 42");
315     std::string keyset_ciphertext =
316         aead.Encrypt(keyset.SerializeAsString(), /* associated_data= */ "")
317             .value();
318     EncryptedKeyset encrypted_keyset;
319     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
320     auto* keyset_info = encrypted_keyset.mutable_keyset_info();
321     keyset_info->set_primary_key_id(42);
322     auto* key_info = keyset_info->add_key_info();
323     key_info->set_key_id(42);
324     key_info->set_type_url("dummy key type");
325     key_info->set_output_prefix_type(OutputPrefixType::TINK);
326     key_info->set_status(KeyStatusType::ENABLED);
327     std::stringbuf buffer;
328     std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
329     auto writer_result = JsonKeysetWriter::New(std::move(destination_stream));
330     ASSERT_TRUE(writer_result.ok()) << writer_result.status();
331     auto status = writer_result.value()->Write(encrypted_keyset);
332     EXPECT_TRUE(status.ok()) << status;
333     std::string json_serialized_encrypted_keyset = buffer.str();
334     EXPECT_TRUE(status.ok()) << status;
335     auto reader = std::move(
336         JsonKeysetReader::New(json_serialized_encrypted_keyset).value());
337     auto result = KeysetHandle::Read(std::move(reader), aead);
338     EXPECT_TRUE(result.ok()) << result.status();
339     auto handle = std::move(result.value());
340     EXPECT_EQ(keyset.SerializeAsString(),
341               TestKeysetHandle::GetKeyset(*handle).SerializeAsString());
342   }
343 
344   {  // AEAD does not match the ciphertext
345     DummyAead aead("dummy aead 42");
346     std::string keyset_ciphertext =
347         aead.Encrypt(keyset.SerializeAsString(), /* associated_data= */ "")
348             .value();
349     EncryptedKeyset encrypted_keyset;
350     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
351     auto reader = std::move(
352         JsonKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
353     DummyAead wrong_aead("wrong aead");
354     auto result = KeysetHandle::Read(std::move(reader), wrong_aead);
355     EXPECT_FALSE(result.ok());
356     EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
357   }
358 
359   {  // Ciphertext does not contain actual keyset.
360     DummyAead aead("dummy aead 42");
361     std::string keyset_ciphertext =
362         aead.Encrypt("not a serialized keyset", /* associated_data= */ "")
363             .value();
364     EncryptedKeyset encrypted_keyset;
365     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
366     auto reader = std::move(
367         JsonKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
368     auto result = KeysetHandle::Read(std::move(reader), aead);
369     EXPECT_FALSE(result.ok());
370     EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
371   }
372 
373   {  // Wrong ciphertext of encrypted keyset.
374     DummyAead aead("dummy aead 42");
375     std::string keyset_ciphertext = "totally wrong ciphertext";
376     EncryptedKeyset encrypted_keyset;
377     encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
378     auto reader = std::move(
379         JsonKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
380     auto result = KeysetHandle::Read(std::move(reader), aead);
381     EXPECT_FALSE(result.ok());
382     EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
383   }
384 }
385 
TEST_F(KeysetHandleTest,WriteEncryptedKeyset_Json)386 TEST_F(KeysetHandleTest, WriteEncryptedKeyset_Json) {
387   // Prepare a valid keyset handle
388   Keyset keyset;
389   Keyset::Key key;
390   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
391              KeyData::SYMMETRIC, &keyset);
392   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
393             KeyData::SYMMETRIC, &keyset);
394   keyset.set_primary_key_id(42);
395   auto reader =
396       std::move(BinaryKeysetReader::New(keyset.SerializeAsString()).value());
397   auto keyset_handle =
398       std::move(CleartextKeysetHandle::Read(std::move(reader)).value());
399 
400   // Prepare a keyset writer.
401   DummyAead aead("dummy aead 42");
402   std::stringbuf buffer;
403   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
404   auto writer =
405       std::move(JsonKeysetWriter::New(std::move(destination_stream)).value());
406 
407   // Write the keyset handle and check the result.
408   auto status = keyset_handle->Write(writer.get(), aead);
409   EXPECT_TRUE(status.ok()) << status;
410   auto reader_result = JsonKeysetReader::New(buffer.str());
411   EXPECT_TRUE(reader_result.ok()) << reader_result.status();
412   auto read_encrypted_result = reader_result.value()->ReadEncrypted();
413   EXPECT_TRUE(read_encrypted_result.ok()) << read_encrypted_result.status();
414   auto encrypted_keyset = std::move(read_encrypted_result.value());
415   auto decrypt_result = aead.Decrypt(encrypted_keyset->encrypted_keyset(),
416                                      /* associated_data= */ "");
417   EXPECT_TRUE(decrypt_result.status().ok()) << decrypt_result.status();
418   auto decrypted = decrypt_result.value();
419   EXPECT_EQ(decrypted, keyset.SerializeAsString());
420 
421   // Try writing to a null-writer.
422   status = keyset_handle->Write(nullptr, aead);
423   EXPECT_FALSE(status.ok());
424   EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
425 }
426 
TEST_F(KeysetHandleTest,ReadEncryptedKeysetWithAssociatedDataGoodKeyset)427 TEST_F(KeysetHandleTest, ReadEncryptedKeysetWithAssociatedDataGoodKeyset) {
428   Keyset keyset;
429   Keyset::Key key;
430   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
431              KeyData::SYMMETRIC, &keyset);
432   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
433             KeyData::SYMMETRIC, &keyset);
434   keyset.set_primary_key_id(42);
435 
436   DummyAead aead("dummy aead 42");
437   std::string keyset_ciphertext =
438       aead.Encrypt(keyset.SerializeAsString(), "aad").value();
439   EncryptedKeyset encrypted_keyset;
440   encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
441   std::unique_ptr<KeysetReader> reader = std::move(
442       BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
443   util::StatusOr<std::unique_ptr<KeysetHandle>> result =
444       KeysetHandle::ReadWithAssociatedData(std::move(reader), aead, "aad");
445   EXPECT_THAT(result, IsOk());
446   auto handle = std::move(result.value());
447   EXPECT_EQ(keyset.SerializeAsString(),
448             TestKeysetHandle::GetKeyset(*handle).SerializeAsString());
449 }
450 
451 // Check that the generated keyset handle correctly propagates annotations.
TEST_F(KeysetHandleTest,ReadEncryptedWithAssociatedDataAndAnnotations)452 TEST_F(KeysetHandleTest, ReadEncryptedWithAssociatedDataAndAnnotations) {
453   const absl::flat_hash_map<std::string, std::string> kAnnotations = {
454       {"key1", "value1"}, {"key2", "value2"}};
455   constexpr absl::string_view kAssociatedData = "some associated data";
456   Keyset keyset = GetTestKeyset();
457   DummyAead aead("dummy aead 42");
458   std::string keyset_ciphertext =
459       *aead.Encrypt(keyset.SerializeAsString(), kAssociatedData);
460   EncryptedKeyset encrypted_keyset;
461   encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
462   util::StatusOr<std::unique_ptr<KeysetReader>> reader =
463       BinaryKeysetReader::New(encrypted_keyset.SerializeAsString());
464   util::StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
465       KeysetHandle::ReadWithAssociatedData(*std::move(reader), aead,
466                                            kAssociatedData, kAnnotations);
467   ASSERT_THAT(keyset_handle, IsOk());
468 
469   auto primitive_wrapper = absl::make_unique<MockAeadPrimitiveWrapper>();
470   absl::flat_hash_map<std::string, std::string> generated_annotations;
471   EXPECT_CALL(*primitive_wrapper, Wrap(_))
472       .WillOnce(
473           [&generated_annotations](
474               std::unique_ptr<PrimitiveSet<Aead>> generated_primitive_set) {
475             generated_annotations = generated_primitive_set->get_annotations();
476             std::unique_ptr<Aead> aead = absl::make_unique<DummyAead>("");
477             return aead;
478           });
479   Registry::Reset();
480   ASSERT_THAT(Registry::RegisterPrimitiveWrapper(std::move(primitive_wrapper)),
481               IsOk());
482   ASSERT_THAT(Registry::RegisterKeyTypeManager(
483                   absl::make_unique<FakeAeadKeyManager>("some_key_type"),
484                   /*new_key_allowed=*/true),
485               IsOk());
486   ASSERT_THAT(Registry::RegisterKeyTypeManager(
487                   absl::make_unique<FakeAeadKeyManager>("some_other_key_type"),
488                   /*new_key_allowed=*/true),
489               IsOk());
490 
491   ASSERT_THAT((*keyset_handle)->GetPrimitive<Aead>(), IsOk());
492   EXPECT_EQ(generated_annotations, kAnnotations);
493   // This is needed to cleanup mocks.
494   Registry::Reset();
495 }
496 
TEST_F(KeysetHandleTest,ReadEncryptedKeysetWithAssociatedDataWrongAad)497 TEST_F(KeysetHandleTest, ReadEncryptedKeysetWithAssociatedDataWrongAad) {
498   Keyset keyset;
499   Keyset::Key key;
500   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
501              KeyData::SYMMETRIC, &keyset);
502   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
503             KeyData::SYMMETRIC, &keyset);
504   keyset.set_primary_key_id(42);
505   DummyAead aead("dummy aead 42");
506   std::string keyset_ciphertext =
507       aead.Encrypt(keyset.SerializeAsString(), "aad").value();
508   EncryptedKeyset encrypted_keyset;
509   encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
510   auto reader = std::move(
511       BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
512   auto result = KeysetHandle::ReadWithAssociatedData(std::move(reader), aead,
513                                                      "different");
514   EXPECT_THAT(result, Not(IsOk()));
515   EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
516 }
517 
TEST_F(KeysetHandleTest,ReadEncryptedKeysetWithAssociatedDataEmptyAad)518 TEST_F(KeysetHandleTest, ReadEncryptedKeysetWithAssociatedDataEmptyAad) {
519   Keyset keyset;
520   Keyset::Key key;
521   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
522              KeyData::SYMMETRIC, &keyset);
523   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
524             KeyData::SYMMETRIC, &keyset);
525   keyset.set_primary_key_id(42);
526   DummyAead aead("dummy aead 42");
527   std::string keyset_ciphertext =
528       aead.Encrypt(keyset.SerializeAsString(), "aad").value();
529   EncryptedKeyset encrypted_keyset;
530   encrypted_keyset.set_encrypted_keyset(keyset_ciphertext);
531   auto reader = std::move(
532       BinaryKeysetReader::New(encrypted_keyset.SerializeAsString()).value());
533   auto result = KeysetHandle::Read(std::move(reader), aead);
534   EXPECT_THAT(result, Not(IsOk()));
535   EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
536 }
537 
TEST_F(KeysetHandleTest,WriteEncryptedKeysetWithAssociatedData)538 TEST_F(KeysetHandleTest, WriteEncryptedKeysetWithAssociatedData) {
539   // Prepare a valid keyset handle
540   Keyset keyset;
541   Keyset::Key key;
542   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
543              KeyData::SYMMETRIC, &keyset);
544   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
545             KeyData::SYMMETRIC, &keyset);
546   keyset.set_primary_key_id(42);
547   auto reader =
548       std::move(BinaryKeysetReader::New(keyset.SerializeAsString()).value());
549   auto keyset_handle =
550       std::move(CleartextKeysetHandle::Read(std::move(reader)).value());
551 
552   // Prepare a keyset writer.
553   DummyAead aead("dummy aead 42");
554   std::stringbuf buffer;
555   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
556   auto writer =
557       std::move(BinaryKeysetWriter::New(std::move(destination_stream)).value());
558 
559   // Write the keyset handle and check the result.
560   auto status =
561       keyset_handle->WriteWithAssociatedData(writer.get(), aead, "aad");
562   EXPECT_TRUE(status.ok()) << status;
563   auto reader_result = BinaryKeysetReader::New(buffer.str());
564   EXPECT_TRUE(reader_result.ok()) << reader_result.status();
565   auto read_encrypted_result = reader_result.value()->ReadEncrypted();
566   EXPECT_TRUE(read_encrypted_result.ok()) << read_encrypted_result.status();
567   auto encrypted_keyset = std::move(read_encrypted_result.value());
568   auto decrypt_result =
569       aead.Decrypt(encrypted_keyset->encrypted_keyset(), "aad");
570   EXPECT_TRUE(decrypt_result.status().ok()) << decrypt_result.status();
571   auto decrypted = decrypt_result.value();
572   EXPECT_EQ(decrypted, keyset.SerializeAsString());
573 
574   // Try writing to a null-writer.
575   status = keyset_handle->Write(nullptr, aead);
576   EXPECT_FALSE(status.ok());
577   EXPECT_EQ(absl::StatusCode::kInvalidArgument, status.code());
578 }
579 
TEST_F(KeysetHandleTest,GenerateNew)580 TEST_F(KeysetHandleTest, GenerateNew) {
581   const google::crypto::tink::KeyTemplate* templates[] = {
582       &AeadKeyTemplates::Aes128Gcm(),
583       &AeadKeyTemplates::Aes256Gcm(),
584       &AeadKeyTemplates::Aes128CtrHmacSha256(),
585       &AeadKeyTemplates::Aes256CtrHmacSha256(),
586   };
587   for (auto templ : templates) {
588     EXPECT_THAT(KeysetHandle::GenerateNew(*templ).status(), IsOk());
589     EXPECT_THAT(KeysetHandle::GenerateNew(*templ, KeyGenConfigGlobalRegistry())
590                     .status(),
591                 IsOk());
592   }
593 }
594 
TEST_F(KeysetHandleTest,GenerateNewWithBespokeConfig)595 TEST_F(KeysetHandleTest, GenerateNewWithBespokeConfig) {
596   KeyGenConfiguration config;
597   EXPECT_THAT(
598       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(), config).status(),
599       StatusIs(absl::StatusCode::kNotFound));
600 
601   ASSERT_THAT(internal::KeyGenConfigurationImpl::AddKeyTypeManager(
602                   absl::make_unique<AesGcmKeyManager>(), config),
603               IsOk());
604   EXPECT_THAT(
605       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(), config).status(),
606       IsOk());
607 }
608 
TEST_F(KeysetHandleTest,GenerateNewWithGlobalRegistryConfig)609 TEST_F(KeysetHandleTest, GenerateNewWithGlobalRegistryConfig) {
610   EXPECT_THAT(KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(),
611                                         KeyGenConfigGlobalRegistry()),
612               IsOk());
613 }
614 
TEST_F(KeysetHandleTest,GenerateNewWithAnnotations)615 TEST_F(KeysetHandleTest, GenerateNewWithAnnotations) {
616   const absl::flat_hash_map<std::string, std::string> kAnnotations = {
617       {"key1", "value1"}, {"key2", "value2"}};
618 
619   // `handle` depends on the global registry.
620   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
621       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(), kAnnotations);
622   ASSERT_THAT(handle, IsOk());
623 
624   // `config_handle` uses a config that depends on the global registry.
625   util::StatusOr<std::unique_ptr<KeysetHandle>> config_handle =
626       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(),
627                                 KeyGenConfigGlobalRegistry(), kAnnotations);
628   ASSERT_THAT(config_handle, IsOk());
629 
630   for (KeysetHandle h : {**handle, **config_handle}) {
631     auto primitive_wrapper = absl::make_unique<MockAeadPrimitiveWrapper>();
632     absl::flat_hash_map<std::string, std::string> generated_annotations;
633     EXPECT_CALL(*primitive_wrapper, Wrap(_))
634         .WillOnce(
635             [&generated_annotations](
636                 std::unique_ptr<PrimitiveSet<Aead>> generated_primitive_set) {
637               generated_annotations =
638                   generated_primitive_set->get_annotations();
639               std::unique_ptr<Aead> aead = absl::make_unique<DummyAead>("");
640               return aead;
641             });
642 
643     Registry::Reset();
644     ASSERT_THAT(
645         Registry::RegisterPrimitiveWrapper(std::move(primitive_wrapper)),
646         IsOk());
647     ASSERT_THAT(Registry::RegisterKeyTypeManager(
648                     absl::make_unique<FakeAeadKeyManager>(
649                         "type.googleapis.com/google.crypto.tink.AesGcmKey"),
650                     /*new_key_allowed=*/true),
651                 IsOk());
652 
653     EXPECT_THAT(h.GetPrimitive<Aead>(), IsOk());
654     EXPECT_EQ(generated_annotations, kAnnotations);
655 
656     // This is needed to cleanup mocks.
657     Registry::Reset();
658   }
659 }
660 
TEST_F(KeysetHandleTest,GenerateNewErrors)661 TEST_F(KeysetHandleTest, GenerateNewErrors) {
662   KeyTemplate templ;
663   templ.set_type_url("type.googleapis.com/some.unknown.KeyType");
664   templ.set_output_prefix_type(OutputPrefixType::TINK);
665 
666   auto handle_result = KeysetHandle::GenerateNew(templ);
667   EXPECT_FALSE(handle_result.ok());
668   EXPECT_EQ(absl::StatusCode::kNotFound, handle_result.status().code());
669 }
670 
TEST_F(KeysetHandleTest,UnknownPrefixIsInvalid)671 TEST_F(KeysetHandleTest, UnknownPrefixIsInvalid) {
672   KeyTemplate templ(AeadKeyTemplates::Aes128Gcm());
673   templ.set_output_prefix_type(OutputPrefixType::UNKNOWN_PREFIX);
674   auto handle_result = KeysetHandle::GenerateNew(templ);
675   EXPECT_FALSE(handle_result.ok());
676 }
677 
CompareKeyMetadata(const Keyset::Key & expected,const Keyset::Key & actual)678 void CompareKeyMetadata(const Keyset::Key& expected,
679                         const Keyset::Key& actual) {
680   EXPECT_EQ(expected.status(), actual.status());
681   EXPECT_EQ(expected.key_id(), actual.key_id());
682   EXPECT_EQ(expected.output_prefix_type(), actual.output_prefix_type());
683 }
684 
CreateEcdsaMultiKeyset()685 util::StatusOr<const Keyset> CreateEcdsaMultiKeyset() {
686   Keyset keyset;
687   EcdsaSignKeyManager key_manager;
688   EcdsaKeyFormat key_format;
689 
690   if (!key_format.ParseFromString(SignatureKeyTemplates::EcdsaP256().value())) {
691     return util::Status(absl::StatusCode::kInvalidArgument,
692                         "Failed to parse EcdsaP256 key template");
693   }
694   AddTinkKey(EcdsaSignKeyManager().get_key_type(),
695              /* key_id= */ 623628, key_manager.CreateKey(key_format).value(),
696              KeyStatusType::ENABLED, KeyData::ASYMMETRIC_PRIVATE, &keyset);
697 
698   if (!key_format.ParseFromString(
699           SignatureKeyTemplates::EcdsaP384Sha384().value())) {
700     return util::Status(absl::StatusCode::kInvalidArgument,
701                         "Failed to parse EcdsaP384Sha384 key template");
702   }
703   AddLegacyKey(EcdsaSignKeyManager().get_key_type(),
704                /* key_id= */ 36285, key_manager.CreateKey(key_format).value(),
705                KeyStatusType::DISABLED, KeyData::ASYMMETRIC_PRIVATE, &keyset);
706 
707   if (!key_format.ParseFromString(
708           SignatureKeyTemplates::EcdsaP384Sha512().value())) {
709     return util::Status(absl::StatusCode::kInvalidArgument,
710                         "Failed to parse EcdsaP384Sha512 key template");
711   }
712   AddRawKey(EcdsaSignKeyManager().get_key_type(),
713             /* key_id= */ 42, key_manager.CreateKey(key_format).value(),
714             KeyStatusType::ENABLED, KeyData::ASYMMETRIC_PRIVATE, &keyset);
715   keyset.set_primary_key_id(42);
716 
717   return keyset;
718 }
719 
720 // TODO(b/265865177): Modernize existing GetPublicKeysetHandle tests.
TEST_F(KeysetHandleTest,GetPublicKeysetHandle)721 TEST_F(KeysetHandleTest, GetPublicKeysetHandle) {
722   {  // A keyset with a single key.
723     auto handle_result =
724         KeysetHandle::GenerateNew(SignatureKeyTemplates::EcdsaP256());
725     ASSERT_TRUE(handle_result.ok()) << handle_result.status();
726     auto handle = std::move(handle_result.value());
727     auto public_handle_result = handle->GetPublicKeysetHandle();
728     ASSERT_TRUE(public_handle_result.ok()) << public_handle_result.status();
729     auto keyset = TestKeysetHandle::GetKeyset(*handle);
730     auto public_keyset =
731         TestKeysetHandle::GetKeyset(*(public_handle_result.value()));
732     EXPECT_EQ(keyset.primary_key_id(), public_keyset.primary_key_id());
733     EXPECT_EQ(keyset.key_size(), public_keyset.key_size());
734     CompareKeyMetadata(keyset.key(0), public_keyset.key(0));
735     EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC,
736               public_keyset.key(0).key_data().key_material_type());
737   }
738   {  // A keyset with multiple keys.
739     util::StatusOr<const Keyset> keyset = CreateEcdsaMultiKeyset();
740     ASSERT_THAT(keyset, IsOk());
741     std::unique_ptr<KeysetHandle> handle =
742         TestKeysetHandle::GetKeysetHandle(*keyset);
743     util::StatusOr<std::unique_ptr<KeysetHandle>> public_handle =
744         handle->GetPublicKeysetHandle();
745     ASSERT_THAT(public_handle, IsOk());
746 
747     const Keyset& public_keyset = TestKeysetHandle::GetKeyset(**public_handle);
748     EXPECT_EQ(keyset->primary_key_id(), public_keyset.primary_key_id());
749     EXPECT_EQ(keyset->key_size(), public_keyset.key_size());
750     for (int i = 0; i < keyset->key_size(); i++) {
751       CompareKeyMetadata(keyset->key(i), public_keyset.key(i));
752       EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC,
753                 public_keyset.key(i).key_data().key_material_type());
754     }
755   }
756 }
757 
TEST_F(KeysetHandleTest,GetPublicKeysetHandleErrors)758 TEST_F(KeysetHandleTest, GetPublicKeysetHandleErrors) {
759   {  // A keyset with a single key.
760     auto handle_result =
761         KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Eax());
762     ASSERT_TRUE(handle_result.ok()) << handle_result.status();
763     auto handle = std::move(handle_result.value());
764     auto public_handle_result = handle->GetPublicKeysetHandle();
765     ASSERT_FALSE(public_handle_result.ok());
766     EXPECT_PRED_FORMAT2(testing::IsSubstring, "ASYMMETRIC_PRIVATE",
767                         std::string(public_handle_result.status().message()));
768   }
769   {  // A keyset with multiple keys.
770     Keyset keyset;
771 
772     EcdsaKeyFormat ecdsa_key_format;
773     ASSERT_TRUE(ecdsa_key_format.ParseFromString(
774         SignatureKeyTemplates::EcdsaP256().value()));
775     google::crypto::tink::AesGcmKeyFormat aead_key_format;
776     aead_key_format.set_key_size(16);
777     AddTinkKey(EcdsaSignKeyManager().get_key_type(),
778                /* key_id= */ 623628,
779                EcdsaSignKeyManager().CreateKey(ecdsa_key_format).value(),
780                KeyStatusType::ENABLED, KeyData::ASYMMETRIC_PRIVATE, &keyset);
781     AddLegacyKey(AesGcmKeyManager().get_key_type(),
782                  /* key_id= */ 42,
783                  AesGcmKeyManager().CreateKey(aead_key_format).value(),
784                  KeyStatusType::ENABLED,
785                  KeyData::ASYMMETRIC_PRIVATE,  // Intentionally wrong setting.
786                  &keyset);
787     keyset.set_primary_key_id(42);
788     auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
789     auto public_handle_result = handle->GetPublicKeysetHandle();
790     ASSERT_FALSE(public_handle_result.ok());
791     EXPECT_PRED_FORMAT2(testing::IsSubstring, "PrivateKeyFactory",
792                         std::string(public_handle_result.status().message()));
793   }
794 }
795 
TEST_F(KeysetHandleTest,GetPublicKeysetHandleWithBespokeConfigSucceeds)796 TEST_F(KeysetHandleTest, GetPublicKeysetHandleWithBespokeConfigSucceeds) {
797   util::StatusOr<const Keyset> keyset = CreateEcdsaMultiKeyset();
798   ASSERT_THAT(keyset, IsOk());
799   std::unique_ptr<KeysetHandle> handle =
800       TestKeysetHandle::GetKeysetHandle(*keyset);
801 
802   KeyGenConfiguration config;
803   ASSERT_THAT(internal::KeyGenConfigurationImpl::AddAsymmetricKeyManagers(
804                   absl::make_unique<EcdsaSignKeyManager>(),
805                   absl::make_unique<EcdsaVerifyKeyManager>(), config),
806               IsOk());
807   util::StatusOr<std::unique_ptr<KeysetHandle>> public_handle =
808       handle->GetPublicKeysetHandle(config);
809   ASSERT_THAT(public_handle, IsOk());
810 
811   const Keyset& public_keyset = TestKeysetHandle::GetKeyset(**public_handle);
812   EXPECT_EQ(keyset->primary_key_id(), public_keyset.primary_key_id());
813   EXPECT_EQ(keyset->key_size(), public_keyset.key_size());
814   for (int i = 0; i < keyset->key_size(); i++) {
815     CompareKeyMetadata(keyset->key(i), public_keyset.key(i));
816     EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC,
817               public_keyset.key(i).key_data().key_material_type());
818   }
819 }
820 
TEST_F(KeysetHandleTest,GetPublicKeysetHandleWithBespokeConfigFails)821 TEST_F(KeysetHandleTest, GetPublicKeysetHandleWithBespokeConfigFails) {
822   KeyGenConfiguration config;
823   ASSERT_THAT(internal::KeyGenConfigurationImpl::AddKeyTypeManager(
824                   absl::make_unique<AesGcmKeyManager>(), config),
825               IsOk());
826   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
827       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(), config);
828   ASSERT_THAT(handle, IsOk());
829   EXPECT_THAT((*handle)->GetPublicKeysetHandle(config).status(),
830               StatusIs(absl::StatusCode::kInvalidArgument));
831 }
832 
TEST_F(KeysetHandleTest,GetPublicKeysetHandleWithGlobalRegistryConfigSucceeds)833 TEST_F(KeysetHandleTest,
834        GetPublicKeysetHandleWithGlobalRegistryConfigSucceeds) {
835   util::StatusOr<const Keyset> keyset = CreateEcdsaMultiKeyset();
836   ASSERT_THAT(keyset, IsOk());
837   std::unique_ptr<KeysetHandle> handle =
838       TestKeysetHandle::GetKeysetHandle(*keyset);
839 
840   util::StatusOr<std::unique_ptr<KeysetHandle>> public_handle =
841       handle->GetPublicKeysetHandle(KeyGenConfigGlobalRegistry());
842   ASSERT_THAT(public_handle, IsOk());
843 
844   const Keyset& public_keyset = TestKeysetHandle::GetKeyset(**public_handle);
845   EXPECT_EQ(keyset->primary_key_id(), public_keyset.primary_key_id());
846   EXPECT_EQ(keyset->key_size(), public_keyset.key_size());
847   for (int i = 0; i < keyset->key_size(); i++) {
848     CompareKeyMetadata(keyset->key(i), public_keyset.key(i));
849     EXPECT_EQ(KeyData::ASYMMETRIC_PUBLIC,
850               public_keyset.key(i).key_data().key_material_type());
851   }
852 }
853 
TEST_F(KeysetHandleTest,GetPublicKeysetHandleWithGlobalRegistryConfigFails)854 TEST_F(KeysetHandleTest, GetPublicKeysetHandleWithGlobalRegistryConfigFails) {
855   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
856       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(),
857                                 KeyGenConfigGlobalRegistry());
858   ASSERT_THAT(handle, IsOk());
859   EXPECT_THAT(
860       (*handle)->GetPublicKeysetHandle(KeyGenConfigGlobalRegistry()).status(),
861       StatusIs(absl::StatusCode::kInvalidArgument));
862 }
863 
TEST_F(KeysetHandleTest,GetPrimitive)864 TEST_F(KeysetHandleTest, GetPrimitive) {
865   Keyset keyset;
866   KeyData key_data_0 =
867       *Registry::NewKeyData(AeadKeyTemplates::Aes128Gcm()).value();
868   AddKeyData(key_data_0, /*key_id=*/0,
869              google::crypto::tink::OutputPrefixType::TINK,
870              KeyStatusType::ENABLED, &keyset);
871   KeyData key_data_1 =
872       *Registry::NewKeyData(AeadKeyTemplates::Aes256Gcm()).value();
873   AddKeyData(key_data_1, /*key_id=*/1,
874              google::crypto::tink::OutputPrefixType::TINK,
875              KeyStatusType::ENABLED, &keyset);
876   KeyData key_data_2 =
877       *Registry::NewKeyData(AeadKeyTemplates::Aes256Gcm()).value();
878   AddKeyData(key_data_2, /*key_id=*/2,
879              google::crypto::tink::OutputPrefixType::RAW,
880              KeyStatusType::ENABLED, &keyset);
881   keyset.set_primary_key_id(1);
882   std::unique_ptr<KeysetHandle> keyset_handle =
883       TestKeysetHandle::GetKeysetHandle(keyset);
884 
885   // Check that encryption with the primary can be decrypted with key_data_1.
886   auto aead_result = keyset_handle->GetPrimitive<Aead>();
887   ASSERT_TRUE(aead_result.ok()) << aead_result.status();
888   std::unique_ptr<Aead> aead = std::move(aead_result.value());
889 
890   std::string plaintext = "plaintext";
891   std::string aad = "aad";
892   std::string encryption = aead->Encrypt(plaintext, aad).value();
893   EXPECT_EQ(aead->Decrypt(encryption, aad).value(), plaintext);
894 
895   std::unique_ptr<Aead> raw_aead =
896       Registry::GetPrimitive<Aead>(key_data_2).value();
897   EXPECT_FALSE(raw_aead->Decrypt(encryption, aad).ok());
898 
899   std::string raw_encryption = raw_aead->Encrypt(plaintext, aad).value();
900   EXPECT_EQ(aead->Decrypt(raw_encryption, aad).value(), plaintext);
901 }
902 
TEST_F(KeysetHandleTest,GetPrimitiveWithBespokeConfigSucceeds)903 TEST_F(KeysetHandleTest, GetPrimitiveWithBespokeConfigSucceeds) {
904   KeyGenConfiguration key_gen_config;
905   ASSERT_THAT(internal::KeyGenConfigurationImpl::AddKeyTypeManager(
906                   absl::make_unique<AesGcmKeyManager>(), key_gen_config),
907               IsOk());
908   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
909       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(), key_gen_config);
910   ASSERT_THAT(handle, IsOk());
911 
912   Configuration config;
913   ASSERT_THAT(internal::ConfigurationImpl::AddKeyTypeManager(
914                   absl::make_unique<AesGcmKeyManager>(), config),
915               IsOk());
916   ASSERT_THAT(internal::ConfigurationImpl::AddPrimitiveWrapper(
917                   absl::make_unique<AeadWrapper>(), config),
918               IsOk());
919 
920   EXPECT_THAT((*handle)->GetPrimitive<Aead>(config).status(), IsOk());
921 }
922 
TEST_F(KeysetHandleTest,GetPrimitiveWithBespokeConfigFailsIfEmpty)923 TEST_F(KeysetHandleTest, GetPrimitiveWithBespokeConfigFailsIfEmpty) {
924   KeyGenConfiguration key_gen_config;
925   ASSERT_THAT(internal::KeyGenConfigurationImpl::AddKeyTypeManager(
926                   absl::make_unique<AesGcmKeyManager>(), key_gen_config),
927               IsOk());
928   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
929       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(), key_gen_config);
930   ASSERT_THAT(handle, IsOk());
931 
932   Configuration config;
933   EXPECT_THAT((*handle)->GetPrimitive<Aead>(config).status(),
934               StatusIs(absl::StatusCode::kNotFound));
935 }
936 
TEST_F(KeysetHandleTest,GetPrimitiveWithGlobalRegistryConfig)937 TEST_F(KeysetHandleTest, GetPrimitiveWithGlobalRegistryConfig) {
938   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
939       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(),
940                                 KeyGenConfigGlobalRegistry());
941   ASSERT_THAT(handle, IsOk());
942 
943   EXPECT_THAT((*handle)->GetPrimitive<Aead>(ConfigGlobalRegistry()), IsOk());
944 }
945 
TEST_F(KeysetHandleTest,GetPrimitiveWithConfigFips1402)946 TEST_F(KeysetHandleTest, GetPrimitiveWithConfigFips1402) {
947   if (!internal::IsFipsEnabledInSsl()) {
948     GTEST_SKIP() << "Only test in FIPS mode";
949   }
950 
951   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
952       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(),
953                                 KeyGenConfigFips140_2());
954   ASSERT_THAT(handle, IsOk());
955   EXPECT_THAT((*handle)->GetPrimitive<Aead>(ConfigFips140_2()), IsOk());
956 }
957 
TEST_F(KeysetHandleTest,GetPrimitiveWithConfigFips1402FailsWithNonFipsHandle)958 TEST_F(KeysetHandleTest, GetPrimitiveWithConfigFips1402FailsWithNonFipsHandle) {
959   if (!internal::IsFipsEnabledInSsl()) {
960     GTEST_SKIP() << "Only test in FIPS mode";
961   }
962 
963   Keyset keyset;
964   AesGcmSivKey key_proto;
965   *key_proto.mutable_key_value() = subtle::Random::GetRandomBytes(16);
966   test::AddTinkKey(AeadKeyTemplates::Aes256GcmSiv().type_url(), /*key_id=*/13,
967                    key_proto, KeyStatusType::ENABLED, KeyData::SYMMETRIC,
968                    &keyset);
969   keyset.set_primary_key_id(13);
970 
971   std::unique_ptr<KeysetHandle> handle =
972       TestKeysetHandle::GetKeysetHandle(keyset);
973   EXPECT_THAT(handle->GetPrimitive<Aead>(ConfigFips140_2()).status(),
974               StatusIs(absl::StatusCode::kNotFound));
975 }
976 
977 // Tests that GetPrimitive(nullptr) fails with a non-ok status.
TEST_F(KeysetHandleTest,GetPrimitiveNullptrKeyManager)978 TEST_F(KeysetHandleTest, GetPrimitiveNullptrKeyManager) {
979   Keyset keyset;
980   AddKeyData(*Registry::NewKeyData(AeadKeyTemplates::Aes128Gcm()).value(),
981              /*key_id=*/0, google::crypto::tink::OutputPrefixType::TINK,
982              KeyStatusType::ENABLED, &keyset);
983   keyset.set_primary_key_id(0);
984   std::unique_ptr<KeysetHandle> keyset_handle =
985       TestKeysetHandle::GetKeysetHandle(keyset);
986   ASSERT_THAT(keyset_handle->GetPrimitive<Aead>(nullptr).status(),
987               test::StatusIs(absl::StatusCode::kInvalidArgument));
988 }
989 
990 // Test creating with custom key manager. For this, we reset the registry before
991 // asking for the primitive.
TEST_F(KeysetHandleTest,GetPrimitiveCustomKeyManager)992 TEST_F(KeysetHandleTest, GetPrimitiveCustomKeyManager) {
993   auto handle_result = KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm());
994   ASSERT_TRUE(handle_result.ok()) << handle_result.status();
995   std::unique_ptr<KeysetHandle> handle = std::move(handle_result.value());
996   Registry::Reset();
997   ASSERT_TRUE(
998       Registry::RegisterPrimitiveWrapper(absl::make_unique<AeadWrapper>())
999           .ok());
1000   // Without custom key manager it now fails.
1001   ASSERT_FALSE(handle->GetPrimitive<Aead>().ok());
1002   AesGcmKeyManager key_type_manager;
1003   std::unique_ptr<KeyManager<Aead>> key_manager =
1004       crypto::tink::internal::MakeKeyManager<Aead>(&key_type_manager);
1005   // With custom key manager it works ok.
1006   ASSERT_TRUE(handle->GetPrimitive<Aead>(key_manager.get()).ok());
1007 }
1008 
1009 // Compile time check: ensures that the KeysetHandle can be copied.
TEST_F(KeysetHandleTest,Copiable)1010 TEST_F(KeysetHandleTest, Copiable) {
1011   auto handle_result = KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Eax());
1012   ASSERT_TRUE(handle_result.ok()) << handle_result.status();
1013   std::unique_ptr<KeysetHandle> handle = std::move(handle_result.value());
1014   KeysetHandle handle_copy = *handle;
1015 }
1016 
TEST_F(KeysetHandleTest,ReadNoSecret)1017 TEST_F(KeysetHandleTest, ReadNoSecret) {
1018   Keyset keyset;
1019   Keyset::Key key;
1020   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1021              KeyData::ASYMMETRIC_PUBLIC, &keyset);
1022   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
1023             KeyData::REMOTE, &keyset);
1024   keyset.set_primary_key_id(42);
1025   auto handle_result = KeysetHandle::ReadNoSecret(keyset.SerializeAsString());
1026   ASSERT_THAT(handle_result, IsOk());
1027   std::unique_ptr<KeysetHandle>& keyset_handle = handle_result.value();
1028 
1029   const Keyset& result = CleartextKeysetHandle::GetKeyset(*keyset_handle);
1030   // We check that result equals keyset. For lack of a better method we do this
1031   // by hand.
1032   EXPECT_EQ(result.primary_key_id(), keyset.primary_key_id());
1033   ASSERT_EQ(result.key_size(), keyset.key_size());
1034   ASSERT_EQ(result.key(0).key_id(), keyset.key(0).key_id());
1035   ASSERT_EQ(result.key(1).key_id(), keyset.key(1).key_id());
1036 }
1037 
TEST_F(KeysetHandleTest,ReadNoSecretWithAnnotations)1038 TEST_F(KeysetHandleTest, ReadNoSecretWithAnnotations) {
1039   const absl::flat_hash_map<std::string, std::string> kAnnotations = {
1040       {"key1", "value1"}, {"key2", "value2"}};
1041   Keyset keyset = GetPublicTestKeyset();
1042   util::StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
1043       KeysetHandle::ReadNoSecret(keyset.SerializeAsString(), kAnnotations);
1044   ASSERT_THAT(keyset_handle, IsOk());
1045   auto primitive_wrapper = absl::make_unique<MockAeadPrimitiveWrapper>();
1046   absl::flat_hash_map<std::string, std::string> generated_annotations;
1047   EXPECT_CALL(*primitive_wrapper, Wrap(_))
1048       .WillOnce(
1049           [&generated_annotations](
1050               std::unique_ptr<PrimitiveSet<Aead>> generated_primitive_set) {
1051             generated_annotations = generated_primitive_set->get_annotations();
1052             std::unique_ptr<Aead> aead = absl::make_unique<DummyAead>("");
1053             return aead;
1054           });
1055   Registry::Reset();
1056   ASSERT_THAT(Registry::RegisterPrimitiveWrapper(std::move(primitive_wrapper)),
1057               IsOk());
1058   ASSERT_THAT(Registry::RegisterKeyTypeManager(
1059                   absl::make_unique<FakeAeadKeyManager>("some_key_type"),
1060                   /*new_key_allowed=*/true),
1061               IsOk());
1062   ASSERT_THAT(Registry::RegisterKeyTypeManager(
1063                   absl::make_unique<FakeAeadKeyManager>("some_other_key_type"),
1064                   /*new_key_allowed=*/true),
1065               IsOk());
1066 
1067   EXPECT_THAT((*keyset_handle)->GetPrimitive<Aead>(), IsOk());
1068   EXPECT_EQ(generated_annotations, kAnnotations);
1069   // This is needed to cleanup mocks.
1070   Registry::Reset();
1071 }
1072 
TEST_F(KeysetHandleTest,ReadNoSecretFailForTypeUnknown)1073 TEST_F(KeysetHandleTest, ReadNoSecretFailForTypeUnknown) {
1074   Keyset keyset;
1075   Keyset::Key key;
1076   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1077              KeyData::UNKNOWN_KEYMATERIAL, &keyset);
1078   keyset.set_primary_key_id(42);
1079   auto result = KeysetHandle::ReadNoSecret(keyset.SerializeAsString());
1080   EXPECT_THAT(result.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
1081 }
1082 
TEST_F(KeysetHandleTest,ReadNoSecretFailForTypeSymmetric)1083 TEST_F(KeysetHandleTest, ReadNoSecretFailForTypeSymmetric) {
1084   Keyset keyset;
1085   Keyset::Key key;
1086   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1087              KeyData::SYMMETRIC, &keyset);
1088   keyset.set_primary_key_id(42);
1089   auto result = KeysetHandle::ReadNoSecret(keyset.SerializeAsString());
1090   EXPECT_THAT(result.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
1091 }
1092 
TEST_F(KeysetHandleTest,ReadNoSecretFailForTypeAssymmetricPrivate)1093 TEST_F(KeysetHandleTest, ReadNoSecretFailForTypeAssymmetricPrivate) {
1094   Keyset keyset;
1095   Keyset::Key key;
1096   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1097              KeyData::ASYMMETRIC_PRIVATE, &keyset);
1098   keyset.set_primary_key_id(42);
1099   auto result = KeysetHandle::ReadNoSecret(keyset.SerializeAsString());
1100   EXPECT_THAT(result.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
1101 }
1102 
TEST_F(KeysetHandleTest,ReadNoSecretFailForHidden)1103 TEST_F(KeysetHandleTest, ReadNoSecretFailForHidden) {
1104   Keyset keyset;
1105   Keyset::Key key;
1106   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1107              KeyData::ASYMMETRIC_PUBLIC, &keyset);
1108   for (int i = 0; i < 10; ++i) {
1109     AddTinkKey(absl::StrCat("more key type", i), i, key, KeyStatusType::ENABLED,
1110                KeyData::ASYMMETRIC_PUBLIC, &keyset);
1111   }
1112   AddRawKey("some_other_key_type", 10, key, KeyStatusType::ENABLED,
1113             KeyData::ASYMMETRIC_PRIVATE, &keyset);
1114   for (int i = 0; i < 10; ++i) {
1115     AddRawKey(absl::StrCat("more key type", i + 100), i + 100, key,
1116               KeyStatusType::ENABLED, KeyData::ASYMMETRIC_PUBLIC, &keyset);
1117   }
1118 
1119   keyset.set_primary_key_id(42);
1120   auto result = KeysetHandle::ReadNoSecret(keyset.SerializeAsString());
1121   EXPECT_THAT(result.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
1122 }
1123 
TEST_F(KeysetHandleTest,ReadNoSecretFailForInvalidString)1124 TEST_F(KeysetHandleTest, ReadNoSecretFailForInvalidString) {
1125   auto result = KeysetHandle::ReadNoSecret("bad serialized keyset");
1126   EXPECT_FALSE(result.ok());
1127   EXPECT_EQ(absl::StatusCode::kInvalidArgument, result.status().code());
1128 }
1129 
TEST_F(KeysetHandleTest,WriteNoSecret)1130 TEST_F(KeysetHandleTest, WriteNoSecret) {
1131   Keyset keyset;
1132   Keyset::Key key;
1133   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1134              KeyData::ASYMMETRIC_PUBLIC, &keyset);
1135   AddRawKey("some_other_key_type", 711, key, KeyStatusType::ENABLED,
1136             KeyData::REMOTE, &keyset);
1137   keyset.set_primary_key_id(42);
1138 
1139   auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
1140 
1141   std::stringbuf buffer;
1142   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
1143   auto writer =
1144       test::DummyKeysetWriter::New(std::move(destination_stream)).value();
1145   auto result = handle->WriteNoSecret(writer.get());
1146   EXPECT_TRUE(result.ok());
1147 }
1148 
TEST_F(KeysetHandleTest,WriteNoSecretFailForTypeUnknown)1149 TEST_F(KeysetHandleTest, WriteNoSecretFailForTypeUnknown) {
1150   Keyset keyset;
1151   Keyset::Key key;
1152   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1153              KeyData::UNKNOWN_KEYMATERIAL, &keyset);
1154   keyset.set_primary_key_id(42);
1155 
1156   auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
1157 
1158   std::stringbuf buffer;
1159   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
1160   auto writer =
1161       test::DummyKeysetWriter::New(std::move(destination_stream)).value();
1162   auto result = handle->WriteNoSecret(writer.get());
1163   EXPECT_FALSE(result.ok());
1164 }
1165 
TEST_F(KeysetHandleTest,WriteNoSecretFailForTypeSymmetric)1166 TEST_F(KeysetHandleTest, WriteNoSecretFailForTypeSymmetric) {
1167   Keyset keyset;
1168   Keyset::Key key;
1169   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1170              KeyData::SYMMETRIC, &keyset);
1171   keyset.set_primary_key_id(42);
1172 
1173   auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
1174 
1175   std::stringbuf buffer;
1176   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
1177   auto writer =
1178       test::DummyKeysetWriter::New(std::move(destination_stream)).value();
1179   auto result = handle->WriteNoSecret(writer.get());
1180   EXPECT_FALSE(result.ok());
1181 }
1182 
TEST_F(KeysetHandleTest,WriteNoSecretFailForTypeAssymmetricPrivate)1183 TEST_F(KeysetHandleTest, WriteNoSecretFailForTypeAssymmetricPrivate) {
1184   Keyset keyset;
1185   Keyset::Key key;
1186   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1187              KeyData::ASYMMETRIC_PRIVATE, &keyset);
1188   keyset.set_primary_key_id(42);
1189 
1190   auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
1191 
1192   std::stringbuf buffer;
1193   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
1194   auto writer =
1195       test::DummyKeysetWriter::New(std::move(destination_stream)).value();
1196   auto result = handle->WriteNoSecret(writer.get());
1197   EXPECT_FALSE(result.ok());
1198 }
1199 
TEST_F(KeysetHandleTest,WriteNoSecretFailForHidden)1200 TEST_F(KeysetHandleTest, WriteNoSecretFailForHidden) {
1201   Keyset keyset;
1202   Keyset::Key key;
1203   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1204              KeyData::ASYMMETRIC_PUBLIC, &keyset);
1205   for (int i = 0; i < 10; ++i) {
1206     AddTinkKey(absl::StrCat("more key type", i), i, key, KeyStatusType::ENABLED,
1207                KeyData::ASYMMETRIC_PUBLIC, &keyset);
1208   }
1209   AddRawKey("some_other_key_type", 10, key, KeyStatusType::ENABLED,
1210             KeyData::ASYMMETRIC_PRIVATE, &keyset);
1211   for (int i = 0; i < 10; ++i) {
1212     AddRawKey(absl::StrCat("more key type", i + 100), i + 100, key,
1213               KeyStatusType::ENABLED, KeyData::ASYMMETRIC_PUBLIC, &keyset);
1214   }
1215 
1216   keyset.set_primary_key_id(42);
1217 
1218   auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
1219 
1220   std::stringbuf buffer;
1221   std::unique_ptr<std::ostream> destination_stream(new std::ostream(&buffer));
1222   auto writer =
1223       test::DummyKeysetWriter::New(std::move(destination_stream)).value();
1224   auto result = handle->WriteNoSecret(writer.get());
1225   EXPECT_FALSE(result.ok());
1226 }
1227 
TEST_F(KeysetHandleTest,GetKeysetInfo)1228 TEST_F(KeysetHandleTest, GetKeysetInfo) {
1229   Keyset keyset;
1230   Keyset::Key key;
1231   AddTinkKey("some_key_type", 42, key, KeyStatusType::ENABLED,
1232              KeyData::ASYMMETRIC_PUBLIC, &keyset);
1233   for (int i = 0; i < 10; ++i) {
1234     AddTinkKey(absl::StrCat("more key type", i), i, key, KeyStatusType::ENABLED,
1235                KeyData::ASYMMETRIC_PUBLIC, &keyset);
1236   }
1237   AddRawKey("some_other_key_type", 10, key, KeyStatusType::ENABLED,
1238             KeyData::ASYMMETRIC_PRIVATE, &keyset);
1239   for (int i = 0; i < 10; ++i) {
1240     AddRawKey(absl::StrCat("more key type", i + 100), i + 100, key,
1241               KeyStatusType::ENABLED, KeyData::ASYMMETRIC_PUBLIC, &keyset);
1242   }
1243   keyset.set_primary_key_id(42);
1244 
1245   auto handle = TestKeysetHandle::GetKeysetHandle(keyset);
1246   auto keyset_info = handle->GetKeysetInfo();
1247 
1248   EXPECT_EQ(keyset.primary_key_id(), keyset_info.primary_key_id());
1249   for (int i = 0; i < keyset.key_size(); ++i) {
1250     auto key_info = keyset_info.key_info(i);
1251     auto key = keyset.key(i);
1252     EXPECT_EQ(key.key_data().type_url(), key_info.type_url());
1253     EXPECT_EQ(key.status(), key_info.status());
1254     EXPECT_EQ(key.key_id(), key_info.key_id());
1255     EXPECT_EQ(key.output_prefix_type(), key_info.output_prefix_type());
1256   }
1257 }
1258 
TEST_F(KeysetHandleTest,GetEntryFromSingleKeyKeyset)1259 TEST_F(KeysetHandleTest, GetEntryFromSingleKeyKeyset) {
1260   Keyset keyset;
1261   Keyset::Key key;
1262   AddTinkKey("first_key_type", 11, key, KeyStatusType::ENABLED,
1263              KeyData::SYMMETRIC, &keyset);
1264   keyset.set_primary_key_id(11);
1265   std::unique_ptr<KeysetHandle> handle =
1266       TestKeysetHandle::GetKeysetHandle(keyset);
1267   ASSERT_THAT(handle->Validate(), IsOk());
1268   ASSERT_THAT(*handle, SizeIs(1));
1269 
1270   ASSERT_THAT(handle->ValidateAt(0), IsOk());
1271   KeysetHandle::Entry entry = (*handle)[0];
1272 
1273   EXPECT_THAT(entry.GetId(), Eq(11));
1274   EXPECT_THAT(entry.GetStatus(), Eq(KeyStatus::kEnabled));
1275   EXPECT_THAT(entry.IsPrimary(), IsTrue());
1276   EXPECT_THAT(entry.GetKey()->GetIdRequirement(), Eq(11));
1277   EXPECT_THAT(entry.GetKey()->GetParameters().HasIdRequirement(), IsTrue());
1278 }
1279 
TEST_F(KeysetHandleTest,GetEntryFromMultipleKeyKeyset)1280 TEST_F(KeysetHandleTest, GetEntryFromMultipleKeyKeyset) {
1281   Keyset keyset;
1282   Keyset::Key key;
1283   AddRawKey("first_key_type", 11, key, KeyStatusType::DISABLED,
1284             KeyData::SYMMETRIC, &keyset);
1285   AddTinkKey("second_key_type", 22, key, KeyStatusType::ENABLED,
1286              KeyData::SYMMETRIC, &keyset);
1287   AddRawKey("third_key_type", 33, key, KeyStatusType::DESTROYED,
1288             KeyData::SYMMETRIC, &keyset);
1289   keyset.set_primary_key_id(22);
1290 
1291   std::unique_ptr<KeysetHandle> handle =
1292       TestKeysetHandle::GetKeysetHandle(keyset);
1293   ASSERT_THAT(handle->Validate(), IsOk());
1294   ASSERT_THAT(*handle, SizeIs(3));
1295 
1296   ASSERT_THAT(handle->ValidateAt(0), IsOk());
1297   KeysetHandle::Entry entry0 = (*handle)[0];
1298   EXPECT_THAT(entry0.GetId(), Eq(11));
1299   EXPECT_THAT(entry0.GetStatus(), Eq(KeyStatus::kDisabled));
1300   EXPECT_THAT(entry0.IsPrimary(), IsFalse());
1301   EXPECT_THAT(entry0.GetKey()->GetIdRequirement(), Eq(absl::nullopt));
1302   EXPECT_THAT(entry0.GetKey()->GetParameters().HasIdRequirement(), IsFalse());
1303 
1304   ASSERT_THAT(handle->ValidateAt(1), IsOk());
1305   KeysetHandle::Entry entry1 = (*handle)[1];
1306   EXPECT_THAT(entry1.GetId(), Eq(22));
1307   EXPECT_THAT(entry1.GetStatus(), Eq(KeyStatus::kEnabled));
1308   EXPECT_THAT(entry1.IsPrimary(), IsTrue());
1309   EXPECT_THAT(entry1.GetKey()->GetIdRequirement(), Eq(22));
1310   EXPECT_THAT(entry1.GetKey()->GetParameters().HasIdRequirement(), IsTrue());
1311 
1312   ASSERT_THAT(handle->ValidateAt(2), IsOk());
1313   KeysetHandle::Entry entry2 = (*handle)[2];
1314   EXPECT_THAT(entry2.GetId(), Eq(33));
1315   EXPECT_THAT(entry2.GetStatus(), Eq(KeyStatus::kDestroyed));
1316   EXPECT_THAT(entry2.IsPrimary(), IsFalse());
1317   EXPECT_THAT(entry2.GetKey()->GetIdRequirement(), Eq(absl::nullopt));
1318   EXPECT_THAT(entry2.GetKey()->GetParameters().HasIdRequirement(), IsFalse());
1319 }
1320 
TEST_F(KeysetHandleDeathTest,EntryWithIndexOutOfBoundsCrashes)1321 TEST_F(KeysetHandleDeathTest, EntryWithIndexOutOfBoundsCrashes) {
1322   Keyset keyset;
1323   Keyset::Key key;
1324   AddTinkKey("first_key_type", 11, key, KeyStatusType::ENABLED,
1325              KeyData::SYMMETRIC, &keyset);
1326   keyset.set_primary_key_id(11);
1327   std::unique_ptr<KeysetHandle> handle =
1328       TestKeysetHandle::GetKeysetHandle(keyset);
1329   ASSERT_THAT(handle->Validate(), IsOk());
1330   ASSERT_THAT(*handle, SizeIs(1));
1331 
1332   EXPECT_DEATH_IF_SUPPORTED((*handle)[-1],
1333                             "Invalid index -1 for keyset of size 1");
1334   EXPECT_DEATH_IF_SUPPORTED((*handle)[1],
1335                             "Invalid index 1 for keyset of size 1");
1336 }
1337 
TEST_F(KeysetHandleDeathTest,EntryWithUnknownStatusFails)1338 TEST_F(KeysetHandleDeathTest, EntryWithUnknownStatusFails) {
1339   Keyset keyset;
1340   Keyset::Key key;
1341   AddTinkKey("first_key_type", 11, key, KeyStatusType::UNKNOWN_STATUS,
1342              KeyData::SYMMETRIC, &keyset);
1343   keyset.set_primary_key_id(11);
1344   std::unique_ptr<KeysetHandle> handle =
1345       TestKeysetHandle::GetKeysetHandle(keyset);
1346   ASSERT_THAT(*handle, SizeIs(1));
1347 
1348   EXPECT_THAT(handle->Validate(), StatusIs(absl::StatusCode::kInvalidArgument));
1349   EXPECT_THAT(handle->ValidateAt(0),
1350               StatusIs(absl::StatusCode::kInvalidArgument));
1351   EXPECT_DEATH_IF_SUPPORTED((*handle)[0], "Invalid key status type.");
1352 }
1353 
TEST_F(KeysetHandleDeathTest,EntryWithUnprintableTypeUrlFails)1354 TEST_F(KeysetHandleDeathTest, EntryWithUnprintableTypeUrlFails) {
1355   Keyset keyset;
1356   Keyset::Key key;
1357   AddRawKey("invalid key type url with spaces", 11, key, KeyStatusType::ENABLED,
1358             KeyData::SYMMETRIC, &keyset);
1359   keyset.set_primary_key_id(11);
1360 
1361   std::unique_ptr<KeysetHandle> handle =
1362       TestKeysetHandle::GetKeysetHandle(keyset);
1363   ASSERT_THAT(*handle, SizeIs(1));
1364 
1365   EXPECT_THAT(handle->Validate(),
1366               StatusIs(absl::StatusCode::kFailedPrecondition));
1367   EXPECT_THAT(handle->ValidateAt(0),
1368               StatusIs(absl::StatusCode::kFailedPrecondition));
1369   EXPECT_DEATH_IF_SUPPORTED((*handle)[0],
1370                             "Non-printable ASCII character in type URL.");
1371 }
1372 
TEST_F(KeysetHandleTest,GetPrimary)1373 TEST_F(KeysetHandleTest, GetPrimary) {
1374   Keyset keyset;
1375   Keyset::Key key;
1376   AddTinkKey("first_key_type", 11, key, KeyStatusType::ENABLED,
1377              KeyData::SYMMETRIC, &keyset);
1378   AddTinkKey("first_key_type", 22, key, KeyStatusType::ENABLED,
1379              KeyData::SYMMETRIC, &keyset);
1380   AddTinkKey("first_key_type", 33, key, KeyStatusType::ENABLED,
1381              KeyData::SYMMETRIC, &keyset);
1382   keyset.set_primary_key_id(33);
1383   std::unique_ptr<KeysetHandle> handle =
1384       TestKeysetHandle::GetKeysetHandle(keyset);
1385   ASSERT_THAT(handle->Validate(), IsOk());
1386   ASSERT_THAT(*handle, SizeIs(3));
1387 
1388   util::StatusOr<KeysetHandle::Entry> primary = handle->GetPrimary();
1389   ASSERT_THAT(primary, IsOk());
1390 
1391   EXPECT_THAT(primary->GetId(), Eq(33));
1392   EXPECT_THAT(primary->GetStatus(), Eq(KeyStatus::kEnabled));
1393   EXPECT_THAT(primary->IsPrimary(), IsTrue());
1394 }
1395 
TEST_F(KeysetHandleDeathTest,NonexistentPrimaryFails)1396 TEST_F(KeysetHandleDeathTest, NonexistentPrimaryFails) {
1397   Keyset keyset;
1398   Keyset::Key key;
1399   AddTinkKey("first_key_type", 11, key, KeyStatusType::ENABLED,
1400              KeyData::SYMMETRIC, &keyset);
1401   std::unique_ptr<KeysetHandle> handle =
1402       TestKeysetHandle::GetKeysetHandle(keyset);
1403   ASSERT_THAT(*handle, SizeIs(1));
1404 
1405   EXPECT_THAT(handle->Validate(),
1406               StatusIs(absl::StatusCode::kFailedPrecondition));
1407   EXPECT_DEATH_IF_SUPPORTED(handle->GetPrimary(), "Keyset has no primary");
1408 }
1409 
TEST_F(KeysetHandleDeathTest,MultiplePrimariesFail)1410 TEST_F(KeysetHandleDeathTest, MultiplePrimariesFail) {
1411   Keyset keyset;
1412   Keyset::Key key;
1413   AddTinkKey("first_key_type", 11, key, KeyStatusType::ENABLED,
1414              KeyData::SYMMETRIC, &keyset);
1415   AddTinkKey("second_key_type", 11, key, KeyStatusType::ENABLED,
1416              KeyData::SYMMETRIC, &keyset);
1417   // Multiple primaries since two distinct keys share the same key id.
1418   keyset.set_primary_key_id(11);
1419   std::unique_ptr<KeysetHandle> handle =
1420       TestKeysetHandle::GetKeysetHandle(keyset);
1421   ASSERT_THAT(*handle, SizeIs(2));
1422 
1423   EXPECT_THAT(handle->Validate(),
1424               StatusIs(absl::StatusCode::kFailedPrecondition));
1425   EXPECT_DEATH_IF_SUPPORTED(handle->GetPrimary(),
1426                             "Keyset has more than one primary");
1427 }
1428 
TEST_F(KeysetHandleDeathTest,GetDisabledPrimaryFails)1429 TEST_F(KeysetHandleDeathTest, GetDisabledPrimaryFails) {
1430   Keyset keyset;
1431   Keyset::Key key;
1432   AddTinkKey("first_key_type", 11, key, KeyStatusType::DISABLED,
1433              KeyData::SYMMETRIC, &keyset);
1434   keyset.set_primary_key_id(11);
1435   std::unique_ptr<KeysetHandle> handle =
1436       TestKeysetHandle::GetKeysetHandle(keyset);
1437   ASSERT_THAT(*handle, SizeIs(1));
1438 
1439   EXPECT_THAT(handle->Validate(),
1440               StatusIs(absl::StatusCode::kFailedPrecondition));
1441   EXPECT_DEATH_IF_SUPPORTED(handle->GetPrimary(),
1442                             "Keyset has primary that is not enabled");
1443 }
1444 
1445 }  // namespace
1446 }  // namespace tink
1447 }  // namespace crypto
1448