Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to get all supported algorithms #30

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions _jose.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,96 @@ def to_compact(dict flat not None):
finally:
jansson.json_decref(cjose)
free(ret)

def get_supported_algorithms():
cdef jose.jose_jwe_crypter_t *jwe_crypter
cdef jose.jose_jwe_wrapper_t *jwe_wrapper
cdef jose.jose_jwe_zipper_t *jwe_zipper
cdef jose.jose_jwk_generator_t *jwk_generator
cdef jose.jose_jwk_hasher_t *jwk_hasher
cdef jose.jose_jwk_op_t *jwk_op
cdef jose.jose_jwk_type_t *jwk_type
cdef jose.jose_jws_signer_t *jws_signer
cdef char *p
cdef size_t i

result = {
'jwk_types': {},
'jwk_ops': [],
'jwk_generators': set(),
'jwk_hashers': {},
'jws_signers': set(),
'jwe_crypters': set(),
'jwe_wrappers': set(),
'jwe_zippers': set(),
}

jwe_crypter = jose.jose_jwe_crypters()
while jwe_crypter is not NULL:
result['jwe_crypters'].add(ascii2obj(jwe_crypter.enc))
jwe_crypter = jwe_crypter.next

jwe_wrapper = jose.jose_jwe_wrappers()
while jwe_wrapper is not NULL:
result['jwe_wrappers'].add(ascii2obj(jwe_wrapper.alg))
jwe_wrapper = jwe_wrapper.next

jwe_zipper = jose.jose_jwe_zippers()
while jwe_zipper is not NULL:
result['jwe_zippers'].add(ascii2obj(jwe_zipper.zip))
jwe_zipper = jwe_zipper.next

jwk_generator = jose.jose_jwk_generators()
while jwk_generator is not NULL:
result['jwk_generators'].add(ascii2obj(jwk_generator.kty))
jwk_generator = jwk_generator.next

jwk_hasher = jose.jose_jwk_hashers()
while jwk_hasher is not NULL:
name = ascii2obj(jwk_hasher.name)
result['jwk_hashers'][name] = jwk_hasher.size
jwk_hasher = jwk_hasher.next

jwk_op = jose.jose_jwk_ops()
while jwk_op is not NULL:
result['jwk_ops'].append(
(ascii2obj(jwk_op.pub),
ascii2obj(jwk_op.prv),
ascii2obj(jwk_op.use))
)
jwk_op = jwk_op.next

jwk_type = jose.jose_jwk_types()
while jwk_type is not NULL:
name = ascii2obj(jwk_type.kty)
reqs = []
prvs = []

if jwk_type.req is not NULL:
for i in range(255):
p = jwk_type.req[i]
if p is NULL:
break
reqs.append(ascii2obj(p))

if jwk_type.prv is not NULL:
for i in range(255):
p = jwk_type.prv[i]
if p is NULL:
break
prvs.append(ascii2obj(p))

result['jwk_types'][name] = {
'req': reqs,
'prv': prvs,
'sym': True if jwk_type.sym else False
}

jwk_type = jwk_type.next

jws_signer = jose.jose_jws_signers()
while jws_signer is not NULL:
result['jws_signers'].add(ascii2obj(jws_signer.alg))
jws_signer = jws_signer.next

return result
3 changes: 2 additions & 1 deletion src/jose/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
from __future__ import absolute_import

from ._jose import JoseOperationError
from ._jose import get_supported_algorithms

__all__ = ('JoseOperationError', )
__all__ = ('JoseOperationError', 'get_supported_algorithms')
48 changes: 48 additions & 0 deletions src/jose/jose.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,51 @@ cdef extern from "jose/jws.h":
cdef extern from "jose/jose.h":
jansson.json_t *jose_from_compact(const char *jose)
char *jose_to_compact(const jansson.json_t *jose)

cdef extern from "jose/hooks.h":
ctypedef struct jose_jwk_type_t:
jose_jwk_type_t *next
bool sym
const char *kty
const char **req
const char **prv

ctypedef struct jose_jwk_op_t:
jose_jwk_op_t *next
const char *pub
const char *prv
const char *use

ctypedef struct jose_jwk_generator_t:
jose_jwk_generator_t *next
const char *kty

ctypedef struct jose_jwk_hasher_t:
jose_jwk_hasher_t *next
const char *name
size_t size

ctypedef struct jose_jws_signer_t:
jose_jws_signer_t *next
const char *alg

ctypedef struct jose_jwe_crypter_t:
jose_jwe_crypter_t *next
const char *enc

ctypedef struct jose_jwe_wrapper_t:
jose_jwe_wrapper_t *next
const char *alg

ctypedef struct jose_jwe_zipper_t:
jose_jwe_zipper_t *next
const char *zip

jose_jwk_type_t *jose_jwk_types()
jose_jwk_op_t *jose_jwk_ops()
jose_jwk_generator_t *jose_jwk_generators()
jose_jwk_hasher_t *jose_jwk_hashers()
jose_jws_signer_t *jose_jws_signers()
jose_jwe_crypter_t *jose_jwe_crypters()
jose_jwe_wrapper_t *jose_jwe_wrappers()
jose_jwe_zipper_t *jose_jwe_zippers()
53 changes: 53 additions & 0 deletions tests/test_jose.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,59 @@ def test_jws_sign(self):
jose.jws.sign(jws, jwk, None)
jose.jws.sign(jws, jwk, sig)

def test_get_supported_algorithms(self):
sup = jose.get_supported_algorithms()
self.assertEqual(
set(sup),
{'jwe_crypters', 'jwe_wrappers', 'jwe_zippers', 'jwk_generators',
'jwk_hashers', 'jwk_ops', 'jwk_types', 'jws_signers'})
self.assertEqual(
sup['jwe_crypters'],
{'A128CBC-HS256', 'A128GCM', 'A192CBC-HS384', 'A192GCM',
'A256CBC-HS512', 'A256GCM'}
)
self.assertEqual(
sup['jwe_wrappers'],
{'A128GCMKW', 'A128KW', 'A192GCMKW', 'A192KW',
'A256GCMKW', 'A256KW', 'ECDH-ES', 'ECDH-ES+A128KW',
'ECDH-ES+A192KW', 'ECDH-ES+A256KW', 'PBES2-HS256+A128KW',
'PBES2-HS384+A192KW', 'PBES2-HS512+A256KW', 'RSA-OAEP',
'RSA-OAEP-256', 'RSA1_5', 'dir'}
)
self.assertEqual(sup['jwe_zippers'], {'DEF'})
self.assertEqual(sup['jwk_generators'], {'EC', 'oct', 'RSA'})
self.assertEqual(
sup['jws_signers'],
{'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'PS256',
'PS384', 'PS512', 'RS256', 'RS384', 'RS512'})
self.assertEqual(
sup['jwk_hashers'],
{'sha1': 20,
'sha224': 28,
'sha256': 32,
'sha384': 48,
'sha512': 64})
self.assertEqual(
sorted(sup['jwk_ops']),
[('encrypt', 'decrypt', 'enc'),
('verify', 'sign', 'sig'),
('wrapKey', 'unwrapKey', 'enc')]
)
self.assertEqual(
sup['jwk_types'],
{
'EC': {'prv': ['d'],
'req': ['crv', 'x', 'y'],
'sym': False},
'RSA': {'prv': ['p', 'd', 'q', 'dp', 'dq', 'qi', 'oth'],
'req': ['e', 'n'],
'sym': False},
'oct': {'prv': ['k'],
'req': ['k'],
'sym': True},
}
)

def test_compact(self):
filename = os.path.join(HERE, 'vectors', 'rfc7515_A.1.jwsc')
with open(filename, 'rb') as f:
Expand Down