From 266cba1b3ba317e20d9a8e35c2267ae5462cc03a Mon Sep 17 00:00:00 2001 From: masv3971 Date: Thu, 26 Oct 2023 10:53:59 +0200 Subject: [PATCH] Add transaction_id in pdf keywords. --- .vscode/settings.json | 7 +- Makefile | 4 +- src/pkcs11_ca_service/common/__init__.py | 1 + src/pkcs11_ca_service/common/helpers.py | 1 + src/pkcs11_ca_service/pdf/__init__.py | 1 + src/pkcs11_ca_service/pdf/app.py | 28 +++--- src/pkcs11_ca_service/pdf/exceptions.py | 2 + src/pkcs11_ca_service/pdf/models.py | 23 ++--- src/pkcs11_ca_service/pdf/routers/__init__.py | 1 + src/pkcs11_ca_service/pdf/routers/pdf.py | 22 ++--- src/pkcs11_ca_service/pdf/routers/status.py | 2 + .../pdf/routers/utils/pdf.py | 85 ++++++++++++------- .../pdf/routers/utils/status.py | 11 +-- src/pkcs11_ca_service/pdf/tests/test_sign.py | 12 +++ 14 files changed, 126 insertions(+), 74 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index dc1097d..d5914f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "addsig", "asyncpg", + "certvalidator", "fastapi", "HEALTHCHECK", "jsonschema", @@ -17,5 +18,9 @@ "secp", "subfilter", "timestamper" - ] + ], + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + }, + "python.formatting.provider": "none" } \ No newline at end of file diff --git a/Makefile b/Makefile index fead20f..6fc0729 100644 --- a/Makefile +++ b/Makefile @@ -36,12 +36,14 @@ ci: docker-build docker-push vscode_venv: $(info Creating virtualenv in devcontainer) + python3 -m venv .venv vscode_pip: vscode_venv $(info Installing pip packages in devcontainer) pip3 install --upgrade pip pip3 install pip-tools - pip3 install -r requirements.txt + .venv/bin/pip install -r requirements.txt +# .venv/bin/mypy --install-types vscode_packages: $(info Installing apt packages in devcontainer) diff --git a/src/pkcs11_ca_service/common/__init__.py b/src/pkcs11_ca_service/common/__init__.py index b3ef18e..5c48a1f 100644 --- a/src/pkcs11_ca_service/common/__init__.py +++ b/src/pkcs11_ca_service/common/__init__.py @@ -1 +1,2 @@ +"""common""" __author__ = "masv" diff --git a/src/pkcs11_ca_service/common/helpers.py b/src/pkcs11_ca_service/common/helpers.py index eef566d..d992457 100644 --- a/src/pkcs11_ca_service/common/helpers.py +++ b/src/pkcs11_ca_service/common/helpers.py @@ -1,3 +1,4 @@ +"""helpers""" import time from datetime import datetime, timezone diff --git a/src/pkcs11_ca_service/pdf/__init__.py b/src/pkcs11_ca_service/pdf/__init__.py index b3ef18e..f4f5126 100644 --- a/src/pkcs11_ca_service/pdf/__init__.py +++ b/src/pkcs11_ca_service/pdf/__init__.py @@ -1 +1,2 @@ +"""pdf""" __author__ = "masv" diff --git a/src/pkcs11_ca_service/pdf/app.py b/src/pkcs11_ca_service/pdf/app.py index 9af07b5..0bc1836 100644 --- a/src/pkcs11_ca_service/pdf/app.py +++ b/src/pkcs11_ca_service/pdf/app.py @@ -1,15 +1,15 @@ +"""pdf app""" + import logging -# from logging import Logger, getLogger + from fastapi import FastAPI -from typing import Optional from pyhanko.sign import signers, SimpleSigner, timestamps from pyhanko.keys import load_cert_from_pemder from pyhanko_certvalidator import ValidationContext -from pkcs11_ca_service.common.helpers import unix_ts from pkcs11_ca_service.pdf.context import ContextRequestRoute from pkcs11_ca_service.pdf.routers.pdf import pdf_router from pkcs11_ca_service.pdf.routers.status import status_router -from .exceptions import ( +from pkcs11_ca_service.pdf.exceptions import ( RequestValidationError, validation_exception_handler, HTTPErrorDetail, @@ -22,10 +22,7 @@ class PDFAPI(FastAPI): """PDF API""" - def __init__(self, - service_name: str = "pdf_api", - timestamp_url: str = "http://ca:8005/timestamp01" - ): + def __init__(self, service_name: str = "pdf_api", timestamp_url: str = "http://ca:8005/timestamp01"): self.service_name = service_name self.logger = logging.getLogger(self.service_name) self.logger.setLevel(logging.DEBUG) @@ -35,9 +32,7 @@ def __init__(self, ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) - formatter = logging.Formatter( - '%(asctime)s - %(name)s - %(levelname)s - %(message)s' - ) + formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") ch.setFormatter(formatter) @@ -60,11 +55,12 @@ def __init__(self, self.logger.info(msg=f"cert_path: {self.cert_path}") self.logger.info(msg=f"key_path: {self.key_path}") - self.cms_signer: Optional[SimpleSigner] = signers.SimpleSigner.load( + self.simple_signer: SimpleSigner = signers.SimpleSigner.load( key_file=self.key_path, cert_file=self.cert_path, # ca_chain_files=(self.chain_path), - signature_mechanism=None) + # signature_mechanism=None + ) self.cert_pemder = load_cert_from_pemder(self.cert_path) @@ -85,10 +81,8 @@ def init_api(service_name: str = "pdf_api") -> PDFAPI: app.include_router(status_router) # Exception handling - app.add_exception_handler(RequestValidationError, - validation_exception_handler) - app.add_exception_handler( - HTTPErrorDetail, http_error_detail_handler) + app.add_exception_handler(RequestValidationError, validation_exception_handler) + app.add_exception_handler(HTTPErrorDetail, http_error_detail_handler) app.add_exception_handler(Exception, unexpected_error_handler) app.logger.info(msg="app running...") diff --git a/src/pkcs11_ca_service/pdf/exceptions.py b/src/pkcs11_ca_service/pdf/exceptions.py index 13e08b2..c80857f 100644 --- a/src/pkcs11_ca_service/pdf/exceptions.py +++ b/src/pkcs11_ca_service/pdf/exceptions.py @@ -1,3 +1,5 @@ +"""pdf exceptions""" + from __future__ import annotations import logging diff --git a/src/pkcs11_ca_service/pdf/models.py b/src/pkcs11_ca_service/pdf/models.py index 680c897..3bfb391 100644 --- a/src/pkcs11_ca_service/pdf/models.py +++ b/src/pkcs11_ca_service/pdf/models.py @@ -1,6 +1,7 @@ -from pydantic import BaseModel, validator +"""pdf model""" + from typing import Optional -from datetime import datetime +from pydantic import BaseModel, validator class PDFSignRequest(BaseModel): @@ -24,29 +25,29 @@ class PDFSignReply(BaseModel): """Class to represent reply""" transaction_id: str - data: str - error: str + data: Optional[str] = None + error: Optional[str] = None create_ts: Optional[int] class PDFValidateRequest(BaseModel): """Class to represent request""" - data: str - -class PDFValidateData(BaseModel): - """Class to represent validation data""" - valid: bool + data: str class PDFValidateReply(BaseModel): """Class to represent reply""" - data: PDFValidateData - error: str + + valid_signature: bool = False + transaction_id: Optional[str] = None + is_revoked: bool = False + error: Optional[str] = None class StatusReply(BaseModel): """Class to represent status reply""" + status: str message: Optional[str] = None last_check: int diff --git a/src/pkcs11_ca_service/pdf/routers/__init__.py b/src/pkcs11_ca_service/pdf/routers/__init__.py index b3ef18e..bcf1236 100644 --- a/src/pkcs11_ca_service/pdf/routers/__init__.py +++ b/src/pkcs11_ca_service/pdf/routers/__init__.py @@ -1 +1,2 @@ +"""http router""" __author__ = "masv" diff --git a/src/pkcs11_ca_service/pdf/routers/pdf.py b/src/pkcs11_ca_service/pdf/routers/pdf.py index 21aeb73..e41c33a 100644 --- a/src/pkcs11_ca_service/pdf/routers/pdf.py +++ b/src/pkcs11_ca_service/pdf/routers/pdf.py @@ -1,3 +1,5 @@ +"""pdf router""" + from typing import Any from fastapi import APIRouter from pkcs11_ca_service.pdf.routers.utils.pdf import sign, validate @@ -19,24 +21,24 @@ @pdf_router.post("/sign", response_model=PDFSignReply) def endpoint_sign_pdf(req: ContextRequest, in_data: PDFSignRequest) -> Any: - """ endpoint for signing a base64 encoded PDF """ + """endpoint for signing a base64 encoded PDF""" - req.app.logger.info( - f"Received a base64 PDF, transaction_id: {in_data.transaction_id}") + req.app.logger.info(f"Received a base64 PDF, transaction_id: {in_data.transaction_id}") - reply = sign(req=req, - transaction_id=in_data.transaction_id, - base64_pdf=in_data.data, - reason=in_data.reason, - location=in_data.location, - ) + reply = sign( + req=req, + transaction_id=in_data.transaction_id, + base64_pdf=in_data.data, + reason=in_data.reason, + location=in_data.location, + ) return reply @pdf_router.post("/validate", response_model=PDFValidateReply) def endpoint_validate_pdf(req: ContextRequest, in_data: PDFValidateRequest) -> Any: - """ endpoint for validation of a base64 encoded PDF """ + """endpoint for validation of a base64 encoded PDF""" req.app.logger.info("Validate a signed base64 PDF") diff --git a/src/pkcs11_ca_service/pdf/routers/status.py b/src/pkcs11_ca_service/pdf/routers/status.py index f2687b7..8eb6e9b 100644 --- a/src/pkcs11_ca_service/pdf/routers/status.py +++ b/src/pkcs11_ca_service/pdf/routers/status.py @@ -1,3 +1,5 @@ +"""status router""" + from typing import Any from fastapi import APIRouter from pkcs11_ca_service.pdf.routers.utils.status import healthy diff --git a/src/pkcs11_ca_service/pdf/routers/utils/pdf.py b/src/pkcs11_ca_service/pdf/routers/utils/pdf.py index 2e893a4..4ba6d36 100644 --- a/src/pkcs11_ca_service/pdf/routers/utils/pdf.py +++ b/src/pkcs11_ca_service/pdf/routers/utils/pdf.py @@ -1,30 +1,33 @@ +"""pdf utils""" + import base64 from io import BytesIO -from pkcs11_ca_service.common.helpers import unix_ts +from typing import Optional from pyhanko.sign import signers from pyhanko.sign.fields import SigSeedSubFilter from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter from pyhanko.sign.validation import validate_pdf_signature from pyhanko.pdf_utils.reader import PdfFileReader -from pkcs11_ca_service.pdf.models import PDFSignReply, PDFValidateReply, PDFValidateData +from pyhanko.pdf_utils.crypt.api import PdfKeyNotAvailableError +from pkcs11_ca_service.pdf.models import PDFSignReply, PDFValidateReply from pkcs11_ca_service.pdf.context import ContextRequest +from pkcs11_ca_service.common.helpers import unix_ts + def sign(req: ContextRequest, transaction_id: str, base64_pdf: str, reason: str, location: str) -> PDFSignReply: """sign a PDF""" - req.app.logger.info( - msg=f"Trying to sign the PDF, transaction_id: {transaction_id}" - ) - pdf_writer = IncrementalPdfFileWriter( - input_stream=BytesIO(base64.b64decode(base64_pdf)) - ) + req.app.logger.info(msg=f"Trying to sign the PDF, transaction_id: {transaction_id}") + pdf_writer = IncrementalPdfFileWriter(input_stream=BytesIO(base64.urlsafe_b64decode(base64_pdf)), strict=False) + + pdf_writer.document_meta.keywords = [f"transaction_id:{transaction_id}"] - f = BytesIO() + signed_pdf = BytesIO() signature_meta = signers.PdfSignatureMetadata( - field_name='Signature1', + field_name="Signature1", location=location, reason=reason, subfilter=SigSeedSubFilter.PADES, @@ -33,21 +36,31 @@ def sign(req: ContextRequest, transaction_id: str, base64_pdf: str, reason: str, validation_context=req.app.validator_context, ) - signers.sign_pdf( - pdf_writer, - signature_meta=signature_meta, - signer=req.app.cms_signer, - output=f, - # timestamper=req.app.tst_client, - ) + try: + signers.sign_pdf( + pdf_writer, + signature_meta=signature_meta, + signer=req.app.simple_signer, + output=signed_pdf, + # timestamper=req.app.tst_client, + ) + except PdfKeyNotAvailableError as _e: + err_msg = f"ca_pdfsign: input pdf is encrypted, err: {_e}" - base64_encoded = base64.b64encode(f.getvalue()).decode("utf-8") + req.app.logger.warn(err_msg) - req.app.logger.info( - msg=f"Successfully signed the PDF, transaction_id: {transaction_id}" - ) + return PDFSignReply( + transaction_id=transaction_id, + data=None, + create_ts=unix_ts(), + error=err_msg, + ) - f.close() + base64_encoded = base64.b64encode(signed_pdf.getvalue()).decode("utf-8") + + req.app.logger.info(msg=f"Successfully signed the PDF, transaction_id: {transaction_id}") + + signed_pdf.close() return PDFSignReply( transaction_id=transaction_id, @@ -57,14 +70,24 @@ def sign(req: ContextRequest, transaction_id: str, base64_pdf: str, reason: str, ) +def get_transaction_id_from_keywords(req: ContextRequest, pdf: PdfFileReader) -> Optional[str]: + """simple function to get transaction_id from a list of keywords""" + for keyword in pdf.document_meta_view.keywords: + entry = keyword.split(sep=":") + if entry[0] == "transaction_id": + req.app.logger.info(msg=f"found transaction_id: {entry[1]}") + return entry[1] + return None + def validate(req: ContextRequest, base64_pdf: str) -> PDFValidateReply: """validate a PDF""" req.app.logger.info(msg="Trying to validate the PDF") - pdf = PdfFileReader( - BytesIO(base64.b64decode(base64_pdf.encode("utf-8"), validate=True)) - ) + pdf = PdfFileReader(BytesIO(base64.b64decode(base64_pdf.encode("utf-8"), validate=True))) + + if len(pdf.embedded_signatures) == 0: + return PDFValidateReply(error="No signature found") sig = pdf.embedded_signatures[0] status = validate_pdf_signature( @@ -72,6 +95,10 @@ def validate(req: ContextRequest, base64_pdf: str) -> PDFValidateReply: signer_validation_context=req.app.validator_context, ) + transaction_id = get_transaction_id_from_keywords(req=req, pdf=pdf) + + req.app.logger.info(msg=f"status: {status}") + # status_ltv = validate_pdf_ltv_signature( # sig, # RevocationInfoValidationType.PADES_LTA, @@ -80,9 +107,9 @@ def validate(req: ContextRequest, base64_pdf: str) -> PDFValidateReply: # req.app.logger.info(msg=status_ltv.pretty_print_details()) + req.app.logger.info(msg="Successfully validate PDF") + return PDFValidateReply( - data=PDFValidateData( - valid=status.valid, - ), - error="", + valid_signature=status.valid, + transaction_id= transaction_id, ) diff --git a/src/pkcs11_ca_service/pdf/routers/utils/status.py b/src/pkcs11_ca_service/pdf/routers/utils/status.py index 61981ba..c4e8aac 100644 --- a/src/pkcs11_ca_service/pdf/routers/utils/status.py +++ b/src/pkcs11_ca_service/pdf/routers/utils/status.py @@ -1,4 +1,4 @@ -from datetime import timedelta +"""status utils""" from pkcs11_ca_service.common.helpers import unix_ts from pkcs11_ca_service.pdf.models import StatusReply from pkcs11_ca_service.pdf.context import ContextRequest @@ -13,12 +13,13 @@ def healthy(req: ContextRequest) -> StatusReply: if now > req.app.status_storage.next_check: pdf = "JVBERi0xLjMNCiXi48/TDQoNCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YWxvZw0KL091dGxpbmVzIDIgMCBSDQovUGFnZXMgMyAwIFINCj4+DQplbmRvYmoNCg0KMiAwIG9iag0KPDwNCi9UeXBlIC9PdXRsaW5lcw0KL0NvdW50IDANCj4+DQplbmRvYmoNCg0KMyAwIG9iag0KPDwNCi9UeXBlIC9QYWdlcw0KL0NvdW50IDINCi9LaWRzIFsgNCAwIFIgNiAwIFIgXSANCj4+DQplbmRvYmoNCg0KNCAwIG9iag0KPDwNCi9UeXBlIC9QYWdlDQovUGFyZW50IDMgMCBSDQovUmVzb3VyY2VzIDw8DQovRm9udCA8PA0KL0YxIDkgMCBSIA0KPj4NCi9Qcm9jU2V0IDggMCBSDQo+Pg0KL01lZGlhQm94IFswIDAgNjEyLjAwMDAgNzkyLjAwMDBdDQovQ29udGVudHMgNSAwIFINCj4+DQplbmRvYmoNCg0KNSAwIG9iag0KPDwgL0xlbmd0aCAxMDc0ID4+DQpzdHJlYW0NCjIgSg0KQlQNCjAgMCAwIHJnDQovRjEgMDAyNyBUZg0KNTcuMzc1MCA3MjIuMjgwMCBUZA0KKCBBIFNpbXBsZSBQREYgRmlsZSApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY4OC42MDgwIFRkDQooIFRoaXMgaXMgYSBzbWFsbCBkZW1vbnN0cmF0aW9uIC5wZGYgZmlsZSAtICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjY0LjcwNDAgVGQNCigganVzdCBmb3IgdXNlIGluIHRoZSBWaXJ0dWFsIE1lY2hhbmljcyB0dXRvcmlhbHMuIE1vcmUgdGV4dC4gQW5kIG1vcmUgKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NTIuNzUyMCBUZA0KKCB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDYyOC44NDgwIFRkDQooIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjE2Ljg5NjAgVGQNCiggdGV4dC4gQW5kIG1vcmUgdGV4dC4gQm9yaW5nLCB6enp6ei4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNjA0Ljk0NDAgVGQNCiggbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDU5Mi45OTIwIFRkDQooIEFuZCBtb3JlIHRleHQuIEFuZCBtb3JlIHRleHQuICkgVGoNCkVUDQpCVA0KL0YxIDAwMTAgVGYNCjY5LjI1MDAgNTY5LjA4ODAgVGQNCiggQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA1NTcuMTM2MCBUZA0KKCB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBFdmVuIG1vcmUuIENvbnRpbnVlZCBvbiBwYWdlIDIgLi4uKSBUag0KRVQNCmVuZHN0cmVhbQ0KZW5kb2JqDQoNCjYgMCBvYmoNCjw8DQovVHlwZSAvUGFnZQ0KL1BhcmVudCAzIDAgUg0KL1Jlc291cmNlcyA8PA0KL0ZvbnQgPDwNCi9GMSA5IDAgUiANCj4+DQovUHJvY1NldCA4IDAgUg0KPj4NCi9NZWRpYUJveCBbMCAwIDYxMi4wMDAwIDc5Mi4wMDAwXQ0KL0NvbnRlbnRzIDcgMCBSDQo+Pg0KZW5kb2JqDQoNCjcgMCBvYmoNCjw8IC9MZW5ndGggNjc2ID4+DQpzdHJlYW0NCjIgSg0KQlQNCjAgMCAwIHJnDQovRjEgMDAyNyBUZg0KNTcuMzc1MCA3MjIuMjgwMCBUZA0KKCBTaW1wbGUgUERGIEZpbGUgMiApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY4OC42MDgwIFRkDQooIC4uLmNvbnRpbnVlZCBmcm9tIHBhZ2UgMS4gWWV0IG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NzYuNjU2MCBUZA0KKCBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSB0ZXh0LiBBbmQgbW9yZSApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY2NC43MDQwIFRkDQooIHRleHQuIE9oLCBob3cgYm9yaW5nIHR5cGluZyB0aGlzIHN0dWZmLiBCdXQgbm90IGFzIGJvcmluZyBhcyB3YXRjaGluZyApIFRqDQpFVA0KQlQNCi9GMSAwMDEwIFRmDQo2OS4yNTAwIDY1Mi43NTIwIFRkDQooIHBhaW50IGRyeS4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gQW5kIG1vcmUgdGV4dC4gKSBUag0KRVQNCkJUDQovRjEgMDAxMCBUZg0KNjkuMjUwMCA2NDAuODAwMCBUZA0KKCBCb3JpbmcuICBNb3JlLCBhIGxpdHRsZSBtb3JlIHRleHQuIFRoZSBlbmQsIGFuZCBqdXN0IGFzIHdlbGwuICkgVGoNCkVUDQplbmRzdHJlYW0NCmVuZG9iag0KDQo4IDAgb2JqDQpbL1BERiAvVGV4dF0NCmVuZG9iag0KDQo5IDAgb2JqDQo8PA0KL1R5cGUgL0ZvbnQNCi9TdWJ0eXBlIC9UeXBlMQ0KL05hbWUgL0YxDQovQmFzZUZvbnQgL0hlbHZldGljYQ0KL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcNCj4+DQplbmRvYmoNCg0KMTAgMCBvYmoNCjw8DQovQ3JlYXRvciAoUmF2ZSBcKGh0dHA6Ly93d3cubmV2cm9uYS5jb20vcmF2ZVwpKQ0KL1Byb2R1Y2VyIChOZXZyb25hIERlc2lnbnMpDQovQ3JlYXRpb25EYXRlIChEOjIwMDYwMzAxMDcyODI2KQ0KPj4NCmVuZG9iag0KDQp4cmVmDQowIDExDQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwMDAwMTkgMDAwMDAgbg0KMDAwMDAwMDA5MyAwMDAwMCBuDQowMDAwMDAwMTQ3IDAwMDAwIG4NCjAwMDAwMDAyMjIgMDAwMDAgbg0KMDAwMDAwMDM5MCAwMDAwMCBuDQowMDAwMDAxNTIyIDAwMDAwIG4NCjAwMDAwMDE2OTAgMDAwMDAgbg0KMDAwMDAwMjQyMyAwMDAwMCBuDQowMDAwMDAyNDU2IDAwMDAwIG4NCjAwMDAwMDI1NzQgMDAwMDAgbg0KDQp0cmFpbGVyDQo8PA0KL1NpemUgMTENCi9Sb290IDEgMCBSDQovSW5mbyAxMCAwIFINCj4+DQoNCnN0YXJ0eHJlZg0KMjcxNA0KJSVFT0YNCg==" - signed_pdf = sign(req=req, transaction_id="trans_id_status-check", - base64_pdf=pdf, reason="status_check", location="tidan") + signed_pdf = sign( + req=req, transaction_id="trans_id_status-check", base64_pdf=pdf, reason="status_check", location="tidan" + ) validate_pdf = validate(req=req, base64_pdf=signed_pdf.data) - req.app.status_storage.next_check = now+5 + req.app.status_storage.next_check = now + 5 req.app.status_storage = StatusReply( status="STATUS_FAIL", @@ -26,7 +27,7 @@ def healthy(req: ContextRequest) -> StatusReply: next_check=req.app.status_storage.next_check, ) - if validate_pdf.data.valid: + if validate_pdf.valid_signature: req.app.status_storage.status = "STATUS_OK" return req.app.status_storage diff --git a/src/pkcs11_ca_service/pdf/tests/test_sign.py b/src/pkcs11_ca_service/pdf/tests/test_sign.py index eb03de3..44a9011 100644 --- a/src/pkcs11_ca_service/pdf/tests/test_sign.py +++ b/src/pkcs11_ca_service/pdf/tests/test_sign.py @@ -1,10 +1,15 @@ import unittest import requests +from pkcs11_ca_service.pdf.app import init_api +from pkcs11_ca_service.pdf.context import ContextRequest +from pkcs11_ca_service.pdf.routers.utils.pdf import sign, validate + class TestSign(unittest.TestCase): """ Test pdf signing """ url = "http://localhost:8006" + app = init_api() def test_sign(self) -> None: """ @@ -18,3 +23,10 @@ def test_sign(self) -> None: verify=False, ) assert req.status_code == 200 + + def test_sign_pdf(self) -> None: + """ Test signing of pdf """ + base64_pdf = "" + signed_pdf_reply = sign(req= ContextRequest, transaction_id= "test", base64_pdf= base64_pdf, reason= "test", location="test") + res = validate(req=ContextRequest, base64_pdf=signed_pdf_reply.data) + assert res.valid_signature is True \ No newline at end of file