m32 / endesive

en-crypt, de-crypt, si-gn, ve-rify - smime, pdf, xades and plain files in pure python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Signature that seem corrupted right after signing.

vicpara opened this issue · comments

I have a PDF file I would like to sign.
The signing process is successful yet when opening in the Adobe Reader the signature doesn't seem valid because the file was altered after signing.

Many other PDF files are correctly signed using the same code. I wonder what is special about this PDF file.

The file that cannot be validated is attached below:
tosign.doesntwork.pdf

The following is a file that is signed with the same code and the validation checks in Acrobat:
tosign.ok.pdf

The code:

class CloudHSM(hsm.BaseHSM):
    ...


sigOpts = {
        'sigflags': 3,
        'aligned': 16384,
        'sigandcertify': True,
        'contact': 'John Does Good',
        'location': 'Brussels',
        'reason': 'Approved and signed',
    }
    google_hsm = CloudHSM(project_id, location_id,
                           key_ring_id, key_id, version_id)

    content = None
    with open(fname, 'rb') as content_file:
        content = content_file.read()

    signer_cert = read_signer_cert()
    interim_certs = read_interim_certs_all()

    signed_data = pdf.cms.sign(
        content,
        sigOpts,
        None,
        signer_cert,
        [],
        'sha512',
        google_hsm,
        None,
        ocspurl=ocspurlserver,
        ocspissuer=read_issuer_cert()
    )
    fname = fname.replace('.pdf', '.signed.pdf')
    print("Output at:", fname)

    with open(fname, 'wb') as fp:
        fp.write(content)
        fp.write(signed_data)

I signed the file tosign.doesntwork.pdf and my acrobat sees nothing wrong with it. The only message is that the signature is untrusted.
tosign-signed-cms-hsm.pdf

Thank you for checking the file. I looked more into it and managed to narrow the problem down.

Using 'sigandcertify': True seems to be the problem.

When I use the option 'sigandcertify': True in the signature options, Adobe Acrobat shows an error that the document was modified after it was signed. If I remove 'sigandcertify': True the signature is fine and Adobe doesn't complain.

The error appears only for the tosign.doesntwork.pdf file. The 'ok' file works without problems.

I have the same effect, after signing with pdf-sign-cms.py the result is ok, but after enabling sigandcertify, acrobat reports an error.

Signing with PDFSign.java makes the same error.

$ ./java-showsignature /devel/tosign-signed-java.pdf
Signature found
Signature covers whole document
Name: Example User
Modified: 11.03.2023 06:01:25
....
Certificate valid at signing time
Certificate valid at signing time: Sat Mar 11 06:01:25 CET 2023
Signature verified
Certificate is not self-signed

The process of verifying signed documents in Acrobat is apparently more complicated, and there is no information available about what is being checked.

I noticed using PDFBox that the files with problems for 'signandcertify' have two IDs in their trailer. I may also be looking in the wrong place.

Could this be something that interferes with the signing process at all.

/ID in trailer? - This is normal

What I was trying to say is that the PDFs that fail on Certify already have the IDs present.

Files that can be certified don't have any IDs before signing at all. Perhaps not all IDs are not computed/ created/ stored correctly inside the PDF in the first place (HexStrings vs Strings).

/ID is not required if the pdf file is not signed or has no password, it is required for the password, also for the signature. The first one (/ID[0]) is specific to the document, /ID[1] is created e.g. with the next version of the pdf document. pdf-sign java also creates it.
This is not the case, the pdf.pdf from the examples also has /ID before signing and it's ok.

I've done more testing today. Tagged PDFs seem to require special treatment during signing and certification. Some people believe it's an incorrect Adobe Acrobat behavior.

A 'bad' file that is initially signed with 'signandcertify= False' will initially appear as OK in Adobe. When other signature fields are signed or added, the first signature will appear as red and corrupted. Even when using Adobe to sign these signature fields, the initial signature will get red. Apparently there are some flags that need to be set to tell Adobe to consider this not part of the outline/ tagged objects.

Other users experienced the same issue with iText and Foxit Reader. It seems related to tagged PDFs. The outline will get updated once any signature is applied and therefore will be rendered as a non legitimate modification. Bug in Adobe?

[1] https://stackoverflow.com/questions/70889989/pdf-signature-invalidates-existing-signature-in-acrobat-reader

[2] https://community.adobe.com/t5/acrobat-reader-discussions/invalid-signatures-after-adobe-reader-update-2022-001-20085/td-p/12892048

[3] https://github.com/mkl-public/testarea-itext7/blob/master/src/test/java/mkl/testarea/itext7/signature/MultipleSignaturesAndTagging.java#L42

Thank you for your commitment. Unfortunately, I'm leaving home soon and won't be able to look into this issue for a few weeks.

Got it. No problem. Enjoy your vacation.

https://helpx.adobe.com/acrobat/using/certificate-based-signatures.html
Certify (sigandcertify=true) != Sign With Certificate (sigandcertify=false)

certificates used to certify the document must have the appropriate entry in the certificate, certificates used in endesive do not have this entry, also my private certificate does not have this entry - maybe it's this direction

Thank you. Indeed they are different. I confirm I have a certificate that permits certification.
I've been using endesive without any issues for 2 years. All PDFs were generated by Ms Word, GDocs, Office365 or wkhtmltopdf, pdf-lib or puppet. The sigandcertify=true and my certificate worked well without any issues.

It's only now that I start to see PDFs received from external sources that fail with the same code and certificate.

What is the difference between approval and signature?

I like it - imagine this situation: we want to conclude a contract between three people living in different places in the world, but I want to have all signatures in fixed places. I create a pdf document with three places to approve and send it to the next person. If she also agrees with the document, she approves it (next field) and sends it to the last person. The last person puts their own signature and sends the document to the notary who signs it (signandcertify:true)

If you only finally approved the document (signandcertify:True) but did not fill in all fields for signatures, acrobat shows errors in the signed document.

pdf-tosign-error.pdf - example with 3 places for (custom) signatures - yours file.
pdf-tosign-error-1.pdf, pdf-tosign-error-2.pdf, pdf-tosign-error-3.pdf - output generated by acrobat after filling next signature field
pdf-tosign-error-3-signed-cms-m32-unizeto.pdf - signandcertify:True = final document.

pdf-tosign-error-signed-cms-m32-unizeto.pdf - only approved pdf-tosign-error.pdf without filled fields

pdf-tosign-error.pdf
pdf-tosign-error-1.pdf
pdf-tosign-error-2.pdf
pdf-tosign-error-3.pdf
pdf-tosign-error-3-signed-cms-m32-unizeto.pdf
pdf-tosign-error-signed-cms-m32-unizeto.pdf

If you only finally approved the document (signandcertify:True) but did not fill in all fields for signatures, acrobat shows errors in the signed document.

I think this problem is something specific to these 'broken' PDFs.

In principle, someone should be able to create a PDF, signandcertify:true and then have the 3 signatories sign the 3 fields as suggested above. When the document is signedandcertify first, the signature generally permits further signatures to be attached as well as commenting and form filling. So the order of the signing/ signing+certification shouldn't matter. These operations shouldn't make the signature/certification invalid.

Screenshot 2023-04-04 at 00 02 06

If you repeat the process with a PDF created by MS Word or by any other PDF tool that creates PDFs 'for printing' the signatures will be valid regardless of the order in which they are applied.

This pdf has 3 places for signatures.

If I sign with acrobat reader at these places, the final signature (signandcertify:true) will create a valid document like pdf-tosign-error-3-signed-cms-m32-unizeto.pdf.

If I use endesive to sign only on the first field, the acrobatreader will not sign the next ones - the signing dialog cannot be closed.
If I only sign with endesive then each subsequent signature destroys the previous one.

It seems to be a bug with filling in existing annotations, but I don't know how to fix it.

Yes, i think you are right about the bug.
Other people complaining about a similar problem if not the same: https://community.adobe.com/t5/acrobat-reader-discussions/invalid-signatures-after-adobe-reader-update-2022-001-20085/td-p/12892048

look at the changes in pdf-sign-cms-twice-(1|2|end).py - docmdp must be in every document