forked from mpdavis/python-jose
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_jws.py
395 lines (323 loc) · 16.9 KB
/
test_jws.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
import json
import warnings
import pytest
from jose import jwk, jws
from jose.backends import RSAKey
from jose.constants import ALGORITHMS
from jose.exceptions import JWSError
try:
from jose.backends.cryptography_backend import CryptographyRSAKey
except ImportError:
CryptographyRSAKey = None
@pytest.fixture
def payload():
payload = b"test payload"
return payload
class TestJWS:
def test_unicode_token(self):
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
jws.verify(token, "secret", ["HS256"])
def test_multiple_keys(self):
old_jwk_verify = jwk.HMACKey.verify
try:
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
def raise_exception(self, msg, sig):
if self.prepared_key == b"incorrect":
raise Exception("Mocked function jose.jwk.HMACKey.verify")
else:
return True
jwk.HMACKey.verify = raise_exception
jws.verify(token, {"keys": ["incorrect", "secret"]}, ["HS256"])
finally:
jwk.HMACKey.verify = old_jwk_verify
def test_invalid_algorithm(self):
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", [None])
def test_not_enough_segments(self):
token = "eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_header_invalid_padding(self):
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9A.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_header_not_json(self):
token = "dGVzdA.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_claims_invalid_padding(self):
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.AeyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_claims_not_json(self):
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.dGVzdA.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_invalid_key(self, payload):
with pytest.raises(JWSError):
jws.sign(payload, "secret", algorithm="RS256")
@pytest.mark.parametrize(
"key",
[
b"key",
"key",
],
)
def test_round_trip_with_different_key_types(self, key):
signed_data = jws.sign({"testkey": "testvalue"}, key, algorithm=ALGORITHMS.HS256)
verified_bytes = jws.verify(signed_data, key, algorithms=[ALGORITHMS.HS256])
verified_data = json.loads(verified_bytes.decode("utf-8"))
assert "testkey" in verified_data.keys()
assert verified_data["testkey"] == "testvalue"
class TestJWK:
def test_jwk(self, payload):
key_data = "key"
key = jwk.construct(key_data, algorithm="HS256")
token = jws.sign(payload, key, algorithm=ALGORITHMS.HS256)
assert jws.verify(token, key_data, ALGORITHMS.HS256) == payload
class TestHMAC:
def testHMAC256(self, payload):
token = jws.sign(payload, "secret", algorithm=ALGORITHMS.HS256)
assert jws.verify(token, "secret", ALGORITHMS.HS256) == payload
def testHMAC384(self, payload):
token = jws.sign(payload, "secret", algorithm=ALGORITHMS.HS384)
assert jws.verify(token, "secret", ALGORITHMS.HS384) == payload
def testHMAC512(self, payload):
token = jws.sign(payload, "secret", algorithm=ALGORITHMS.HS512)
assert jws.verify(token, "secret", ALGORITHMS.HS512) == payload
def test_wrong_alg(self, payload):
token = jws.sign(payload, "secret", algorithm=ALGORITHMS.HS256)
with pytest.raises(JWSError):
jws.verify(token, "secret", ALGORITHMS.HS384)
def test_wrong_key(self, payload):
token = jws.sign(payload, "secret", algorithm=ALGORITHMS.HS256)
with pytest.raises(JWSError):
jws.verify(token, "another", ALGORITHMS.HS256)
def test_unsupported_alg(self, payload):
with pytest.raises(JWSError):
jws.sign(payload, "secret", algorithm="SOMETHING")
def test_add_headers(self, payload):
additional_headers = {"test": "header"}
expected_headers = {
"test": "header",
"alg": "HS256",
"typ": "JWT",
}
token = jws.sign(payload, "secret", headers=additional_headers)
header, payload, signing_input, signature = jws._load(token)
assert expected_headers == header
rsa_private_key = """-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----"""
rsa_public_key = """-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtSKfSeI0fukRIX38AHlK
B1YPpX8PUYN2JdvfM+XjNmLfU1M74N0VmdzIX95sneQGO9kC2xMIE+AIlt52Yf/K
gBZggAlS9Y0Vx8DsSL2HvOjguAdXir3vYLvAyyHin/mUisJOqccFKChHKjnk0uXy
/38+1r17/cYTp76brKpU1I4kM20M//dbvLBWjfzyw9ehufr74aVwr+0xJfsBVr2o
aQFww/XHGz69Q7yHK6DbxYO4w4q2sIfcC4pT8XTPHo4JZ2M733Ea8a7HxtZS563/
mhhRZLU5aynQpwaVv2U++CL6EvGt8TlNZOkeRv8wz+Rt8B70jzoRpVK36rR+pHKl
XhMGT619v82LneTdsqA25Wi2Ld/c0niuul24A6+aaj2u9SWbxA9LmVtFntvNbRaH
XE1SLpLPoIp8uppGF02Nz2v3ld8gCnTTWfq/BQ80Qy8e0coRRABECZrjIMzHEg6M
loRDy4na0pRQv61VogqRKDU2r3/VezFPQDb3ciYsZjWBr3HpNOkUjTrvLmFyOE9Q
5R/qQGmc6BYtfk5rn7iIfXlkJAZHXhBy+ElBuiBM+YSkFM7dH92sSIoZ05V4MP09
Xcppx7kdwsJy72Sust9Hnd9B7V35YnVF6W791lVHnenhCJOziRmkH4xLLbPkaST2
Ks3IHH7tVltM6NsRk3jNdVMCAwEAAQ==
-----END PUBLIC KEY-----"""
@pytest.fixture
def jwk_set():
return {
"keys": [
{
"alg": "RS256",
"e": "AQAB",
"kid": "40aa42edac0614d7ca3f57f97ee866cdfba3b61a",
"kty": "RSA",
"n": "6lm9AEGLPFpVqnfeVFuTIZsj7vz_kxla6uW1WWtosM_MtIjXkyyiSolxiSOs3bzG66iVm71023QyOzKYFbio0hI-yZauG3g9nH-zb_AHScsjAKagHtrHmTdtq0JcNkQnAaaUwxVbjwMlYAcOh87W5jWj_MAcPvc-qjy8-WJ81UgoOUZNiKByuF4-9igxKZeskGRXuTPX64kWGBmKl-tM7VnCGMKoK3m92NPrktfBoNN_EGGthNfQsKFUdQFJFtpMuiXp9Gib7dcMGabxcG2GUl-PU086kPUyUdUYiMN2auKSOxSUZgDjT7DcI8Sn8kdQ0-tImaHi54JNa1PNNdKRpw",
"use": "sig",
},
{
"alg": "RS256",
"e": "AQAB",
"kid": "8fbbeea40332d2c0d27e37e1904af29b64594e57",
"kty": "RSA",
"n": "z7h6_rt35-j6NV2iQvYIuR3xvsxmEImgMl8dc8CFl4SzEWrry3QILajKxQZA9YYYfXIcZUG_6R6AghVMJetNIl2AhCoEr3RQjjNsm9PE6h5p2kQ-zIveFeb__4oIkVihYtxtoYBSdVj69nXLUAJP2bxPfU8RDp5X7hT62pKR05H8QLxH8siIQ5qR2LGFw_dJcitAVRRQofuaj_9u0CLZBfinqyRkBc7a0zi7pBxtEiIbn9sRr8Kkb_Boap6BHbnLS-YFBVarcgFBbifRf7NlK5dqE9z4OUb-dx8wCMRIPVAx_hV4Qx2anTgp1sDA6V4vd4NaCOZX-mSctNZqQmKtNw",
"use": "sig",
},
{
"alg": "RS256",
"e": "AQAB",
"kid": "6758b0b8eb341e90454860432d6a1648bf4de03b",
"kty": "RSA",
"n": "5K0rYaA7xtqSe1nFn_nCA10uUXY81NcohMeFsYLbBlx_NdpsmbpgtXJ6ektYR7rUdtMMLu2IONlNhkWlx-lge91okyacUrWHP88PycilUE-RnyVjbPEm3seR0VefgALfN4y_e77ljq2F7W2_kbUkTvDzriDIWvQT0WwVF5FIOBydfDDs92S-queaKgLBwt50SXJCZryLew5ODrwVsFGI4Et6MLqjS-cgWpCNwzcRqjBRsse6DXnex_zSRII4ODzKIfX4qdFBKZHO_BkTsK9DNkUayrr9cz8rFRK6TEH6XTVabgsyd6LP6PTxhpiII_pTYRSWk7CGMnm2nO0dKxzaFQ",
"use": "sig",
},
]
}
google_id_token = (
"eyJhbGciOiJSUzI1NiIsImtpZCI6IjhmYmJlZWE0MDMzMmQyYzBkMjdlMzdlMTkwN"
"GFmMjliNjQ1OTRlNTcifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5"
"jb20iLCJhdF9oYXNoIjoiUUY5RnRjcHlmbUFBanJuMHVyeUQ5dyIsImF1ZCI6IjQw"
"NzQwODcxODE5Mi5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwN"
"zkzMjQxNjk2NTIwMzIzNDA3NiIsImF6cCI6IjQwNzQwODcxODE5Mi5hcHBzLmdvb2"
"dsZXVzZXJjb250ZW50LmNvbSIsImlhdCI6MTQ2ODYyMjQ4MCwiZXhwIjoxNDY4NjI"
"2MDgwfQ.Nz6VREh7smvfVRWNHlbKZ6W_DX57akRUGrDTcns06ndAwrslwUlBeFsWY"
"RLon_tDw0QCeQCGvw7l1AT440UQBRP-mtqK_2Yny2JmIQ7Ll6UAIHRhXOD1uj9w5v"
"X0jyI1MbjDtODeDWWn_9EDJRBd4xmwKhAONuWodTgSi7qGe1UVmzseFNNkKdoo54d"
"XhCJiyiRAMnWB_FQDveRJghche131pd9O_E4Wj6hf_zCcMTaDaLDOmElcQe-WsKWA"
"A3YwHFEWOLO_7x6u4uGmhItPGH7zsOTzYxPYhZMSZusgVg9fbE1kSlHVSyQrcp_rR"
"WNz7vOIbvIlBR9Jrq5MIqbkkg"
)
class TestGetKeys:
def test_dict(self):
assert ({},) == jws._get_keys({})
def test_custom_object(self):
class MyDict(dict):
pass
mydict = MyDict()
assert (mydict,) == jws._get_keys(mydict)
def test_RFC7517_string(self):
key = '{"keys": [{}, {}]}'
assert [{}, {}] == jws._get_keys(key)
def test_RFC7517_jwk(self):
key = {"kty": "hsa", "k": "secret", "alg": "HS256", "use": "sig"}
assert (key,) == jws._get_keys(key)
def test_RFC7517_mapping(self):
key = {"keys": [{}, {}]}
assert [{}, {}] == jws._get_keys(key)
def test_string(self):
assert ("test",) == jws._get_keys("test")
def test_tuple(self):
assert ("test", "key") == jws._get_keys(("test", "key"))
def test_list(self):
assert ["test", "key"] == jws._get_keys(["test", "key"])
def test_jwk(self):
jwkey = jwk.construct("key", algorithm="HS256")
assert (jwkey,) == jws._get_keys(jwkey)
@pytest.mark.skipif(RSAKey is None, reason="RSA is not available")
class TestRSA:
def test_jwk_set(self, jwk_set):
# Would raise a JWSError if validation failed.
payload = jws.verify(google_id_token, jwk_set, ALGORITHMS.RS256)
iss = json.loads(payload.decode("utf-8"))["iss"]
assert iss == "https://accounts.google.com"
def test_jwk_set_failure(self, jwk_set):
# Remove the key that was used to sign this token.
del jwk_set["keys"][1]
with pytest.raises(JWSError):
payload = jws.verify(google_id_token, jwk_set, ALGORITHMS.RS256) # noqa: F841
def test_RSA256(self, payload):
token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS256)
assert jws.verify(token, rsa_public_key, ALGORITHMS.RS256) == payload
def test_RSA384(self, payload):
token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS384)
assert jws.verify(token, rsa_public_key, ALGORITHMS.RS384) == payload
def test_RSA512(self, payload):
token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS512)
assert jws.verify(token, rsa_public_key, ALGORITHMS.RS512) == payload
def test_wrong_alg(self, payload):
token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS256)
with pytest.raises(JWSError):
jws.verify(token, rsa_public_key, ALGORITHMS.RS384)
def test_wrong_key(self, payload):
token = jws.sign(payload, rsa_private_key, algorithm=ALGORITHMS.RS256)
with pytest.raises(JWSError):
jws.verify(token, rsa_public_key, ALGORITHMS.HS256)
def test_private_verify_raises_warning(self, payload):
token = jws.sign(payload, rsa_private_key, algorithm="RS256")
# verify with public
jws.verify(token, rsa_public_key, algorithms="RS256")
with warnings.catch_warnings(record=True) as w:
# verify with private raises warning
jws.verify(token, rsa_private_key, algorithms="RS256")
assert ("Attempting to verify a message with a private key. " "This is not recommended.") == str(
w[-1].message
)
ec_private_key = """-----BEGIN EC PRIVATE KEY-----
MIHcAgEBBEIBzs13YUnYbLfYXTz4SG4DE4rPmsL3wBTdy34JcO+BDpI+NDZ0pqam
UM/1sGZT+8hqUjSeQo6oz+Mx0VS6SJh31zygBwYFK4EEACOhgYkDgYYABACYencK
8pm/iAeDVptaEZTZwNT0yW/muVwvvwkzS/D6GDCLsnLfI6e1FwEnTJF/GPFUlN5l
9JSLxsbbFdM1muI+NgBE6ZLR1GZWjsNzu7BOB8RMy/mvSTokZwyIaWvWSn3hOF4i
/4iczJnzJhUKDqHe5dJ//PLd7R3WVHxkvv7jFNTKYg==
-----END EC PRIVATE KEY-----"""
ec_public_key = """-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAmHp3CvKZv4gHg1abWhGU2cDU9Mlv
5rlcL78JM0vw+hgwi7Jy3yOntRcBJ0yRfxjxVJTeZfSUi8bG2xXTNZriPjYAROmS
0dRmVo7Dc7uwTgfETMv5r0k6JGcMiGlr1kp94TheIv+InMyZ8yYVCg6h3uXSf/zy
3e0d1lR8ZL7+4xTUymI=
-----END PUBLIC KEY-----"""
class TestEC:
def test_EC256(self, payload):
token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES256)
assert jws.verify(token, ec_public_key, ALGORITHMS.ES256) == payload
def test_EC384(self, payload):
token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES384)
assert jws.verify(token, ec_public_key, ALGORITHMS.ES384) == payload
def test_EC512(self, payload):
token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES512)
assert jws.verify(token, ec_public_key, ALGORITHMS.ES512) == payload
def test_wrong_alg(self, payload):
token = jws.sign(payload, ec_private_key, algorithm=ALGORITHMS.ES256)
with pytest.raises(JWSError):
jws.verify(token, rsa_public_key, ALGORITHMS.ES384)
class TestLoad:
def test_header_not_mapping(self):
token = "WyJ0ZXN0Il0.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_claims_not_mapping(self):
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.WyJ0ZXN0Il0.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])
def test_signature_padding(self):
token = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.aatvagLDLoaiJKxOKqpBXSEGy7SYSifZhjntgm9ctpyj8"
with pytest.raises(JWSError):
jws.verify(token, "secret", ["HS256"])