1*e7b1675dSTing-Kang Chang // Copyright 2020 Google LLC
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ///////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang #include "signature_impl.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <memory>
20*e7b1675dSTing-Kang Chang #include <ostream>
21*e7b1675dSTing-Kang Chang #include <sstream>
22*e7b1675dSTing-Kang Chang #include <string>
23*e7b1675dSTing-Kang Chang
24*e7b1675dSTing-Kang Chang #include "gmock/gmock.h"
25*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
26*e7b1675dSTing-Kang Chang #include "tink/binary_keyset_writer.h"
27*e7b1675dSTing-Kang Chang #include "tink/cleartext_keyset_handle.h"
28*e7b1675dSTing-Kang Chang #include "tink/signature/signature_config.h"
29*e7b1675dSTing-Kang Chang #include "tink/signature/signature_key_templates.h"
30*e7b1675dSTing-Kang Chang
31*e7b1675dSTing-Kang Chang namespace crypto {
32*e7b1675dSTing-Kang Chang namespace tink {
33*e7b1675dSTing-Kang Chang namespace {
34*e7b1675dSTing-Kang Chang
35*e7b1675dSTing-Kang Chang using ::crypto::tink::BinaryKeysetWriter;
36*e7b1675dSTing-Kang Chang using ::crypto::tink::CleartextKeysetHandle;
37*e7b1675dSTing-Kang Chang using ::crypto::tink::SignatureKeyTemplates;
38*e7b1675dSTing-Kang Chang
39*e7b1675dSTing-Kang Chang using ::testing::IsEmpty;
40*e7b1675dSTing-Kang Chang using ::tink_testing_api::CreationRequest;
41*e7b1675dSTing-Kang Chang using ::tink_testing_api::CreationResponse;
42*e7b1675dSTing-Kang Chang using ::tink_testing_api::SignatureSignRequest;
43*e7b1675dSTing-Kang Chang using ::tink_testing_api::SignatureSignResponse;
44*e7b1675dSTing-Kang Chang using ::tink_testing_api::SignatureVerifyRequest;
45*e7b1675dSTing-Kang Chang using ::tink_testing_api::SignatureVerifyResponse;
46*e7b1675dSTing-Kang Chang
47*e7b1675dSTing-Kang Chang using crypto::tink::KeysetHandle;
48*e7b1675dSTing-Kang Chang using google::crypto::tink::KeyTemplate;
49*e7b1675dSTing-Kang Chang
KeysetBytes(const KeysetHandle & keyset_handle)50*e7b1675dSTing-Kang Chang std::string KeysetBytes(const KeysetHandle& keyset_handle) {
51*e7b1675dSTing-Kang Chang std::stringbuf keyset;
52*e7b1675dSTing-Kang Chang auto writer_result =
53*e7b1675dSTing-Kang Chang BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
54*e7b1675dSTing-Kang Chang EXPECT_TRUE(writer_result.ok());
55*e7b1675dSTing-Kang Chang auto status =
56*e7b1675dSTing-Kang Chang CleartextKeysetHandle::Write(writer_result.value().get(), keyset_handle);
57*e7b1675dSTing-Kang Chang EXPECT_TRUE(status.ok());
58*e7b1675dSTing-Kang Chang return keyset.str();
59*e7b1675dSTing-Kang Chang }
60*e7b1675dSTing-Kang Chang
61*e7b1675dSTing-Kang Chang class SignatureImplTest : public ::testing::Test {
62*e7b1675dSTing-Kang Chang protected:
SetUpTestSuite()63*e7b1675dSTing-Kang Chang static void SetUpTestSuite() {
64*e7b1675dSTing-Kang Chang ASSERT_TRUE(SignatureConfig::Register().ok());
65*e7b1675dSTing-Kang Chang }
66*e7b1675dSTing-Kang Chang };
67*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,CreatePublicKeySignSuccess)68*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, CreatePublicKeySignSuccess) {
69*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
70*e7b1675dSTing-Kang Chang const KeyTemplate& key_template = SignatureKeyTemplates::EcdsaP256();
71*e7b1675dSTing-Kang Chang ::crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
72*e7b1675dSTing-Kang Chang private_keyset_handle = KeysetHandle::GenerateNew(key_template);
73*e7b1675dSTing-Kang Chang ASSERT_TRUE(private_keyset_handle.status().ok())
74*e7b1675dSTing-Kang Chang << private_keyset_handle.status();
75*e7b1675dSTing-Kang Chang
76*e7b1675dSTing-Kang Chang CreationRequest request;
77*e7b1675dSTing-Kang Chang request.mutable_annotated_keyset()->set_serialized_keyset(
78*e7b1675dSTing-Kang Chang KeysetBytes(**private_keyset_handle));
79*e7b1675dSTing-Kang Chang CreationResponse response;
80*e7b1675dSTing-Kang Chang
81*e7b1675dSTing-Kang Chang EXPECT_TRUE(signature.CreatePublicKeySign(nullptr, &request, &response).ok());
82*e7b1675dSTing-Kang Chang EXPECT_THAT(response.err(), IsEmpty());
83*e7b1675dSTing-Kang Chang }
84*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,CreatePublicKeySignFailure)85*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, CreatePublicKeySignFailure) {
86*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
87*e7b1675dSTing-Kang Chang
88*e7b1675dSTing-Kang Chang CreationRequest request;
89*e7b1675dSTing-Kang Chang request.mutable_annotated_keyset()->set_serialized_keyset("\x80");
90*e7b1675dSTing-Kang Chang CreationResponse response;
91*e7b1675dSTing-Kang Chang
92*e7b1675dSTing-Kang Chang EXPECT_TRUE(signature.CreatePublicKeySign(nullptr, &request, &response).ok());
93*e7b1675dSTing-Kang Chang EXPECT_THAT(response.err(), Not(IsEmpty()));
94*e7b1675dSTing-Kang Chang }
95*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,CreatePublicKeyVerifySuccess)96*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, CreatePublicKeyVerifySuccess) {
97*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
98*e7b1675dSTing-Kang Chang const KeyTemplate& key_template = SignatureKeyTemplates::EcdsaP256();
99*e7b1675dSTing-Kang Chang ::crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
100*e7b1675dSTing-Kang Chang private_keyset_handle = KeysetHandle::GenerateNew(key_template);
101*e7b1675dSTing-Kang Chang ASSERT_TRUE(private_keyset_handle.status().ok())
102*e7b1675dSTing-Kang Chang << private_keyset_handle.status();
103*e7b1675dSTing-Kang Chang ::crypto::tink::util::StatusOr<std::unique_ptr<KeysetHandle>>
104*e7b1675dSTing-Kang Chang public_keyset_handle = (*private_keyset_handle)->GetPublicKeysetHandle();
105*e7b1675dSTing-Kang Chang ASSERT_TRUE(public_keyset_handle.status().ok())
106*e7b1675dSTing-Kang Chang << public_keyset_handle.status();
107*e7b1675dSTing-Kang Chang
108*e7b1675dSTing-Kang Chang CreationRequest request;
109*e7b1675dSTing-Kang Chang request.mutable_annotated_keyset()->set_serialized_keyset(
110*e7b1675dSTing-Kang Chang KeysetBytes(**public_keyset_handle));
111*e7b1675dSTing-Kang Chang CreationResponse response;
112*e7b1675dSTing-Kang Chang
113*e7b1675dSTing-Kang Chang EXPECT_TRUE(
114*e7b1675dSTing-Kang Chang signature.CreatePublicKeyVerify(nullptr, &request, &response).ok());
115*e7b1675dSTing-Kang Chang EXPECT_THAT(response.err(), IsEmpty());
116*e7b1675dSTing-Kang Chang }
117*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,CreatePublicKeyVerifyFailure)118*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, CreatePublicKeyVerifyFailure) {
119*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
120*e7b1675dSTing-Kang Chang
121*e7b1675dSTing-Kang Chang CreationRequest request;
122*e7b1675dSTing-Kang Chang request.mutable_annotated_keyset()->set_serialized_keyset("\x80");
123*e7b1675dSTing-Kang Chang CreationResponse response;
124*e7b1675dSTing-Kang Chang
125*e7b1675dSTing-Kang Chang EXPECT_TRUE(
126*e7b1675dSTing-Kang Chang signature.CreatePublicKeyVerify(nullptr, &request, &response).ok());
127*e7b1675dSTing-Kang Chang EXPECT_THAT(response.err(), Not(IsEmpty()));
128*e7b1675dSTing-Kang Chang }
129*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,SignVerifySuccess)130*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, SignVerifySuccess) {
131*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
132*e7b1675dSTing-Kang Chang const KeyTemplate& key_template = SignatureKeyTemplates::EcdsaP256();
133*e7b1675dSTing-Kang Chang auto private_handle_result = KeysetHandle::GenerateNew(key_template);
134*e7b1675dSTing-Kang Chang EXPECT_TRUE(private_handle_result.ok());
135*e7b1675dSTing-Kang Chang auto public_handle_result =
136*e7b1675dSTing-Kang Chang private_handle_result.value()->GetPublicKeysetHandle();
137*e7b1675dSTing-Kang Chang EXPECT_TRUE(public_handle_result.ok());
138*e7b1675dSTing-Kang Chang
139*e7b1675dSTing-Kang Chang SignatureSignRequest sign_request;
140*e7b1675dSTing-Kang Chang sign_request.mutable_private_annotated_keyset()->set_serialized_keyset(
141*e7b1675dSTing-Kang Chang KeysetBytes(*private_handle_result.value()));
142*e7b1675dSTing-Kang Chang sign_request.set_data("some data");
143*e7b1675dSTing-Kang Chang SignatureSignResponse sign_response;
144*e7b1675dSTing-Kang Chang
145*e7b1675dSTing-Kang Chang EXPECT_TRUE(signature.Sign(nullptr, &sign_request, &sign_response).ok());
146*e7b1675dSTing-Kang Chang EXPECT_THAT(sign_response.err(), IsEmpty());
147*e7b1675dSTing-Kang Chang
148*e7b1675dSTing-Kang Chang SignatureVerifyRequest verify_request;
149*e7b1675dSTing-Kang Chang verify_request.mutable_public_annotated_keyset()->set_serialized_keyset(
150*e7b1675dSTing-Kang Chang KeysetBytes(*public_handle_result.value()));
151*e7b1675dSTing-Kang Chang verify_request.set_signature(sign_response.signature());
152*e7b1675dSTing-Kang Chang verify_request.set_data("some data");
153*e7b1675dSTing-Kang Chang SignatureVerifyResponse verify_response;
154*e7b1675dSTing-Kang Chang
155*e7b1675dSTing-Kang Chang EXPECT_TRUE(
156*e7b1675dSTing-Kang Chang signature.Verify(nullptr, &verify_request, &verify_response).ok());
157*e7b1675dSTing-Kang Chang EXPECT_THAT(verify_response.err(), IsEmpty());
158*e7b1675dSTing-Kang Chang }
159*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,SignBadKeysetFail)160*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, SignBadKeysetFail) {
161*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
162*e7b1675dSTing-Kang Chang SignatureSignRequest sign_request;
163*e7b1675dSTing-Kang Chang sign_request.mutable_private_annotated_keyset()->set_serialized_keyset(
164*e7b1675dSTing-Kang Chang "bad private keyset");
165*e7b1675dSTing-Kang Chang sign_request.set_data("some data");
166*e7b1675dSTing-Kang Chang SignatureSignResponse sign_response;
167*e7b1675dSTing-Kang Chang
168*e7b1675dSTing-Kang Chang EXPECT_TRUE(signature.Sign(nullptr, &sign_request, &sign_response).ok());
169*e7b1675dSTing-Kang Chang EXPECT_THAT(sign_response.err(), Not(IsEmpty()));
170*e7b1675dSTing-Kang Chang }
171*e7b1675dSTing-Kang Chang
TEST_F(SignatureImplTest,VerifyBadCiphertextFail)172*e7b1675dSTing-Kang Chang TEST_F(SignatureImplTest, VerifyBadCiphertextFail) {
173*e7b1675dSTing-Kang Chang tink_testing_api::SignatureImpl signature;
174*e7b1675dSTing-Kang Chang const KeyTemplate& key_template = SignatureKeyTemplates::EcdsaP256();
175*e7b1675dSTing-Kang Chang auto private_handle_result = KeysetHandle::GenerateNew(key_template);
176*e7b1675dSTing-Kang Chang EXPECT_TRUE(private_handle_result.ok());
177*e7b1675dSTing-Kang Chang auto public_handle_result =
178*e7b1675dSTing-Kang Chang private_handle_result.value()->GetPublicKeysetHandle();
179*e7b1675dSTing-Kang Chang EXPECT_TRUE(public_handle_result.ok());
180*e7b1675dSTing-Kang Chang
181*e7b1675dSTing-Kang Chang SignatureVerifyRequest verify_request;
182*e7b1675dSTing-Kang Chang verify_request.mutable_public_annotated_keyset()->set_serialized_keyset(
183*e7b1675dSTing-Kang Chang KeysetBytes(*public_handle_result.value()));
184*e7b1675dSTing-Kang Chang verify_request.set_signature("bad signature");
185*e7b1675dSTing-Kang Chang verify_request.set_data("some data");
186*e7b1675dSTing-Kang Chang SignatureVerifyResponse verify_response;
187*e7b1675dSTing-Kang Chang
188*e7b1675dSTing-Kang Chang EXPECT_TRUE(
189*e7b1675dSTing-Kang Chang signature.Verify(nullptr, &verify_request, &verify_response).ok());
190*e7b1675dSTing-Kang Chang EXPECT_THAT(verify_response.err(), Not(IsEmpty()));
191*e7b1675dSTing-Kang Chang }
192*e7b1675dSTing-Kang Chang
193*e7b1675dSTing-Kang Chang } // namespace
194*e7b1675dSTing-Kang Chang } // namespace tink
195*e7b1675dSTing-Kang Chang } // namespace crypto
196