Source code for cwt.helpers.hcert

from typing import Any, Dict, Union

from cryptography import x509
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
from cryptography.hazmat.primitives.hashes import SHA256

from ..algs.ec2 import EC2Key
from ..const import COSE_KEY_TYPES
from ..cose_key import COSEKey
from ..cose_key_interface import COSEKeyInterface
from ..utils import uint_to_bytes


def _generate_kid(cert: bytes) -> bytes:
    c = x509.load_pem_x509_certificate(cert)
    fp = c.fingerprint(SHA256())
    return fp[0:8]


[docs] def load_pem_hcert_dsc(cert: Union[str, bytes]) -> COSEKeyInterface: """ Loads PEM-formatted DSC (Digital Signing Certificate) issued by CSCA (Certificate Signing Certificate Authority) as a COSEKey. At this time, the kid of the COSE key will be generated as a 8-byte truncated SHA256 fingerprint of the DSC complient with `Electronic Health Certificate Specification <https://github.com/ehn-dcc-development/hcert-spec/blob/main/hcert_spec.md>`_. Args: cert(str): A DSC. Returns: COSEKeyInterface: A DSC's public key as a COSE key. """ if isinstance(cert, str): cert = cert.encode("utf-8") k: Any = None if b"BEGIN CERTIFICATE" in cert: k = x509.load_pem_x509_certificate(cert).public_key() else: raise ValueError("Invalid PEM data.") params: Dict[int, Any] = {} params[2] = _generate_kid(cert) if isinstance(k, RSAPublicKey): alg = -37 # "PS256" params[1] = COSE_KEY_TYPES["RSA"] params[3] = alg pub_nums = k.public_numbers() params[-1] = uint_to_bytes(pub_nums.n) params[-2] = uint_to_bytes(pub_nums.e) elif isinstance(k, EllipticCurvePublicKey): alg = -7 # "ES256" params[3] = alg params.update(EC2Key.to_cose_key(k)) else: raise ValueError(f"Unsupported or unknown key type: {type(k)}.") return COSEKey.new(params)