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/jwt_key_templates.h"
18
19 #include <memory>
20 #include <string>
21 #include <utility>
22
23 #include "gtest/gtest.h"
24 #include "tink/jwt/jwt_mac.h"
25 #include "tink/jwt/jwt_mac_config.h"
26 #include "tink/jwt/jwt_public_key_sign.h"
27 #include "tink/jwt/jwt_public_key_verify.h"
28 #include "tink/jwt/jwt_signature_config.h"
29 #include "tink/jwt/jwt_validator.h"
30 #include "tink/jwt/raw_jwt.h"
31 #include "tink/jwt/verified_jwt.h"
32 #include "tink/util/status.h"
33 #include "tink/util/test_matchers.h"
34 #include "tink/util/test_util.h"
35
36 using ::crypto::tink::test::IsOk;
37 using google::crypto::tink::KeyTemplate;
38
39 namespace crypto {
40 namespace tink {
41 namespace {
42
43 class JwtMacKeyTemplatesTest : public testing::TestWithParam<KeyTemplate> {
SetUp()44 void SetUp() override { ASSERT_TRUE(JwtMacRegister().ok()); }
45 };
46
TEST_P(JwtMacKeyTemplatesTest,CreateComputeVerify)47 TEST_P(JwtMacKeyTemplatesTest, CreateComputeVerify) {
48 KeyTemplate key_template = GetParam();
49
50 util::StatusOr<std::unique_ptr<crypto::tink::KeysetHandle>> keyset_handle =
51 KeysetHandle::GenerateNew(key_template);
52 ASSERT_THAT(keyset_handle, IsOk());
53 util::StatusOr<std::unique_ptr<crypto::tink::JwtMac>> jwt_mac =
54 (*keyset_handle)->GetPrimitive<JwtMac>();
55 ASSERT_THAT(jwt_mac, IsOk());
56
57 util::StatusOr<RawJwt> raw_jwt =
58 RawJwtBuilder().SetIssuer("issuer").WithoutExpiration().Build();
59 ASSERT_THAT(raw_jwt, IsOk());
60
61 util::StatusOr<std::string> compact =
62 (*jwt_mac)->ComputeMacAndEncode(*raw_jwt);
63 ASSERT_THAT(compact, IsOk());
64
65 util::StatusOr<JwtValidator> validator = JwtValidatorBuilder()
66 .ExpectIssuer("issuer")
67 .AllowMissingExpiration()
68 .Build();
69 ASSERT_THAT(validator, IsOk());
70 util::StatusOr<VerifiedJwt> verified_jwt =
71 (*jwt_mac)->VerifyMacAndDecode(*compact, *validator);
72 ASSERT_THAT(verified_jwt, IsOk());
73 EXPECT_THAT(verified_jwt->GetIssuer(), test::IsOkAndHolds("issuer"));
74
75 util::StatusOr<JwtValidator> validator2 = JwtValidatorBuilder()
76 .ExpectIssuer("unknown")
77 .AllowMissingExpiration()
78 .Build();
79 ASSERT_THAT(validator2, IsOk());
80 EXPECT_FALSE((*jwt_mac)->VerifyMacAndDecode(*compact, *validator2).ok());
81 }
82
83 INSTANTIATE_TEST_SUITE_P(JwtMacKeyTemplatesTest, JwtMacKeyTemplatesTest,
84 testing::Values(JwtHs256Template(), JwtHs384Template(),
85 JwtHs512Template()));
86
87 class JwtSignatureKeyTemplatesTest
88 : public testing::TestWithParam<KeyTemplate> {
SetUp()89 void SetUp() override { ASSERT_TRUE(JwtSignatureRegister().ok()); }
90 };
91
TEST_P(JwtSignatureKeyTemplatesTest,CreateComputeVerify)92 TEST_P(JwtSignatureKeyTemplatesTest, CreateComputeVerify) {
93 KeyTemplate key_template = GetParam();
94
95 util::StatusOr<std::unique_ptr<KeysetHandle>> private_handle =
96 KeysetHandle::GenerateNew(key_template);
97 ASSERT_THAT(private_handle, IsOk());
98 util::StatusOr<std::unique_ptr<JwtPublicKeySign>> sign =
99 (*private_handle)->GetPrimitive<JwtPublicKeySign>();
100 ASSERT_THAT(sign, IsOk());
101 util::StatusOr<std::unique_ptr<KeysetHandle>> public_handle =
102 (*private_handle)->GetPublicKeysetHandle();
103 ASSERT_THAT(public_handle, IsOk());
104 util::StatusOr<std::unique_ptr<JwtPublicKeyVerify>> verify =
105 (*public_handle)->GetPrimitive<JwtPublicKeyVerify>();
106 ASSERT_THAT(verify, IsOk());
107
108 util::StatusOr<RawJwt> raw_jwt =
109 RawJwtBuilder().SetIssuer("issuer").WithoutExpiration().Build();
110 ASSERT_THAT(raw_jwt, IsOk());
111
112 util::StatusOr<std::string> compact = (*sign)->SignAndEncode(*raw_jwt);
113 ASSERT_THAT(compact, IsOk());
114
115 util::StatusOr<JwtValidator> validator = JwtValidatorBuilder()
116 .ExpectIssuer("issuer")
117 .AllowMissingExpiration()
118 .Build();
119 ASSERT_THAT(validator, IsOk());
120 util::StatusOr<VerifiedJwt> verified_jwt =
121 (*verify)->VerifyAndDecode(*compact, *validator);
122 ASSERT_THAT(verified_jwt, IsOk());
123 EXPECT_THAT(verified_jwt->GetIssuer(), test::IsOkAndHolds("issuer"));
124
125 util::StatusOr<JwtValidator> validator2 = JwtValidatorBuilder()
126 .ExpectIssuer("unknown")
127 .AllowMissingExpiration()
128 .Build();
129 ASSERT_THAT(validator, IsOk());
130 EXPECT_FALSE((*verify)->VerifyAndDecode(*compact, *validator2).ok());
131 }
132
133 INSTANTIATE_TEST_SUITE_P(
134 JwtSignatureKeyTemplatesTest, JwtSignatureKeyTemplatesTest,
135 testing::Values(JwtEs256Template(), JwtEs384Template(), JwtEs512Template(),
136 RawJwtEs256Template(), JwtRs256_2048_F4_Template(),
137 JwtRs256_3072_F4_Template(), JwtRs384_3072_F4_Template(),
138 JwtRs512_4096_F4_Template(), RawJwtRs256_2048_F4_Template(),
139 JwtPs256_2048_F4_Template(), JwtPs256_3072_F4_Template(),
140 JwtPs384_3072_F4_Template(), JwtPs512_4096_F4_Template(),
141 RawJwtPs256_2048_F4_Template()));
142 } // namespace
143 } // namespace tink
144 } // namespace crypto
145