Skip to content

Commit

Permalink
Merge pull request #48 from IdentityPython/develop
Browse files Browse the repository at this point in the history
Preparation for persistent storage of dynamic information.
  • Loading branch information
rohe authored Jun 22, 2020
2 parents 81c908b + 02de6f2 commit 0f65fd9
Show file tree
Hide file tree
Showing 22 changed files with 2,229 additions and 566 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ python:
addons:
apt:
packages:
-
-
install:
- pip install codecov
- pip install tox
Expand All @@ -26,6 +26,6 @@ deploy:
tags: true
distributions: bdist_wheel
skip_existing: true
user: __token__
username: __token__
password:
secure: "kW7wRRnQDkeD/bvDrktoLTLrFV4W0B548PhtXVBD7rfbx09oE+jmoM6Ojc2y+t18XQ0zYIfO1qXdoenzti2YiY8xGgA1EYDpHuT0d+DX3tPuLiXou+pts+dXo5Q0YJRFlmBgxtyT+eHhScojDPvDmCFQodIQhiGK1cyzV1p+jE9W/wjiCOQWSQ0LoIV/ajjIMArEmucqwU1wlXxPPgVaV2EuZ7hXBULA6C1DKJENja+qeORtDdW6DMXPJQ4AD74dR+IHaqX4W+mRjRO8wZHKBxrxQ65nZErcfwjbqWRhPIUWzkVngC21BWrs/5eMvxuSPDj4XUY/wiB/1xR883bM6YypEqlCM5x3CFA6a65iI+dfT4iqQRdwOF04oxDkNf2N1LBx8Pv01KxDs5cblv3i/TQHoBIKH8wY6yxrVT2gtcGOwj5+/Pay3PGUN4S8YyzzmSuX/trQgWl/6BD2UPDRchhz24AfV8vXPr6ljBllNdGtWVWJd0ad7u2nqTrUcec909cAhz9SHP1LO8IqCjh8XGdQATOmZXptXJLLmysN9+OwgyTA4SH0Q4FKPG/xriq2cbMCfBTnBOTb5N9ZCm1VeGZlcMdva9UDcRWjtEStAy+gnYQc10EBD060O0jUDB9qdm5zyiTSqOY701828Z2a5uMWXqWUlEsbF61BN6cuD4s="
secure: sCvQSnLW2R9i01dTvG1JyZ+lU99jXjEmPeniSTB8SAZMlfIbuo8I5kjkKxxaa4uTOU3mZiWDG/wq/liUuUzxjXYLA47gwVqU6QrkgIh0/QqGIN1+GYtHqZZETueGClSS8drCgYchpknNTA+30JL/kpt4fjq5hSUFII5BuybVYbh5WVnmwjhZOnZdKxVuQrrfzNVe14wr/TY7VvtL7W5bSCigxYh4oSUiFB6WkFyPZFetqYRO5eCTRt4Tn/hT3Y5Aiz033hMFhrjB4XxuWK7P1f6WVVGRMfAwa4XuC3w0oPSp/9I0cMBtLkExs+tdq25lgmJOcdzVwo3QHPs4pn6AjHKPyoTr/jiuysKnSZCwgcMPFpORgrOWQh/qFxHqNFI0QzNasZXhEBDJaaR2pN/GLjW97NiuaCFuZ/me0SWtpdhPuJpjgx9xxwymRRC4aBu6aPrzoxFGABp4Bkica7KsBmWgQ0ZFMPO6bXB6bU5w8a+wlOY/6I8b06/cIOIyMh8Tas7UwO2/e0L65qhAkR3u1evmagex94w9UameP+518yYik0L5uwrn7vPeRNpH1UEctd3RG73HlEdu8wMCo0pPrvFqsQGtIiPTLPx99453z8Z/raWwAa1Zpn2c8mSm9YIOQZ20rsiFy1vfwAm2b7/dfm005hUirmfwtiG7Oq8iLdg=
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
author="Roland Hedberg",
author_email="[email protected]",
license="Apache 2.0",
packages=["cryptojwt", "cryptojwt/jwe", "cryptojwt/jwk", "cryptojwt/jws", "cryptojwt/tools"],
packages=["cryptojwt", "cryptojwt/jwe", "cryptojwt/jwk", "cryptojwt/jws", "cryptojwt/tools",
"cryptojwt/serialize"],
package_dir={"": "src"},
classifiers=[
"Development Status :: 4 - Beta",
Expand Down
2 changes: 1 addition & 1 deletion src/cryptojwt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
except ImportError:
pass

__version__ = '0.8.4'
__version__ = '1.0.0'

logger = logging.getLogger(__name__)

Expand Down
20 changes: 12 additions & 8 deletions src/cryptojwt/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ class MissingKey(JWKESTException):
""" No usable key """


class KeyIOError(Exception):
pass


class UnknownKeyType(KeyIOError):
pass


class UpdateFailed(KeyIOError):
pass


class UnknownKeytype(Invalid):
"""An unknown key type"""

Expand Down Expand Up @@ -87,18 +99,10 @@ class WrongKeyType(JWKESTException):
pass


class UnknownKeyType(JWKESTException):
pass


class UnsupportedKeyType(JWKESTException):
pass


class UpdateFailed(JWKESTException):
pass


class WrongUsage(JWKESTException):
pass

Expand Down
9 changes: 9 additions & 0 deletions src/cryptojwt/jwk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ def appropriate_for(self, usage, **kwargs):
elif self.key_ops:
return usage in self.key_ops

def update(self):
pass


def pems_to_x5c(cert_chain):
"""
Expand Down Expand Up @@ -303,6 +306,12 @@ def certificate_fingerprint(der, hash="sha256"):
return ':'.join([fp[i:i + 2] for i in range(0, len(fp), 2)]).upper()


def calculate_x5t(der, hash='sha1'):
val = certificate_fingerprint(der, hash)
val = val.replace(':', '')
return base64.b64encode(as_bytes(val))


def pem_hash(pem_file):
with open(pem_file, "r") as fp:
pem = fp.read()
Expand Down
2 changes: 1 addition & 1 deletion src/cryptojwt/jwk/jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def key_from_jwk_dict(jwk_dict, private=None):
"""

# uncouple from the original item
_jwk_dict = copy.copy(jwk_dict)
_jwk_dict = copy.deepcopy(jwk_dict)

if 'kty' not in _jwk_dict:
raise MissingValue('kty missing')
Expand Down
37 changes: 20 additions & 17 deletions src/cryptojwt/jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def __init__(self, key_jar=None, iss='', lifetime=0,
enc_enc="A128CBC-HS256", enc_alg="RSA1_5", msg_cls=None,
iss2msg_cls=None, skew=15,
allowed_sign_algs=None, allowed_enc_algs=None,
allowed_enc_encs=None):
allowed_enc_encs=None, zip=''):
self.key_jar = key_jar # KeyJar instance
self.iss = iss # My identifier
self.lifetime = lifetime # default life time of the signature
Expand All @@ -99,6 +99,7 @@ def __init__(self, key_jar=None, iss='', lifetime=0,
self.allowed_sign_algs = allowed_sign_algs
self.allowed_enc_algs = allowed_enc_algs
self.allowed_enc_encs = allowed_enc_encs
self.zip = zip

def receiver_keys(self, recv, use):
"""
Expand All @@ -107,7 +108,7 @@ def receiver_keys(self, recv, use):
:param use: What the keys should be usable for
:return: A list of keys.
"""
return self.key_jar.get(use, owner=recv)
return self.key_jar.get(use, issuer_id=recv)

def receivers(self):
"""Return a list of identifiers.
Expand All @@ -117,20 +118,22 @@ def receivers(self):
"""
return self.key_jar.owners

def my_keys(self, owner_id='', use='sig'):
_k = self.key_jar.get(use, owner=owner_id)
if owner_id != '':
def my_keys(self, issuer_id='', use='sig'):
_k = self.key_jar.get(use, issuer_id=issuer_id)
if issuer_id != '':
try:
_k.extend(self.key_jar.get(use, owner=''))
_k.extend(self.key_jar.get(use, issuer_id=''))
except KeyError:
pass
return _k

def _encrypt(self, payload, recv, cty='JWT'):
def _encrypt(self, payload, recv, cty='JWT', zip=''):
kwargs = {"alg": self.enc_alg, "enc": self.enc_enc}

if cty:
kwargs["cty"] = cty
if zip:
kwargs['zip'] = zip

# use the clients public key for encryption
_jwe = JWE(payload, **kwargs)
Expand Down Expand Up @@ -173,28 +176,28 @@ def pack_init(self, recv, aud):

return argv

def pack_key(self, owner_id='', kid=''):
def pack_key(self, issuer_id='', kid=''):
"""
Find a key to be used for signing the Json Web Token
:param owner_id: Owner of the keys to chose from
:param issuer_id: Owner of the keys to chose from
:param kid: Key ID
:return: One key
"""
keys = pick_key(self.my_keys(owner_id, 'sig'), 'sig', alg=self.alg,
keys = pick_key(self.my_keys(issuer_id, 'sig'), 'sig', alg=self.alg,
kid=kid)

if not keys:
raise NoSuitableSigningKeys('kid={}'.format(kid))

return keys[0] # Might be more then one if kid == ''

def pack(self, payload=None, kid='', owner='', recv='', aud=None, **kwargs):
def pack(self, payload=None, kid='', issuer_id='', recv='', aud=None, **kwargs):
"""
:param payload: Information to be carried as payload in the JWT
:param kid: Key ID
:param owner: The owner of the the keys that are to be used for signing
:param issuer_id: The owner of the the keys that are to be used for signing
:param recv: The intended immediate receiver
:param aud: Intended audience for this JWS/JWE, not expected to
contain the recipient.
Expand All @@ -221,12 +224,12 @@ def pack(self, payload=None, kid='', owner='', recv='', aud=None, **kwargs):

_args['jti'] = _jti

if not owner and self.iss:
owner = self.iss
if not issuer_id and self.iss:
issuer_id = self.iss

if self.sign:
if self.alg != 'none':
_key = self.pack_key(owner, kid)
_key = self.pack_key(issuer_id, kid)
# _args['kid'] = _key.kid
else:
_key = None
Expand All @@ -238,9 +241,9 @@ def pack(self, payload=None, kid='', owner='', recv='', aud=None, **kwargs):

if _encrypt:
if not self.sign:
return self._encrypt(_sjwt, recv, cty='json')
return self._encrypt(_sjwt, recv, cty='json', zip=self.zip)

return self._encrypt(_sjwt, recv)
return self._encrypt(_sjwt, recv, zip=self.zip)
else:
return _sjwt

Expand Down
Loading

0 comments on commit 0f65fd9

Please sign in to comment.