Skip to content

Commit d5e57e6

Browse files
committed
Increased test coverage
1 parent edab740 commit d5e57e6

File tree

6 files changed

+155
-45
lines changed

6 files changed

+155
-45
lines changed

src/cryptojwt/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
except ImportError:
1616
pass
1717

18-
__version__ = '0.6.3'
18+
__version__ = '0.6.4'
1919

2020
logger = logging.getLogger(__name__)
2121

src/cryptojwt/jwe/jwe.py

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -85,29 +85,15 @@ def encrypt(self, keys=None, cek="", iv="", **kwargs):
8585

8686
# Determine Encryption Class by Algorithm
8787
if _alg in ["RSA-OAEP", "RSA-OAEP-256", "RSA1_5"]:
88-
keys = [k for k in keys if isinstance(k, RSAKey)]
8988
encrypter = JWE_RSA(self.msg, **self._dict)
9089
elif _alg.startswith("A") and _alg.endswith("KW"):
91-
keys = [k for k in keys if isinstance(k, SYMKey)]
9290
encrypter = JWE_SYM(self.msg, **self._dict)
93-
elif _alg.startswith("ECDH-ES"):
94-
keys = [k for k in keys if isinstance(k, ECKey)]
95-
if not keys:
96-
logger.error(KEY_ERR.format(_alg))
97-
raise NoSuitableEncryptionKey(_alg)
98-
91+
else: # _alg.startswith("ECDH-ES"):
9992
encrypter = JWE_EC(**self._dict)
10093
cek, encrypted_key, iv, params, eprivk = encrypter.enc_setup(
10194
self.msg, key=keys[0], **self._dict)
10295
kwargs["encrypted_key"] = encrypted_key
10396
kwargs["params"] = params
104-
else:
105-
logger.error("'{}' is not a supported algorithm".format(_alg))
106-
raise NotSupportedAlgorithm
107-
108-
if not keys:
109-
logger.error(KEY_ERR.format(_alg))
110-
raise NoSuitableEncryptionKey(_alg)
11197

11298
if cek:
11399
kwargs["cek"] = cek
@@ -120,10 +106,8 @@ def encrypt(self, keys=None, cek="", iv="", **kwargs):
120106
_key = key.key
121107
elif isinstance(key, ECKey):
122108
_key = key.public_key()
123-
elif isinstance(key, RSAKey):
124-
_key = key.public_key()
125-
else:
126-
raise ValueError('Unknown key type')
109+
else: # isinstance(key, RSAKey):
110+
_key = key.public_key()
127111

128112
if key.kid:
129113
encrypter["kid"] = key.kid
@@ -138,8 +122,8 @@ def encrypt(self, keys=None, cek="", iv="", **kwargs):
138122
"Encrypted message using key with kid={}".format(key.kid))
139123
return token
140124

141-
logger.error("Could not find any suitable encryption key")
142-
raise NoSuitableEncryptionKey()
125+
# logger.error("Could not find any suitable encryption key")
126+
# raise NoSuitableEncryptionKey()
143127

144128
def decrypt(self, token=None, keys=None, alg=None, cek=None):
145129
if token:
@@ -174,11 +158,6 @@ def decrypt(self, token=None, keys=None, alg=None, cek=None):
174158
elif _alg.startswith("A") and _alg.endswith("KW"):
175159
decrypter = JWE_SYM(self.msg, **self._dict)
176160
elif _alg.startswith("ECDH-ES"):
177-
178-
# ECDH-ES Requires the Server ECDH-ES Key to be set
179-
if not keys:
180-
raise NoSuitableECDHKey(_alg)
181-
182161
decrypter = JWE_EC(**self._dict)
183162

184163
if isinstance(keys[0], AsymmetricKey):

src/cryptojwt/jwe/jwe_ec.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ def enc_setup(self, msg, key=None, auth_data=b'', **kwargs):
7676
apv = get_random_bytes(16)
7777

7878
# Handle Local Key and Ephemeral Public Key
79-
if not key:
80-
raise Exception("EC Key Required for ECDH-ES JWE Encryption Setup")
79+
if not key or not isinstance(key, ECKey):
80+
raise ValueError("EC Key Required for ECDH-ES JWE Encryption Setup")
8181

8282
# epk is either an Elliptic curve key instance or a JWK description of
8383
# one. This key belongs to the entity on the other side.
@@ -88,10 +88,11 @@ def enc_setup(self, msg, key=None, auth_data=b'', **kwargs):
8888
default_backend())
8989
epk = ECKey().load_key(_epk.public_key())
9090
else:
91-
if isinstance(_epk, ec.EllipticCurvePublicKey):
91+
if isinstance(_epk, ec.EllipticCurvePrivateKey):
9292
epk = ECKey().load_key(_epk)
9393
elif isinstance(_epk, ECKey):
9494
epk = _epk
95+
_epk = epk.private_key()
9596
else:
9697
raise ValueError("epk of a type I can't handle")
9798

@@ -113,7 +114,7 @@ def enc_setup(self, msg, key=None, auth_data=b'', **kwargs):
113114
try:
114115
dk_len = KEY_LEN[self.enc]
115116
except KeyError:
116-
raise Exception(
117+
raise ValueError(
117118
"Unknown key length for algorithm %s" % self.enc)
118119

119120
cek = ecdh_derive_key(_epk, key.pub_key, apu, apv,

src/cryptojwt/jwe/jwekey.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def _generate_key(encalg, cek=""):
3232
try:
3333
_key = get_random_bytes(KEY_LEN_BYTES[encalg])
3434
except KeyError:
35-
raise Exception("Unsupported encryption algorithm %s" % encalg)
35+
raise ValueError("Unsupported encryption algorithm %s" % encalg)
3636

3737
return _key
3838

src/cryptojwt/jwx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def pick_keys(self, keys, use="", alg=""):
191191
_k = self.alg2keytype(alg)
192192
if _k is None:
193193
logger.error("Unknown algorithm '%s'" % alg)
194-
return []
194+
raise ValueError('Unknown cryptography algorithm')
195195

196196
logger.debug("Picking key by key type={0}".format(_k))
197197
_kty = [_k.lower(), _k.upper(), _k.lower().encode("utf-8"),

tests/test_07_jwe.py

Lines changed: 142 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
import pytest
88
from cryptography.hazmat.backends import default_backend
99
from cryptography.hazmat.primitives.asymmetric import ec
10-
from cryptojwt.exception import MissingKey
10+
from oic import rndstr
11+
12+
from cryptojwt.exception import MissingKey, BadSyntax, HeaderError
1113
from cryptojwt.exception import Unsupported
1214
from cryptojwt.exception import VerificationError
1315
from cryptojwt.jwe.exception import UnsupportedBitLength, \
14-
NoSuitableEncryptionKey
16+
NoSuitableEncryptionKey, WrongEncryptionAlgorithm, NoSuitableDecryptionKey
1517

16-
from cryptojwt.utils import b64e
18+
from cryptojwt.utils import b64e, as_bytes
1719

1820
from cryptojwt.jwe.aes import AES_CBCEncrypter
1921
from cryptojwt.jwe.aes import AES_GCMEncrypter
@@ -349,6 +351,50 @@ def test_ecdh_encrypt_decrypt_keywrapped_key():
349351
assert msg == plain
350352

351353

354+
def test_ecdh_enc_setup_wrong_key():
355+
jwenc = JWE_EC(plain, alg="ECDH-ES+A128KW", enc="A128GCM")
356+
with pytest.raises(ValueError):
357+
jwenc.enc_setup(plain, key=priv_key)
358+
359+
360+
def test_ecdh_enc_setup_enk():
361+
jwenc = JWE_EC(plain, alg="ECDH-ES+A128KW", enc="A128GCM")
362+
assert jwenc.enc_setup(plain, key=eck_bob, epk=alice)
363+
364+
365+
def test_ecdh_enc_setup_enk_eckey():
366+
jwenc = JWE_EC(plain, alg="ECDH-ES+A128KW", enc="A128GCM")
367+
assert jwenc.enc_setup(plain, key=eck_bob, epk=eck_alice)
368+
369+
370+
def test_ecdh_setup_iv():
371+
jwenc = JWE_EC(plain, alg="ECDH-ES+A128KW", enc="A128GCM")
372+
iv0 = rndstr(16)
373+
cek, encrypted_key, iv, params, ret_epk = jwenc.enc_setup(plain, iv=iv0,
374+
key=eck_bob)
375+
assert iv == iv0
376+
377+
378+
def test_ecdh_setup_cek():
379+
jwenc = JWE_EC(plain, alg="ECDH-ES+A128KW", enc="A128GCM")
380+
cek0 = as_bytes(rndstr(16))
381+
cek, encrypted_key, iv, params, ret_epk = jwenc.enc_setup(plain, cek=cek0,
382+
key=eck_bob)
383+
assert cek == cek0
384+
385+
386+
def test_ecdh_setup_unknown_alg():
387+
jwenc = JWE_EC(plain, alg="ECDH-ES+A128KW", enc="A384GCM")
388+
with pytest.raises(ValueError):
389+
jwenc.enc_setup(plain, key=eck_bob)
390+
391+
392+
def test_ecdh_setup_unknown_alg_2():
393+
jwenc = JWE_EC(plain, alg="ECDH-ES", enc="A384GCM")
394+
with pytest.raises(ValueError):
395+
jwenc.enc_setup(plain, key=eck_bob)
396+
397+
352398
def test_sym_encrypt_decrypt():
353399
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
354400
kid="some-key-id")
@@ -373,10 +419,10 @@ def test_verify_headers():
373419
jwenc = JWE(plain, alg="ECDH-ES", enc="A128GCM")
374420
jwt = jwenc.encrypt([eck_bob])
375421
assert jwt
376-
decryptor = factory(jwt, alg="ECDH-ES", enc="A128GCM")
377-
assert decryptor.jwt.verify_headers(alg='ECDH-ES', enc='A128GCM')
378-
assert decryptor.jwt.verify_headers(alg='RS256') is False
379-
assert decryptor.jwt.verify_headers(kid='RS256') is False
422+
decrypter = factory(jwt, alg="ECDH-ES", enc="A128GCM")
423+
assert decrypter.jwt.verify_headers(alg='ECDH-ES', enc='A128GCM')
424+
assert decrypter.jwt.verify_headers(alg='RS256') is False
425+
assert decrypter.jwt.verify_headers(kid='RS256') is False
380426

381427

382428
def test_encrypt_no_keys():
@@ -391,17 +437,101 @@ def test_encrypt_jwk_key():
391437
jwenc = JWE(plain, alg="ECDH-ES", enc="A128GCM", jwk=eck_bob)
392438
_enc = jwenc.encrypt()
393439
assert _enc
394-
decryptor = factory(_enc, alg="ECDH-ES", enc="A128GCM")
395-
res = decryptor.decrypt()
440+
decrypter = factory(_enc, alg="ECDH-ES", enc="A128GCM")
441+
res = decrypter.decrypt()
396442
assert res == plain
397443

398444

399-
def test_sym_encrypt_decrypt_JWE():
445+
def test_sym_encrypt_decrypt_jwe():
400446
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
401447
kid="some-key-id")
402448
jwe = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
403449
_jwe = jwe.encrypt(keys=[encryption_key], kid="some-key-id")
404-
decryptor = factory(_jwe, alg="A128KW", enc="A128CBC-HS256")
450+
decrypter = factory(_jwe, alg="A128KW", enc="A128CBC-HS256")
405451

406-
resp = decryptor.decrypt(_jwe, [encryption_key])
452+
resp = decrypter.decrypt(_jwe, [encryption_key])
407453
assert resp == plain
454+
455+
456+
def test_sym_jwenc():
457+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
458+
kid="some-key-id")
459+
jwe = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
460+
_jwe = jwe.encrypt(keys=[encryption_key], kid="some-key-id")
461+
decrypter = factory(_jwe, alg="A128KW", enc="A128CBC-HS256")
462+
463+
_jwenc = decrypter.jwt
464+
assert _jwenc.b64_protected_header() == _jwenc.b64part[0]
465+
assert _jwenc.b64_encrypted_key() == _jwenc.b64part[1]
466+
assert _jwenc.b64_initialization_vector() == _jwenc.b64part[2]
467+
assert _jwenc.b64_ciphertext() == _jwenc.b64part[3]
468+
assert _jwenc.b64_authentication_tag() == _jwenc.b64part[4]
469+
470+
assert _jwenc.protected_header() == _jwenc.part[0]
471+
assert _jwenc.encrypted_key() == _jwenc.part[1]
472+
assert _jwenc.initialization_vector() == _jwenc.part[2]
473+
assert _jwenc.ciphertext() == _jwenc.part[3]
474+
assert _jwenc.authentication_tag() == _jwenc.part[4]
475+
476+
477+
def test_wrong_key_type():
478+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
479+
kid="some-key-id")
480+
jwenc = JWE(plain, alg="ECDH-ES", enc="A128GCM")
481+
with pytest.raises(NoSuitableEncryptionKey):
482+
jwenc.encrypt([encryption_key])
483+
484+
485+
def test_wrong_alg():
486+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
487+
kid="some-key-id")
488+
jwe = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
489+
_jwe = jwe.encrypt(keys=[encryption_key], kid="some-key-id")
490+
with pytest.raises(HeaderError):
491+
decrypter = factory(_jwe, alg="A192KW", enc="A128CBC-HS256")
492+
493+
494+
def test_wrong_alg_2():
495+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
496+
kid="some-key-id")
497+
jwe = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
498+
_jwe = jwe.encrypt(keys=[encryption_key], kid="some-key-id")
499+
decrypter = factory(_jwe, alg="A128KW", enc="A128CBC-HS256")
500+
with pytest.raises(WrongEncryptionAlgorithm):
501+
decrypter.decrypt(_jwe, [encryption_key], alg='A192KW')
502+
503+
504+
def test_no_key():
505+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
506+
kid="some-key-id")
507+
jwe = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
508+
_jwe = jwe.encrypt(keys=[encryption_key], kid="some-key-id")
509+
decrypter = factory(_jwe, alg="A128KW", enc="A128CBC-HS256")
510+
with pytest.raises(NoSuitableDecryptionKey):
511+
decrypter.decrypt(_jwe, [])
512+
513+
514+
def test_unknown_alg():
515+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
516+
kid="some-key-id")
517+
jwenc = JWE(plain, alg="BCD", enc="A128GCM")
518+
with pytest.raises(ValueError):
519+
jwenc.encrypt([encryption_key])
520+
521+
522+
def test_nothing():
523+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
524+
kid="some-key-id")
525+
526+
decrypter = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
527+
with pytest.raises(ValueError):
528+
decrypter.decrypt(keys=[encryption_key])
529+
530+
531+
def test_invalid():
532+
encryption_key = SYMKey(use="enc", key='DukeofHazardpass',
533+
kid="some-key-id")
534+
535+
decrypter = JWE(plain, alg="A128KW", enc="A128CBC-HS256")
536+
with pytest.raises(BadSyntax):
537+
decrypter.decrypt('a.b.c.d.e', keys=[encryption_key])

0 commit comments

Comments
 (0)