1 // Copyright 2017 Google Inc.
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/signature/ecdsa_verify_key_manager.h"
18
19 #include <string>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "absl/status/status.h"
24 #include "tink/internal/ec_util.h"
25 #include "tink/public_key_sign.h"
26 #include "tink/public_key_verify.h"
27 #include "tink/signature/ecdsa_sign_key_manager.h"
28 #include "tink/subtle/ecdsa_sign_boringssl.h"
29 #include "tink/util/enums.h"
30 #include "tink/util/secret_data.h"
31 #include "tink/util/status.h"
32 #include "tink/util/statusor.h"
33 #include "tink/util/test_matchers.h"
34 #include "tink/util/test_util.h"
35 #include "proto/ecdsa.pb.h"
36
37 namespace crypto {
38 namespace tink {
39
40 using ::crypto::tink::test::IsOk;
41 using ::crypto::tink::test::StatusIs;
42 using ::crypto::tink::util::Enums;
43 using ::google::crypto::tink::EcdsaKeyFormat;
44 using ::google::crypto::tink::EcdsaParams;
45 using ::google::crypto::tink::EcdsaPrivateKey;
46 using ::google::crypto::tink::EcdsaPublicKey;
47 using ::google::crypto::tink::EcdsaSignatureEncoding;
48 using ::google::crypto::tink::EllipticCurveType;
49 using ::google::crypto::tink::HashType;
50 using ::google::crypto::tink::KeyData;
51 using ::testing::Eq;
52 using ::testing::Not;
53
54 namespace {
55
TEST(EcdsaVerifyKeyManagerTest,Basics)56 TEST(EcdsaVerifyKeyManagerTest, Basics) {
57 EXPECT_THAT(EcdsaVerifyKeyManager().get_version(), Eq(0));
58 EXPECT_THAT(EcdsaVerifyKeyManager().key_material_type(),
59 Eq(KeyData::ASYMMETRIC_PUBLIC));
60 EXPECT_THAT(EcdsaVerifyKeyManager().get_key_type(),
61 Eq("type.googleapis.com/google.crypto.tink.EcdsaPublicKey"));
62 }
63
TEST(EcdsaVerifyKeyManagerTest,ValidateEmptyKey)64 TEST(EcdsaVerifyKeyManagerTest, ValidateEmptyKey) {
65 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(EcdsaPublicKey()),
66 Not(IsOk()));
67 }
68
CreateValidPrivateKey()69 EcdsaPrivateKey CreateValidPrivateKey() {
70 EcdsaKeyFormat key_format;
71 EcdsaParams* params = key_format.mutable_params();
72 params->set_hash_type(HashType::SHA256);
73 params->set_curve(EllipticCurveType::NIST_P256);
74 params->set_encoding(EcdsaSignatureEncoding::DER);
75 return EcdsaSignKeyManager().CreateKey(key_format).value();
76 }
77
CreateValidPublicKey()78 EcdsaPublicKey CreateValidPublicKey() {
79 return EcdsaSignKeyManager().GetPublicKey(CreateValidPrivateKey()).value();
80 }
81
82 // Checks that a public key generaed by the SignKeyManager is considered valid.
TEST(EcdsaVerifyKeyManagerTest,PublicKeyValid)83 TEST(EcdsaVerifyKeyManagerTest, PublicKeyValid) {
84 EcdsaPublicKey key = CreateValidPublicKey();
85 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key), IsOk());
86 }
87
TEST(EcdsaSignKeyManagerTest,ValidateKeyBadHashP256)88 TEST(EcdsaSignKeyManagerTest, ValidateKeyBadHashP256) {
89 EcdsaPublicKey key = CreateValidPublicKey();
90 EcdsaParams* params = key.mutable_params();
91 params->set_curve(EllipticCurveType::NIST_P256);
92 params->set_hash_type(HashType::SHA512);
93 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key), Not(IsOk()));
94 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key),
95 StatusIs(absl::StatusCode::kInvalidArgument));
96 }
97
TEST(EcdsaSignKeyManagerTest,ValidateKeyBadHashP384)98 TEST(EcdsaSignKeyManagerTest, ValidateKeyBadHashP384) {
99 EcdsaPublicKey key = CreateValidPublicKey();
100 EcdsaParams* params = key.mutable_params();
101 params->set_curve(EllipticCurveType::NIST_P384);
102 params->set_hash_type(HashType::SHA256);
103 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key), Not(IsOk()));
104 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key),
105 StatusIs(absl::StatusCode::kInvalidArgument));
106 }
107
TEST(EcdsaSignKeyManagerTest,ValidateKeyBadHashP521)108 TEST(EcdsaSignKeyManagerTest, ValidateKeyBadHashP521) {
109 EcdsaPublicKey key = CreateValidPublicKey();
110 EcdsaParams* params = key.mutable_params();
111 params->set_curve(EllipticCurveType::NIST_P521);
112 params->set_hash_type(HashType::SHA256);
113 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key), Not(IsOk()));
114 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateKey(key),
115 StatusIs(absl::StatusCode::kInvalidArgument));
116 }
117
TEST(EcdsaSignKeyManagerTest,ValidateParams)118 TEST(EcdsaSignKeyManagerTest, ValidateParams) {
119 EcdsaParams params;
120 params.set_hash_type(HashType::SHA256);
121 params.set_curve(EllipticCurveType::NIST_P256);
122 params.set_encoding(EcdsaSignatureEncoding::DER);
123 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params), IsOk());
124 }
125
TEST(EcdsaSignKeyManagerTest,ValidateParamsHashP384)126 TEST(EcdsaSignKeyManagerTest, ValidateParamsHashP384) {
127 EcdsaParams params;
128 params.set_hash_type(HashType::SHA384);
129 params.set_curve(EllipticCurveType::NIST_P384);
130 params.set_encoding(EcdsaSignatureEncoding::DER);
131 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params), IsOk());
132 }
133
TEST(EcdsaSignKeyManagerTest,ValidateParamsBadHashP256)134 TEST(EcdsaSignKeyManagerTest, ValidateParamsBadHashP256) {
135 EcdsaParams params;
136 params.set_hash_type(HashType::SHA512);
137 params.set_curve(EllipticCurveType::NIST_P256);
138 params.set_encoding(EcdsaSignatureEncoding::DER);
139 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params), Not(IsOk()));
140 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params),
141 StatusIs(absl::StatusCode::kInvalidArgument));
142 }
143
TEST(EcdsaSignKeyManagerTest,ValidateParamsBadHashP384)144 TEST(EcdsaSignKeyManagerTest, ValidateParamsBadHashP384) {
145 EcdsaParams params;
146 params.set_curve(EllipticCurveType::NIST_P384);
147 params.set_hash_type(HashType::SHA256);
148 params.set_encoding(EcdsaSignatureEncoding::DER);
149 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params), Not(IsOk()));
150 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params),
151 StatusIs(absl::StatusCode::kInvalidArgument));
152 }
153
TEST(EcdsaSignKeyManagerTest,ValidateParamsBadHashP521)154 TEST(EcdsaSignKeyManagerTest, ValidateParamsBadHashP521) {
155 EcdsaParams params;
156 params.set_curve(EllipticCurveType::NIST_P521);
157 params.set_hash_type(HashType::SHA256);
158 params.set_encoding(EcdsaSignatureEncoding::DER);
159 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params), Not(IsOk()));
160 EXPECT_THAT(EcdsaVerifyKeyManager().ValidateParams(params),
161 StatusIs(absl::StatusCode::kInvalidArgument));
162 }
163
TEST(EcdsaSignKeyManagerTest,Create)164 TEST(EcdsaSignKeyManagerTest, Create) {
165 EcdsaPrivateKey private_key = CreateValidPrivateKey();
166 EcdsaPublicKey public_key =
167 EcdsaSignKeyManager().GetPublicKey(private_key).value();
168
169 internal::EcKey ec_key;
170 ec_key.curve = Enums::ProtoToSubtle(public_key.params().curve());
171 ec_key.pub_x = public_key.x();
172 ec_key.pub_y = public_key.y();
173 ec_key.priv = util::SecretDataFromStringView(private_key.key_value());
174
175 auto direct_signer_or = subtle::EcdsaSignBoringSsl::New(
176 ec_key, Enums::ProtoToSubtle(public_key.params().hash_type()),
177 Enums::ProtoToSubtle(public_key.params().encoding()));
178 ASSERT_THAT(direct_signer_or, IsOk());
179
180 auto verifier_or =
181 EcdsaVerifyKeyManager().GetPrimitive<PublicKeyVerify>(public_key);
182 ASSERT_THAT(verifier_or, IsOk());
183
184 std::string message = "Some message";
185 EXPECT_THAT(verifier_or.value()->Verify(
186 direct_signer_or.value()->Sign(message).value(), message),
187 IsOk());
188 }
189
TEST(EcdsaSignKeyManagerTest,CreateDifferentPrivateKey)190 TEST(EcdsaSignKeyManagerTest, CreateDifferentPrivateKey) {
191 EcdsaPrivateKey private_key = CreateValidPrivateKey();
192 // Note: we create a new key in the next line.
193 EcdsaPublicKey public_key =
194 EcdsaSignKeyManager().GetPublicKey(CreateValidPrivateKey()).value();
195
196 internal::EcKey ec_key;
197 ec_key.curve = Enums::ProtoToSubtle(public_key.params().curve());
198 ec_key.pub_x = public_key.x();
199 ec_key.pub_y = public_key.y();
200 ec_key.priv = util::SecretDataFromStringView(private_key.key_value());
201
202 auto direct_signer_or = subtle::EcdsaSignBoringSsl::New(
203 ec_key, Enums::ProtoToSubtle(public_key.params().hash_type()),
204 Enums::ProtoToSubtle(public_key.params().encoding()));
205 ASSERT_THAT(direct_signer_or, IsOk());
206
207 auto verifier_or =
208 EcdsaVerifyKeyManager().GetPrimitive<PublicKeyVerify>(public_key);
209 ASSERT_THAT(verifier_or, IsOk());
210
211 std::string message = "Some message";
212 EXPECT_THAT(verifier_or.value()->Verify(
213 direct_signer_or.value()->Sign(message).value(), message),
214 Not(IsOk()));
215 }
216
217 } // namespace
218 } // namespace tink
219 } // namespace crypto
220