xref: /aosp_15_r20/external/tink/testing/cc/keyset_impl_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 "keyset_impl.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 "tink/aead/aead_key_templates.h"
28 #include "tink/binary_keyset_reader.h"
29 #include "tink/binary_keyset_writer.h"
30 #include "tink/cleartext_keyset_handle.h"
31 #include "tink/config/tink_config.h"
32 #include "tink/hybrid/hybrid_key_templates.h"
33 #include "tink/util/test_matchers.h"
34 #include "proto/testing_api.grpc.pb.h"
35 
36 namespace crypto {
37 namespace tink {
38 namespace {
39 
40 using ::crypto::tink::AeadKeyTemplates;
41 using ::crypto::tink::BinaryKeysetReader;
42 using ::crypto::tink::BinaryKeysetWriter;
43 using ::crypto::tink::CleartextKeysetHandle;
44 using ::crypto::tink::HybridKeyTemplates;
45 using ::google::crypto::tink::KeyTemplate;
46 using ::testing::Eq;
47 using ::testing::IsEmpty;
48 using ::crypto::tink::test::IsOk;
49 using ::tink_testing_api::KeysetFromJsonRequest;
50 using ::tink_testing_api::KeysetFromJsonResponse;
51 using ::tink_testing_api::KeysetGenerateRequest;
52 using ::tink_testing_api::KeysetGenerateResponse;
53 using ::tink_testing_api::KeysetPublicRequest;
54 using ::tink_testing_api::KeysetPublicResponse;
55 using ::tink_testing_api::KeysetReadEncryptedRequest;
56 using ::tink_testing_api::KeysetReadEncryptedResponse;
57 using ::tink_testing_api::KeysetToJsonRequest;
58 using ::tink_testing_api::KeysetToJsonResponse;
59 using ::tink_testing_api::KeysetWriteEncryptedRequest;
60 using ::tink_testing_api::KeysetWriteEncryptedResponse;
61 
62 class KeysetImplTest : public ::testing::Test {
63  protected:
SetUpTestSuite()64   static void SetUpTestSuite() { ASSERT_TRUE(TinkConfig::Register().ok()); }
65 };
66 
TEST_F(KeysetImplTest,GenerateSuccess)67 TEST_F(KeysetImplTest, GenerateSuccess) {
68   tink_testing_api::KeysetImpl keyset;
69   const KeyTemplate& key_template = AeadKeyTemplates::Aes128Eax();
70   KeysetGenerateRequest request;
71   std::string templ;
72   EXPECT_TRUE(key_template.SerializeToString(&templ));
73   request.set_template_(templ);
74   KeysetGenerateResponse response;
75 
76   EXPECT_TRUE(keyset.Generate(nullptr, &request, &response).ok());
77   EXPECT_THAT(response.err(), IsEmpty());
78 
79   auto reader_result = BinaryKeysetReader::New(response.keyset());
80   ASSERT_TRUE(reader_result.ok());
81   auto handle_result =
82       CleartextKeysetHandle::Read(std::move(reader_result.value()));
83   EXPECT_TRUE(handle_result.ok());
84 }
85 
TEST_F(KeysetImplTest,GenerateFail)86 TEST_F(KeysetImplTest, GenerateFail) {
87   tink_testing_api::KeysetImpl keyset;
88 
89   KeysetGenerateRequest request;
90   request.set_template_("bad template");
91   KeysetGenerateResponse response;
92   EXPECT_TRUE(keyset.Generate(nullptr, &request, &response).ok());
93   EXPECT_THAT(response.err(), Not(IsEmpty()));
94 }
95 
AeadKeyset()96 util::StatusOr<std::string> AeadKeyset() {
97   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
98       KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm());
99   if (!handle.ok()) {
100     return handle.status();
101   }
102   std::stringbuf keyset;
103   util::StatusOr<std::unique_ptr<BinaryKeysetWriter>> writer =
104       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
105   if (!handle.ok()) {
106     return handle.status();
107   }
108   util::Status status = CleartextKeysetHandle::Write(writer->get(), **handle);
109   if (!status.ok()) {
110     return status;
111   }
112   return keyset.str();
113 }
114 
ValidPrivateKeyset()115 util::StatusOr<std::string> ValidPrivateKeyset() {
116   util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
117       KeysetHandle::GenerateNew(
118           HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm());
119   if (!handle.ok()) {
120     return handle.status();
121   }
122   std::stringbuf keyset;
123   util::StatusOr<std::unique_ptr<BinaryKeysetWriter>> writer =
124       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
125   if (!writer.ok()) {
126     return writer.status();
127   }
128   util::Status status = CleartextKeysetHandle::Write(writer->get(), **handle);
129   if (!status.ok()) {
130     return status;
131   }
132   return keyset.str();
133 }
134 
TEST_F(KeysetImplTest,PublicSuccess)135 TEST_F(KeysetImplTest, PublicSuccess) {
136   tink_testing_api::KeysetImpl keyset;
137 
138   util::StatusOr<std::string> private_keyset = ValidPrivateKeyset();
139   ASSERT_THAT(private_keyset.status(), IsOk());
140 
141   KeysetPublicRequest request;
142   request.set_private_keyset(*private_keyset);
143   KeysetPublicResponse response;
144 
145   EXPECT_TRUE(keyset.Public(nullptr, &request, &response).ok());
146   EXPECT_THAT(response.err(), IsEmpty());
147 
148   auto reader_result = BinaryKeysetReader::New(response.public_keyset());
149   ASSERT_TRUE(reader_result.ok());
150   auto public_handle_result =
151       CleartextKeysetHandle::Read(std::move(reader_result.value()));
152   EXPECT_TRUE(public_handle_result.ok());
153 }
154 
TEST_F(KeysetImplTest,PublicFail)155 TEST_F(KeysetImplTest, PublicFail) {
156   tink_testing_api::KeysetImpl keyset;
157 
158   KeysetPublicRequest request;
159   request.set_private_keyset("bad keyset");
160   KeysetPublicResponse response;
161   EXPECT_TRUE(keyset.Public(nullptr, &request, &response).ok());
162   EXPECT_THAT(response.err(), Not(IsEmpty()));
163 }
164 
TEST_F(KeysetImplTest,FromJsonSuccess)165 TEST_F(KeysetImplTest, FromJsonSuccess) {
166   tink_testing_api::KeysetImpl keyset;
167   std::string json_keyset = R""""(
168         {
169           "primaryKeyId": 42,
170           "key": [
171             {
172               "keyData": {
173                 "typeUrl": "type.googleapis.com/google.crypto.tink.FakeKeyType",
174                 "keyMaterialType": "SYMMETRIC",
175                 "value": "AFakeTestKeyValue1234567"
176               },
177               "outputPrefixType": "TINK",
178               "keyId": 42,
179               "status": "ENABLED"
180             }
181           ]
182         })"""";
183   KeysetFromJsonRequest from_request;
184   from_request.set_json_keyset(json_keyset);
185   KeysetFromJsonResponse from_response;
186   EXPECT_TRUE(keyset.FromJson(nullptr, &from_request, &from_response).ok());
187   EXPECT_THAT(from_response.err(), IsEmpty());
188   std::string output = from_response.keyset();
189 
190   auto reader_result = BinaryKeysetReader::New(from_response.keyset());
191   EXPECT_TRUE(reader_result.ok());
192   auto keyset_proto_result = reader_result.value()->Read();
193   EXPECT_TRUE(keyset_proto_result.ok());
194   EXPECT_THAT(keyset_proto_result.value()->primary_key_id(), Eq(42));
195 }
196 
TEST_F(KeysetImplTest,ToFromJsonSuccess)197 TEST_F(KeysetImplTest, ToFromJsonSuccess) {
198   tink_testing_api::KeysetImpl keyset;
199   util::StatusOr<std::string> private_keyset = ValidPrivateKeyset();
200   EXPECT_THAT(private_keyset.status(), IsOk());
201 
202   KeysetToJsonRequest to_request;
203   to_request.set_keyset(*private_keyset);
204   KeysetToJsonResponse to_response;
205   EXPECT_TRUE(keyset.ToJson(nullptr, &to_request, &to_response).ok());
206   EXPECT_THAT(to_response.err(), IsEmpty());
207   std::string json_keyset = to_response.json_keyset();
208 
209   KeysetFromJsonRequest from_request;
210   from_request.set_json_keyset(json_keyset);
211   KeysetFromJsonResponse from_response;
212   EXPECT_TRUE(keyset.FromJson(nullptr, &from_request, &from_response).ok());
213   EXPECT_THAT(from_response.err(), IsEmpty());
214   std::string output = from_response.keyset();
215   EXPECT_THAT(from_response.keyset(), Eq(*private_keyset));
216 }
217 
TEST_F(KeysetImplTest,ToJsonFail)218 TEST_F(KeysetImplTest, ToJsonFail) {
219   tink_testing_api::KeysetImpl keyset;
220 
221   KeysetToJsonRequest request;
222   request.set_keyset("bad keyset");
223   KeysetToJsonResponse response;
224   EXPECT_TRUE(keyset.ToJson(nullptr, &request, &response).ok());
225   EXPECT_THAT(response.err(), Not(IsEmpty()));
226 }
227 
TEST_F(KeysetImplTest,FromJsonFail)228 TEST_F(KeysetImplTest, FromJsonFail) {
229   tink_testing_api::KeysetImpl keyset;
230 
231   KeysetFromJsonRequest request;
232   request.set_json_keyset("bad json keyset");
233   KeysetFromJsonResponse response;
234   EXPECT_TRUE(keyset.FromJson(nullptr, &request, &response).ok());
235   EXPECT_THAT(response.err(), Not(IsEmpty()));
236 }
237 
TEST_F(KeysetImplTest,ReadWriteEncryptedKeysetSuccess)238 TEST_F(KeysetImplTest, ReadWriteEncryptedKeysetSuccess) {
239   tink_testing_api::KeysetImpl keyset_impl;
240 
241   util::StatusOr<std::string> master_keyset = AeadKeyset();
242   ASSERT_THAT(master_keyset.status(), IsOk());
243   util::StatusOr<std::string> keyset = AeadKeyset();
244   ASSERT_THAT(master_keyset.status(), IsOk());
245 
246   KeysetWriteEncryptedRequest write_request;
247   write_request.set_keyset(*keyset);
248   write_request.set_master_keyset(*master_keyset);
249   write_request.set_keyset_writer_type(tink_testing_api::KEYSET_WRITER_BINARY);
250   KeysetWriteEncryptedResponse write_response;
251 
252   ASSERT_TRUE(
253       keyset_impl
254           .WriteEncrypted(/*context=*/nullptr, &write_request, &write_response)
255           .ok());
256   ASSERT_THAT(write_response.err(), IsEmpty());
257 
258   KeysetReadEncryptedRequest read_request;
259   read_request.set_encrypted_keyset(write_response.encrypted_keyset());
260   read_request.set_master_keyset(*master_keyset);
261   read_request.set_keyset_reader_type(tink_testing_api::KEYSET_READER_BINARY);
262   KeysetReadEncryptedResponse read_response;
263 
264   ASSERT_TRUE(
265       keyset_impl
266           .ReadEncrypted(/*context=*/nullptr, &read_request, &read_response)
267           .ok());
268   EXPECT_THAT(read_response.err(), IsEmpty());
269   EXPECT_EQ(read_response.keyset(), *keyset);
270 }
271 
TEST_F(KeysetImplTest,ReadWriteEncryptedWithAssociatedDataKeysetSuccess)272 TEST_F(KeysetImplTest, ReadWriteEncryptedWithAssociatedDataKeysetSuccess) {
273   tink_testing_api::KeysetImpl keyset_impl;
274 
275   util::StatusOr<std::string> master_keyset = AeadKeyset();
276   ASSERT_THAT(master_keyset.status(), IsOk());
277   util::StatusOr<std::string> keyset = AeadKeyset();
278   ASSERT_THAT(keyset.status(), IsOk());
279   std::string associated_data = "associated_data";
280 
281   KeysetWriteEncryptedRequest write_request;
282   write_request.set_keyset(*keyset);
283   write_request.set_master_keyset(*master_keyset);
284   write_request.mutable_associated_data()->set_value(associated_data);
285   write_request.set_keyset_writer_type(tink_testing_api::KEYSET_WRITER_BINARY);
286   KeysetWriteEncryptedResponse write_response;
287 
288   ASSERT_TRUE(
289       keyset_impl
290           .WriteEncrypted(/*context=*/nullptr, &write_request, &write_response)
291           .ok());
292   ASSERT_THAT(write_response.err(), IsEmpty());
293 
294   KeysetReadEncryptedRequest read_request;
295   read_request.set_encrypted_keyset(write_response.encrypted_keyset());
296   read_request.set_master_keyset(*master_keyset);
297   read_request.mutable_associated_data()->set_value(associated_data);
298   read_request.set_keyset_reader_type(tink_testing_api::KEYSET_READER_BINARY);
299   KeysetReadEncryptedResponse read_response;
300 
301   ASSERT_TRUE(
302       keyset_impl
303           .ReadEncrypted(/*context=*/nullptr, &read_request, &read_response)
304           .ok());
305   EXPECT_THAT(read_response.err(), IsEmpty());
306   EXPECT_EQ(read_response.keyset(), *keyset);
307 }
308 
TEST_F(KeysetImplTest,WriteEncryptedKeysetFail)309 TEST_F(KeysetImplTest, WriteEncryptedKeysetFail) {
310   tink_testing_api::KeysetImpl keyset_impl;
311 
312   util::StatusOr<std::string> master_keyset = AeadKeyset();
313   ASSERT_THAT(master_keyset.status(), IsOk());
314 
315   KeysetWriteEncryptedRequest write_request;
316   write_request.set_keyset("invalid");
317   write_request.set_master_keyset(*master_keyset);
318   write_request.set_keyset_writer_type(tink_testing_api::KEYSET_WRITER_BINARY);
319   KeysetWriteEncryptedResponse write_response;
320 
321   ASSERT_TRUE(
322       keyset_impl
323           .WriteEncrypted(/*context=*/nullptr, &write_request, &write_response)
324           .ok());
325   EXPECT_THAT(write_response.err(), Not(IsEmpty()));
326 }
327 
TEST_F(KeysetImplTest,ReadEncryptedKeysetFail)328 TEST_F(KeysetImplTest, ReadEncryptedKeysetFail) {
329   tink_testing_api::KeysetImpl keyset_impl;
330 
331   util::StatusOr<std::string> master_keyset = AeadKeyset();
332   ASSERT_THAT(master_keyset.status(), IsOk());
333 
334   KeysetReadEncryptedRequest read_request;
335   read_request.set_encrypted_keyset("invalid");
336   read_request.set_master_keyset(*master_keyset);
337   read_request.set_keyset_reader_type(tink_testing_api::KEYSET_READER_BINARY);
338   KeysetReadEncryptedResponse read_response;
339 
340   ASSERT_TRUE(
341       keyset_impl
342           .ReadEncrypted(/*context=*/nullptr, &read_request, &read_response)
343           .ok());
344   EXPECT_THAT(read_response.err(), Not(IsEmpty()));
345 }
346 
347 }  // namespace
348 }  // namespace tink
349 }  // namespace crypto
350