xref: /aosp_15_r20/external/tink/cc/examples/walkthrough/load_encrypted_keyset_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 "walkthrough/load_encrypted_keyset.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 "absl/memory/memory.h"
27 #include "absl/status/status.h"
28 #include "absl/strings/string_view.h"
29 #include "tink/aead.h"
30 #include "tink/aead/aead_config.h"
31 #include "walkthrough/load_cleartext_keyset.h"
32 #include "walkthrough/test_util.h"
33 #include "tink/kms_clients.h"
34 #include "tink/registry.h"
35 #include "tink/util/statusor.h"
36 #include "tink/util/test_matchers.h"
37 
38 namespace tink_walkthrough {
39 namespace {
40 
41 constexpr absl::string_view kSerializedMasterKeyKeyset = R"json({
42   "key": [
43     {
44       "keyData": {
45         "keyMaterialType": "SYMMETRIC",
46         "typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
47         "value": "GiBWyUfGgYk3RTRhj/LIUzSudIWlyjCftCOypTr0jCNSLg=="
48       },
49       "keyId": 294406504,
50       "outputPrefixType": "TINK",
51       "status": "ENABLED"
52     }
53   ],
54   "primaryKeyId": 294406504
55 })json";
56 
57 constexpr absl::string_view kSerializedKeysetToEncrypt = R"json({
58   "key": [
59     {
60       "keyData": {
61         "keyMaterialType": "SYMMETRIC",
62         "typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
63         "value": "GhD+9l0RANZjzZEZ8PDp7LRW"
64       },
65       "keyId": 1931667682,
66       "outputPrefixType": "TINK",
67       "status": "ENABLED"
68     }
69   ],
70   "primaryKeyId": 1931667682
71 })json";
72 
73 // Encryption of kSerializedKeysetToEncrypt using kSerializedMasterKeyKeyset.
74 constexpr absl::string_view kEncryptedKeyset = R"json({
75   "encryptedKeyset": "ARGMSWi6YHyZ/Oqxl00XSq631a0q2UPmf+rCvCIAggSZrwCmxFF797MpY0dqgaXu1fz2eQ8zFNhlyTXv9kwg1kY6COpyhY/68zNBUkyKX4CharLYfpg1LgRl+6rMzIQa0XDHh7ZDmp1CevzecZIKnG83uDRHxxSv3h8c/Kc="
76 })json";
77 
78 constexpr absl::string_view kFakeKmsKeyUri = "fake://some_key";
79 
80 using ::crypto::tink::Aead;
81 using ::crypto::tink::KeysetHandle;
82 using ::crypto::tink::Registry;
83 using ::crypto::tink::test::IsOk;
84 using ::crypto::tink::test::IsOkAndHolds;
85 using ::crypto::tink::test::StatusIs;
86 using ::crypto::tink::util::Status;
87 using ::crypto::tink::util::StatusOr;
88 using ::testing::Environment;
89 
90 // Test environment used to register KMS clients only once for the whole test.
91 class LoadKeysetTestEnvironment : public Environment {
92  public:
93   ~LoadKeysetTestEnvironment() override = default;
94 
95   // Register FakeKmsClient and AlwaysFailingFakeKmsClient.
SetUp()96   void SetUp() override {
97     auto fake_kms =
98         absl::make_unique<FakeKmsClient>(kSerializedMasterKeyKeyset);
99     ASSERT_THAT(crypto::tink::KmsClients::Add(std::move(fake_kms)), IsOk());
100     auto failing_kms = absl::make_unique<AlwaysFailingFakeKmsClient>();
101     ASSERT_THAT(crypto::tink::KmsClients::Add(std::move(failing_kms)), IsOk());
102   }
103 };
104 
105 // Unused.
106 Environment *const test_env =
107     testing::AddGlobalTestEnvironment(new LoadKeysetTestEnvironment());
108 
109 class LoadKeysetTest : public ::testing::Test {
110  public:
TearDown()111   void TearDown() override { Registry::Reset(); }
112 };
113 
TEST_F(LoadKeysetTest,LoadKeysetFailsWhenNoKmsRegistered)114 TEST_F(LoadKeysetTest, LoadKeysetFailsWhenNoKmsRegistered) {
115   StatusOr<std::unique_ptr<KeysetHandle>> expected_keyset =
116       LoadKeyset(kEncryptedKeyset, /*master_key_uri=*/"other_kms://some_key");
117   EXPECT_THAT(expected_keyset.status(), StatusIs(absl::StatusCode::kNotFound));
118 }
119 
TEST_F(LoadKeysetTest,LoadKeysetFailsWhenKmsClientFails)120 TEST_F(LoadKeysetTest, LoadKeysetFailsWhenKmsClientFails) {
121   StatusOr<std::unique_ptr<KeysetHandle>> expected_keyset =
122       LoadKeyset(kEncryptedKeyset, /*master_key_uri=*/"failing://some_key");
123   EXPECT_THAT(expected_keyset.status(),
124               StatusIs(absl::StatusCode::kUnimplemented));
125 }
126 
TEST_F(LoadKeysetTest,LoadKeysetFailsWhenAeadNotRegistered)127 TEST_F(LoadKeysetTest, LoadKeysetFailsWhenAeadNotRegistered) {
128   StatusOr<std::unique_ptr<KeysetHandle>> expected_keyset =
129       LoadKeyset(kEncryptedKeyset, kFakeKmsKeyUri);
130   EXPECT_THAT(expected_keyset.status(), StatusIs(absl::StatusCode::kNotFound));
131 }
132 
TEST_F(LoadKeysetTest,LoadKeysetFailsWhenInvalidKeyset)133 TEST_F(LoadKeysetTest, LoadKeysetFailsWhenInvalidKeyset) {
134   ASSERT_THAT(crypto::tink::AeadConfig::Register(), IsOk());
135   StatusOr<std::unique_ptr<KeysetHandle>> expected_keyset =
136       LoadKeyset("invalid", kFakeKmsKeyUri);
137   EXPECT_THAT(expected_keyset.status(),
138               StatusIs(absl::StatusCode::kInvalidArgument));
139   Registry::Reset();
140 }
141 
TEST_F(LoadKeysetTest,LoadKeysetSucceeds)142 TEST_F(LoadKeysetTest, LoadKeysetSucceeds) {
143   ASSERT_THAT(crypto::tink::AeadConfig::Register(), IsOk());
144   StatusOr<std::unique_ptr<KeysetHandle>> handle =
145       LoadKeyset(kEncryptedKeyset, kFakeKmsKeyUri);
146   ASSERT_THAT(handle, IsOk());
147   StatusOr<std::unique_ptr<Aead>> aead = (*handle)->GetPrimitive<Aead>();
148   ASSERT_THAT(aead, IsOk());
149 
150   StatusOr<std::unique_ptr<KeysetHandle>> expected_keyset =
151       LoadKeyset(kSerializedKeysetToEncrypt);
152   ASSERT_THAT(expected_keyset, IsOk());
153   StatusOr<std::unique_ptr<Aead>> expected_aead =
154       (*expected_keyset)->GetPrimitive<Aead>();
155   ASSERT_THAT(expected_aead, IsOk());
156 
157   std::string associated_data = "Some associated data";
158   std::string plaintext = "Some plaintext";
159 
160   StatusOr<std::string> ciphertext =
161       (*aead)->Encrypt(plaintext, associated_data);
162   ASSERT_THAT(ciphertext, IsOk());
163   EXPECT_THAT((*expected_aead)->Decrypt(*ciphertext, associated_data),
164               IsOkAndHolds(plaintext));
165 }
166 
167 }  // namespace
168 }  // namespace tink_walkthrough
169