Skip to content

Commit 86d9c50

Browse files
author
Gasper Zejn
committed
Try importing RSAKey and ECKey at top of jwk module, where they're currently expected to be (for compatibility), but pass if it fails. Maybe user just needs one of them, which works, or HMACKey. Function jwk.get_key will still try to import RSAKey or ECKey if needed, and throw an ImportError if unsuccessful.
1 parent 78b86d4 commit 86d9c50

File tree

4 files changed

+33
-14
lines changed

4 files changed

+33
-14
lines changed

jose/backends/pycrypto_backend.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,7 @@ def to_pem(self):
117117
begin = b'-----BEGIN RSA PUBLIC KEY-----'
118118
end = b'-----END RSA PUBLIC KEY-----'
119119
if pem.startswith(begin) and pem.strip().endswith(end):
120-
pem = b'-----BEGIN PUBLIC KEY-----' + pem.strip()[len(begin):-len(end)] + b'-----END PUBLIC KEY-----\n'
120+
pem = b'-----BEGIN PUBLIC KEY-----' + pem.strip()[len(begin):-len(end)] + b'-----END PUBLIC KEY-----'
121+
if not pem.endswith(b'\n'):
122+
pem = pem + b'\n'
121123
return pem

jose/jwk.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88
from jose.utils import base64url_decode
99
from jose.utils import constant_time_string_compare
1010
from jose.backends.base import Key
11-
from jose.backends import RSAKey, ECKey
11+
12+
try:
13+
from jose.backends import RSAKey
14+
except ImportError:
15+
pass
16+
17+
try:
18+
from jose.backends import ECKey
19+
except ImportError:
20+
pass
1221

1322

1423
def get_key(algorithm):
@@ -17,8 +26,10 @@ def get_key(algorithm):
1726
elif algorithm in ALGORITHMS.HMAC:
1827
return HMACKey
1928
elif algorithm in ALGORITHMS.RSA:
29+
from jose.backends import RSAKey
2030
return RSAKey
2131
elif algorithm in ALGORITHMS.EC:
32+
from jose.backends import ECKey
2233
return ECKey
2334
return None
2435

tests/algorithms/test_RSA.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
import sys
33

4-
from jose.jwk import RSAKey
4+
from jose.backends.pycrypto_backend import RSAKey
55
from jose.backends.cryptography_backend import CryptographyRSAKey
66
from jose.constants import ALGORITHMS
77
from jose.exceptions import JOSEError
@@ -135,11 +135,13 @@ def test_bad_cert(self):
135135

136136
def test_signing_parity(self):
137137
key1 = RSAKey(private_key, ALGORITHMS.RS256)
138-
public_key = key1.public_key().to_pem().decode('utf-8')
138+
public_key = key1.public_key().to_pem()
139139
vkey1 = RSAKey(public_key, ALGORITHMS.RS256)
140140
key2 = CryptographyRSAKey(private_key, ALGORITHMS.RS256)
141141
vkey2 = CryptographyRSAKey(public_key, ALGORITHMS.RS256)
142142

143+
assert key2.public_key().to_pem() == public_key
144+
143145
msg = b'test'
144146
sig1 = key1.sign(msg)
145147
sig2 = key2.sign(msg)

tests/test_jwk.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from jose import jwk
22
from jose.exceptions import JWKError
3-
from jose.backends.cryptography_backend import CryptographyECKey
3+
from jose.backends.base import Key
4+
from jose.backends.pycrypto_backend import RSAKey
5+
from jose.backends.cryptography_backend import CryptographyECKey, CryptographyRSAKey
46
from jose.backends.ecdsa_backend import ECDSAECKey
57

68
import pytest
@@ -48,21 +50,21 @@ def test_invalid_hash_alg(self):
4850
key = jwk.HMACKey(hmac_key, 'RS512')
4951

5052
with pytest.raises(JWKError):
51-
key = jwk.RSAKey(rsa_key, 'HS512')
53+
key = RSAKey(rsa_key, 'HS512')
5254

5355
with pytest.raises(JWKError):
54-
key = jwk.ECKey(ec_key, 'RS512')
56+
key = ECDSAECKey(ec_key, 'RS512')
5557

5658
def test_invalid_jwk(self):
5759

5860
with pytest.raises(JWKError):
5961
key = jwk.HMACKey(rsa_key, 'HS256')
6062

6163
with pytest.raises(JWKError):
62-
key = jwk.RSAKey(hmac_key, 'RS256')
64+
key = RSAKey(hmac_key, 'RS256')
6365

6466
with pytest.raises(JWKError):
65-
key = jwk.ECKey(rsa_key, 'ES256')
67+
key = ECDSAECKey(rsa_key, 'ES256')
6668

6769
def test_RSAKey_errors(self):
6870

@@ -75,7 +77,7 @@ def test_RSAKey_errors(self):
7577
}
7678

7779
with pytest.raises(JWKError):
78-
key = jwk.RSAKey(rsa_key, 'HS256')
80+
key = RSAKey(rsa_key, 'HS256')
7981

8082
rsa_key = {
8183
"kty": "oct",
@@ -86,7 +88,7 @@ def test_RSAKey_errors(self):
8688
}
8789

8890
with pytest.raises(JWKError):
89-
key = jwk.RSAKey(rsa_key, 'RS256')
91+
key = RSAKey(rsa_key, 'RS256')
9092

9193
def test_construct_from_jwk(self):
9294

@@ -123,9 +125,11 @@ def test_construct_from_jwk_missing_alg(self):
123125
key = jwk.construct("key", algorithm="NONEXISTENT")
124126

125127
def test_get_key(self):
126-
assert jwk.get_key("HS256") == jwk.HMACKey
127-
assert jwk.get_key("RS256") == jwk.RSAKey
128-
assert jwk.get_key("ES256") == jwk.ECKey
128+
hs_key = jwk.get_key("HS256")
129+
assert hs_key == jwk.HMACKey
130+
assert issubclass(hs_key, Key)
131+
assert issubclass(jwk.get_key("RS256"), Key)
132+
assert issubclass(jwk.get_key("ES256"), Key)
129133

130134
assert jwk.get_key("NONEXISTENT") == None
131135

0 commit comments

Comments
 (0)