|
2 | 2 |
|
3 | 3 | from jwt.algorithms import Algorithm, HMACAlgorithm, NoneAlgorithm |
4 | 4 | from jwt.exceptions import InvalidKeyError |
| 5 | +from jwt.utils import base64url_decode |
5 | 6 |
|
6 | 7 | import pytest |
7 | 8 |
|
| 9 | +from .keys import load_hmac_key |
8 | 10 | from .utils import ensure_bytes, ensure_unicode, key_path |
9 | 11 |
|
10 | 12 | try: |
11 | 13 | from jwt.algorithms import RSAAlgorithm, ECAlgorithm, RSAPSSAlgorithm |
12 | | - |
| 14 | + from .keys import load_rsa_pub_key, load_ec_pub_key |
13 | 15 | has_crypto = True |
14 | 16 | except ImportError: |
15 | 17 | has_crypto = False |
@@ -257,3 +259,102 @@ def test_rsa_pss_verify_should_return_true_if_signature_valid(self): |
257 | 259 |
|
258 | 260 | result = algo.verify(jwt_message, jwt_pub_key, jwt_sig) |
259 | 261 | assert result |
| 262 | + |
| 263 | + |
| 264 | +class TestAlgorithmsCookbook: |
| 265 | + """ |
| 266 | + These test vectors were taken from IETF JOSE Cookbook Draft |
| 267 | + (https://www.ietf.org/id/draft-ietf-jose-cookbook-08.txt) |
| 268 | + """ |
| 269 | + |
| 270 | + def test_hmac_verify_should_return_true_for_test_vector(self): |
| 271 | + signing_input = ensure_bytes( |
| 272 | + 'eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZ' |
| 273 | + 'jMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ' |
| 274 | + '29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIG' |
| 275 | + 'lmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmc' |
| 276 | + 'gd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4' |
| 277 | + ) |
| 278 | + |
| 279 | + signature = base64url_decode(ensure_bytes( |
| 280 | + 's0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0' |
| 281 | + )) |
| 282 | + |
| 283 | + algo = HMACAlgorithm(HMACAlgorithm.SHA256) |
| 284 | + key = algo.prepare_key(load_hmac_key()) |
| 285 | + |
| 286 | + result = algo.verify(signing_input, key, signature) |
| 287 | + assert result |
| 288 | + |
| 289 | + @pytest.mark.skipif(not has_crypto, reason='Not supported without cryptography library') |
| 290 | + def test_rsa_verify_should_return_true_for_test_vector(self): |
| 291 | + signing_input = ensure_bytes( |
| 292 | + 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhb' |
| 293 | + 'XBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb' |
| 294 | + '3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdS' |
| 295 | + 'Bkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmU' |
| 296 | + 'geW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4' |
| 297 | + ) |
| 298 | + |
| 299 | + signature = base64url_decode(ensure_bytes( |
| 300 | + 'MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZop' |
| 301 | + 'dHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJ' |
| 302 | + 'K3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4' |
| 303 | + 'QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic' |
| 304 | + '1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogor' |
| 305 | + 'ee7vjbU5y18kDquDg' |
| 306 | + )) |
| 307 | + |
| 308 | + algo = RSAAlgorithm(RSAAlgorithm.SHA256) |
| 309 | + key = algo.prepare_key(load_rsa_pub_key()) |
| 310 | + |
| 311 | + result = algo.verify(signing_input, key, signature) |
| 312 | + assert result |
| 313 | + |
| 314 | + @pytest.mark.skipif(True, "I'm not 100% sure if this test is correct") |
| 315 | + @pytest.mark.skipif(not has_crypto, reason='Not supported without cryptography library') |
| 316 | + def test_rsapss_verify_should_return_true_for_test_vector(self): |
| 317 | + signing_input = ensure_bytes( |
| 318 | + 'eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhb' |
| 319 | + 'XBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb' |
| 320 | + '3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdS' |
| 321 | + 'Bkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmU' |
| 322 | + 'geW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4' |
| 323 | + ) |
| 324 | + |
| 325 | + signature = base64url_decode(ensure_bytes( |
| 326 | + 'cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN' |
| 327 | + '6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvW' |
| 328 | + 'Xzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ij' |
| 329 | + 'Q7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6ui' |
| 330 | + 'P1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmW' |
| 331 | + 'jwZ6oD4ifKo8DYM-X72Eaw' |
| 332 | + )) |
| 333 | + |
| 334 | + algo = RSAPSSAlgorithm(RSAPSSAlgorithm.SHA384) |
| 335 | + key = algo.prepare_key(load_rsa_pub_key()) |
| 336 | + |
| 337 | + result = algo.verify(signing_input, key, signature) |
| 338 | + assert result |
| 339 | + |
| 340 | + @pytest.mark.skipif(not has_crypto, reason='Not supported without cryptography library') |
| 341 | + def test_ec_verify_should_return_true_for_test_vector(self): |
| 342 | + signing_input = ensure_bytes( |
| 343 | + 'eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhb' |
| 344 | + 'XBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb' |
| 345 | + '3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdS' |
| 346 | + 'Bkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmU' |
| 347 | + 'geW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4' |
| 348 | + ) |
| 349 | + |
| 350 | + signature = base64url_decode(ensure_bytes( |
| 351 | + 'AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9P' |
| 352 | + 'lon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890j' |
| 353 | + 'l8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2' |
| 354 | + )) |
| 355 | + |
| 356 | + algo = ECAlgorithm(ECAlgorithm.SHA512) |
| 357 | + key = algo.prepare_key(load_ec_pub_key()) |
| 358 | + |
| 359 | + result = algo.verify(signing_input, key, signature) |
| 360 | + assert result |
0 commit comments