diff --git a/pymdoccbor/mdoc/issuer.py b/pymdoccbor/mdoc/issuer.py index 2295998..076eda0 100644 --- a/pymdoccbor/mdoc/issuer.py +++ b/pymdoccbor/mdoc/issuer.py @@ -23,6 +23,7 @@ class MdocCborIssuer: """ MdocCborIssuer helper class to create a new mdoc """ + def __init__( self, key_label: str | None = None, @@ -80,7 +81,7 @@ def new( devicekeyinfo: dict | CoseKey | str | None = None, cert_path: str | None = None, revocation: dict | None = None, - status: dict | None = None + status: dict | None = None, ) -> dict: """ create a new mdoc with signed mso @@ -121,7 +122,7 @@ def new( if isinstance(devicekeyinfo, str): device_key_bytes = base64.urlsafe_b64decode(devicekeyinfo.encode("utf-8")) public_key = serialization.load_pem_public_key(device_key_bytes) - + if isinstance(public_key, EllipticCurvePublicKey): curve_name = public_key.curve.name curve_map = { @@ -160,20 +161,18 @@ def new( -1: "Ed25519", # Curve identifier for Ed25519 -2: public_key.public_bytes( encoding=serialization.Encoding.Raw, - format=serialization.PublicFormat.Raw - ) + format=serialization.PublicFormat.Raw, + ), } elif isinstance(public_key, RSAPublicKey): devicekeyinfo = { 1: 3, # RSAKey -1: public_key.public_numbers().n.to_bytes( - (public_key.public_numbers().n.bit_length() + 7) // 8, - "big" + (public_key.public_numbers().n.bit_length() + 7) // 8, "big" ), -2: public_key.public_numbers().e.to_bytes( - (public_key.public_numbers().e.bit_length() + 7) // 8, - "big" - ) + (public_key.public_numbers().e.bit_length() + 7) // 8, "big" + ), } else: raise TypeError("Loaded public key is not an EllipticCurvePublicKey") @@ -191,7 +190,7 @@ def new( kid=self.kid, validity=validity, revocation=revocation, - cert_info=self.cert_info + cert_info=self.cert_info, ) else: @@ -202,10 +201,14 @@ def new( cert_path=cert_path, validity=validity, revocation=revocation, - cert_info=self.cert_info + cert_info=self.cert_info, ) - mso = msoi.sign(doctype=doctype, device_key=devicekeyinfo, valid_from=datetime.now(timezone.utc)) + mso = msoi.sign( + doctype=doctype, + device_key=devicekeyinfo, + valid_from=datetime.now(timezone.utc), + ) mso_cbor = mso.encode( tag=False, @@ -216,18 +219,17 @@ def new( slot_id=self.slot_id, ) - res = { "version": self.version, "documents": [ { - "docType": doctype, # 'org.iso.18013.5.1.mDL' - "issuerSigned": { - "nameSpaces": { - ns: [v for k, v in dgst.items()] - for ns, dgst in msoi.disclosure_map.items() + "docType": doctype, # 'org.iso.18013.5.1.mDL' + "issuerSigned": { + "nameSpaces": { + ns: [v for k, v in dgst.items()] + for ns, dgst in msoi.disclosure_map.items() }, - "issuerAuth": cbor2.decoder.loads(mso_cbor), + "issuerAuth": cbor2.loads(mso_cbor), }, } ], diff --git a/pymdoccbor/tests/test_08_mdoc_cbor.py b/pymdoccbor/tests/test_08_mdoc_cbor.py index e0cc121..265990c 100644 --- a/pymdoccbor/tests/test_08_mdoc_cbor.py +++ b/pymdoccbor/tests/test_08_mdoc_cbor.py @@ -1,71 +1,65 @@ import os import cbor2 +import datetime from pymdoccbor.mdoc.issuer import MdocCborIssuer from pymdoccbor.tests.micov_data import MICOV_DATA from pymdoccbor.mdoc.verifier import MdocCbor from pymdoccbor.tests.pkey import PKEY from pymdoccbor.tests.cert_data import CERT_DATA + +def normalize_dates(obj): + if isinstance(obj, dict): + return {k: normalize_dates(v) for k, v in obj.items()} + elif isinstance(obj, list): + return [normalize_dates(v) for v in obj] + elif isinstance(obj, datetime.date): + return obj.isoformat() + return obj + + def test_mdoc_cbor_creation(): - mdoci = MdocCborIssuer( - private_key=PKEY, - alg="ES256", - cert_info=CERT_DATA - ) + mdoci = MdocCborIssuer(private_key=PKEY, alg="ES256", cert_info=CERT_DATA) mdoc = mdoci.new( data=MICOV_DATA, - #devicekeyinfo=PKEY, # TODO + # devicekeyinfo=PKEY, # TODO doctype="org.micov.medical.1", - validity={ - "issuance_date": "2024-12-31", - "expiry_date": "2050-12-31" - }, + validity={"issuance_date": "2024-12-31", "expiry_date": "2050-12-31"}, status={ - "status_list": { - "idx": 412, - "uri": "https://example.com/statuslists/1" - } - } + "status_list": {"idx": 412, "uri": "https://example.com/statuslists/1"} + }, ) - data = cbor2.dumps(mdoc) + data = cbor2.dumps(mdoc, datetime_as_timestamp=True) mdocp = MdocCbor() mdocp.loads(data) mdocp.verify() assert mdoc - assert 'org.micov.medical.1' in mdocp.disclosure_map - assert mdocp.disclosure_map == MICOV_DATA + assert "org.micov.medical.1" in mdocp.disclosure_map + + assert normalize_dates(mdocp.disclosure_map) == normalize_dates(MICOV_DATA) assert mdocp.status == { - "status_list": { - "idx": 412, - "uri": "https://example.com/statuslists/1" - } + "status_list": {"idx": 412, "uri": "https://example.com/statuslists/1"} } + def test_mdoc_cbor_invalid_status(): - mdoci = MdocCborIssuer( - private_key=PKEY, - alg="ES256", - cert_info=CERT_DATA - ) + mdoci = MdocCborIssuer(private_key=PKEY, alg="ES256", cert_info=CERT_DATA) try: mdoci.new( data=MICOV_DATA, - #devicekeyinfo=PKEY, # TODO + # devicekeyinfo=PKEY, # TODO doctype="org.micov.medical.1", - validity={ - "issuance_date": "2024-12-31", - "expiry_date": "2050-12-31" - }, + validity={"issuance_date": "2024-12-31", "expiry_date": "2050-12-31"}, status={ "status_list": { "idx": 412, # "uri": "https://example.com/statuslists/1" # Missing URI } - } + }, ) except Exception as e: assert str(e) == "uri is required" @@ -73,18 +67,15 @@ def test_mdoc_cbor_invalid_status(): try: mdoci.new( data=MICOV_DATA, - #devicekeyinfo=PKEY, # TODO + # devicekeyinfo=PKEY, # TODO doctype="org.micov.medical.1", - validity={ - "issuance_date": "2024-12-31", - "expiry_date": "2050-12-31" - }, + validity={"issuance_date": "2024-12-31", "expiry_date": "2050-12-31"}, status={ "status_list": { - #"idx": 412, + # "idx": 412, "uri": "https://example.com/statuslists/1" # Missing URI } - } + }, ) except Exception as e: assert str(e) == "idx is required" @@ -92,18 +83,15 @@ def test_mdoc_cbor_invalid_status(): try: mdoci.new( data=MICOV_DATA, - #devicekeyinfo=PKEY, # TODO + # devicekeyinfo=PKEY, # TODO doctype="org.micov.medical.1", - validity={ - "issuance_date": "2024-12-31", - "expiry_date": "2050-12-31" - }, + validity={"issuance_date": "2024-12-31", "expiry_date": "2050-12-31"}, status={ "not_status_list": { "idx": 412, - "uri": "https://example.com/statuslists/1" # Missing URI + "uri": "https://example.com/statuslists/1", # Missing URI } - } + }, ) except Exception as e: - assert str(e) == "status_list is required" \ No newline at end of file + assert str(e) == "status_list is required" diff --git a/requirements-dev.txt b/requirements-dev.txt index d1cbabb..bba41c6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,4 +7,4 @@ autoflake bandit autopep8 pycose>=1.0.1 -cbor2>=5.4.0,<5.5.0 \ No newline at end of file +cbor2>=5.4.0 diff --git a/setup.py b/setup.py index b4c7076..295ec91 100644 --- a/setup.py +++ b/setup.py @@ -35,9 +35,5 @@ def readme(): # scripts=[f'{_pkg_name}/bin/{_pkg_name}'], packages=find_packages(include=["pymdoccbor", "pymdoccbor.*"]), include_package_data=True, - install_requires=[ - "cbor2>=5.4.0,<5.5.0", - "cbor-diag>=1.1.0,<1.2", - "pycose>=1.0.1" - ], + install_requires=["cbor2>=5.4.0", "cbor-diag>=1.1.0", "pycose>=1.0.1"], )