82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
class JWSAlgorithm:
|
|
"""Interface for JWS algorithm. JWA specification (RFC7518) SHOULD
|
|
implement the algorithms for JWS with this base implementation.
|
|
"""
|
|
name = None
|
|
description = None
|
|
algorithm_type = 'JWS'
|
|
algorithm_location = 'alg'
|
|
|
|
def prepare_key(self, raw_data):
|
|
"""Prepare key for signing and verifying signature."""
|
|
raise NotImplementedError()
|
|
|
|
def sign(self, msg, key):
|
|
"""Sign the text msg with a private/sign key.
|
|
|
|
:param msg: message bytes to be signed
|
|
:param key: private key to sign the message
|
|
:return: bytes
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
def verify(self, msg, sig, key):
|
|
"""Verify the signature of text msg with a public/verify key.
|
|
|
|
:param msg: message bytes to be signed
|
|
:param sig: result signature to be compared
|
|
:param key: public key to verify the signature
|
|
:return: boolean
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
|
|
class JWSHeader(dict):
|
|
"""Header object for JWS. It combine the protected header and unprotected
|
|
header together. JWSHeader itself is a dict of the combined dict. e.g.
|
|
|
|
>>> protected = {'alg': 'HS256'}
|
|
>>> header = {'kid': 'a'}
|
|
>>> jws_header = JWSHeader(protected, header)
|
|
>>> print(jws_header)
|
|
{'alg': 'HS256', 'kid': 'a'}
|
|
>>> jws_header.protected == protected
|
|
>>> jws_header.header == header
|
|
|
|
:param protected: dict of protected header
|
|
:param header: dict of unprotected header
|
|
"""
|
|
def __init__(self, protected, header):
|
|
obj = {}
|
|
if protected:
|
|
obj.update(protected)
|
|
if header:
|
|
obj.update(header)
|
|
super().__init__(obj)
|
|
self.protected = protected
|
|
self.header = header
|
|
|
|
@classmethod
|
|
def from_dict(cls, obj):
|
|
if isinstance(obj, cls):
|
|
return obj
|
|
return cls(obj.get('protected'), obj.get('header'))
|
|
|
|
|
|
class JWSObject(dict):
|
|
"""A dict instance to represent a JWS object."""
|
|
def __init__(self, header, payload, type='compact'):
|
|
super().__init__(
|
|
header=header,
|
|
payload=payload,
|
|
)
|
|
self.header = header
|
|
self.payload = payload
|
|
self.type = type
|
|
|
|
@property
|
|
def headers(self):
|
|
"""Alias of ``header`` for JSON typed JWS."""
|
|
if self.type == 'json':
|
|
return self['header']
|