From 244a575be6042bdb661a9b84926371e046b52ad4 Mon Sep 17 00:00:00 2001 From: Sergey Kovalskiy Date: Mon, 16 Dec 2024 17:33:24 +0200 Subject: [PATCH] fix: support loading hex certificates For unknown reason, sometimes certificates come encoded as hex string, not as base64. --- esteid/idcard/signer.py | 55 ++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/esteid/idcard/signer.py b/esteid/idcard/signer.py index 27c3871..89e4b60 100644 --- a/esteid/idcard/signer.py +++ b/esteid/idcard/signer.py @@ -35,6 +35,19 @@ def id_code(self) -> str: cert_holder_info = CertificateHolderInfo.from_certificate(certificate_handle) return cert_holder_info.id_code + @classmethod + def _load_from_base64(self, data: str): + try: + certificate_bin = base64.b64decode(certificate_hex) + except binascii.Error: + raise ValueError("Invalid base64 string") from e + return load_certificate(certificate_bin) + + @classmethod + def _load_from_hex(self, data: str): + certificate_bin = bytes(bytearray.fromhex(certificate_hex)) + return load_certificate(certificate_bin) + def setup(self, initial_data: dict = None): """ Receives a user certificate from the front end @@ -50,32 +63,22 @@ def setup(self, initial_data: dict = None): raise InvalidParameter("Missing required parameter 'certificate'", param="certificate") from e try: - certificate = base64.b64decode(certificate_hex) - except binascii.Error as e: - if settings.ESTEID_ID_CARD_VERBOSE_ERRORS: - logger.exception( - "Failed to decode parameter `certificate` from DER encoding. " - "Certificate HEX representation: %r", - certificate_hex, - ) - raise InvalidParameter( - "Failed to decode parameter `certificate` from DER encoding", param="certificate" - ) from e - - try: - self._certificate_handle = load_certificate(certificate) - except ValueError as e: - if settings.ESTEID_ID_CARD_VERBOSE_ERRORS: - logger.exception( - "Failed to recognize `certificate` as a supported certificate format. " - "Certificate HEX representation: %r", - certificate_hex, - ) - raise InvalidParameter( - "Failed to recognize `certificate` as a supported certificate format", param="certificate" - ) from e - - self.certificate = certificate + self._certificate_handle = self._load_from_hex(certificate_hex) + except ValueError: + try: + self._certificate_handle = self._load_from_base64(certificate_hex) + except ValueError: + if settings.ESTEID_ID_CARD_VERBOSE_ERRORS: + logger.exception( + "Failed to recognize `certificate` as a supported certificate format. " + "Certificate representation: %r", + certificate_hex, + ) + raise InvalidParameter( + "Failed to recognize `certificate` as a supported certificate format", param="certificate" + ) from e + + self.certificate = self._certificate_handle.asn1.dump() def prepare(self, container: pyasice.Container = None, files: List[DataFile] = None) -> dict: container = self.open_container(container, files)