Commit 72665470 authored by Simo Sorce's avatar Simo Sorce

Add a class method to generate JWKs

Deprecates the use of a the 'generate' keyword to create new random keys.
Issue #30
Signed-off-by: default avatarSimo Sorce <simo@redhat.com>
Reviewed-by: default avatarNathaniel McCallum <npmccallum@redhat.com>
Closes #30
Closes #32
parent d4ddafcd
......@@ -63,17 +63,17 @@ Examples
Create a 256bit symmetric key::
>>> from jwcrypto import jwk
>>> key = jwk.JWK(generate='oct', size=256)
>>> key = jwk.JWK.generate(kty='oct', size=256)
Export the key with::
>>> key.export()
'{"k":"X6TBlwY2so8EwKZ2TFXM7XHSgWBKQJhcspzYydp5Y-o","kty":"oct"}'
Create a 2048bit RSA keypair::
>>> jwk.JWK(generate='RSA', size=2048)
>>> jwk.JWK.generate(kty='RSA', size=2048)
Create a P-256 EC keypair and export the public key::
>>> key = jwk.JWK(generate='EC', crv='P-256')
>>> key = jwk.JWK.generate(kty='EC', crv='P-256')
>>> key.export(private_key=False)
'{"y":"VYlYwBfOTIICojCPfdUjnmkpN-g-lzZKxzjAoFmDRm8",
"x":"3mdE0rODWRju6qqU01Kw5oPYdNxBOMisFvJFH1vEu9Q",
......
......@@ -166,15 +166,20 @@ class JWK(object):
:data:`JWKTypesRegistry` variable. The valid key parameters per
key type are defined in the :data:`JWKValuesregistry` variable.
Alternatively if the 'generate' parameter is provided, with a
valid key type as value then a new key will be generated according
to the defaults or provided key strenght options (type specific).
To generate a new random key call the class method generate() with
the appropriate 'kty' parameter, and other parameters as needed (key
size, public exponents, curve types, etc..)
Valid options per type, when generating new keys:
* oct: size(int)
* RSA: public_exponent(int), size(int)
* EC: curve(str) (one of P-256, P-384, P-521)
Deprecated:
Alternatively if the 'generate' parameter is provided, with a
valid key type as value then a new key will be generated according
to the defaults or provided key strenght options (type specific).
:raises InvalidJWKType: if the key type is invalid
:raises InvalidJWKValue: if incorrect or inconsistent parameters
are provided.
......@@ -185,9 +190,20 @@ class JWK(object):
if 'generate' in kwargs:
self.generate_key(**kwargs)
else:
elif kwargs:
self.import_key(**kwargs)
@classmethod
def generate(cls, **kwargs):
obj = cls()
try:
kty = kwargs['kty']
gen = getattr(obj, '_generate_%s' % kty)
except (KeyError, AttributeError):
raise InvalidJWKType(kty)
gen(kwargs)
return obj
def generate_key(self, **kwargs):
params = kwargs.copy()
try:
......
......@@ -186,9 +186,9 @@ class TestJWK(unittest.TestCase):
_ = jwk.JWK(**RSAPrivateKey)
def test_generate_keys(self):
jwk.JWK(generate='oct', size=256)
jwk.JWK(generate='RSA', size=4096)
jwk.JWK(generate='EC', curve='P-521')
jwk.JWK.generate(kty='oct', size=256)
jwk.JWK.generate(kty='RSA', size=4096)
jwk.JWK.generate(kty='EC', curve='P-521')
def test_export_public_keys(self):
k = jwk.JWK(**RSAPrivateKey)
......@@ -198,7 +198,7 @@ class TestJWK(unittest.TestCase):
self.assertEqual(k.key_id, k2.key_id)
def test_generate_oct_key(self):
key = jwk.JWK(generate='oct', size=128)
key = jwk.JWK.generate(kty='oct', size=128)
E = jwe.JWE('test', '{"alg":"A128KW","enc":"A128GCM"}')
E.add_recipient(key)
e = E.serialize()
......@@ -207,13 +207,13 @@ class TestJWK(unittest.TestCase):
def test_generate_EC_key(self):
# Backwards compat curve
key = jwk.JWK(generate='EC', curve='P-256')
key = jwk.JWK.generate(kty='EC', curve='P-256')
key.get_curve('P-256')
# New param
key = jwk.JWK(generate='EC', crv='P-521')
key = jwk.JWK.generate(kty='EC', crv='P-521')
key.get_curve('P-521')
# New param prevails
key = jwk.JWK(generate='EC', curve='P-256', crv='P-521')
key = jwk.JWK.generate(kty='EC', curve='P-256', crv='P-521')
key.get_curve('P-521')
def test_jwkset(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment