xref: /aosp_15_r20/external/tink/testing/cc/hybrid_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 "hybrid_impl.h"
18 
19 #include <memory>
20 #include <ostream>
21 #include <sstream>
22 #include <string>
23 
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "tink/binary_keyset_writer.h"
27 #include "tink/cleartext_keyset_handle.h"
28 #include "tink/hybrid/hybrid_config.h"
29 #include "tink/hybrid/hybrid_key_templates.h"
30 #include "proto/testing_api.grpc.pb.h"
31 
32 namespace crypto {
33 namespace tink {
34 namespace {
35 
36 using ::crypto::tink::BinaryKeysetWriter;
37 using ::crypto::tink::CleartextKeysetHandle;
38 using ::crypto::tink::HybridKeyTemplates;
39 
40 using ::testing::Eq;
41 using ::testing::IsEmpty;
42 using ::tink_testing_api::CreationRequest;
43 using ::tink_testing_api::CreationResponse;
44 using ::tink_testing_api::HybridDecryptRequest;
45 using ::tink_testing_api::HybridDecryptResponse;
46 using ::tink_testing_api::HybridEncryptRequest;
47 using ::tink_testing_api::HybridEncryptResponse;
48 
49 using crypto::tink::KeysetHandle;
50 using google::crypto::tink::KeyTemplate;
51 
KeysetBytes(const KeysetHandle & keyset_handle)52 std::string KeysetBytes(const KeysetHandle& keyset_handle) {
53   std::stringbuf keyset;
54   auto writer_result =
55       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
56   EXPECT_TRUE(writer_result.ok());
57   auto status =
58       CleartextKeysetHandle::Write(writer_result.value().get(), keyset_handle);
59   EXPECT_TRUE(status.ok());
60   return keyset.str();
61 }
62 
63 class HybridImplTest : public ::testing::Test {
64  protected:
SetUpTestSuite()65   static void SetUpTestSuite() { ASSERT_TRUE(HybridConfig::Register().ok()); }
66 };
67 
TEST_F(HybridImplTest,CreateHybridDecryptSuccess)68 TEST_F(HybridImplTest, CreateHybridDecryptSuccess) {
69   tink_testing_api::HybridImpl hybrid;
70   const KeyTemplate& key_template =
71       HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm();
72   ::crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
73       private_keyset_handle = KeysetHandle::GenerateNew(key_template);
74   ASSERT_TRUE(private_keyset_handle.status().ok())
75       << private_keyset_handle.status();
76 
77   CreationRequest request;
78   request.mutable_annotated_keyset()->set_serialized_keyset(
79       KeysetBytes(**private_keyset_handle));
80   CreationResponse response;
81 
82   EXPECT_TRUE(hybrid.CreateHybridDecrypt(nullptr, &request, &response).ok());
83   EXPECT_THAT(response.err(), IsEmpty());
84 }
85 
TEST_F(HybridImplTest,CreateHybridDecryptFailure)86 TEST_F(HybridImplTest, CreateHybridDecryptFailure) {
87   tink_testing_api::HybridImpl hybrid;
88 
89   CreationRequest request;
90   request.mutable_annotated_keyset()->set_serialized_keyset("\x80");
91   CreationResponse response;
92 
93   EXPECT_TRUE(hybrid.CreateHybridDecrypt(nullptr, &request, &response).ok());
94   EXPECT_THAT(response.err(), Not(IsEmpty()));
95 }
96 
TEST_F(HybridImplTest,CreateHybridEncryptSuccess)97 TEST_F(HybridImplTest, CreateHybridEncryptSuccess) {
98   tink_testing_api::HybridImpl hybrid;
99   const KeyTemplate& key_template =
100       HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm();
101   ::crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
102       private_keyset_handle = KeysetHandle::GenerateNew(key_template);
103   ASSERT_TRUE(private_keyset_handle.status().ok())
104       << private_keyset_handle.status();
105   ::crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
106       public_keyset_handle = (*private_keyset_handle)->GetPublicKeysetHandle();
107   ASSERT_TRUE(public_keyset_handle.status().ok())
108       << public_keyset_handle.status();
109 
110   CreationRequest request;
111   request.mutable_annotated_keyset()->set_serialized_keyset(
112       KeysetBytes(**public_keyset_handle));
113   CreationResponse response;
114 
115   EXPECT_TRUE(hybrid.CreateHybridEncrypt(nullptr, &request, &response).ok());
116   EXPECT_THAT(response.err(), IsEmpty());
117 }
118 
TEST_F(HybridImplTest,CreateHybridEncryptFailure)119 TEST_F(HybridImplTest, CreateHybridEncryptFailure) {
120   tink_testing_api::HybridImpl hybrid;
121 
122   CreationRequest request;
123   request.mutable_annotated_keyset()->set_serialized_keyset("\x80");
124   CreationResponse response;
125 
126   EXPECT_TRUE(hybrid.CreateHybridEncrypt(nullptr, &request, &response).ok());
127   EXPECT_THAT(response.err(), Not(IsEmpty()));
128 }
129 
TEST_F(HybridImplTest,EncryptDecryptSuccess)130 TEST_F(HybridImplTest, EncryptDecryptSuccess) {
131   tink_testing_api::HybridImpl hybrid;
132   const KeyTemplate& key_template =
133       HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm();
134   auto private_handle_result = KeysetHandle::GenerateNew(key_template);
135   EXPECT_TRUE(private_handle_result.ok());
136   auto public_handle_result =
137       private_handle_result.value()->GetPublicKeysetHandle();
138   EXPECT_TRUE(public_handle_result.ok());
139 
140   HybridEncryptRequest enc_request;
141   enc_request.mutable_public_annotated_keyset()->set_serialized_keyset(
142       KeysetBytes(*public_handle_result.value()));
143   enc_request.set_plaintext("Plain text");
144   enc_request.set_context_info("context");
145   HybridEncryptResponse enc_response;
146 
147   EXPECT_TRUE(hybrid.Encrypt(nullptr, &enc_request, &enc_response).ok());
148   EXPECT_THAT(enc_response.err(), IsEmpty());
149 
150   HybridDecryptRequest dec_request;
151   dec_request.mutable_private_annotated_keyset()->set_serialized_keyset(
152       KeysetBytes(*private_handle_result.value()));
153   dec_request.set_ciphertext(enc_response.ciphertext());
154   dec_request.set_context_info("context");
155   HybridDecryptResponse dec_response;
156 
157   EXPECT_TRUE(hybrid.Decrypt(nullptr, &dec_request, &dec_response).ok());
158   EXPECT_THAT(dec_response.err(), IsEmpty());
159   EXPECT_THAT(dec_response.plaintext(), Eq("Plain text"));
160 }
161 
TEST_F(HybridImplTest,EncryptBadKeysetFail)162 TEST_F(HybridImplTest, EncryptBadKeysetFail) {
163   tink_testing_api::HybridImpl hybrid;
164   HybridEncryptRequest enc_request;
165   enc_request.mutable_public_annotated_keyset()->set_serialized_keyset(
166       "bad keyset");
167   enc_request.set_plaintext("Plain text");
168   enc_request.set_context_info("context");
169   HybridEncryptResponse enc_response;
170 
171   EXPECT_TRUE(hybrid.Encrypt(nullptr, &enc_request, &enc_response).ok());
172   EXPECT_THAT(enc_response.err(), Not(IsEmpty()));
173 }
174 
TEST_F(HybridImplTest,DecryptBadCiphertextFail)175 TEST_F(HybridImplTest, DecryptBadCiphertextFail) {
176   tink_testing_api::HybridImpl hybrid;
177   const KeyTemplate& key_template =
178       HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm();
179   auto private_handle_result = KeysetHandle::GenerateNew(key_template);
180   EXPECT_TRUE(private_handle_result.ok());
181 
182   HybridDecryptRequest dec_request;
183   dec_request.mutable_private_annotated_keyset()->set_serialized_keyset(
184       KeysetBytes(*private_handle_result.value()));
185   dec_request.set_ciphertext("bad ciphertext");
186   dec_request.set_context_info("context");
187   HybridDecryptResponse dec_response;
188 
189   EXPECT_TRUE(hybrid.Decrypt(nullptr, &dec_request, &dec_response).ok());
190   EXPECT_THAT(dec_response.err(), Not(IsEmpty()));
191 }
192 
193 }  // namespace
194 }  // namespace tink
195 }  // namespace crypto
196