Commit 06da1cd5 authored by Simo Sorce's avatar Simo Sorce

Allow to pass an 'alg' argument to key generation

If an 'alg' argument is apssed in at key generation, then it can be used
to determine the key size appropriate for the desired algorithm.
An explicit 'size' argument always takes precendence.
An 'alg' parameter is accpeted for 'oct' and 'RSA' keys only.

Resolves #50
Signed-off-by: 's avatarSimo Sorce <simo@redhat.com>
Reviewed-by: 's avatarChristian Heimes <cheimes@redhat.com>
Closes #59
parent 4df4a7b3
......@@ -1104,13 +1104,17 @@ class JWA(object):
'A256GCM': _A256Gcm
}
@classmethod
def instantiate_alg(cls, name, use=None):
alg = cls.algorithms_registry[name]
if use is not None and alg.algorithm_use != use:
raise KeyError
return alg()
@classmethod
def signing_alg(cls, name):
try:
obj = cls.algorithms_registry[name]()
if obj.algorithm_use != 'sig':
raise KeyError()
return obj
return cls.instantiate_alg(name, use='sig')
except KeyError:
raise InvalidJWAAlgorithm(
'%s is not a valid Signign algorithm name' % name)
......@@ -1118,10 +1122,7 @@ class JWA(object):
@classmethod
def keymgmt_alg(cls, name):
try:
obj = cls.algorithms_registry[name]()
if obj.algorithm_use != 'kex':
raise KeyError()
return obj
return cls.instantiate_alg(name, use='kex')
except KeyError:
raise InvalidJWAAlgorithm(
'%s is not a valid Key Management algorithm name' % name)
......@@ -1129,10 +1130,7 @@ class JWA(object):
@classmethod
def encryption_alg(cls, name):
try:
obj = cls.algorithms_registry[name]()
if obj.algorithm_use != 'enc':
raise KeyError()
return obj
return cls.instantiate_alg(name, use='enc')
except KeyError:
raise InvalidJWAAlgorithm(
'%s is not a valid Encryption algorithm name' % name)
......@@ -227,11 +227,22 @@ class JWK(object):
gen(params)
def _generate_oct(self, params):
size = 128
def _get_gen_size(self, params, default_size=None):
size = default_size
if 'size' in params:
size = params['size']
del params['size']
elif 'alg' in params:
try:
from jwcrypto.jwa import JWA
alg = JWA.instantiate_alg(params['alg'])
except KeyError:
raise ValueError("Invalid 'alg' parameter")
size = alg.min_key_size
return size
def _generate_oct(self, params):
size = self._get_gen_size(params, 128)
key = os.urandom(size // 8)
params['kty'] = 'oct'
params['k'] = base64url_encode(key)
......@@ -243,13 +254,10 @@ class JWK(object):
def _generate_RSA(self, params):
pubexp = 65537
size = 2048
size = self._get_gen_size(params, 2048)
if 'public_exponent' in params:
pubexp = params['public_exponent']
del params['public_exponent']
if 'size' in params:
size = params['size']
del params['size']
key = rsa.generate_private_key(pubexp, size, default_backend())
self._import_pyca_pri_rsa(key, **params)
......
......@@ -198,8 +198,12 @@ class TestJWK(unittest.TestCase):
jwk.JWK.generate(kty='oct', size=256)
jwk.JWK.generate(kty='RSA', size=4096)
jwk.JWK.generate(kty='EC', curve='P-521')
k = jwk.JWK.generate(kty='oct', size=256, kid='MySymmetricKey')
k = jwk.JWK.generate(kty='oct', alg='A192KW', kid='MySymmetricKey')
self.assertEqual(k.key_id, 'MySymmetricKey')
self.assertEqual(len(base64url_decode(k.get_op_key('encrypt'))), 24)
jwk.JWK.generate(kty='RSA', alg='RS256')
k = jwk.JWK.generate(kty='RSA', size=4096, alg='RS256')
self.assertEqual(k.get_op_key('encrypt').key_size, 4096)
def test_export_public_keys(self):
k = jwk.JWK(**RSAPrivateKey)
......
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