Source code for cwt.signer

from typing import Any, Dict, Union

from .cbor_processor import CBORProcessor
from .const import COSE_ALGORITHMS_SIGNATURE
from .cose_key import COSEKey
from .cose_key_interface import COSEKeyInterface
from .utils import to_cose_header


[docs] class Signer(CBORProcessor): """ A Signer information. """ def __init__( self, cose_key: COSEKeyInterface, protected: Union[Dict[int, Any], bytes], unprotected: Dict[int, Any], signature: bytes = b"", ): self._cose_key = cose_key if isinstance(protected, bytes): self._protected = protected else: self._protected = b"" if not protected else self._dumps(protected) self._unprotected = unprotected self._signature = signature return @property def cose_key(self) -> COSEKeyInterface: """ The COSE key for the signer. """ return self._cose_key @property def protected(self) -> bytes: """ The parameters that are to be cryptographically protected. """ return self._protected @property def unprotected(self) -> Dict[int, Any]: """ The parameters that are not cryptographically protected. """ return self._unprotected @property def signature(self) -> bytes: """ The signature that the signer signed. """ return self._signature
[docs] @classmethod def new( cls, cose_key: COSEKeyInterface, protected: Union[dict, bytes] = {}, unprotected: dict = {}, signature: bytes = b"", ): """ Creates a signer information object (COSE_Signature). Args: cose_key (COSEKey): A signature key for the signer. protected (Union[dict, bytes]): Parameters that are to be cryptographically protected. unprotected (dict): Parameters that are not cryptographically protected. signature (bytes): A signature as bytes. Returns: Signer: A signer information object. Raises: ValueError: Invalid arguments. """ p: Union[Dict[int, Any], bytes] = ( to_cose_header(protected, algs=COSE_ALGORITHMS_SIGNATURE) if isinstance(protected, dict) else protected ) u = to_cose_header(unprotected, algs=COSE_ALGORITHMS_SIGNATURE) return cls(cose_key, p, u, signature)
[docs] @classmethod def from_jwk(cls, data: Union[str, bytes, Dict[str, Any]]): """ Creates a signer information object (COSE_Signature) from JWK. The ``alg`` in the JWK will be included in the protected header, and the ``kid`` in the JWT will be include in the unprotected header. If you want to include any other parameters in the protected/unprotected header, you have to use :func:`Signer.new <cwt.Signer.new>`. Args: data (Union[str, bytes, Dict[str, Any]]): A JWK. Returns: Signer: A signer information object. Raises: ValueError: Invalid arguments. DecodeError: Failed to decode the key data. """ protected: Dict[int, Any] = {} unprotected: Dict[int, Any] = {} cose_key = COSEKey.from_jwk(data) # alg if cose_key.alg not in COSE_ALGORITHMS_SIGNATURE.values(): raise ValueError(f"Unsupported or unknown alg for signature: {cose_key.alg}.") protected[1] = cose_key.alg # kid if cose_key.kid: unprotected[4] = cose_key.kid return cls(cose_key, protected, unprotected)
[docs] @classmethod def from_pem( cls, data: Union[str, bytes], alg: Union[int, str] = "", kid: Union[bytes, str] = b"", ): """ Creates a signer information object (COSE_Signature) from PEM-formatted key. The ``alg`` in the JWK will be included in the protected header, and the ``kid`` in the JWT will be include in the unprotected header. If you want to include any other parameters in the protected/unprotected header, you have to use :func:`Signer.new <cwt.Signer.new>`. Args: data (Union[str, bytes]): A PEM-formatted key. alg (Union[int, str]): An algorithm label(int) or name(str). It is only used when an algorithm cannot be specified by the PEM data, such as RSA family algorithms. kid (Union[bytes, str]): A key identifier. Returns: Signer: A signer information object. Raises: ValueError: Invalid arguments. DecodeError: Failed to decode the key data. """ protected: Dict[int, Any] = {} unprotected: Dict[int, Any] = {} cose_key = COSEKey.from_pem(data, alg=alg, kid=kid) # alg protected[1] = cose_key.alg # kid if cose_key.kid: unprotected[4] = cose_key.kid return cls(cose_key, protected, unprotected)
[docs] def sign(self, msg: bytes): """ Returns a digital signature for the specified message using the specified key value. Args: msg (bytes): A message to be signed. Raises: ValueError: Invalid arguments. EncodeError: Failed to sign the message. """ self._signature = self._cose_key.sign(msg) return
[docs] def verify(self, msg: bytes): """ Verifies that the specified digital signature is valid for the specified message. Args: msg (bytes): A message to be verified. Raises: ValueError: Invalid arguments. VerifyError: Failed to verify. """ self._cose_key.verify(msg, self._signature) return