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/jwt/internal/raw_jwt_hmac_key_manager.h"
18
19 #include <memory>
20 #include <sstream>
21 #include <utility>
22
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "tink/core/key_manager_impl.h"
26 #include "tink/keyset_handle.h"
27 #include "tink/mac.h"
28 #include "tink/mac/mac_config.h"
29 #include "tink/registry.h"
30 #include "tink/util/istream_input_stream.h"
31 #include "tink/util/secret_data.h"
32 #include "tink/util/status.h"
33 #include "tink/util/statusor.h"
34 #include "tink/util/test_matchers.h"
35 #include "proto/jwt_hmac.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::IstreamInputStream;
44 using ::crypto::tink::util::StatusOr;
45 using ::google::crypto::tink::JwtHmacAlgorithm;
46 using ::google::crypto::tink::JwtHmacKey;
47 using ::google::crypto::tink::JwtHmacKeyFormat;
48 using ::google::crypto::tink::KeyTemplate;
49 using ::google::crypto::tink::OutputPrefixType;
50 using ::testing::Eq;
51 using ::testing::Not;
52 using ::testing::SizeIs;
53
54 namespace {
55
TEST(RawJwtHmacKeyManagerTest,Basics)56 TEST(RawJwtHmacKeyManagerTest, Basics) {
57 EXPECT_THAT(RawJwtHmacKeyManager().get_version(), Eq(0));
58 EXPECT_THAT(RawJwtHmacKeyManager().get_key_type(),
59 Eq("type.googleapis.com/google.crypto.tink.JwtHmacKey"));
60 EXPECT_THAT(RawJwtHmacKeyManager().key_material_type(),
61 Eq(google::crypto::tink::KeyData::SYMMETRIC));
62 }
63
TEST(RawJwtHmacKeyManagerTest,ValidateEmptyKey)64 TEST(RawJwtHmacKeyManagerTest, ValidateEmptyKey) {
65 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(JwtHmacKey()), Not(IsOk()));
66 }
67
TEST(RawJwtHmacKeyManagerTest,ValidateEmptyKeyFormat)68 TEST(RawJwtHmacKeyManagerTest, ValidateEmptyKeyFormat) {
69 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(JwtHmacKeyFormat()),
70 Not(IsOk()));
71 }
72
73 // BETTER TESTS.
74
TEST(RawJwtHmacKeyManagerTest,ValidateHS256KeyFormat)75 TEST(RawJwtHmacKeyManagerTest, ValidateHS256KeyFormat) {
76 JwtHmacKeyFormat key_format;
77 key_format.set_algorithm(JwtHmacAlgorithm::HS256);
78 key_format.set_key_size(32);
79 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format), IsOk());
80 key_format.set_key_size(33);
81 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format), IsOk());
82 key_format.set_key_size(31);
83 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format),
84 Not(IsOk()));
85 }
86
TEST(RawJwtHmacKeyManagerTest,ValidateHS384KeyFormat)87 TEST(RawJwtHmacKeyManagerTest, ValidateHS384KeyFormat) {
88 JwtHmacKeyFormat key_format;
89 key_format.set_algorithm(JwtHmacAlgorithm::HS384);
90 key_format.set_key_size(48);
91 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format), IsOk());
92 key_format.set_key_size(49);
93 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format), IsOk());
94 key_format.set_key_size(47);
95 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format),
96 Not(IsOk()));
97 }
98
TEST(RawJwtHmacKeyManagerTest,ValidateHS512KeyFormat)99 TEST(RawJwtHmacKeyManagerTest, ValidateHS512KeyFormat) {
100 JwtHmacKeyFormat key_format;
101 key_format.set_algorithm(JwtHmacAlgorithm::HS512);
102 key_format.set_key_size(64);
103 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format), IsOk());
104 key_format.set_key_size(65);
105 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format), IsOk());
106 key_format.set_key_size(63);
107 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format),
108 Not(IsOk()));
109 }
110
TEST(RawJwtHmacKeyManagerTest,Sha1IsInvalidKeyFormat)111 TEST(RawJwtHmacKeyManagerTest, Sha1IsInvalidKeyFormat) {
112 JwtHmacKeyFormat key_format;
113 key_format.set_algorithm(JwtHmacAlgorithm::HS_UNKNOWN);
114 key_format.set_key_size(32);
115 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKeyFormat(key_format),
116 Not(IsOk()));
117 }
118
TEST(RawJwtHmacKeyManagerTest,CreateKeyWithSha256)119 TEST(RawJwtHmacKeyManagerTest, CreateKeyWithSha256) {
120 JwtHmacKeyFormat key_format;
121 key_format.set_key_size(32);
122 key_format.set_algorithm(JwtHmacAlgorithm::HS256);
123 auto hmac_key_or = RawJwtHmacKeyManager().CreateKey(key_format);
124 ASSERT_THAT(hmac_key_or, IsOk());
125 EXPECT_THAT(hmac_key_or.value().version(), Eq(0));
126 EXPECT_THAT(hmac_key_or.value().algorithm(), Eq(key_format.algorithm()));
127 EXPECT_THAT(hmac_key_or.value().key_value(), SizeIs(key_format.key_size()));
128
129 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(hmac_key_or.value()), IsOk());
130 }
131
TEST(RawJwtHmacKeyManagerTest,CreateKeyWithSha384)132 TEST(RawJwtHmacKeyManagerTest, CreateKeyWithSha384) {
133 JwtHmacKeyFormat key_format;
134 key_format.set_key_size(48);
135 key_format.set_algorithm(JwtHmacAlgorithm::HS384);
136 auto hmac_key_or = RawJwtHmacKeyManager().CreateKey(key_format);
137 ASSERT_THAT(hmac_key_or, IsOk());
138 EXPECT_THAT(hmac_key_or.value().version(), Eq(0));
139 EXPECT_THAT(hmac_key_or.value().algorithm(), Eq(key_format.algorithm()));
140 EXPECT_THAT(hmac_key_or.value().key_value(), SizeIs(key_format.key_size()));
141
142 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(hmac_key_or.value()), IsOk());
143 }
144
TEST(RawJwtHmacKeyManagerTest,CreateKeyWithSha512)145 TEST(RawJwtHmacKeyManagerTest, CreateKeyWithSha512) {
146 JwtHmacKeyFormat key_format;
147 key_format.set_key_size(64);
148 key_format.set_algorithm(JwtHmacAlgorithm::HS512);
149 auto key_or = RawJwtHmacKeyManager().CreateKey(key_format);
150 ASSERT_THAT(key_or, IsOk());
151 EXPECT_THAT(key_or.value().version(), Eq(0));
152 EXPECT_THAT(key_or.value().algorithm(), Eq(key_format.algorithm()));
153 EXPECT_THAT(key_or.value().key_value(), SizeIs(key_format.key_size()));
154
155 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key_or.value()), IsOk());
156 }
157
TEST(RawJwtHmacKeyManagerTest,ValidateHS256Key)158 TEST(RawJwtHmacKeyManagerTest, ValidateHS256Key) {
159 JwtHmacKey key;
160 key.set_version(0);
161 key.set_algorithm(JwtHmacAlgorithm::HS256);
162 key.set_key_value("0123456789abcdef0123456789abcdef"); // 32 bytes
163 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key), IsOk());
164 key.set_key_value("0123456789abcdef0123456789abcde"); // 31 bytes
165 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key), Not(IsOk()));
166 }
167
TEST(RawJwtHmacKeyManagerTest,ValidateHS384Key)168 TEST(RawJwtHmacKeyManagerTest, ValidateHS384Key) {
169 JwtHmacKey key;
170 key.set_version(0);
171 key.set_algorithm(JwtHmacAlgorithm::HS384);
172 key.set_key_value(
173 "0123456789abcdef0123456789abcdef0123456789abcdef"); // 48 bytes
174 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key), IsOk());
175 key.set_key_value(
176 "0123456789abcdef0123456789abcdef0123456789abcde"); // 47 bytes
177 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key), Not(IsOk()));
178 }
179
TEST(RawJwtHmacKeyManagerTest,ValidateHS512Key)180 TEST(RawJwtHmacKeyManagerTest, ValidateHS512Key) {
181 JwtHmacKey key;
182 key.set_version(0);
183 key.set_algorithm(JwtHmacAlgorithm::HS512);
184 key.set_key_value( // 64 bytes
185 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
186 key.set_key_value( // 63 bytes
187 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde");
188 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key), Not(IsOk()));
189 }
190
TEST(RawJwtHmacKeyManagerTest,Sha1KeyIsInvalid)191 TEST(RawJwtHmacKeyManagerTest, Sha1KeyIsInvalid) {
192 JwtHmacKey key;
193 key.set_version(0);
194 key.set_algorithm(JwtHmacAlgorithm::HS_UNKNOWN);
195 key.set_key_value("0123456789abcdef0123456789abcdef");
196 EXPECT_THAT(RawJwtHmacKeyManager().ValidateKey(key), Not(IsOk()));
197 }
198
TEST(RawJwtHmacKeyManagerTest,DeriveKeyIsNotImplemented)199 TEST(RawJwtHmacKeyManagerTest, DeriveKeyIsNotImplemented) {
200 JwtHmacKeyFormat format;
201 format.set_key_size(32);
202 format.set_version(0);
203 format.set_algorithm(JwtHmacAlgorithm::HS256);
204 IstreamInputStream input_stream{
205 absl::make_unique<std::stringstream>("0123456789abcdef0123456789abcdef")};
206
207 StatusOr<JwtHmacKey> key_or =
208 RawJwtHmacKeyManager().DeriveKey(format, &input_stream);
209 EXPECT_THAT(key_or.status(), StatusIs(absl::StatusCode::kUnimplemented));
210 }
211
TEST(RawJwtHmacKeyManagerTest,GetPrimitiveFromNewKeysetHandle)212 TEST(RawJwtHmacKeyManagerTest, GetPrimitiveFromNewKeysetHandle) {
213 Registry::Reset();
214 ASSERT_THAT(MacConfig::Register(), IsOk());
215 ASSERT_THAT(Registry::RegisterKeyTypeManager(
216 absl::make_unique<RawJwtHmacKeyManager>(), true),
217 IsOk());
218
219 JwtHmacKeyFormat key_format;
220 key_format.set_algorithm(JwtHmacAlgorithm::HS256);
221 key_format.set_key_size(32);
222 KeyTemplate key_template;
223 key_template.set_type_url(
224 "type.googleapis.com/google.crypto.tink.JwtHmacKey");
225 key_template.set_output_prefix_type(OutputPrefixType::RAW);
226 key_format.SerializeToString(key_template.mutable_value());
227
228 auto handle_result = KeysetHandle::GenerateNew(key_template);
229 ASSERT_TRUE(handle_result.ok()) << handle_result.status();
230 std::unique_ptr<KeysetHandle> handle = std::move(handle_result.value());
231
232 auto mac_result = handle->GetPrimitive<Mac>();
233 ASSERT_TRUE(mac_result.ok()) << mac_result.status();
234 std::unique_ptr<Mac> mac = std::move(mac_result.value());
235 auto tag_or = mac->ComputeMac("some plaintext");
236 ASSERT_THAT(tag_or, IsOk());
237 EXPECT_THAT(mac->VerifyMac(tag_or.value(), "some plaintext"), IsOk());
238 }
239
240 } // namespace
241 } // namespace jwt_internal
242 } // namespace tink
243 } // namespace crypto
244