m32/endesive

cert ok? False why?

drfixer opened this issue · 3 comments

I've edited my verification code as below and still having the same problem. I added the root CA to trusted_cert_pems. Is the third argument (a custom path to the root CA) ok in pdf.verify?

I am trying to verify a signed pdf using pdf.cms.py. I am using a selfsigned certificate created with openssl that I added manually to a root certificate which is inside a "certificate" folder in my project.

When I check the certificate using:

$ openssl verify -CAfile cacert.pem certificate.pem

I get the response:

certificate.pem: OK

But when I try to verify with pdf verify from endesive, the response I get is the following:

signature ok? True
hash ok? True
cert ok? False

So the signature and hash seem to be ok but why is the "cert ok?" False?

Here is my code for signing the document:

def sign_pdf(source_file_path):
    #generate anonymized identifier using email

    # Define the signature details
    dct = {
        "sigflags": 3,
        "sigpage": 0,
        # "sigbutton": True,
        "contact": "the email",
        "location": "location",
        "signingdate": datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S+00"00"'),
        "reason": "verification",
        "signature": "Digital Signature",
        "signaturebox": (0, 0, 100, 100),
        "password": "the password",
    }

    with open("/Users/***/Desktop/venvs/officetools/simplesurg/certificate.pfx", "rb") as fp:
        p12 = pkcs12.load_key_and_certificates(
            fp.read(), b"simplesurg", default_backend()
        )
    fname = source_file_path
    datau = open(fname, "rb").read()
    datas = cms.sign(datau, dct, p12[0], p12[1], p12[2], "sha256")
    #fname = f"/Users/***/Desktop/venvs/officetools/simplesurg/createform/static/createform/signed_pdfs/{os.path.basename(fname).replace(".pdf", "-signed-cms.pdf")}"

    return datau + datas

...here is my code for verifying the signature:

from endesive import pdf

trusted_cert_pems = (
    open("/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/certificate.pem", "rb").read(),
    open("/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/rootcertificate/cacert.pem", "rb").read(),
    )

print("*" * 20, "/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/createform/static/createform/signed_pdfs/1/2024-04-07/CottoOrtizEdwinOP27-signed-cms.pdf")

try:
    data = open("/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/createform/static/createform/signed_pdfs/1/2024-04-07/CottoOrtizEdwinOP27-signed-cms.pdf", "rb").read()
except Exception as e:
    print(e)

no = 0
for (hashok, signatureok, certok) in pdf.verify(
    data, trusted_cert_pems, "/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/rootcertificate/cacert.pem"
):
    print("*" * 10, "signature no:", no)
    print("signature ok?", signatureok)
    print("hash ok?", hashok)
    print("cert ok?", certok)
m32 commented

see examples/pdf-verify.py
pdf.verify uses trusted system certificates and trusted user certificates specified in the trusted_cert_pems variable.

Your root certificate does not appear in these lists

Thank you for your reply.

I've edited my verification code as below and still having the same problem. I added the root CA to trusted_cert_pems. Is the third argument (a custom path to the root CA) ok in pdf.verify?

...here is my new code for verifying the signature:

from endesive import pdf

trusted_cert_pems = (
    open("/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/certificate.pem", "rb").read(),
    open("/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/rootcertificate/cacert.pem", "rb").read(),
    )

print("*" * 20, "/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/createform/static/createform/signed_pdfs/1/2024-04-07/CottoOrtizEdwinOP27-signed-cms.pdf")

try:
    data = open("/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/createform/static/createform/signed_pdfs/1/2024-04-07/CottoOrtizEdwinOP27-signed-cms.pdf", "rb").read()
except Exception as e:
    print(e)

no = 0
for (hashok, signatureok, certok) in pdf.verify(
    data, trusted_cert_pems, "/Users/josej.echenique/Desktop/venvs/officetools/simplesurg/rootcertificate/cacert.pem"
):
    print("*" * 10, "signature no:", no)
    print("signature ok?", signatureok)
    print("hash ok?", hashok)
    print("cert ok?", certok)
m32 commented

I have too little information, no access to the pdf file before and after signing, as well as certificates.
I can only guess, and it makes no sense :( I can only refer you to examples.

The third argument is the directory used by openssl - root cert store. If your certificate is signed by intermediate authorities, then in this directory there is a file with the self-signed CA certificate that was signed by the CA that issued your certificate.

in verifier.py there is:
validator = CertificateValidator(
cert, othercerts, validation_context=self.context
)
try:
path = validator.validate_usage(set(["digital_signature"]))
certok = True
except Exception as ex:
print("*" * 10, "failed certificate verification:", str(ex))

in ex there is information that openssl conveys