KTH (Royal Institute of Technology) Computational Biology Yüksek Lisans Öğrencisi
29 Jun 2013
The first half of the GSoC 2012 is over now. Since LibreOffice team set ‘merging GSoC feature branch into master’ as a requirement for the midterm, I have marked PDF Signing fature as experimental feature and merged into master1, and recently I have deleted my feature branch. From now on, I’ll continue to work on the master.
All changes I have made can be seen in the merge commit but let me explain what those commits mean in detail.
First, I have added the Signature widget annotation type to
emitSignature and finalizeSignature methods are added to PDFWriterImpl class. Those methods are called in
PDFWriterImpl::emit() which is the final operation of PDF creation, it writes all the prepared PDF structures to the given file in order. Page, resource, outline, catalog, annotations, metadata objects are all written to the PDF file in the emit method.
At the beginning of the emit method, I have checked the PDFWriterContext to see if signing is requested2 and then create a Signature annotation object. Next, after the Catalog object is emitted, the main Signature objects (
/Type /SigRef) are emitted. But, unfortunately we have to include a byte range in the signature dictionary as well as the digest of that byte range. Since the document is not finalized yet (the last part is the Trailer in the PDF file.), we cannot specify a ByteRange and the document digest now. Instead, we write a dummy ByteRange value and a dummy signature and reserve a space to fill it later when the document is finalized. Of course, we have to write down the offset values of that dummy byte range and digest object, so we can fill them later on.
Finally, when the trailer is emitted in the ::emit method, we are ready to fix the ByteRange values and include the digest value. This is what the finalizeSignature method does. finalizeSignature calculates the real ByteRange value and fix the old values. Next, reads the whole PDF data to create a PKCS7 object using NSS library. But since we don’t have a certificate now (PDF export dialog has to be changed to make users select the certificate) PKCS7 object creation is not implemented.
I have added a new Digital Signatures tab to the PDF export dialog3. But this wasn’t easy. First I thought that certificate selection dialog is used in document signing and it must be easy to re-use it. But, that dialog (
xmlsecurity/source/dialogs/certificatechooser.cxx) seems to be an internal part of the xmlsecurity module and can only used in the signDocumentContent method of the XDocumentDigitalSignatures UNO interface. So, I had to extend that UNO interface and added a chooseCertificate method. It just asks user to choose a certificate and returns it. That’s all. So, certificate chooser dialog can now be used in anywhere using the
So, to finalize the signed PDF document now I have:
Also, I now the byte offset of digital signature to write the computed PKCS7 object. I hope, adding a few lines will be enough to complete signing :)
By the way, since I didn’t use
--enable-werror configure option and ignored some warnings caused by my changes, I have broken some builds in the master tinderbox. Sorry about that :) Now I know, I must use
--enable-dbgutil all the time.
As you know, PDF export dialog has a great deal of options. This dialog, which resides in
filter/source/pdf/impdialog.cxx, basically takes all PDF export parameters and passes them to PDFFilter class and it forwards those parameters to PDFExport class. Finally, PDFExport class instantiate a PDFWriterContext object and pass it to the vcl::PDFWriter class. (I want to thank GDB to make this process easier to understand.)
Right now, password box is an ordinary text edit. So be careful, your private key password will be exposed :) As a second matter, the design of the certificate selection is ugly. I may use the certificate selection design of Thunderbird. There are disabled text edit, a select and clear button. Thus, I can also remove Sign PDF File checkbox.↩