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 "jwt_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/jwt/jwt_key_templates.h"
29 #include "tink/jwt/jwt_mac_config.h"
30 #include "tink/jwt/jwt_signature_config.h"
31 #include "tink/util/test_matchers.h"
32 #include "proto/testing_api.grpc.pb.h"
33
34 namespace crypto {
35 namespace tink {
36 namespace {
37
38 using ::crypto::tink::BinaryKeysetWriter;
39 using ::crypto::tink::CleartextKeysetHandle;
40 using ::crypto::tink::KeysetHandle;
41 using ::crypto::tink::test::IsOk;
42 using ::google::crypto::tink::KeyTemplate;
43 using ::testing::ElementsAre;
44 using ::testing::Eq;
45 using ::testing::IsEmpty;
46 using ::testing::Not;
47 using ::tink_testing_api::CreationRequest;
48 using ::tink_testing_api::CreationResponse;
49 using ::tink_testing_api::JwtFromJwkSetRequest;
50 using ::tink_testing_api::JwtFromJwkSetResponse;
51 using ::tink_testing_api::JwtSignRequest;
52 using ::tink_testing_api::JwtSignResponse;
53 using ::tink_testing_api::JwtToJwkSetRequest;
54 using ::tink_testing_api::JwtToJwkSetResponse;
55 using ::tink_testing_api::JwtToken;
56 using ::tink_testing_api::JwtValidator;
57 using ::tink_testing_api::JwtVerifyRequest;
58 using ::tink_testing_api::JwtVerifyResponse;
59
ValidKeyset()60 std::string ValidKeyset() {
61 const KeyTemplate& key_template = ::crypto::tink::JwtHs256Template();
62 util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
63 KeysetHandle::GenerateNew(key_template);
64 EXPECT_THAT(handle.status(), IsOk());
65
66 std::stringbuf keyset;
67 util::StatusOr<std::unique_ptr<BinaryKeysetWriter>> writer =
68 BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
69 EXPECT_THAT(writer.status(), IsOk());
70
71 util::Status status = CleartextKeysetHandle::Write((*writer).get(), **handle);
72 EXPECT_THAT(status, IsOk());
73 return keyset.str();
74 }
75
76 class JwtImplMacTest : public ::testing::Test {
77 protected:
SetUpTestSuite()78 static void SetUpTestSuite() { ASSERT_THAT(JwtMacRegister(), IsOk()); }
79 };
80
TEST_F(JwtImplMacTest,CreateJwtMacSuccess)81 TEST_F(JwtImplMacTest, CreateJwtMacSuccess) {
82 tink_testing_api::JwtImpl jwt;
83 std::string keyset = ValidKeyset();
84 CreationRequest request;
85 request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
86 CreationResponse response;
87
88 EXPECT_TRUE(jwt.CreateJwtMac(nullptr, &request, &response).ok());
89 EXPECT_THAT(response.err(), IsEmpty());
90 }
91
TEST_F(JwtImplMacTest,CreateJwtMacFails)92 TEST_F(JwtImplMacTest, CreateJwtMacFails) {
93 tink_testing_api::JwtImpl jwt;
94 CreationRequest request;
95 request.mutable_annotated_keyset()->set_serialized_keyset("bad keyset");
96 CreationResponse response;
97
98 EXPECT_TRUE(jwt.CreateJwtMac(nullptr, &request, &response).ok());
99 EXPECT_THAT(response.err(), Not(IsEmpty()));
100 }
101
TEST_F(JwtImplMacTest,MacComputeVerifySuccess)102 TEST_F(JwtImplMacTest, MacComputeVerifySuccess) {
103 tink_testing_api::JwtImpl jwt;
104 std::string keyset = ValidKeyset();
105 JwtSignRequest comp_request;
106 comp_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
107 JwtToken* raw_jwt = comp_request.mutable_raw_jwt();
108 raw_jwt->mutable_type_header()->set_value("type_header");
109 raw_jwt->mutable_issuer()->set_value("issuer");
110 raw_jwt->mutable_subject()->set_value("subject");
111 raw_jwt->mutable_audiences()->Add("audience1");
112 raw_jwt->mutable_audiences()->Add("audience2");
113 raw_jwt->mutable_jwt_id()->set_value("jwt_id");
114 raw_jwt->mutable_not_before()->set_seconds(12345);
115 raw_jwt->mutable_not_before()->set_nanos(123000000);
116 raw_jwt->mutable_issued_at()->set_seconds(23456);
117 raw_jwt->mutable_expiration()->set_seconds(34567);
118 auto custom_claims = raw_jwt->mutable_custom_claims();
119 (*custom_claims)["null_claim"].set_null_value(
120 tink_testing_api::NullValue::NULL_VALUE);
121 (*custom_claims)["bool_claim"].set_bool_value(true);
122 (*custom_claims)["number_claim"].set_number_value(123.456);
123 (*custom_claims)["string_claim"].set_string_value("string_value");
124 JwtSignResponse comp_response;
125 EXPECT_TRUE(
126 jwt.ComputeMacAndEncode(nullptr, &comp_request, &comp_response).ok());
127 EXPECT_THAT(comp_response.err(), IsEmpty());
128
129 JwtVerifyRequest verify_request;
130 verify_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
131 verify_request.set_signed_compact_jwt(comp_response.signed_compact_jwt());
132 JwtValidator* validator = verify_request.mutable_validator();
133 validator->mutable_expected_type_header()->set_value("type_header");
134 validator->mutable_expected_issuer()->set_value("issuer");
135 validator->mutable_expected_audience()->set_value("audience2");
136 validator->mutable_now()->set_seconds(23456);
137 JwtVerifyResponse verify_response;
138
139 ASSERT_TRUE(
140 jwt.VerifyMacAndDecode(nullptr, &verify_request, &verify_response).ok());
141 ASSERT_THAT(verify_response.err(), IsEmpty());
142 const JwtToken& verified_jwt = verify_response.verified_jwt();
143 EXPECT_EQ(verified_jwt.type_header().value(), "type_header");
144 EXPECT_THAT(verified_jwt.issuer().value(), Eq("issuer"));
145 EXPECT_THAT(verified_jwt.subject().value(), Eq("subject"));
146 EXPECT_THAT(verified_jwt.audiences_size(), Eq(2));
147 EXPECT_THAT(verified_jwt.audiences(0), Eq("audience1"));
148 EXPECT_THAT(verified_jwt.audiences(1), Eq("audience2"));
149 EXPECT_THAT(verified_jwt.jwt_id().value(), Eq("jwt_id"));
150 EXPECT_THAT(verified_jwt.not_before().seconds(), Eq(12345));
151 EXPECT_THAT(verified_jwt.not_before().nanos(), Eq(0));
152 EXPECT_THAT(verified_jwt.issued_at().seconds(), Eq(23456));
153 EXPECT_THAT(verified_jwt.issued_at().nanos(), Eq(0));
154 EXPECT_THAT(verified_jwt.expiration().seconds(), Eq(34567));
155 EXPECT_THAT(verified_jwt.expiration().nanos(), Eq(0));
156 auto verified_custom_claims = verified_jwt.custom_claims();
157 EXPECT_THAT(verified_custom_claims["null_claim"].null_value(),
158 Eq(tink_testing_api::NullValue::NULL_VALUE));
159 EXPECT_THAT(verified_custom_claims["bool_claim"].bool_value(), Eq(true));
160 EXPECT_THAT(verified_custom_claims["number_claim"].number_value(),
161 Eq(123.456));
162 EXPECT_THAT(verified_custom_claims["string_claim"].string_value(),
163 Eq("string_value"));
164 }
165
TEST_F(JwtImplMacTest,ComputeBadKeysetFail)166 TEST_F(JwtImplMacTest, ComputeBadKeysetFail) {
167 tink_testing_api::JwtImpl jwt;
168 JwtSignRequest comp_request;
169 comp_request.mutable_annotated_keyset()->set_serialized_keyset("bad keyset");
170 comp_request.mutable_raw_jwt()->mutable_issuer()->set_value("issuer");
171 JwtSignResponse comp_response;
172
173 EXPECT_TRUE(
174 jwt.ComputeMacAndEncode(nullptr, &comp_request, &comp_response).ok());
175 EXPECT_THAT(comp_response.err(), Not(IsEmpty()));
176 }
177
TEST_F(JwtImplMacTest,VerifyWithWrongIssuerFails)178 TEST_F(JwtImplMacTest, VerifyWithWrongIssuerFails) {
179 tink_testing_api::JwtImpl jwt;
180 std::string keyset = ValidKeyset();
181 JwtSignRequest comp_request;
182 comp_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
183 comp_request.mutable_raw_jwt()->mutable_issuer()->set_value("unknown");
184 JwtSignResponse comp_response;
185 EXPECT_TRUE(
186 jwt.ComputeMacAndEncode(nullptr, &comp_request, &comp_response).ok());
187 EXPECT_THAT(comp_response.err(), IsEmpty());
188
189 JwtVerifyRequest verify_request;
190 verify_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
191 verify_request.set_signed_compact_jwt(comp_response.signed_compact_jwt());
192 verify_request.mutable_validator()->mutable_expected_issuer()->set_value(
193 "issuer");
194 JwtVerifyResponse verify_response;
195
196 EXPECT_TRUE(
197 jwt.VerifyMacAndDecode(nullptr, &verify_request, &verify_response).ok());
198 EXPECT_THAT(verify_response.err(), Not(IsEmpty()));
199 }
200
201 class JwtImplSignatureTest : public ::testing::Test {
202 protected:
SetUpTestSuite()203 static void SetUpTestSuite() { ASSERT_THAT(JwtSignatureRegister(), IsOk()); }
SetUp()204 void SetUp() override {
205 const KeyTemplate& key_template = ::crypto::tink::JwtEs256Template();
206 util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
207 KeysetHandle::GenerateNew(key_template);
208 EXPECT_THAT(handle.status(), IsOk());
209
210 std::stringbuf keyset;
211 util::StatusOr<std::unique_ptr<BinaryKeysetWriter>> writer =
212 BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
213 EXPECT_THAT(writer.status(), IsOk());
214
215 util::Status status =
216 CleartextKeysetHandle::Write((*writer).get(), **handle);
217 EXPECT_THAT(status, IsOk());
218 private_keyset_ = keyset.str();
219
220 util::StatusOr<std::unique_ptr<crypto::tink::KeysetHandle>> pub_handle =
221 (*handle)->GetPublicKeysetHandle();
222 EXPECT_THAT(pub_handle.status(), IsOk());
223
224 std::stringbuf pub_keyset;
225 util::StatusOr<std::unique_ptr<BinaryKeysetWriter>> pub_writer =
226 BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&pub_keyset));
227 EXPECT_THAT(writer.status(), IsOk());
228
229 util::Status pub_status =
230 CleartextKeysetHandle::Write(pub_writer->get(), **pub_handle);
231 EXPECT_THAT(pub_status, IsOk());
232 public_keyset_ = pub_keyset.str();
233 }
234 std::string private_keyset_;
235 std::string public_keyset_;
236 };
237
TEST_F(JwtImplSignatureTest,CreatePublicKeySignSuccess)238 TEST_F(JwtImplSignatureTest, CreatePublicKeySignSuccess) {
239 tink_testing_api::JwtImpl jwt;
240 CreationRequest request;
241 request.mutable_annotated_keyset()->set_serialized_keyset(private_keyset_);
242 CreationResponse response;
243
244 EXPECT_TRUE(jwt.CreateJwtPublicKeySign(nullptr, &request, &response).ok());
245 EXPECT_THAT(response.err(), IsEmpty());
246 }
247
TEST_F(JwtImplSignatureTest,CreatePublicKeySignFailure)248 TEST_F(JwtImplSignatureTest, CreatePublicKeySignFailure) {
249 tink_testing_api::JwtImpl jwt;
250
251 CreationRequest request;
252 request.mutable_annotated_keyset()->set_serialized_keyset("\x80");
253 CreationResponse response;
254
255 EXPECT_TRUE(jwt.CreateJwtPublicKeySign(nullptr, &request, &response).ok());
256 EXPECT_THAT(response.err(), Not(IsEmpty()));
257 }
258
TEST_F(JwtImplSignatureTest,CreatePublicKeyVerifySuccess)259 TEST_F(JwtImplSignatureTest, CreatePublicKeyVerifySuccess) {
260 tink_testing_api::JwtImpl jwt;
261
262 CreationRequest request;
263 request.mutable_annotated_keyset()->set_serialized_keyset(public_keyset_);
264 CreationResponse response;
265
266 EXPECT_TRUE(jwt.CreateJwtPublicKeyVerify(nullptr, &request, &response).ok());
267 EXPECT_THAT(response.err(), IsEmpty());
268 }
269
TEST_F(JwtImplSignatureTest,CreatePublicKeyVerifyFailure)270 TEST_F(JwtImplSignatureTest, CreatePublicKeyVerifyFailure) {
271 tink_testing_api::JwtImpl jwt;
272
273 CreationRequest request;
274 request.mutable_annotated_keyset()->set_serialized_keyset("\x80");
275 CreationResponse response;
276
277 EXPECT_TRUE(jwt.CreateJwtPublicKeyVerify(nullptr, &request, &response).ok());
278 EXPECT_THAT(response.err(), Not(IsEmpty()));
279 }
280
TEST_F(JwtImplSignatureTest,SignVerifySuccess)281 TEST_F(JwtImplSignatureTest, SignVerifySuccess) {
282 tink_testing_api::JwtImpl jwt;
283 JwtSignRequest comp_request;
284 comp_request.mutable_annotated_keyset()->set_serialized_keyset(
285 private_keyset_);
286 JwtToken* raw_jwt = comp_request.mutable_raw_jwt();
287 raw_jwt->mutable_type_header()->set_value("type_header");
288 raw_jwt->mutable_issuer()->set_value("issuer");
289 raw_jwt->mutable_subject()->set_value("subject");
290 raw_jwt->mutable_audiences()->Add("audience1");
291 raw_jwt->mutable_audiences()->Add("audience2");
292 raw_jwt->mutable_jwt_id()->set_value("jwt_id");
293 raw_jwt->mutable_not_before()->set_seconds(12345);
294 raw_jwt->mutable_issued_at()->set_seconds(23456);
295 raw_jwt->mutable_expiration()->set_seconds(34567);
296 auto custom_claims = raw_jwt->mutable_custom_claims();
297 (*custom_claims)["null_claim"].set_null_value(
298 tink_testing_api::NullValue::NULL_VALUE);
299 (*custom_claims)["bool_claim"].set_bool_value(true);
300 (*custom_claims)["number_claim"].set_number_value(123.456);
301 (*custom_claims)["string_claim"].set_string_value("string_value");
302 JwtSignResponse comp_response;
303 EXPECT_TRUE(
304 jwt.PublicKeySignAndEncode(nullptr, &comp_request, &comp_response).ok());
305 EXPECT_THAT(comp_response.err(), IsEmpty());
306
307 JwtVerifyRequest verify_request;
308 verify_request.mutable_annotated_keyset()->set_serialized_keyset(
309 public_keyset_);
310 verify_request.set_signed_compact_jwt(comp_response.signed_compact_jwt());
311 JwtValidator* validator = verify_request.mutable_validator();
312 validator->mutable_expected_type_header()->set_value("type_header");
313 validator->mutable_expected_issuer()->set_value("issuer");
314 validator->mutable_expected_audience()->set_value("audience2");
315 validator->mutable_now()->set_seconds(23456);
316 JwtVerifyResponse verify_response;
317
318 ASSERT_TRUE(
319 jwt.PublicKeyVerifyAndDecode(nullptr, &verify_request, &verify_response)
320 .ok());
321 ASSERT_THAT(verify_response.err(), IsEmpty());
322 const JwtToken& verified_jwt = verify_response.verified_jwt();
323 EXPECT_EQ(verified_jwt.type_header().value(), "type_header");
324 EXPECT_THAT(verified_jwt.issuer().value(), Eq("issuer"));
325 EXPECT_THAT(verified_jwt.subject().value(), Eq("subject"));
326 ASSERT_THAT(verified_jwt.audiences(),
327 ElementsAre("audience1", "audience2"));
328 EXPECT_THAT(verified_jwt.jwt_id().value(), Eq("jwt_id"));
329 EXPECT_THAT(verified_jwt.not_before().seconds(), Eq(12345));
330 EXPECT_THAT(verified_jwt.issued_at().seconds(), Eq(23456));
331 EXPECT_THAT(verified_jwt.expiration().seconds(), Eq(34567));
332 auto verified_custom_claims = verified_jwt.custom_claims();
333 EXPECT_THAT(verified_custom_claims["null_claim"].null_value(),
334 Eq(tink_testing_api::NullValue::NULL_VALUE));
335 EXPECT_THAT(verified_custom_claims["bool_claim"].bool_value(), Eq(true));
336 EXPECT_THAT(verified_custom_claims["number_claim"].number_value(),
337 Eq(123.456));
338 EXPECT_THAT(verified_custom_claims["string_claim"].string_value(),
339 Eq("string_value"));
340 }
341
TEST_F(JwtImplSignatureTest,SignWithBadKeysetFails)342 TEST_F(JwtImplSignatureTest, SignWithBadKeysetFails) {
343 tink_testing_api::JwtImpl jwt;
344 JwtSignRequest comp_request;
345 comp_request.mutable_annotated_keyset()->set_serialized_keyset("bad keyset");
346 comp_request.mutable_raw_jwt()->mutable_issuer()->set_value("issuer");
347 JwtSignResponse comp_response;
348
349 EXPECT_TRUE(
350 jwt.PublicKeySignAndEncode(nullptr, &comp_request, &comp_response).ok());
351 EXPECT_THAT(comp_response.err(), Not(IsEmpty()));
352 }
353
TEST_F(JwtImplSignatureTest,VerifyWithWrongIssuerFails)354 TEST_F(JwtImplSignatureTest, VerifyWithWrongIssuerFails) {
355 tink_testing_api::JwtImpl jwt;
356 JwtSignRequest comp_request;
357 comp_request.mutable_annotated_keyset()->set_serialized_keyset(
358 private_keyset_);
359 comp_request.mutable_raw_jwt()->mutable_issuer()->set_value("unknown");
360 JwtSignResponse comp_response;
361 EXPECT_TRUE(
362 jwt.PublicKeySignAndEncode(nullptr, &comp_request, &comp_response).ok());
363 EXPECT_THAT(comp_response.err(), IsEmpty());
364
365 JwtVerifyRequest verify_request;
366 verify_request.mutable_annotated_keyset()->set_serialized_keyset(
367 public_keyset_);
368 verify_request.set_signed_compact_jwt(comp_response.signed_compact_jwt());
369 verify_request.mutable_validator()->mutable_expected_issuer()->set_value(
370 "issuer");
371 JwtVerifyResponse verify_response;
372
373 EXPECT_TRUE(
374 jwt.PublicKeyVerifyAndDecode(nullptr, &verify_request, &verify_response)
375 .ok());
376 EXPECT_THAT(verify_response.err(), Not(IsEmpty()));
377 }
378
TEST_F(JwtImplSignatureTest,SignConvertToAndFromJwkVerifySuccess)379 TEST_F(JwtImplSignatureTest, SignConvertToAndFromJwkVerifySuccess) {
380 tink_testing_api::JwtImpl jwt;
381
382 // Create a signed token
383 JwtSignRequest comp_request;
384 comp_request.mutable_annotated_keyset()->set_serialized_keyset(
385 private_keyset_);
386 JwtToken* raw_jwt = comp_request.mutable_raw_jwt();
387 raw_jwt->mutable_issuer()->set_value("issuer");
388 raw_jwt->mutable_expiration()->set_seconds(34567);
389 JwtSignResponse comp_response;
390 ASSERT_TRUE(
391 jwt.PublicKeySignAndEncode(nullptr, &comp_request, &comp_response).ok());
392 ASSERT_THAT(comp_response.err(), IsEmpty());
393
394 // Generate a JWK set from the public key
395 JwtToJwkSetRequest to_jwk_request;
396 to_jwk_request.set_keyset(public_keyset_);
397
398 JwtToJwkSetResponse to_jwk_response;
399 ASSERT_TRUE(jwt.ToJwkSet(nullptr, &to_jwk_request, &to_jwk_response).ok());
400 ASSERT_THAT(to_jwk_response.err(), IsEmpty());
401
402 // Generate a public keyset from the JWK set
403 JwtFromJwkSetRequest from_jwk_request;
404 from_jwk_request.set_jwk_set(to_jwk_response.jwk_set());
405
406 JwtFromJwkSetResponse from_jwk_response;
407 ASSERT_TRUE(
408 jwt.FromJwkSet(nullptr, &from_jwk_request, &from_jwk_response).ok());
409 ASSERT_THAT(from_jwk_response.err(), IsEmpty());
410
411 // Verify the token using the public keyset
412 JwtVerifyRequest verify_request;
413 verify_request.mutable_annotated_keyset()->set_serialized_keyset(
414 from_jwk_response.keyset());
415 verify_request.set_signed_compact_jwt(comp_response.signed_compact_jwt());
416 JwtValidator* validator = verify_request.mutable_validator();
417 validator->mutable_expected_issuer()->set_value("issuer");
418 validator->mutable_now()->set_seconds(23456);
419 JwtVerifyResponse verify_response;
420
421 ASSERT_TRUE(
422 jwt.PublicKeyVerifyAndDecode(nullptr, &verify_request, &verify_response)
423 .ok());
424 ASSERT_THAT(verify_response.err(), IsEmpty());
425 const JwtToken& verified_jwt = verify_response.verified_jwt();
426 EXPECT_THAT(verified_jwt.issuer().value(), Eq("issuer"));
427 EXPECT_THAT(verified_jwt.expiration().seconds(), Eq(34567));
428 }
429
TEST_F(JwtImplSignatureTest,FromJwkInvalidFails)430 TEST_F(JwtImplSignatureTest, FromJwkInvalidFails) {
431 tink_testing_api::JwtImpl jwt;
432 JwtFromJwkSetRequest from_jwk_request;
433 from_jwk_request.set_jwk_set("invalid");
434
435 JwtFromJwkSetResponse from_jwk_response;
436 ASSERT_TRUE(
437 jwt.FromJwkSet(nullptr, &from_jwk_request, &from_jwk_response).ok());
438 EXPECT_THAT(from_jwk_response.err(), Not(IsEmpty()));
439 }
440
TEST_F(JwtImplSignatureTest,ToJwkInvalidFails)441 TEST_F(JwtImplSignatureTest, ToJwkInvalidFails) {
442 tink_testing_api::JwtImpl jwt;
443 JwtToJwkSetRequest to_jwk_request;
444 to_jwk_request.set_keyset("invalid");
445
446 JwtToJwkSetResponse to_jwk_response;
447 ASSERT_TRUE(jwt.ToJwkSet(nullptr, &to_jwk_request, &to_jwk_response).ok());
448 EXPECT_THAT(to_jwk_response.err(), Not(IsEmpty()));
449 }
450
451 } // namespace
452 } // namespace tink
453 } // namespace crypto
454
455