Skip to content

Commit fe46f39

Browse files
committed
fix: add warnings when using str/bytes as key
1 parent 2b1078d commit fe46f39

11 files changed

Lines changed: 125 additions & 84 deletions

File tree

src/joserfc/jwk.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import typing as t
2+
import warnings
23
from ._keys import (
34
JWKRegistry,
45
KeySet,
@@ -78,5 +79,10 @@ def guess_key(key: KeyFlexible, obj: GuestProtocol, use_random: bool = False) ->
7879

7980
def _normalize_key(key: KeyBase) -> t.Union[Key, KeySet]:
8081
if isinstance(key, (str, bytes)):
82+
warnings.warn(
83+
"Please use a Key object instead of bytes or string.",
84+
DeprecationWarning,
85+
stacklevel=2,
86+
)
8187
return OctKey.import_key(key)
8288
return key

src/joserfc/jws.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,15 +295,17 @@ def detach_content(value: DetachValue) -> DetachValue:
295295
.. code-block:: python
296296
297297
>>> from joserfc import jws
298-
>>> encoded_text = jws.serialize_compact({"alg": "HS256"}, b"hello", "secret")
298+
>>> from joserfc.jwk import OctKey
299+
>>> key = OctKey.import_key("secret")
300+
>>> encoded_text = jws.serialize_compact({"alg": "HS256"}, b"hello", key)
299301
>>> jws.detach_content(encoded_text)
300302
'eyJhbGciOiJIUzI1NiJ9..UYmO_lPAY5V0Wf4KZsfhiYs1SxqXPhxvjuYqellDV5A'
301303
302304
You can also detach the JSON serialization:
303305
304306
.. code-block:: python
305307
306-
>>> obj = jws.serialize_json({"protected": {"alg": "HS256"}}, b"hello", "secret")
308+
>>> obj = jws.serialize_json({"protected": {"alg": "HS256"}}, b"hello", key)
307309
>>> jws.detach_content(obj)
308310
{
309311
'payload': '',

tests/jwe/test_compact.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ def test_ECDH_ES_with_OKP_key(self):
9898
)
9999

100100
def test_dir_alg(self):
101-
self.assertRaises(InvalidKeyLengthError, encrypt_compact, {"alg": "dir", "enc": "A128GCM"}, b"j", "secret")
101+
key = OctKey.import_key("secret")
102+
self.assertRaises(
103+
InvalidKeyLengthError,
104+
encrypt_compact, {"alg": "dir", "enc": "A128GCM"}, b"j", key
105+
)
102106
for enc in JWE_ENC_MODELS:
103107
key = OctKey.generate_key(enc.cek_size)
104108
self.run_case('dir', enc.name, key, key)

tests/jwe/test_errors.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,34 @@
1212

1313
class TestJWEErrors(TestCase):
1414
def test_dir_with_invalid_key_type(self):
15-
key = load_key("ec-p256-private.pem")
15+
key1 = load_key("ec-p256-private.pem")
1616
protected = {"alg": "dir", "enc": "A128CBC-HS256"}
1717
self.assertRaises(
1818
InvalidKeyTypeError,
1919
jwe.encrypt_compact,
20-
protected, b"i", key,
20+
protected, b"i", key1,
2121
)
2222

2323
protected = {"alg": "A128KW", "enc": "A128CBC-HS256"}
2424
self.assertRaises(
2525
InvalidKeyTypeError,
2626
jwe.encrypt_compact,
27-
protected, b"i", key,
27+
protected, b"i", key1,
2828
)
2929

3030
protected = {"alg": "ECDH-ES+A128KW", "enc": "A128CBC-HS256"}
31+
key2 = OctKey.import_key("secret")
3132
self.assertRaises(
3233
InvalidKeyTypeError,
3334
jwe.encrypt_compact,
34-
protected, b"i", "secret",
35+
protected, b"i", key2,
3536
)
3637

3738
protected = {"alg": "PBES2-HS256+A128KW", "enc": "A128CBC-HS256"}
3839
self.assertRaises(
3940
InvalidKeyTypeError,
4041
jwe.encrypt_compact,
41-
protected, b"i", key,
42+
protected, b"i", key1,
4243
algorithms=["PBES2-HS256+A128KW", "A128CBC-HS256"]
4344
)
4445

@@ -64,24 +65,26 @@ def test_A128KW_unwrap_error(self):
6465

6566
def test_invalid_alg(self):
6667
protected = {"alg": "INVALID", "enc": "A128CBC-HS256"}
68+
key = OctKey.import_key("secret")
6769
self.assertRaises(
6870
ValueError,
6971
jwe.encrypt_compact,
70-
protected, b"i", "secret"
72+
protected, b"i", key
7173
)
7274

7375
def test_invalid_key_length(self):
7476
protected = {"alg": "dir", "enc": "A128CBC-HS256"}
77+
key = OctKey.import_key("secret")
7578
self.assertRaises(
7679
InvalidKeyLengthError,
7780
jwe.encrypt_compact,
78-
protected, b"i", "secret"
81+
protected, b"i", key
7982
)
8083
protected = {"alg": "A128KW", "enc": "A128CBC-HS256"}
8184
self.assertRaises(
8285
InvalidKeyLengthError,
8386
jwe.encrypt_compact,
84-
protected, b"i", "secret"
87+
protected, b"i", key
8588
)
8689
protected = {"alg": "RSA-OAEP", "enc": "A128CBC-HS256"}
8790
rsa_key = RSAKey.generate_key(1024)

tests/jwk/test_key_methods.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ def set_kid(self, kid):
2424

2525
class TestKeyMethods(TestCase):
2626
def test_guess_str_key(self):
27-
key = guess_key("key", Guest())
28-
self.assertIsInstance(key, OctKey)
27+
self.assertRaises(
28+
DeprecationWarning,
29+
guess_key, "key", Guest(),
30+
)
2931

3032
def test_guess_bytes_key(self):
31-
key = guess_key(b"key", Guest())
32-
self.assertIsInstance(key, OctKey)
33+
self.assertRaises(
34+
DeprecationWarning,
35+
guess_key, b"key", Guest(),
36+
)
3337

3438
def test_guess_callable_key(self):
3539
oct_key = OctKey.generate_key(parameters={'kid': '1'})
@@ -44,31 +48,34 @@ def key_func2(obj):
4448
def key_func3(obj):
4549
return KeySet([oct_key, rsa_key])
4650

47-
key = guess_key(key_func1, Guest())
48-
self.assertIsInstance(key, OctKey)
51+
self.assertRaises(
52+
DeprecationWarning,
53+
guess_key, key_func1, Guest(),
54+
)
4955

50-
key = guess_key(key_func2, Guest())
51-
self.assertIsInstance(key, RSAKey)
56+
key2 = guess_key(key_func2, Guest())
57+
self.assertIsInstance(key2, RSAKey)
5258

5359
guest = Guest()
5460
guest.set_kid('2')
55-
key = guess_key(key_func3, guest)
56-
self.assertIsInstance(key, RSAKey)
61+
key3 = guess_key(key_func3, guest)
62+
self.assertIsInstance(key3, RSAKey)
5763

5864
def test_guess_key_set(self):
5965
key_set = KeySet([OctKey.generate_key(), RSAKey.generate_key()])
6066
guest = Guest()
6167
guest._headers["alg"] = "HS256"
68+
6269
self.assertRaises(ValueError, guess_key, key_set, guest)
63-
key = guess_key(key_set, guest, True)
64-
self.assertIsInstance(key, OctKey)
65-
key = guess_key(key_set, guest)
70+
key1 = guess_key(key_set, guest, True)
71+
self.assertIsInstance(key1, OctKey)
72+
guess_key(key_set, guest)
6673

6774
guest = Guest()
6875
guest._headers["alg"] = "RS256"
6976
self.assertRaises(ValueError, guess_key, key_set, guest)
70-
key = guess_key(key_set, guest, True)
71-
self.assertIsInstance(key, RSAKey)
77+
key2 = guess_key(key_set, guest, True)
78+
self.assertIsInstance(key2, RSAKey)
7279

7380
guest = Guest()
7481
guest._headers["alg"] = "ES256"

tests/jws/test_compact.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,42 @@
66

77
class TestCompact(TestCase):
88
def test_registry_is_none(self):
9-
value = serialize_compact({"alg": "HS256"}, b"foo", "secret")
9+
key = OctKey.import_key("secret")
10+
value = serialize_compact({"alg": "HS256"}, b"foo", key)
1011
expected = 'eyJhbGciOiJIUzI1NiJ9.Zm9v.0pehoi-RMZM1jl-4TP_C4Y6BJ-bcmsuzfDyQpkpJkh0'
1112
self.assertEqual(value, expected)
1213

13-
obj = deserialize_compact(value, "secret")
14+
obj = deserialize_compact(value, key)
1415
self.assertEqual(obj.payload, b"foo")
1516

1617
def test_bad_signature_error(self):
18+
key = OctKey.import_key("incorrect")
1719
value = b'eyJhbGciOiJIUzI1NiJ9.Zm9v.0pehoi-RMZM1jl-4TP_C4Y6BJ-bcmsuzfDyQpkpJkh0'
18-
self.assertRaises(BadSignatureError, deserialize_compact, value, "incorrect")
20+
self.assertRaises(BadSignatureError, deserialize_compact, value, key)
1921

2022
def test_raise_none_supported_alg(self):
21-
self.assertRaises(ValueError, serialize_compact, {"alg": "HS512"}, b"foo", "secret")
22-
self.assertRaises(ValueError, serialize_compact, {"alg": "NOT"}, b"foo", "secret")
23+
key = OctKey.import_key("secret")
24+
self.assertRaises(ValueError, serialize_compact, {"alg": "HS512"}, b"foo", key)
25+
self.assertRaises(ValueError, serialize_compact, {"alg": "NOT"}, b"foo", key)
2326

2427
def test_invalid_length(self):
25-
self.assertRaises(ValueError, deserialize_compact, b'a.b.c.d', "secret")
28+
key = OctKey.import_key("secret")
29+
self.assertRaises(ValueError, deserialize_compact, b'a.b.c.d', key)
2630

2731
def test_no_invalid_header(self):
2832
# invalid base64
2933
value = b'abc.Zm9v.0pehoi'
30-
self.assertRaises(DecodeError, deserialize_compact, value, "secret")
34+
key = OctKey.import_key("secret")
35+
self.assertRaises(DecodeError, deserialize_compact, value, key)
3136

3237
# no alg value
3338
value = b'eyJhIjoiYiJ9.Zm9v.0pehoi'
34-
self.assertRaises(MissingAlgorithmError, deserialize_compact, value, "secret")
39+
self.assertRaises(MissingAlgorithmError, deserialize_compact, value, key)
3540

3641
def test_invalid_payload(self):
3742
value = b'eyJhbGciOiJIUzI1NiJ9.a$b.0pehoi'
38-
self.assertRaises(DecodeError, deserialize_compact, value, "secret")
43+
key = OctKey.import_key("secret")
44+
self.assertRaises(DecodeError, deserialize_compact, value, key)
3945

4046
def test_with_key_set(self):
4147
keys = KeySet([
@@ -54,7 +60,8 @@ def test_with_key_set(self):
5460

5561
def test_strict_check_header(self):
5662
header = {"alg": "HS256", "custom": "hi"}
57-
self.assertRaises(ValueError, serialize_compact, header, b"hi", "secret")
63+
key = OctKey.import_key("secret")
64+
self.assertRaises(ValueError, serialize_compact, header, b"hi", key)
5865

5966
registry = JWSRegistry(strict_check_header=False)
60-
serialize_compact(header, b"hi", "secret", registry=registry)
67+
serialize_compact(header, b"hi", key, registry=registry)

tests/jws/test_errors.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,92 +15,97 @@
1515

1616
class TestJWSErrors(TestCase):
1717
def test_without_alg(self):
18+
key = OctKey.import_key("secret")
1819
# missing alg
1920
self.assertRaises(
2021
ValueError,
2122
jws.serialize_compact,
22-
{"kid": "123"}, "i", "secret"
23+
{"kid": "123"}, "i", key
2324
)
2425

2526
def test_none_alg(self):
2627
header = {"alg": "none"}
28+
key = OctKey.import_key("secret")
2729
text = jws.serialize_compact(
28-
header, "i", "secret",
30+
header, "i", key,
2931
algorithms=["none"]
3032
)
3133
self.assertRaises(
3234
BadSignatureError,
3335
jws.deserialize_compact,
34-
text, "secret",
36+
text, key,
3537
algorithms=["none"]
3638
)
3739

3840
def test_header_invalid_type(self):
3941
# kid should be a string
4042
header = {"alg": "HS256", "kid": 123}
43+
key = OctKey.import_key("secret")
4144
self.assertRaises(
4245
ValueError,
4346
jws.serialize_compact,
44-
header, "i", "secret",
47+
header, "i", key,
4548
)
4649

4750
# jwk should be a dict
4851
header = {"alg": "HS256", "jwk": "dict"}
4952
self.assertRaises(
5053
ValueError,
5154
jws.serialize_compact,
52-
header, "i", "secret",
55+
header, "i", key,
5356
)
5457

5558
# jku should be a URL
5659
header = {"alg": "HS256", "jku": "url"}
5760
self.assertRaises(
5861
ValueError,
5962
jws.serialize_compact,
60-
header, "i", "secret",
63+
header, "i", key,
6164
)
6265

6366
# x5c should be a chain of string
6467
header = {"alg": "HS256", "x5c": "url"}
6568
self.assertRaises(
6669
ValueError,
6770
jws.serialize_compact,
68-
header, "i", "secret",
71+
header, "i", key,
6972
)
7073
header = {"alg": "HS256", "x5c": [1, 2]}
7174
self.assertRaises(
7275
ValueError,
7376
jws.serialize_compact,
74-
header, "i", "secret",
77+
header, "i", key,
7578
)
7679

7780
def test_crit_header(self):
7881
header = {"alg": "HS256", "crit": ["kid"]}
82+
key = OctKey.import_key("secret")
7983
# missing kid header
8084
self.assertRaises(
8185
ValueError,
8286
jws.serialize_compact,
83-
header, "i", "secret",
87+
header, "i", key,
8488
)
8589

8690
header = {"alg": "HS256", "kid": "1", "crit": ["kid"]}
87-
jws.serialize_compact(header, "i", "secret")
91+
jws.serialize_compact(header, "i", key)
8892

8993
def test_extra_header(self):
9094
header = {"alg": "HS256", "extra": "hi"}
95+
key = OctKey.import_key("secret")
9196
self.assertRaises(
9297
ValueError,
9398
jws.serialize_compact,
94-
header, "i", "secret",
99+
header, "i", key,
95100
)
96101
# bypass extra header
97102
registry = jws.JWSRegistry(strict_check_header=False)
98-
jws.serialize_compact(header, "i", "secret", registry=registry)
103+
jws.serialize_compact(header, "i", key, registry=registry)
99104

100105
# or use a header registry
101106
extra_header = {"extra": HeaderParameter("Extra header", "str", False)}
102107
registry = jws.JWSRegistry(header_registry=extra_header)
103-
jws.serialize_compact(header, "i", "secret", registry=registry)
108+
jws.serialize_compact(header, "i", key, registry=registry)
104109

105110
def test_rsa_invalid_signature(self):
106111
key1 = RSAKey.generate_key()

0 commit comments

Comments
 (0)