From 3690d982602cd81d07bd420310f9a44e53a1f603 Mon Sep 17 00:00:00 2001 From: George Drummond Date: Tue, 19 Mar 2019 10:34:53 -0400 Subject: [PATCH] CRL check is passed in and not hard coded --- atst/utils/pdf_verification.py | 29 ++++++++++---------- tests/utils/test_pdf_verification.py | 40 +++++++++++++++++++--------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/atst/utils/pdf_verification.py b/atst/utils/pdf_verification.py index 81550bbf..a5b914c4 100644 --- a/atst/utils/pdf_verification.py +++ b/atst/utils/pdf_verification.py @@ -1,16 +1,16 @@ import hashlib from OpenSSL import crypto from asn1crypto import cms, pem, core -from atst.domain.authnid.crl import CRLCache, CRLRevocationException from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding class PDFSignature: - def __init__(self, byte_range_start=None, pdf=None): - self.pdf = pdf - self.byte_range_start = byte_range_start + def __init__(self, byte_range_start=None, crl_check=None, pdf=None): self._signers_cert = None + self.byte_range_start = byte_range_start + self.crl_check = crl_check + self.pdf = pdf @property def byte_range(self): @@ -132,14 +132,7 @@ class PDFSignature: Takes the signing certificate and runs it through the CRLCache checker. Returns a boolean. """ - try: - cache = CRLCache( - "ssl/server-certs/ca-chain.pem", - crl_locations=["ssl/client-certs/client-ca.der.crl"], - ) - return cache.crl_check(self.signers_cert) - except CRLRevocationException: - return False + return self.crl_check(self.signers_cert) @property def is_signature_valid(self): @@ -157,6 +150,7 @@ class PDFSignature: if attrs is not None and not isinstance(attrs, core.Void): signed_data = attrs.dump() + print(signed_data) signed_data = b"\x31" + signed_data[1:] else: signed_data = self.binary_data @@ -192,7 +186,12 @@ class PDFSignature: } -def pdf_signature_validations(pdf=None): +def pdf_signature_validations(pdf=None, crl_check=None): + """ + As arguments we accept a pdf binary blob and a callable crl_check. + An example implementation of the crl_check can be found in the + tests (test/utils/test_pdf_verification.py) + """ signatures = [] start_byte = 0 @@ -203,7 +202,9 @@ def pdf_signature_validations(pdf=None): if n == -1: break - signatures.append(PDFSignature(byte_range_start=n, pdf=pdf)) + signatures.append( + PDFSignature(byte_range_start=n, crl_check=crl_check, pdf=pdf) + ) start_byte = n response = {"result": None, "signature_count": len(signatures), "signatures": []} diff --git a/tests/utils/test_pdf_verification.py b/tests/utils/test_pdf_verification.py index 648a84ec..e1f6dcd2 100644 --- a/tests/utils/test_pdf_verification.py +++ b/tests/utils/test_pdf_verification.py @@ -1,17 +1,33 @@ import pytest +from atst.domain.authnid.crl import CRLCache, CRLRevocationException from atst.utils.pdf_verification import pdf_signature_validations -def test_unsigned_pdf(): +@pytest.fixture +def crl_check(): + def _crl_check(signers_cert): + try: + cache = CRLCache( + "ssl/server-certs/ca-chain.pem", + crl_locations=["ssl/client-certs/client-ca.der.crl"], + ) + return cache.crl_check(signers_cert) + except CRLRevocationException: + return False + + return _crl_check + + +def test_unsigned_pdf(crl_check): unsigned_pdf = open("tests/fixtures/sample.pdf", "rb").read() - result = pdf_signature_validations(pdf=unsigned_pdf) + result = pdf_signature_validations(pdf=unsigned_pdf, crl_check=crl_check) assert result == {"result": "FAILURE", "signature_count": 0, "signatures": []} -def test_valid_signed_pdf(): +def test_valid_signed_pdf(crl_check): valid_signed_pdf = open("tests/fixtures/sally-darth-signed.pdf", "rb").read() - result = pdf_signature_validations(pdf=valid_signed_pdf) + result = pdf_signature_validations(pdf=valid_signed_pdf, crl_check=crl_check) assert result == { "result": "OK", @@ -41,10 +57,10 @@ def test_valid_signed_pdf(): } -def test_signed_pdf_thats_been_modified(): +def test_signed_pdf_thats_been_modified(crl_check): valid_signed_pdf = open("tests/fixtures/sally-darth-signed.pdf", "rb").read() modified_pdf = valid_signed_pdf.replace(b"PDF-1.6", b"PDF-1.7") - result = pdf_signature_validations(pdf=modified_pdf) + result = pdf_signature_validations(pdf=modified_pdf, crl_check=crl_check) assert result == { "result": "FAILURE", @@ -74,9 +90,9 @@ def test_signed_pdf_thats_been_modified(): } -def test_signed_pdf_not_on_chain(): +def test_signed_pdf_not_on_chain(crl_check): signed_pdf_not_on_chain = open("tests/fixtures/signed-pdf-not-dod.pdf", "rb").read() - result = pdf_signature_validations(pdf=signed_pdf_not_on_chain) + result = pdf_signature_validations(pdf=signed_pdf_not_on_chain, crl_check=crl_check) assert result == { "result": "FAILURE", @@ -97,11 +113,11 @@ def test_signed_pdf_not_on_chain(): @pytest.mark.skip(reason="Need fixture file") -def test_signed_pdf_dod_revoked(): +def test_signed_pdf_dod_revoked(crl_check): signed_pdf_dod_revoked = open( "tests/fixtures/signed-pdf-dod_revoked.pdf", "rb" ).read() - result = pdf_signature_validations(pdf=signed_pdf_dod_revoked) + result = pdf_signature_validations(pdf=signed_pdf_dod_revoked, crl_check=crl_check) assert result == { "result": "FAILURE", @@ -120,13 +136,13 @@ def test_signed_pdf_dod_revoked(): } -def test_signed_dod_pdf_signer_cert_expired(): +def test_signed_dod_pdf_signer_cert_expired(crl_check): # # TODO: Is this good enough? Do we want an expired DOD certificate? This test is using # a fake DOD certificate. # signed_pdf_dod_revoked = open("tests/fixtures/signed-expired-cert.pdf", "rb").read() - result = pdf_signature_validations(pdf=signed_pdf_dod_revoked) + result = pdf_signature_validations(pdf=signed_pdf_dod_revoked, crl_check=crl_check) assert result == { "result": "FAILURE",