Source code for cwt.cose_key_interface

from typing import Any, Dict, List, Optional, Union

from .cbor_processor import CBORProcessor
from .const import (
    COSE_KEY_OPERATION_VALUES,
    COSE_KEY_TYPES,
    COSE_NAMED_ALGORITHMS_SUPPORTED,
)


[docs] class COSEKeyInterface(CBORProcessor): """ The interface class for a COSE Key used for MAC, signing/verifying and encryption/decryption. """
[docs] def __init__(self, params: Dict[int, Any]): """ Constructor. Args: params (Dict[int, Any]): A COSE key common parameter object formatted to CBOR-like structure ((Dict[int, Any])). """ # kty if 1 not in params: raise ValueError("kty(1) not found.") if not isinstance(params[1], int) and not isinstance(params[1], str): raise ValueError("kty(1) should be int or str(tstr).") if isinstance(params[1], int) and params[1] not in [1, 2, 3, 4, 5, 6]: raise ValueError(f"Unknown kty: {params[1]}") if isinstance(params[1], str) and params[1] not in COSE_KEY_TYPES: raise ValueError(f"Unknown kty: {params[1]}") self._kty: int = params[1] if isinstance(params[1], int) else COSE_KEY_TYPES[params[1]] # kid if 2 in params and not isinstance(params[2], bytes): raise ValueError("kid(2) should be bytes(bstr).") self._kid = params[2] if 2 in params else None # alg self._alg = None if 3 in params: if not isinstance(params[3], int) and not isinstance(params[3], str): raise ValueError("alg(3) should be int or str(tstr).") if isinstance(params[3], str) and params[3] not in COSE_NAMED_ALGORITHMS_SUPPORTED: raise ValueError(f"Unsupported or unknown alg(3): {params[3]}.") self._alg = params[3] if isinstance(params[3], int) else COSE_NAMED_ALGORITHMS_SUPPORTED[params[3]] # key_ops if 4 in params and not isinstance(params[4], list): raise ValueError("key_ops(4) should be list.") self._key_ops: List[int] = params[4] if 4 in params else [] for v in self._key_ops: if v not in COSE_KEY_OPERATION_VALUES.values(): raise ValueError(f"key_ops(4) includes invalid value: {v}.") # Base IV if 5 in params and not isinstance(params[5], bytes): raise ValueError("Base IV(5) should be bytes(bstr).") self._base_iv = params[5] if 5 in params else None return
@property def kty(self) -> int: """ The identifier of the key type. """ return self._kty @property def kid(self) -> Union[bytes, None]: """ The key identifier. """ return self._kid @property def alg(self) -> Union[int, None]: """ The algorithm that is used with the key. """ return self._alg @property def key_ops(self) -> List[int]: """ A set of permissible operations that the key is to be used for. """ return self._key_ops @property def base_iv(self) -> Union[bytes, None]: """ Base IV to be xor-ed with Partial IVs. """ return self._base_iv @property def key(self) -> Any: """ The body of the key. It can be bytes or various PublicKey/PrivateKey objects defined in ``pyca/cryptography`` """ raise NotImplementedError @property def crv(self) -> int: """ The curve (``crv`` parameter value) of the key. """ raise NotImplementedError
[docs] def to_bytes(self) -> bytes: """ Serializes the body of the key as a byte string. """ raise NotImplementedError
[docs] def to_dict(self) -> Dict[int, Any]: """ Returns the CBOR-like structure (Dict[int, Any]) of the COSE key. Returns: Dict[int, Any]: The CBOR-like structure of the COSE key. """ res: Dict[int, Any] = {1: self._kty} if self._kid: res[2] = self._kid if self._alg: res[3] = self._alg if self._key_ops: res[4] = self._key_ops if self._base_iv: res[5] = self._base_iv return res
[docs] def generate_nonce(self) -> bytes: """ Returns a nonce with the size suitable for the algorithm. This function will be called internally in :class:`CWT <cwt.CWT>` when no nonce is specified by the application. This function adopts ``secrets.token_bytes()`` to generate a nonce. If you do not want to use it, you should explicitly set a nonce to :class:`CWT <cwt.CWT>` functions (e.g., :func:`encode_and_encrypt <cwt.CWT.encode_and_encrypt>`). Returns: bytes: A byte string of the generated nonce. Raises: NotImplementedError: Not implemented. """ raise NotImplementedError
[docs] def sign(self, msg: bytes) -> bytes: """ Returns a digital signature for the specified message using the specified key value. Args: msg (bytes): A message to be signed. Returns: bytes: The byte string of the encoded CWT. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. EncodeError: Failed to sign the message. """ raise NotImplementedError
[docs] def verify(self, msg: bytes, sig: bytes): """ Verifies that the specified digital signature is valid for the specified message. Args: msg (bytes): A message to be verified. sig (bytes): A digital signature of the message. Returns: bytes: The byte string of the encoded CWT. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. VerifyError: Failed to verify. """ raise NotImplementedError
[docs] def validate_certificate(self, ca_certs: List[bytes]) -> bool: """ Validate a certificate bound to the key with given trusted CA certificates if the key has `x5c` parameter. Args: ca_certs(List[bytes]): A list of DER-formatted trusted root CA certificates which contains a concatenated list of trusted root certificates. You should specify private CA certificates in your target system. There should be no need to use the public CA certificates for the Web PKI. Returns: bool: The indicator whether the validation is done or not. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. VerifyError: Failed to verify. """ raise NotImplementedError
[docs] def encrypt(self, msg: bytes, nonce: bytes, aad: bytes) -> bytes: """ Encrypts the specified message. Args: msg (bytes): A message to be encrypted. nonce (bytes): A nonce for encryption. aad (bytes): Additional authenticated data. Returns: bytes: The byte string of encrypted data. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. EncodeError: Failed to encrypt the message. """ raise NotImplementedError
[docs] def decrypt(self, msg: bytes, nonce: bytes, aad: bytes) -> bytes: """ Decrypts the specified message. Args: msg (bytes): An encrypted message. nonce (bytes): A nonce for encryption. aad (bytes): Additional authenticated data. Returns: bytes: The byte string of the decrypted data. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. DecodeError: Failed to decrypt the message. """ raise NotImplementedError
[docs] def wrap_key(self, key_to_wrap: bytes) -> bytes: """ Wraps a key. Args: key_to_wrap: A key to wrap. Returns: bytes: A wrapped key as bytes. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. EncodeError: Failed to derive key. """ raise NotImplementedError
[docs] def unwrap_key(self, wrapped_key: bytes) -> bytes: """ Unwraps a key. Args: wrapped_key: A key to be unwrapped. Returns: bytes: An unwrapped key as bytes. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. DecodeError: Failed to unwrap key. """ raise NotImplementedError
[docs] def derive_bytes( self, length: int, material: bytes = b"", info: bytes = b"", public_key: Optional[Any] = None, ) -> bytes: """ Derives a byte string with a key material or key exchange. Args: length (int): The length of derived byte string. material (bytes): A key material as bytes. info (bytes): application supplied information. public_key: A public key for key derivation with key exchange. Returns: bytes: A derived byte string. Raises: NotImplementedError: Not implemented. ValueError: Invalid arguments. EncodeError: Failed to derive key. """ raise NotImplementedError