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

Problem signing more than once on some PDF files. #75

Closed
therpobinski opened this issue Apr 30, 2020 · 21 comments
Closed

Problem signing more than once on some PDF files. #75

therpobinski opened this issue Apr 30, 2020 · 21 comments

Comments

@therpobinski
Copy link
Contributor

Hi guys, I hope you can help me. I have a pdf that I want to sign more than once. When I sign the first time, it usually does, but when I sign the second time, I have an error signing.
I thought the error was somewhat similar to before when we added links, but I think the error is another. I hope you can help me.
This is the pdf signed and with error.

@therpobinski
Copy link
Contributor Author

I have reviewed the signed trailer twice and I really can't find the problem.
Can anyone help me find the error?

<< 
/Size 11
/Info 10 0 R
/Root 2 0 R
>>
startxref
19125
%%EOF
12 0 obj
<<
/Type /Sig
/Filter /Adobe.PPKLite
/SubFilter /adbe.pkcs7.detached
/ByteRange [0 19575 24739 848]                    
/Contents <3082063406092a864886f70d010702a082062530820621020101310f300d06096086480165030402010500300b06092a864886f70d010701a08203d5308203d1308202b9a003020102020900ae9142f187059c8c300d06092a864886f70d0101050500307f310b3009060355040613024247310e300c06035504080c05536f666961310e300c06035504070c05536f66696131153013060355040a0c0c6e6f64652d7369676e7064663110300e06035504030c075369676e5064663127302506092a864886f70d01090116186e6f64652d7369676e706466406578616d706c652e636f6d301e170d3138303932353135323434335a170d3138313032353135323434335a307f310b3009060355040613024247310e300c06035504080c05536f666961310e300c06035504070c05536f66696131153013060355040a0c0c6e6f64652d7369676e7064663110300e06035504030c075369676e5064663127302506092a864886f70d01090116186e6f64652d7369676e706466406578616d706c652e636f6d30820122300d06092a864886f70d01010105000382010f003082010a02820101009d36edaf2f5c7c0bfc62b35aff43be0b6b3c44c389b351ee69d516b62e969e7c6c3c2453e115123690e996363066ff4168af36627b7dbd1878e934b3b4402f6cab6b03a33669841220a49ed598a554553bc8a676707af847efed91857792c7de73cf1f1c78f16281ddcda6dac68c427d125f3b26504ba3785a99cb6e2090a58f98a9db72eb2a178bdeca52685fb491be5a71d52a8927b9574de93714379e8feb37115fea86accb199fd6eaa93cbe80b50a3166e0e5f3b5331a68905067e8e2c510d00117d343c8080b60424de8dfdd1865a2fe35dfd1aebbba126c8cd9ecf4f4ffaa9f95af1254be33f60f76888a0adc33025ab419ceafa9d05f7358614c08410203010001a350304e301d0603551d0e04160414cca979107f2430a51a3e0195fe8993dea7759c81301f0603551d23041830168014cca979107f2430a51a3e0195fe8993dea7759c81300c0603551d13040530030101ff300d06092a864886f70d010105050003820101008c116c5362c7717204d6b2b9c035f874433c48645bb05eed2e23e6216975769495496bb7cb7d4b7f2daec77e8de486c5d6c0014cd13f381e0d04ff28eed3050ab310d99d444e9d4ec22d1c88b8a52331ded8ea91572b1003129421cb6134aebc2cf7f2ec56011ae310367bc2c8261350189dee30bed525163577c181a4dad0d47b4e67f3679c61c4b0e59420e13dd153fe67c11026b56b024495a5a78dadde2afe0429c76c197bbb775d327066925b6fda02c3f7e88425ce6eb85196066d48a65735bb55922f6242b6150a76d742550b3fd6b5b8305abd93fdfe16d6b7ab86be1c08eb01bd565161610b8ca13732dcd0a99b90687959f84da4ae0bd1109cbcf8318202233082021f02010130818c307f310b3009060355040613024247310e300c06035504080c05536f666961310e300c06035504070c05536f66696131153013060355040a0c0c6e6f64652d7369676e7064663110300e06035504030c075369676e5064663127302506092a864886f70d01090116186e6f64652d7369676e706466406578616d706c652e636f6d020900ae9142f187059c8c300d06096086480165030402010500a069301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420dcb453eb587f3b55000029d02cab83a7a1d27e993fa5c2d33ddd741a1cf1650b301c06092a864886f70d010905310f170d3230303530323138353833365a300d06092a864886f70d0101010500048201006eaff16cc04d02c9612d3683484ce929b8071c295cf404409e9ff838b162ea11a353e76a3800ea1144960ae2a3650ddf67ad421af15f1e7c62b90820a35d133d1534d7349b23f335c4e8eca9d9a83683bc4904ebb0db45807992fc8cff0840d01ac51e9fcee654144afce04745c961c2fcb849ad72e076393a6530b3e7b229218a9774d6a5559a3bb35d1689e9e795cc1cc06bffdf4bebe86fa9461374c326cbb402381d7dda338d0ec538536511ac2ca867da068c95592a8b1340facff35bf7f7f525125efa7fc7b85ef02e5ea8de221cf1d568b55bb13c7a00588678fa2c9093db9b45c5d7f7a3bbc4ce8f294db1c64172a0bd73c02a27c3011f24c6a07f8f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>
/Reason (first)
/M (D:20200502185836Z)
/ContactInfo (emailfromp1289@gmail.com)
/Name (Name from p12)
/Location (Location from p12)
>>
endobj

13 0 obj
<<
/Type /Annot
/Subtype /Widget
/FT /Sig
/Rect [0 0 0 0]
/V 12 0 R
/T (Signature1)
/F 4
/P 4 0 R
>>
endobj

14 0 obj
<<
/Type /AcroForm
/SigFlags 3
/Fields [13 0 R]
>>
endobj

2 0 obj
<<
 
/Type /Catalog
/Pages 3 0 R

/AcroForm 14 0 R
>>
endobj

4 0 obj
<<
 
/Type /Page
/Resources << 
/Font << 
/F1 5 0 R
>>
/ProcSet [/PDF /Text /ImageC]
>>
/Contents 1 0 R
/MediaBox [0 0 594 841]
/Parent 3 0 R
/Annots [ 13 0 R]

>>
endobj

xref
0 1
0000000000 65535 f 
2 1
0000025068 00000 n 
4 1
0000025141 00000 n 
12 1
0000019436 00000 n 
13 1
0000024882 00000 n 
14 1
0000025000 00000 n 
trailer
<<
/Size 15
/Prev 19125
/Root 2 0 R
>>
startxref
19125
/Info 15 0 R
>>
startxref
25331
%%EOF
15 0 obj
<<
/Type /Sig
/Filter /Adobe.PPKLite
/SubFilter /adbe.pkcs7.detached
/ByteRange [0 25727 30891 769]                    
/Contents <3082063406092a864886f70d010702a082062530820621020101310f300d06096086480165030402010500300b06092a864886f70d010701a08203d5308203d1308202b9a003020102020900ae9142f187059c8c300d06092a864886f70d0101050500307f310b3009060355040613024247310e300c06035504080c05536f666961310e300c06035504070c05536f66696131153013060355040a0c0c6e6f64652d7369676e7064663110300e06035504030c075369676e5064663127302506092a864886f70d01090116186e6f64652d7369676e706466406578616d706c652e636f6d301e170d3138303932353135323434335a170d3138313032353135323434335a307f310b3009060355040613024247310e300c06035504080c05536f666961310e300c06035504070c05536f66696131153013060355040a0c0c6e6f64652d7369676e7064663110300e06035504030c075369676e5064663127302506092a864886f70d01090116186e6f64652d7369676e706466406578616d706c652e636f6d30820122300d06092a864886f70d01010105000382010f003082010a02820101009d36edaf2f5c7c0bfc62b35aff43be0b6b3c44c389b351ee69d516b62e969e7c6c3c2453e115123690e996363066ff4168af36627b7dbd1878e934b3b4402f6cab6b03a33669841220a49ed598a554553bc8a676707af847efed91857792c7de73cf1f1c78f16281ddcda6dac68c427d125f3b26504ba3785a99cb6e2090a58f98a9db72eb2a178bdeca52685fb491be5a71d52a8927b9574de93714379e8feb37115fea86accb199fd6eaa93cbe80b50a3166e0e5f3b5331a68905067e8e2c510d00117d343c8080b60424de8dfdd1865a2fe35dfd1aebbba126c8cd9ecf4f4ffaa9f95af1254be33f60f76888a0adc33025ab419ceafa9d05f7358614c08410203010001a350304e301d0603551d0e04160414cca979107f2430a51a3e0195fe8993dea7759c81301f0603551d23041830168014cca979107f2430a51a3e0195fe8993dea7759c81300c0603551d13040530030101ff300d06092a864886f70d010105050003820101008c116c5362c7717204d6b2b9c035f874433c48645bb05eed2e23e6216975769495496bb7cb7d4b7f2daec77e8de486c5d6c0014cd13f381e0d04ff28eed3050ab310d99d444e9d4ec22d1c88b8a52331ded8ea91572b1003129421cb6134aebc2cf7f2ec56011ae310367bc2c8261350189dee30bed525163577c181a4dad0d47b4e67f3679c61c4b0e59420e13dd153fe67c11026b56b024495a5a78dadde2afe0429c76c197bbb775d327066925b6fda02c3f7e88425ce6eb85196066d48a65735bb55922f6242b6150a76d742550b3fd6b5b8305abd93fdfe16d6b7ab86be1c08eb01bd565161610b8ca13732dcd0a99b90687959f84da4ae0bd1109cbcf8318202233082021f02010130818c307f310b3009060355040613024247310e300c06035504080c05536f666961310e300c06035504070c05536f66696131153013060355040a0c0c6e6f64652d7369676e7064663110300e06035504030c075369676e5064663127302506092a864886f70d01090116186e6f64652d7369676e706466406578616d706c652e636f6d020900ae9142f187059c8c300d06096086480165030402010500a069301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420a3abb7233ae7083f0a5f511789340754a2582152827a543924d7babc9072289a301c06092a864886f70d010905310f170d3230303530323138353833375a300d06092a864886f70d0101010500048201000a19515c8104bebdad99e358a3b9f5cda43c1cdf64d7045b2e0fe662eb362c43b93b0cb856480379996dc18dec4357a7592e2fb67b31a20e3695df14dbb156f23857a64febfd6fd955d01d5859fd880a8eccf37c8b84d4e056752022bf438088d43414a3e9bbe887883919782e115d6bf74302c7a462d2f550d249b03629433d439447454dfed7193d8fed47e889cb9d60981d3750f20ed14f96f110b354aafacfcded93a7c6c580ccb41fd22c608dc58a5d642aa5c6a8fe94730e782c249ab17b45ba40c50c044fdb13829b7faad4c5d38fc1944e5b3b258060df804464901b4f25e0ca26e4fda18973694212c3995c3597485630ef75fed76dbf9265fc79500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>
/Reason (second)
/M (D:20200502185837Z)
/ContactInfo (emailfromp1289@gmail.com)
/Name (Name from p12)
/Location (Location from p12)
>>
endobj

16 0 obj
<<
/Type /Annot
/Subtype /Widget
/FT /Sig
/Rect [0 0 0 0]
/V 15 0 R
/T (Signature2)
/F 4
/P 4 0 R
>>
endobj

14 0 obj
<<
/Type /AcroForm
/SigFlags 3
/Fields [13 0 R 16 0 R]
>>
endobj

4 0 obj
<<

 
/Type /Page
/Resources << 
/Font << 
/F1 5 0 R
>>
/ProcSet [/PDF /Text /ImageC]
>>
/Contents 1 0 R
/MediaBox [0 0 594 841]
/Parent 3 0 R
/Annots [ 13 0 R 16 0 R]



>>
endobj

xref
0 1
0000000000 65535 f 
4 1
0000031228 00000 n 
14 1
0000031153 00000 n 
15 1
0000025588 00000 n 
16 1
0000031035 00000 n 
trailer
<<
/Size 18
/Prev 25331
/Root 2 0 R
>>
startxref
19125
/Info 15 0 R
>>
startxref
31428
%%EOF

@vbuch
Copy link
Owner

vbuch commented May 4, 2020

Did you try debugging with https://github.com/ninja-labs-tech/verify-pdf ?

@therpobinski
Copy link
Contributor Author

I've finished testing it with the library you recommend, but from what I see, I only get the first signature to verify, not all. I did tests with correctly signed PDFs and others with error and it only takes the first signature, not all.
I also think the problem is due to some 'ByteRange'.
When I sign the first time, everything is correct, but when I sign it the second time, the first signature is damaged and the second is correct.
In the PDF viewer it shows me the following message:

Signature is invalid:
There are errors in the formatting or information contained in the signature (The signature byte range is invalid)

@therpobinski
Copy link
Contributor Author

In some cases I use large PDF files, it cuts the pages and replaces them on blank pages.

@therpobinski
Copy link
Contributor Author

In the library, there is a readRefTable document, this document gets all the references from the PDF, I have noticed that when you sign a second time, the references skip, that is, they are not sequential.

Before the first signature, the document gets this extract.

177 => 1564668,
178 => 1564884,
179 => 1582503,
180 => 1583111,
181 => 1583234,
182 => 1583324,
183 => 1583447,
184 => 1583537,
185 => 1583660,
186 => 1583750,
-1 => 0 } }

At the time of getting the references before signing for the second time, there is a jump:

178 => 1564884,
179 => 1582503,
180 => 1583111,
181 => 1583234,
182 => 1583324,
183 => 1583447,
184 => 1583537,
185 => 1583660,
186 => 1583750,
188 => 1587768,
189 => 1604485,
190 => 1604606,
-1 => 0 } }

If we see, there is no reference 187, and the same thing happens after signing a second time.
Do you think this is why the error occurred?
I realize that when I sign the first time there is no problem, until I sign the second time! I still don't know what the problem is.
I hope you can help me. Thanks!

@therpobinski
Copy link
Contributor Author

I found something that seems to be the problem.
Every time you add the placeholder for the second signature, it will already corrupt the PDF. Looking for a problem, I noticed that according to the PDF spec, there should only be one startxref for each trailer, that is, for each signature, here I found that 2 startxref were added in a trailer and even plus closes the object without being open with >>.

Here the image of what I explain.
On the right side we find the image with a single startxref, and the PDF files that are properly signed only have a startxref for each trailer, but for some reason an additional startxref was added to the image of a the left and closing this with >>.

imagen

Now my question is where can you find the function that this startxref adds? and in which cases add new ones? To solve the problem.
I think with this concern you can help me @vbuch
Thanks!

@vbuch
Copy link
Owner

vbuch commented May 8, 2020

It is great that you found and fixed the issue. That's what the repo is all about. I've written a comment in the related PR #76

@vbuch vbuch closed this as completed May 8, 2020
@vbuch vbuch mentioned this issue May 8, 2020
@therpobinski
Copy link
Contributor Author

The issue regarding startxref has been fixed, but now there is another issue!

imagen
The second signature cannot be verified and worse, it leaves the first sheet blank.

But when I check the Buffer, I see that if the signature exists and there is no more than one startxref for each trailer.
Now what do you think is the problem?
imagen

@vbuch, You think you can keep this issue open until you fix it.

@vbuch vbuch reopened this May 9, 2020
@therpobinski
Copy link
Contributor Author

Hi guys, the bug has been fixed. The problem is that the library was looking for the AcroForm assuming that PDFs would always have a maximum of 99 objects, that is, they would have up to 2 digits, but the problem occurred when it was necessary to sign larger PDFs that have objects with more digits In my case, PDF files had up to 3 digits the first number of the object (eg 390 0 obj).

This can be seen in this line of your code @vbuch lineError

In this line of code, you will see that once the AcromForm is found, it goes back 12 spaces, which means that if the object has more digits than 2, it doesn't take the full id.
For this, with the help of @mgyugcha we were able to solve the problem. We use regular expressions to get the acroformId and the fields. To continue with your code.
In this commit is the solution.

@vbuch, you can check it to do pull-request? Thanks

@vbuch
Copy link
Owner

vbuch commented May 9, 2020

Nice find. I was wondering how magical this 12 was when I was first reviewing it. Well, itbwas not magical enough obviously. The problem with such a regex is that it is executed on a potentially large amount of content. Thats why i would prefer not to have a regex directly but first try to find a smaller portion of relevant content. Extracting the dictionary and then regexing on top of it. It would be really nice if you can find a way to do this. This piece of code is in the pdfkit helper which is a bit of an error but thats just unfortunate. Dont waste too much time on it. It needs some refactoring either way. I guess ill do it when i split the packages. I will accept it with the regex. Give it a quick try just in case you can think of something more performant.

@therpobinski
Copy link
Contributor Author

You are right to make a regular expression in a smaller section. But I am with a late project that does not leave me much time. I hope to solve it later!
On the other hand, I did a pull of its develop branch and two unit tests appeared that have an error. It would be nice if you corrected it, these errors do not intervene at all in the operation, rather they are errors that were expected, I think.
I'm going to do the 'merge request' like this.
One of the ideas for this search for the refex, I intend to search from the last startxref to the end of the document, and there the `regex' is applied.
Until you can correct those errors, I can correct this search.

@therpobinski
Copy link
Contributor Author

Done, I've already uploaded this update.
It's in the last commit of the pull request.
I think with this solution we could close this issue.
Thanks!

@mcalcano
Copy link

Hi @therpobinski I downloaded your repository but i still have the same issue.
Only the last signature remains valid.
Also, with your repository, it empties the first page and just leave an empty or blank page.
image

Have you come across a solution for this?
Thanks for your help!

@therpobinski
Copy link
Contributor Author

Mmmmm is very very strange!
In the last changes made at my branch, no problem! You should see your PDF and find the error.
Or, do you have the String of the 'buffer' to verify it?

@mcalcano
Copy link

mcalcano commented Jun 10, 2020

Hi @therpobinski, thank you for helping.
Yes, that's exactly the branch i'm using!

I have the buffer before and after signing it, i'm attaching them both.

Also, i tried with 4 other files but encountered the same problem!

pdfBuffer_before.txt
pdfBuffer_signed.txt

@therpobinski
Copy link
Contributor Author

You can supply the PDF files or the buffer.string.
Something like this starts the Buffer.string:

%PDF-1.7
%    
1 0 obj
<<
/Creator (Chromium)
/Producer
................................

@mcalcano
Copy link

@therpobinski thanks again!

I'm attaching 3 files:

  • the original PDF
  • the same PDF after signing it once (so the first page is empty and the signature is valid)
  • the signed PDF after signing it again (first page remains empty, last signature is valid and the first one is invalid now)

Seems like the signature is changing the document somehow.
These are new files i just created.

signTest_original.pdf
signTest_1 signature.pdf
signTest_2 signatures.pdf

@therpobinski
Copy link
Contributor Author

Ok, so I check it out! I think it's something from cross-referencing.

@mcalcano
Copy link

@therpobinski thanks again!
any idea how I can fix it or what should I look for?
Have a good day

@therpobinski
Copy link
Contributor Author

Not yet, I am honest, I am very busy at my work, I will review it during the weekend and I tell you some news.

@stale
Copy link

stale bot commented Sep 9, 2020

This issue has been automatically marked as stale because it has not had activity in the past 90 days. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Sep 9, 2020
@stale stale bot closed this as completed Sep 19, 2020
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

3 participants