Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing PDF with annotations results in invalid signature #50

Closed
Twometer opened this issue Nov 4, 2024 · 22 comments
Closed

Signing PDF with annotations results in invalid signature #50

Twometer opened this issue Nov 4, 2024 · 22 comments

Comments

@Twometer
Copy link
Contributor

Twometer commented Nov 4, 2024

I have a PDF that was created with gopdf and contains Link annotations.
The PDF is then signed with pdfsign.

If I open the signed document in Adobe, it reports:

Signature is invalid: There have been changes made that invalidate the signature.

Without the link annotation, everything works fine and the PDF is shown as certified.

@vanbroup
Copy link
Member

vanbroup commented Nov 4, 2024

Can you add some examples code and the resulting PDF files?

@Twometer
Copy link
Contributor Author

Twometer commented Nov 5, 2024

@vanbroup Sure:

Working PDF

image
It says unknown because of my self-signed test certificate, but as you can see it says "Document has not been modified".

PDF download: working.pdf

Failing PDF

image
Here, it says "There have been changes made to this document that invalidate the signature.

The only difference is that this PDF contains a Link annotation

PDF download: failing.pdf

Repro

I am using this code for signing the PDF:

pdfSign.Sign(bytes.NewReader(pdf), pdfWriter, pdfReader, pdfLen, pdfSign.SignData{
	Signature: pdfSign.SignDataSignature{
		CertType:   pdfSign.CertificationSignature,
		DocMDPPerm: pdfSign.AllowFillingExistingFormFieldsAndSignaturesAndCRUDAnnotationsPerms,
		Info: pdfSign.SignDataSignatureInfo{
			Name:        "Test Signing",
			Reason:      "Demonstrating signing failures",
			Location:    "The Internet",
			ContactInfo: "Twometer",
			Date:        time.Now(),
		},
	},

	DigestAlgorithm:   crypto.SHA384,
	Signer:            certs.key,
	Certificate:       certs.cert,
	CertificateChains: [][]*x509.Certificate{certs.chain},
})

Here is the full repro code: https://gist.github.com/Twometer/d6611dee04132251531fbc2962190388

More info

The only difference I can see in those PDFs raw streams is the line

/Annots [<</Type /Annot /Subtype /Link /Rect [0.00 842.00 32.00 810.00] /Border [0 0 0] /A <</S /URI /URI (https://google.com)>>>>]

being present in the Page object.

(And of course some changes to the signature and the xref table)

@vanbroup
Copy link
Member

Thanks for these details @Twometer. I couldn’t find your unsigned file right away, but I’ve just released a new version that should address your issue. Could you please verify if it works?

@Twometer
Copy link
Contributor Author

Thanks @vanbroup, I have just tested the new version (v0.0.0-20241114132424-1f5035cb0e1e) with the same code and the same thing still happens:

image

Do I have to change any settings in the signing configuration?

The unsigned file is created dynamically in the repro code with gopdf, but i've also attached it here: failing-unsigned.pdf

@Twometer
Copy link
Contributor Author

okay one more update, I have tried setting ApprovalSignature instead of CertificationSignature and that seems to work now:

image

Do you have an idea why changing the signature type would "fix" this?

@Twometer
Copy link
Contributor Author

I've noticed today that when viewing the document with an ApprovalSignature that Adobe shows as correctly signed using the Foxit PDF reader, it now complains that the document was corrupted:

foxitSigningError

@vanbroup
Copy link
Member

This doesn't happen with any of the test documents right?

I have not been able to look at your source document yet but have you tried opening that with Acrobat and does it ask you to have the document when closing (this often happens when there is an issue in the source document).

Also, do you know if the document has an xref table or stream? I did do most testing with the tables and less with the streams for now.

@Twometer
Copy link
Contributor Author

Twometer commented Nov 20, 2024

I've tried testfile12.pdf which seems to contain a link annotation as well, and that seems to work fine. With the test document, the CertificationSignature also works fine.

I've also tried opening and closing multiple source files in Adobe, and never got a saving prompt.

My source document has just a regular xref table at the end of the document, no xref streams.

@Twometer
Copy link
Contributor Author

The only difference I can see between the test document and my document is that the /Annots object is inline in my document, but a reference to a separate object in the test document.

@arjen-ag5
Copy link

I have the exact same problem, any progress on this issue? My PDF Is also generated with gopdf, and fails when there is a link annotation in the PDF.

@vanbroup
Copy link
Member

vanbroup commented Dec 9, 2024

The signature has been invalidated because Adobe is repairing the original document.

As @Twometer noted, the page annotations created by gopdf are written as an embedded annotation that needs to be an indirect reference instead:

10 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources 4 0 R
  /Annots [<</Type /Annot /Subtype /Link /Rect [0.00 842.00 32.00 810.00] /Border [0 0 0] /A <</S /URI /URI (https://google.com)>>>>]
  /Contents  11 0 R 
>>
endobj

image

An array of annotation dictionaries that shall contain indirect references to all annotations associated with the page (see 12.5, "Annotations").

@Twometer
Copy link
Contributor Author

Twometer commented Dec 9, 2024

@vanbroup I have found the same paragraph in the spec, so I forked gopdf to write the annotations object correctly but I still got the same error message.

@vanbroup
Copy link
Member

vanbroup commented Dec 9, 2024

Do you have a copy of the file with the correct PDF syntax?

@oneplus1000
Copy link

So that mean "/Annots" are not the root of the issue?

@Twometer
Copy link
Contributor Author

Twometer commented Dec 10, 2024

@vanbroup @oneplus1000

It seems /Annots was actually the root cause of the issue. I ran my test script again with the forked gopdf, and it now works correctly:
image

@vanbroup
Copy link
Member

vanbroup commented Dec 10, 2024

This is great news! Thanks for testing!

It would be great if you could contribute your fix back to gopdf to help others.

@Twometer
Copy link
Contributor Author

I just found out that Foxit Reader still complains about the signature, even with the fixed Annotations:
image

However, I think this may be an issue with Foxit, since it also complains without any annotations.

@vanbroup
Copy link
Member

I can't remember that Foxit Reader complained about any other signed documents. Is it only with the file created by gopdf?

@Twometer
Copy link
Contributor Author

I tried it with testfile12.pdf from your repository, and while Adobe shows it as correctly signed, Foxit does not show it as signed at all.

So Foxit at least has weird behavior also on signed non-gopdf files.

@vanbroup
Copy link
Member

Let me investigate any issues with Foxit Reader, it used to validate correctly.

@vanbroup
Copy link
Member

@Twometer please check with the lasted version

Foxit:
image

Acrobat:
image

@Twometer
Copy link
Contributor Author

@vanbroup
image
It works! Thank you very much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants