# Path: esteid/exceptions.py
# class InvalidParameter(InvalidParameters):
#     """Invalid initialization parameter PARAM received from the request.
# 
#     Takes a `param` kwarg
#     """
# 
#     default_message = _("Invalid value for parameter {param}.")
# 
#     def __init__(self, message=None, *, param, **kwargs):
#         super().__init__(message)
#         self.kwargs = {**kwargs, "param": param}
# 
# Path: esteid/idcard/signer.py
# class IdCardSigner(Signer):
#     certificate: bytes
# 
#     _certificate_handle: "OsCryptoCertificate"
# 
#     @property
#     def id_code(self) -> str:
#         try:
#             certificate_handle = self._certificate_handle
#         except AttributeError as e:
#             raise AttributeError("Attribute id_code not available: certificate not provided") from e
# 
#         cert_holder_info = CertificateHolderInfo.from_certificate(certificate_handle)
#         return cert_holder_info.id_code
# 
#     def setup(self, initial_data: dict = None):
#         """
#         Receives a user certificate from the front end
#         """
#         try:
#             certificate_hex = initial_data["certificate"]
#         except (TypeError, KeyError) as e:
#             raise InvalidParameter("Missing required parameter 'certificate'", param="certificate") from e
# 
#         try:
#             certificate = binascii.a2b_hex(certificate_hex)
#         except (TypeError, ValueError) as e:
#             raise InvalidParameter(
#                 "Failed to decode parameter `certificate` from hex-encoding", param="certificate"
#             ) from e
# 
#         try:
#             self._certificate_handle = load_certificate(certificate)
#         except ValueError as e:
#             raise InvalidParameter(
#                 "Failed to recognize `certificate` as a supported certificate format", param="certificate"
#             ) from e
# 
#         self.certificate = certificate
# 
#     def prepare(self, container: pyasice.Container = None, files: List[DataFile] = None) -> dict:
#         container = self.open_container(container, files)
#         xml_sig = container.prepare_signature(self.certificate)
# 
#         # Note: uses default digest algorithm (sha256)
#         signed_digest = xml_sig.digest()
# 
#         self.save_session_data(digest=signed_digest, container=container, xml_sig=xml_sig)
# 
#         return {
#             # hex-encoded digest to be consumed by the hwcrypto.js library
#             "digest": binascii.b2a_hex(signed_digest).decode(),
#         }
# 
#     def finalize(self, data: dict = None) -> pyasice.Container:
#         try:
#             signature_value = data["signature_value"]
#         except (TypeError, KeyError) as e:
#             raise InvalidParameter("Missing required parameter 'signature_value'", param="signature_value") from e
# 
#         try:
#             signature_value = binascii.a2b_hex(signature_value)
#         except (TypeError, ValueError) as e:
#             raise InvalidParameter(
#                 "Failed to decode parameter `signature_value` from hex-encoding", param="signature_value"
#             ) from e
# 
#         temp_signature_file = self.session_data.temp_signature_file
#         temp_container_file = self.session_data.temp_container_file
#         digest = self.session_data.digest
# 
#         with open(temp_signature_file, "rb") as f:
#             xml_sig = pyasice.XmlSignature(f.read())
# 
#         try:
#             pyasice.verify(xml_sig.get_certificate_value(), signature_value, digest, prehashed=True)
#         except pyasice.SignatureVerificationError as e:
#             raise SignatureVerificationError from e
# 
#         container = pyasice.Container.open(temp_container_file)
# 
#         xml_sig.set_signature_value(signature_value)
# 
#         self.finalize_xml_signature(xml_sig)
# 
#         container.add_signature(xml_sig)
# 
#         return container
# 
# Path: esteid/idcard/signer.py
# class IdCardSigner(Signer):
#     def id_code(self) -> str:
#     def setup(self, initial_data: dict = None):
#     def prepare(self, container: pyasice.Container = None, files: List[DataFile] = None) -> dict:
#     def finalize(self, data: dict = None) -> pyasice.Container:


import binascii
import os
import pytest
from tempfile import NamedTemporaryFile
from time import time
from unittest.mock import Mock, patch
from esteid.exceptions import InvalidParameter
from esteid.idcard import IdCardSigner
from esteid.idcard import signer as signer_module
    signer = IdCardSigner({}, initial=True)
    mock_container = Mock(name="mock_container")
    with patch.object(signer, "open_container", return_value=mock_container), patch.object(signer, "save_session_data"):
        mock_container.prepare_signature.return_value = mock_xml_sig = Mock(name="mock_xml_sig")
        mock_xml_sig.digest.return_value = b"some binary digest"

        yield signer


@pytest.fixture()
def idcard_session_data():
    with NamedTemporaryFile("wb", delete=False) as f:
        f.write(b"xml signature data")
    yield IdCardSigner.SessionData(
        {
            "digest_b64": "MTIz",
            "temp_signature_file": f.name,
            "temp_container_file": "...",
            "timestamp": int(time()),
        }
    )
    os.remove(f.name)


def test_idcardsigner_certificate(static_certificate):
    signer = IdCardSigner({}, initial=True)
    signer.setup({"certificate": binascii.b2a_hex(static_certificate)})

    assert signer.id_code == "11702020200"


# Path: esteid/exceptions.py
# class InvalidParameter(InvalidParameters):
#     """Invalid initialization parameter PARAM received from the request.
# 
#     Takes a `param` kwarg
#     """
# 
#     default_message = _("Invalid value for parameter {param}.")
# 
#     def __init__(self, message=None, *, param, **kwargs):
#         super().__init__(message)
#         self.kwargs = {**kwargs, "param": param}
# 
# Path: esteid/idcard/signer.py
# class IdCardSigner(Signer):
#     certificate: bytes
# 
#     _certificate_handle: "OsCryptoCertificate"
# 
#     @property
#     def id_code(self) -> str:
#         try:
#             certificate_handle = self._certificate_handle
#         except AttributeError as e:
#             raise AttributeError("Attribute id_code not available: certificate not provided") from e
# 
#         cert_holder_info = CertificateHolderInfo.from_certificate(certificate_handle)
#         return cert_holder_info.id_code
# 
#     def setup(self, initial_data: dict = None):
#         """
#         Receives a user certificate from the front end
#         """
#         try:
#             certificate_hex = initial_data["certificate"]
#         except (TypeError, KeyError) as e:
#             raise InvalidParameter("Missing required parameter 'certificate'", param="certificate") from e
# 
#         try:
#             certificate = binascii.a2b_hex(certificate_hex)
#         except (TypeError, ValueError) as e:
#             raise InvalidParameter(
#                 "Failed to decode parameter `certificate` from hex-encoding", param="certificate"
#             ) from e
# 
#         try:
#             self._certificate_handle = load_certificate(certificate)
#         except ValueError as e:
#             raise InvalidParameter(
#                 "Failed to recognize `certificate` as a supported certificate format", param="certificate"
#             ) from e
# 
#         self.certificate = certificate
# 
#     def prepare(self, container: pyasice.Container = None, files: List[DataFile] = None) -> dict:
#         container = self.open_container(container, files)
#         xml_sig = container.prepare_signature(self.certificate)
# 
#         # Note: uses default digest algorithm (sha256)
#         signed_digest = xml_sig.digest()
# 
#         self.save_session_data(digest=signed_digest, container=container, xml_sig=xml_sig)
# 
#         return {
#             # hex-encoded digest to be consumed by the hwcrypto.js library
#             "digest": binascii.b2a_hex(signed_digest).decode(),
#         }
# 
#     def finalize(self, data: dict = None) -> pyasice.Container:
#         try:
#             signature_value = data["signature_value"]
#         except (TypeError, KeyError) as e:
#             raise InvalidParameter("Missing required parameter 'signature_value'", param="signature_value") from e
# 
#         try:
#             signature_value = binascii.a2b_hex(signature_value)
#         except (TypeError, ValueError) as e:
#             raise InvalidParameter(
#                 "Failed to decode parameter `signature_value` from hex-encoding", param="signature_value"
#             ) from e
# 
#         temp_signature_file = self.session_data.temp_signature_file
#         temp_container_file = self.session_data.temp_container_file
#         digest = self.session_data.digest
# 
#         with open(temp_signature_file, "rb") as f:
#             xml_sig = pyasice.XmlSignature(f.read())
# 
#         try:
#             pyasice.verify(xml_sig.get_certificate_value(), signature_value, digest, prehashed=True)
#         except pyasice.SignatureVerificationError as e:
#             raise SignatureVerificationError from e
# 
#         container = pyasice.Container.open(temp_container_file)
# 
#         xml_sig.set_signature_value(signature_value)
# 
#         self.finalize_xml_signature(xml_sig)
# 
#         container.add_signature(xml_sig)
# 
#         return container
# 
# Path: esteid/idcard/signer.py
# class IdCardSigner(Signer):
#     def id_code(self) -> str:
#     def setup(self, initial_data: dict = None):
#     def prepare(self, container: pyasice.Container = None, files: List[DataFile] = None) -> dict:
#     def finalize(self, data: dict = None) -> pyasice.Container:


# Path: esteid/idcard/tests/test_idcardsigner.py
import binascii
import os
import pytest
from tempfile import NamedTemporaryFile
from time import time
from unittest.mock import Mock, patch
from esteid.exceptions import InvalidParameter
from esteid.idcard import IdCardSigner
from esteid.idcard import signer as signer_module

    signer = IdCardSigner({}, initial=True)
    mock_container = Mock(name="mock_container")
    with patch.object(signer, "open_container", return_value=mock_container), patch.object(signer, "save_session_data"):
        mock_container.prepare_signature.return_value = mock_xml_sig = Mock(name="mock_xml_sig")
        mock_xml_sig.digest.return_value = b"some binary digest"

        yield signer


@pytest.fixture()
def idcard_session_data():
    with NamedTemporaryFile("wb", delete=False) as f:
        f.write(b"xml signature data")
    yield IdCardSigner.SessionData(
        {
            "digest_b64": "MTIz",
            "temp_signature_file": f.name,
            "temp_container_file": "...",
            "timestamp": int(time()),
        }
    )
    os.remove(f.name)


def test_idcardsigner_certificate(static_certificate):
    signer = IdCardSigner({}, initial=True)
    signer.setup({"certificate": binascii.b2a_hex(static_certificate)})

    assert signer.id_code == "11702020200"


    with pytest.raises(InvalidParameter, match="Missing required parameter 'certificate'"):