xref: /aosp_15_r20/external/tink/cc/util/fake_kms_client_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2020 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/util/fake_kms_client.h"
18 
19 #include <cstdlib>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "gtest/gtest.h"
25 #include "tink/aead/aead_config.h"
26 #include "tink/aead/aead_key_templates.h"
27 #include "tink/util/status.h"
28 #include "tink/util/statusor.h"
29 #include "tink/util/test_matchers.h"
30 #include "tink/util/test_util.h"
31 #include "proto/kms_aead.pb.h"
32 #include "proto/kms_envelope.pb.h"
33 
34 using google::crypto::tink::KeyTemplate;
35 using google::crypto::tink::KmsAeadKeyFormat;
36 using google::crypto::tink::KmsEnvelopeAeadKeyFormat;
37 using google::crypto::tink::OutputPrefixType;
38 
39 namespace crypto {
40 namespace tink {
41 namespace test {
42 namespace {
43 
44 // TODO(b/174740983) Add this function to aead_key_templates.
NewKmsAeadKeyTemplate(std::string key_uri)45 KeyTemplate NewKmsAeadKeyTemplate(std::string key_uri) {
46   KeyTemplate key_template;
47   key_template.set_type_url(
48       "type.googleapis.com/google.crypto.tink.KmsAeadKey");
49   key_template.set_output_prefix_type(OutputPrefixType::TINK);
50   KmsAeadKeyFormat key_format;
51   key_format.set_key_uri(key_uri);
52   key_format.SerializeToString(key_template.mutable_value());
53   return key_template;
54 }
55 
56 // TODO(b/174740983) Add this function to aead_key_templates.
NewKmsEnvelopeKeyTemplate(std::string key_uri,const KeyTemplate & dek_template)57 KeyTemplate NewKmsEnvelopeKeyTemplate(std::string key_uri,
58                                       const KeyTemplate& dek_template) {
59   KeyTemplate key_template;
60   key_template.set_type_url(
61       "type.googleapis.com/google.crypto.tink.KmsEnvelopeAeadKey");
62   key_template.set_output_prefix_type(OutputPrefixType::TINK);
63   KmsEnvelopeAeadKeyFormat key_format;
64   key_format.set_kek_uri(key_uri);
65   key_format.mutable_dek_template()->MergeFrom(dek_template);
66   key_format.SerializeToString(key_template.mutable_value());
67   return key_template;
68 }
69 
70 class FakeKmsClientTest : public ::testing::Test {
71  protected:
SetUpTestSuite()72   static void SetUpTestSuite() { ASSERT_TRUE(AeadConfig::Register().ok()); }
73 };
74 
TEST_F(FakeKmsClientTest,CreateNewAeadSuccess)75 TEST_F(FakeKmsClientTest, CreateNewAeadSuccess) {
76   auto uri_result = FakeKmsClient::CreateFakeKeyUri();
77   EXPECT_TRUE(uri_result.ok()) << uri_result.status();
78   std::string key_uri = uri_result.value();
79 
80   auto client_result = FakeKmsClient::New(key_uri, "");
81   EXPECT_TRUE(client_result.ok()) << client_result.status();
82   auto client = std::move(client_result.value());
83   EXPECT_TRUE(client->DoesSupport(key_uri));
84 
85   auto aead_result = client->GetAead(key_uri);
86   EXPECT_TRUE(aead_result.ok()) << aead_result.status();
87   auto aead = std::move(aead_result.value());
88 
89   std::string plaintext = "some_plaintext";
90   std::string aad = "some_aad";
91   auto encrypt_result = aead->Encrypt(plaintext, aad);
92   EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
93   std::string ciphertext = encrypt_result.value();
94   auto decrypt_result = aead->Decrypt(ciphertext, aad);
95   EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status();
96   EXPECT_EQ(plaintext, decrypt_result.value());
97 }
98 
TEST_F(FakeKmsClientTest,ClientIsBound)99 TEST_F(FakeKmsClientTest, ClientIsBound) {
100   std::string key_uri =
101       "fake-kms://"
102       "CL3oi0kSVwpMCjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNF"
103       "YXhLZXkSFhICCBAaEPFnQNgtxEG0vEek8bBfgL8YARABGL3oi0kgAQ";
104   auto client_result = FakeKmsClient::New(key_uri, "");
105   EXPECT_TRUE(client_result.ok()) << client_result.status();
106   auto client = std::move(client_result.value());
107 
108   // No other key_uri is accepted, even a valid one.
109   std::string another_key_uri =
110       "fake-kms://"
111       "CO3y2NgHElgKTAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVz"
112       "RWF4S2V5EhYSAggQGhALi4dQMjUR0faRYElRXi__GAEQARjt8tjYByAB";
113   EXPECT_FALSE(client->DoesSupport(another_key_uri));
114   auto aead_result = client->GetAead(another_key_uri);
115   EXPECT_FALSE(aead_result.ok());
116 }
117 
TEST_F(FakeKmsClientTest,ClientIsUnbound)118 TEST_F(FakeKmsClientTest, ClientIsUnbound) {
119   auto client_result = FakeKmsClient::New("", "");
120   EXPECT_TRUE(client_result.ok()) << client_result.status();
121   auto client = std::move(client_result.value());
122 
123   // All valid 'fake-kms' key_uris are accepted.
124   std::string uri =
125       "fake-kms://"
126       "CL3oi0kSVwpMCjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNF"
127       "YXhLZXkSFhICCBAaEPFnQNgtxEG0vEek8bBfgL8YARABGL3oi0kgAQ";
128   EXPECT_TRUE(client->DoesSupport(uri));
129   auto aead_result = client->GetAead(uri);
130   EXPECT_TRUE(aead_result.ok());
131 
132   std::string another_uri =
133       "fake-kms://"
134       "CO3y2NgHElgKTAowdHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVz"
135       "RWF4S2V5EhYSAggQGhALi4dQMjUR0faRYElRXi__GAEQARjt8tjYByAB";
136   EXPECT_TRUE(client->DoesSupport(another_uri));
137   auto another_aead_result = client->GetAead(another_uri);
138   EXPECT_TRUE(another_aead_result.ok()) << another_aead_result.status();
139 }
140 
TEST_F(FakeKmsClientTest,RegisterAndEncryptDecryptWithKmsAead)141 TEST_F(FakeKmsClientTest, RegisterAndEncryptDecryptWithKmsAead) {
142   auto uri_result = FakeKmsClient::CreateFakeKeyUri();
143   EXPECT_TRUE(uri_result.ok()) << uri_result.status();
144   std::string key_uri = uri_result.value();
145   auto status = FakeKmsClient::RegisterNewClient(key_uri, "");
146   EXPECT_THAT(status, IsOk());
147 
148   KeyTemplate key_template = NewKmsAeadKeyTemplate(key_uri);
149   auto handle_result = KeysetHandle::GenerateNew(key_template);
150   EXPECT_TRUE(handle_result.ok()) << handle_result.status();
151   auto aead_result = handle_result.value()->GetPrimitive<crypto::tink::Aead>();
152   EXPECT_TRUE(aead_result.ok()) << aead_result.status();
153   auto aead = std::move(aead_result.value());
154 
155   std::string plaintext = "some_plaintext";
156   std::string aad = "some_aad";
157   auto encrypt_result = aead->Encrypt(plaintext, aad);
158   EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
159   std::string ciphertext = encrypt_result.value();
160   auto decrypt_result = aead->Decrypt(ciphertext, aad);
161   EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status();
162   EXPECT_EQ(plaintext, decrypt_result.value());
163 }
164 
TEST_F(FakeKmsClientTest,RegisterAndEncryptDecryptWithKmsEnvelopeAead)165 TEST_F(FakeKmsClientTest, RegisterAndEncryptDecryptWithKmsEnvelopeAead) {
166   auto uri_result = FakeKmsClient::CreateFakeKeyUri();
167   EXPECT_TRUE(uri_result.ok()) << uri_result.status();
168   std::string key_uri = uri_result.value();
169   auto status = FakeKmsClient::RegisterNewClient(key_uri, "");
170   EXPECT_THAT(status, IsOk());
171 
172   KeyTemplate key_template =
173       NewKmsEnvelopeKeyTemplate(key_uri, AeadKeyTemplates::Aes128Gcm());
174   auto handle_result = KeysetHandle::GenerateNew(key_template);
175   EXPECT_TRUE(handle_result.ok()) << handle_result.status();
176   auto aead_result = handle_result.value()->GetPrimitive<crypto::tink::Aead>();
177   EXPECT_TRUE(aead_result.ok()) << aead_result.status();
178   auto aead = std::move(aead_result.value());
179 
180   std::string plaintext = "some_plaintext";
181   std::string aad = "some_aad";
182   auto encrypt_result = aead->Encrypt(plaintext, aad);
183   EXPECT_TRUE(encrypt_result.ok()) << encrypt_result.status();
184   std::string ciphertext = encrypt_result.value();
185   auto decrypt_result = aead->Decrypt(ciphertext, aad);
186   EXPECT_TRUE(decrypt_result.ok()) << decrypt_result.status();
187   EXPECT_EQ(plaintext, decrypt_result.value());
188 }
189 
190 // TODO(b/174740983): Add test where an unbounded KeyClient is registered.
191 // This is not yet implemented as it would break the isolation of the tests:
192 // Once a unbounded client is registered, it can't currently be unregistered.
193 
194 }  // namespace
195 }  // namespace test
196 }  // namespace tink
197 }  // namespace crypto
198