[Poppler-bugs] [Bug 99416] Sign PDF with digital signature

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Mon Aug 28 13:45:31 UTC 2017


https://bugs.freedesktop.org/show_bug.cgi?id=99416

--- Comment #18 from Hans-Ulrich Jüttner <huj at froreich-bioscientia.de> ---
(In reply to Adrian Johnson from comment #17)
> (In reply to Hans-Ulrich Jüttner from comment #16)
> > > FormWidgetSignature::prepareSignature is writing the entire PDF to memory.
> > > It would be better to write it to a temp file then search it on disk. I
> > > don't like the way you search the PDF file for matching strings. It could
> > > end up matching some random data in another stream. It would be better to
> > > get the offset of the dict object you want to search and start the search
> > > for there for up to some reasonable maximum.
> > > 
> > > eg
> > > 
> > > XRefEntry *entry = doc->getXRef()->getEntry(ref);
> > > Goffset objOffset = entry->offset;
> > > 
> > > Also, don't search for %%EOF to get the file size. Use
> > > doc->getBaseStream()->getLength() or Gfseek(f, 0, SEEK_END), Gftell().
> > > 
> > 
> > Ok, but is it guaranteed that this offset and the length of
> > doc->getBaseStream()
> > are always updated when some objects in the PDF have been changed?
> 
> After saving the PDF, open the saved PDF in a new PDFDoc object.
> 

How is this supposed to be done? The user of the library calls the method
sign() from the Qt5 interface or signDocument() from poppler/Form.h via some
other interface. Are you saying that the doc member of type PDFDoc* within the
FormFieldSignature object should be replaced by a new one? I think that can't
work because there are other references to the PDFDoc object in the library
outside the FormFieldSignature object.

> > > I don't fully understand what signDocument() and prepareSignature() are
> > > doing. Which means some comments would be helpful. It appears you are saving
> > > the PDF, computing the signature, updating the signature object, then saving
> > > the PDF again. This assumes that the second save will produce an identical
> > > file except for the updated signature. I'm not sure if we can assume this
> > > will always be true.
> > > 
> > 
> > As the user later wants to save the signed document for example with the
> > PDFConverter from the Qt5 interface, saving the document again has to produce
> > an identical byte stream. Otherwise the signature would no longer be valid.
> 
> I don't really understand how this works. Do you mean save a copy just after
> we signed the document? Or save any PDF that already has a signature? If we
> want to save an identical copy with the signature preserved we should just
> copy the file. It will be a lot faster. It may work now but what happens if
> we decide to always update the ModDate each time the PDF is saved?
> 

The user of the library opens the PDF document, than perhaps makes some changes
and finally calls the method FormFieldSignature::sign() from the Qt5 interface.
Afterwards he saves the changed document with the PDFConverter class of the
Qt5 interface. If he makes other changes to the document after calling sign()
but before saving, the signature will of course be no longer valid.

> > > My naive understanding is that we could just create a signature dict with a
> > > dummy signature and offsets (large enough for any size, XRef allows up to 10
> > > digits), save the PDF, compute the signature, and overwrite the dummy
> > > signature and offsets in the disk file with the real signature. What am I
> > > missing?
> > 
> > I was striving not to waste to much space for the signature. That's why I
> > calculated a signature with the user's certificate and a hash over an empty
> > string first to see how much space it will take. I had the problem that the
> > byte range object itself changed it's size in the byte stream when some
> > number
> > in it gets an additional digit. Therefore I recalculated the byte range and
> > after it the signature once again. May bee this can be avoided if some extra
> > bytes are added to the space reserved for the signature.
> 
> A byte offset can not exceed 10 digits. Typically at least 6 digits will be
> used. I don't think it is worth trying to save a few bytes.

The problem is not saving a few bytes but specifying the final byte offsets.
If a byte offset changes the number of digits may vary at least between 6 and
10. If for example the total length of the document increases, the byte range
object might have to increase in size too because an additional digit is used
for that length. Thus in turn the start offset of the signature is shifted by
one byte because the byte range object is located in front of the signature.

-- 
You are receiving this mail because:
You are the assignee for the bug.
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/poppler-bugs/attachments/20170828/56d0d3d7/attachment-0001.html>


More information about the Poppler-bugs mailing list