1 // Copyright 2021 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/jwt/internal/raw_jwt_ecdsa_sign_key_manager.h"
18
19 #include <memory>
20 #include <string>
21
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "tink/internal/ec_util.h"
26 #include "tink/jwt/internal/raw_jwt_ecdsa_verify_key_manager.h"
27 #include "tink/public_key_sign.h"
28 #include "tink/public_key_verify.h"
29 #include "tink/subtle/ecdsa_verify_boringssl.h"
30 #include "tink/util/enums.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 namespace jwt_internal {
40
41 using ::crypto::tink::test::IsOk;
42 using ::crypto::tink::test::StatusIs;
43 using ::crypto::tink::util::Enums;
44 using ::crypto::tink::util::StatusOr;
45 using ::google::crypto::tink::EllipticCurveType;
46 using ::google::crypto::tink::HashType;
47 using ::google::crypto::tink::JwtEcdsaAlgorithm;
48 using ::google::crypto::tink::JwtEcdsaKeyFormat;
49 using ::google::crypto::tink::JwtEcdsaPrivateKey;
50 using ::google::crypto::tink::JwtEcdsaPublicKey;
51 using ::google::crypto::tink::KeyData;
52 using ::testing::Eq;
53 using ::testing::Gt;
54 using ::testing::Not;
55 using ::testing::SizeIs;
56
57 namespace {
58
TEST(RawJwtEcdsaSignKeyManagerTest,Basic)59 TEST(RawJwtEcdsaSignKeyManagerTest, Basic) {
60 EXPECT_THAT(RawJwtEcdsaSignKeyManager().get_version(), Eq(0));
61 EXPECT_THAT(RawJwtEcdsaSignKeyManager().key_material_type(),
62 Eq(KeyData::ASYMMETRIC_PRIVATE));
63 EXPECT_THAT(RawJwtEcdsaSignKeyManager().get_key_type(),
64 Eq("type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey"));
65 }
66
TEST(RawJwtEcdsaSignKeyManagerTest,ValidateEmptyKeyFormat)67 TEST(RawJwtEcdsaSignKeyManagerTest, ValidateEmptyKeyFormat) {
68 EXPECT_THAT(
69 RawJwtEcdsaSignKeyManager().ValidateKeyFormat(JwtEcdsaKeyFormat()),
70 Not(IsOk()));
71 }
72
CreateValidEs256KeyFormat()73 JwtEcdsaKeyFormat CreateValidEs256KeyFormat() {
74 JwtEcdsaKeyFormat key_format;
75 key_format.set_algorithm(JwtEcdsaAlgorithm::ES256);
76 return key_format;
77 }
78
TEST(RawJwtEcdsaSignKeyManagerTest,ValidateKeyFormat)79 TEST(RawJwtEcdsaSignKeyManagerTest, ValidateKeyFormat) {
80 JwtEcdsaKeyFormat format = CreateValidEs256KeyFormat();
81 EXPECT_THAT(RawJwtEcdsaSignKeyManager().ValidateKeyFormat(format), IsOk());
82 }
83
TEST(RawJwtEcdsaSignKeyManagerTest,ValidateKeyFormatUnknownAlgorithm)84 TEST(RawJwtEcdsaSignKeyManagerTest, ValidateKeyFormatUnknownAlgorithm) {
85 JwtEcdsaKeyFormat key_format = CreateValidEs256KeyFormat();
86 key_format.set_algorithm(JwtEcdsaAlgorithm::ES_UNKNOWN);
87 EXPECT_THAT(RawJwtEcdsaSignKeyManager().ValidateKeyFormat(key_format),
88 Not(IsOk()));
89 }
90
TEST(RawJwtEcdsaSignKeyManagerTest,CreateKey)91 TEST(RawJwtEcdsaSignKeyManagerTest, CreateKey) {
92 JwtEcdsaKeyFormat format = CreateValidEs256KeyFormat();
93 StatusOr<JwtEcdsaPrivateKey> key =
94 RawJwtEcdsaSignKeyManager().CreateKey(format);
95 ASSERT_THAT(key, IsOk());
96
97 EXPECT_THAT(key->version(), Eq(0));
98
99 EXPECT_THAT(key->public_key().version(), Eq(key->version()));
100 EXPECT_THAT(key->public_key().algorithm(),
101 Eq(format.algorithm()));
102
103 EXPECT_THAT(key->public_key().x(), SizeIs(Gt(0)));
104 EXPECT_THAT(key->public_key().y(), SizeIs(Gt(0)));
105
106 EXPECT_THAT(key->key_value(), SizeIs(Gt(0)));
107 }
108
TEST(RawJwtEcdsaSignKeyManagerTest,CreateKeyValid)109 TEST(RawJwtEcdsaSignKeyManagerTest, CreateKeyValid) {
110 JwtEcdsaKeyFormat format = CreateValidEs256KeyFormat();
111 StatusOr<JwtEcdsaPrivateKey> key =
112 RawJwtEcdsaSignKeyManager().CreateKey(format);
113 ASSERT_THAT(key, IsOk());
114 EXPECT_THAT(RawJwtEcdsaSignKeyManager().ValidateKey(*key),
115 IsOk());
116 }
117
CreateValidEs256Key()118 JwtEcdsaPrivateKey CreateValidEs256Key() {
119 JwtEcdsaKeyFormat format = CreateValidEs256KeyFormat();
120 return RawJwtEcdsaSignKeyManager().CreateKey(format).value();
121 }
122
TEST(RawJwtEcdsaSignKeyManagerTest,ValidateKey)123 TEST(RawJwtEcdsaSignKeyManagerTest, ValidateKey) {
124 JwtEcdsaPrivateKey key = CreateValidEs256Key();
125 EXPECT_THAT(RawJwtEcdsaSignKeyManager().ValidateKey(key), IsOk());
126 }
127
TEST(RawJwtEcdsaSignKeyManagerTest,ValidateKeyUnknownAlgorithm)128 TEST(RawJwtEcdsaSignKeyManagerTest, ValidateKeyUnknownAlgorithm) {
129 JwtEcdsaPrivateKey key = CreateValidEs256Key();
130 key.mutable_public_key()->set_algorithm(JwtEcdsaAlgorithm::ES_UNKNOWN);
131 EXPECT_THAT(RawJwtEcdsaSignKeyManager().ValidateKey(key), Not(IsOk()));
132 EXPECT_THAT(RawJwtEcdsaSignKeyManager().ValidateKey(key),
133 StatusIs(absl::StatusCode::kInvalidArgument));
134 }
135
TEST(RawJwtEcdsaSignKeyManagerTest,GetPublicKey)136 TEST(RawJwtEcdsaSignKeyManagerTest, GetPublicKey) {
137 JwtEcdsaPrivateKey key = CreateValidEs256Key();
138 StatusOr<JwtEcdsaPublicKey> public_key =
139 RawJwtEcdsaSignKeyManager().GetPublicKey(key);
140
141 ASSERT_THAT(public_key, IsOk());
142
143 EXPECT_THAT(public_key->version(), Eq(key.public_key().version()));
144 EXPECT_THAT(public_key->algorithm(),
145 Eq(key.public_key().algorithm()));
146
147 EXPECT_THAT(public_key->x(), Eq(key.public_key().x()));
148 EXPECT_THAT(public_key->y(), Eq(key.public_key().y()));
149 }
150
TEST(RawJwtEcdsaSignKeyManagerTest,Create)151 TEST(RawJwtEcdsaSignKeyManagerTest, Create) {
152 JwtEcdsaPrivateKey private_key = CreateValidEs256Key();
153 util::StatusOr<JwtEcdsaPublicKey> public_key =
154 RawJwtEcdsaSignKeyManager().GetPublicKey(private_key);
155 ASSERT_THAT(public_key, IsOk());
156
157 util::StatusOr<std::unique_ptr<PublicKeySign>> signer =
158 RawJwtEcdsaSignKeyManager().GetPrimitive<PublicKeySign>(private_key);
159 ASSERT_THAT(signer, IsOk());
160
161 internal::EcKey ec_key;
162 ec_key.curve = Enums::ProtoToSubtle(EllipticCurveType::NIST_P256);
163 ec_key.pub_x = public_key->x();
164 ec_key.pub_y = public_key->y();
165 util::StatusOr<std::unique_ptr<subtle::EcdsaVerifyBoringSsl>>
166 direct_verifier = subtle::EcdsaVerifyBoringSsl::New(
167 ec_key, Enums::ProtoToSubtle(HashType::SHA256),
168 subtle::EcdsaSignatureEncoding::IEEE_P1363);
169 ASSERT_THAT(direct_verifier, IsOk());
170
171 std::string message = "Some message";
172 util::StatusOr<std::string> sig = (*signer)->Sign(message);
173 ASSERT_THAT(sig, IsOk());
174 EXPECT_THAT((*direct_verifier)->Verify(*sig, message), IsOk());
175 }
176
TEST(RawJwtEcdsaSignKeyManagerTest,CreateDifferentKey)177 TEST(RawJwtEcdsaSignKeyManagerTest, CreateDifferentKey) {
178 JwtEcdsaPrivateKey private_key = CreateValidEs256Key();
179 // Note: we create a new key in the next line.
180 util::StatusOr<JwtEcdsaPublicKey> public_key = RawJwtEcdsaSignKeyManager()
181 .GetPublicKey(CreateValidEs256Key());
182
183 util::StatusOr<std::unique_ptr<PublicKeySign>> signer =
184 RawJwtEcdsaSignKeyManager().GetPrimitive<PublicKeySign>(private_key);
185 ASSERT_THAT(signer, IsOk());
186
187 internal::EcKey ec_key;
188 ec_key.curve = Enums::ProtoToSubtle(EllipticCurveType::NIST_P256);
189 ec_key.pub_x = public_key->x();
190 ec_key.pub_y = public_key->y();
191 util::StatusOr<std::unique_ptr<subtle::EcdsaVerifyBoringSsl>>
192 direct_verifier = subtle::EcdsaVerifyBoringSsl::New(
193 ec_key, Enums::ProtoToSubtle(HashType::SHA256),
194 subtle::EcdsaSignatureEncoding::IEEE_P1363);
195 ASSERT_THAT(direct_verifier, IsOk());
196
197 std::string message = "Some message";
198 util::StatusOr<std::string> sig = (*signer)->Sign(message);
199 ASSERT_THAT(sig, IsOk());
200 EXPECT_THAT((*direct_verifier)->Verify(*sig, message), Not(IsOk()));
201 }
202
203 } // namespace
204 } // namespace jwt_internal
205 } // namespace tink
206 } // namespace crypto
207