[Libreoffice-commits] .: 16 commits - filter/inc filter/source offapi/com vcl/inc vcl/source xmlsecurity/source

Gökcen Eraslan gokcen at kemper.freedesktop.org
Mon Jul 9 00:17:21 PDT 2012


 filter/inc/filter.hrc                                       |    1 
 filter/source/pdf/impdialog.cxx                             |  155 +++++++-
 filter/source/pdf/impdialog.hrc                             |   13 
 filter/source/pdf/impdialog.hxx                             |   39 ++
 filter/source/pdf/impdialog.src                             |   90 ++++
 filter/source/pdf/pdfexport.cxx                             |   20 +
 filter/source/pdf/pdfexport.hxx                             |    8 
 offapi/com/sun/star/security/XDocumentDigitalSignatures.idl |    4 
 vcl/inc/vcl/pdfwriter.hxx                                   |   37 +
 vcl/source/gdi/pdfwriter_impl.cxx                           |  231 +++++++++++-
 vcl/source/gdi/pdfwriter_impl.hxx                           |    9 
 xmlsecurity/source/component/documentdigitalsignatures.cxx  |   23 +
 xmlsecurity/source/component/documentdigitalsignatures.hxx  |    1 
 13 files changed, 612 insertions(+), 19 deletions(-)

New commits:
commit 9c8dc01d3a40ec905c9d816c733ceb5d621e0426
Merge: f8f2296... 9ba7fda...
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Mon Jul 9 10:16:17 2012 +0300

    Merge branch 'feature/pdf-signing'

commit 9ba7fda79cd36a20732fee663f52bdb4946cb2cf
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sun Jul 8 09:19:49 2012 +0300

    Get der encoded certificate to use in NSS.
    
    Change-Id: I01b033b2ec91d97352c91d732530473d75ad5e3a

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 16f2a0d..7b3cc6f 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6155,6 +6155,10 @@ bool PDFWriterImpl::emitSignature()
 
 bool PDFWriterImpl::finalizeSignature()
 {
+
+    if (!m_aContext.SignCertificate.is())
+        return false;
+
     // 1- calculate last ByteRange value
     sal_uInt64 nOffset = ~0U;
     CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nOffset ) ) );
@@ -6177,6 +6181,13 @@ bool PDFWriterImpl::finalizeSignature()
     // 3- create the PKCS#7 object using NSS
     // use  m_aContext.SignCertificate and m_aContext.SignPassword as certificate and private key password
     // SignCertificate->getEncoded is DER encoded certificate
+    com::sun::star::uno::Sequence< sal_Int8 > derEncoded = m_aContext.SignCertificate->getEncoded();
+
+    if (!derEncoded.hasElements())
+        return false;
+
+    sal_Int8* n_derArray = derEncoded.getArray();
+    sal_Int32 n_derLength = derEncoded.getLength();
 
     // 4- overwrite the PKCS7 content to the m_nSignatureContentOffset
     CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset ) ) );
commit 5f995a0d8ffea95bf6eecf5215da8178159be0ca
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jul 7 23:10:30 2012 +0300

    Add password edit and pass XCertificate to PDFWriter code in VCL.
    
    Now, we have the password of private key and the certificate to
    sign. Ready to use NSS and create necessary PKCS7 object using
    these.
    
    Change-Id: Id69487e92283059fcd558d33cf6a6128df0f50d9

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index dd9c429..f6f9b15 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -249,9 +249,6 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
 
 //prepare values for digital signatures
     mbSignPDF = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignPDF" ) ), sal_False );
-    //msSignLocation = maConfigItem.ReadString( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureLocation" ) ), "" );
-    //msSignContact = maConfigItem.ReadString( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureContactInfo" ) ), "" );
-    //msSignReason = maConfigItem.ReadString( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureReason" ) ), "" );
 
 //queue the tab pages for later creation (created when first shown)
     AddTabPage( RID_PDF_TAB_SIGNING, ImpPDFTabSigningPage::Create, 0 );
@@ -416,7 +413,7 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
 
     Sequence< PropertyValue > aRet( maConfigItem.GetFilterData() );
 
-    int nElementAdded = 9;
+    int nElementAdded = 11;
 
     aRet.realloc( aRet.getLength() + nElementAdded );
 
@@ -472,6 +469,14 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
     aRet[ nLength - nElementAdded ].Value <<= msSignContact;
     nElementAdded--;
 
+    aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignaturePassword" ) );
+    aRet[ nLength - nElementAdded ].Value <<= msSignPassword;
+    nElementAdded--;
+
+    aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureCertificate" ) );
+    aRet[ nLength - nElementAdded ].Value <<= maSignCertificate;
+    nElementAdded--;
+
     return aRet;
 }
 
@@ -1678,13 +1683,16 @@ ImpPDFTabSigningPage::ImpPDFTabSigningPage( Window* pParent,
     SfxTabPage( pParent, PDFFilterResId( RID_PDF_TAB_SIGNING ), rCoreSet ),
 
     maCbSignPDF( this, PDFFilterResId( CB_SIGN_PDF ) ),
+    maFtSignPassword( this, PDFFilterResId( FT_SIGN_PASSWORD ) ),
+    maEdSignPassword( this, PDFFilterResId( ED_SIGN_PASSWORD ) ),
     maFtSignLocation( this, PDFFilterResId( FT_SIGN_LOCATION ) ),
     maEdSignLocation( this, PDFFilterResId( ED_SIGN_LOCATION ) ),
     maFtSignContactInfo( this, PDFFilterResId( FT_SIGN_CONTACT ) ),
     maEdSignContactInfo( this, PDFFilterResId( ED_SIGN_CONTACT ) ),
     maFtSignReason( this, PDFFilterResId( FT_SIGN_REASON ) ),
     maEdSignReason( this, PDFFilterResId( ED_SIGN_REASON ) ),
-    maPbSignSelectCert( this, PDFFilterResId( BTN_SIGN_SELECT_CERT ) )
+    maPbSignSelectCert( this, PDFFilterResId( BTN_SIGN_SELECT_CERT ) ),
+    maSignCertificate()
 {
     FreeResource();
 
@@ -1711,7 +1719,7 @@ IMPL_LINK_NOARG( ImpPDFTabSigningPage, ClickmaPbSignSelectCert )
     if ( !xSigner.is() )
         return 0;
 
-    Reference< security::XCertificate > xCert = xSigner->chooseCertificate();
+    maSignCertificate = xSigner->chooseCertificate();
 
     return 0;
 }
@@ -1728,8 +1736,10 @@ void ImpPDFTabSigningPage::GetFilterConfigItem( ImpPDFTabDialog* paParent  )
 {
     paParent->mbSignPDF = maCbSignPDF.IsChecked();
     paParent->msSignLocation = maEdSignLocation.GetText();
+    paParent->msSignPassword = maEdSignPassword.GetText();
     paParent->msSignContact = maEdSignContactInfo.GetText();
     paParent->msSignReason = maEdSignReason.GetText();
+    paParent->maSignCertificate = maSignCertificate;
 
 }
 
@@ -1739,6 +1749,7 @@ void ImpPDFTabSigningPage::SetFilterConfigItem( const  ImpPDFTabDialog* paParent
 
     maCbSignPDF.SetToggleHdl( LINK( this, ImpPDFTabSigningPage, ToggleSignPDFHdl ) );
     maEdSignLocation.Enable( false );
+    maEdSignPassword.Enable( false );
     maEdSignContactInfo.Enable( false );
     maEdSignReason.Enable( false );
     maPbSignSelectCert.Enable( false );
@@ -1746,15 +1757,18 @@ void ImpPDFTabSigningPage::SetFilterConfigItem( const  ImpPDFTabDialog* paParent
     if (paParent->mbSignPDF)
     {
         maCbSignPDF.Check();
+        maEdSignPassword.SetText(paParent->msSignPassword);
         maEdSignLocation.SetText(paParent->msSignLocation);
         maEdSignContactInfo.SetText(paParent->msSignContact);
         maEdSignReason.SetText(paParent->msSignReason);
+        maSignCertificate = paParent->maSignCertificate;
     }
 }
 
 // -----------------------------------------------------------------------------
 IMPL_LINK_NOARG(ImpPDFTabSigningPage, ToggleSignPDFHdl)
 {
+    maEdSignPassword.Enable( maCbSignPDF.IsChecked() );
     maEdSignLocation.Enable( maCbSignPDF.IsChecked() );
     maEdSignContactInfo.Enable( maCbSignPDF.IsChecked() );
     maEdSignReason.Enable( maCbSignPDF.IsChecked() );
diff --git a/filter/source/pdf/impdialog.hrc b/filter/source/pdf/impdialog.hrc
index e446302..9fede12 100644
--- a/filter/source/pdf/impdialog.hrc
+++ b/filter/source/pdf/impdialog.hrc
@@ -202,10 +202,12 @@
 
 //controls for digital signatures tab page
 #define CB_SIGN_PDF          170
-#define FT_SIGN_LOCATION     171
-#define ED_SIGN_LOCATION     172
-#define FT_SIGN_CONTACT      173
-#define ED_SIGN_CONTACT      174
-#define FT_SIGN_REASON       175
-#define ED_SIGN_REASON       176
-#define BTN_SIGN_SELECT_CERT 177
+#define FT_SIGN_PASSWORD     171
+#define ED_SIGN_PASSWORD     172
+#define FT_SIGN_LOCATION     173
+#define ED_SIGN_LOCATION     174
+#define FT_SIGN_CONTACT      175
+#define ED_SIGN_CONTACT      176
+#define FT_SIGN_REASON       177
+#define ED_SIGN_REASON       178
+#define BTN_SIGN_SELECT_CERT 179
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index b83343b..335aadb 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -151,9 +151,11 @@ protected:
     sal_Bool                    mbExportBmkToPDFDestination;
 
     sal_Bool                    mbSignPDF;
+    ::rtl::OUString             msSignPassword;
     ::rtl::OUString             msSignLocation;
     ::rtl::OUString             msSignContact;
     ::rtl::OUString             msSignReason;
+    com::sun::star::uno::Reference< com::sun::star::security::XCertificate > maSignCertificate;
 
     ::rtl::OUString             maWatermarkText;
 
@@ -441,6 +443,8 @@ public:
 class ImpPDFTabSigningPage : public SfxTabPage
 {
     CheckBox                    maCbSignPDF;
+    FixedText                   maFtSignPassword;
+    Edit                        maEdSignPassword;
     FixedText                   maFtSignLocation;
     Edit                        maEdSignLocation;
     FixedText                   maFtSignContactInfo;
@@ -448,6 +452,7 @@ class ImpPDFTabSigningPage : public SfxTabPage
     FixedText                   maFtSignReason;
     Edit                        maEdSignReason;
     PushButton                  maPbSignSelectCert;
+    com::sun::star::uno::Reference< com::sun::star::security::XCertificate > maSignCertificate;
 
     DECL_LINK( ToggleSignPDFHdl, void* );
     DECL_LINK( ClickmaPbSignSelectCert, void* );
diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src
index b099a53..afae67e 100644
--- a/filter/source/pdf/impdialog.src
+++ b/filter/source/pdf/impdialog.src
@@ -843,23 +843,37 @@ TabPage  RID_PDF_TAB_SIGNING
         Text[ en-US ] = "Select c~ertificate...";
     };
 
-    FixedText FT_SIGN_LOCATION
+    FixedText FT_SIGN_PASSWORD
     {
         Pos = MAP_APPFONT( 12, 35 );
         Size = MAP_APPFONT( 109, 10 );
+        Text[ en-US ] = "Certificate Password";
+    };
+
+    Edit ED_SIGN_PASSWORD
+    {
+        Border = TRUE ;
+        Pos = MAP_APPFONT ( 102, 35 ) ;
+        Size = MAP_APPFONT ( 68 , 12 ) ;
+    };
+
+    FixedText FT_SIGN_LOCATION
+    {
+        Pos = MAP_APPFONT( 12, 48 );
+        Size = MAP_APPFONT( 109, 10 );
         Text[ en-US ] = "Location";
     };
 
     Edit ED_SIGN_LOCATION
     {
         Border = TRUE ;
-        Pos = MAP_APPFONT ( 122, 35 ) ;
-        Size = MAP_APPFONT ( 48 , 12 ) ;
+        Pos = MAP_APPFONT ( 102, 48 ) ;
+        Size = MAP_APPFONT ( 68 , 12 ) ;
     };
 
     FixedText FT_SIGN_CONTACT
     {
-        Pos = MAP_APPFONT( 12, 48 );
+        Pos = MAP_APPFONT( 12, 61 );
         Size = MAP_APPFONT( 109, 10 );
         Text[ en-US ] = "Contact Information";
     };
@@ -867,13 +881,13 @@ TabPage  RID_PDF_TAB_SIGNING
     Edit ED_SIGN_CONTACT
     {
         Border = TRUE ;
-        Pos = MAP_APPFONT ( 122, 48 ) ;
-        Size = MAP_APPFONT ( 48 , 12 ) ;
+        Pos = MAP_APPFONT ( 102, 61 ) ;
+        Size = MAP_APPFONT ( 68 , 12 ) ;
     };
 
     FixedText FT_SIGN_REASON
     {
-        Pos = MAP_APPFONT( 12, 61 );
+        Pos = MAP_APPFONT( 12, 74 );
         Size = MAP_APPFONT( 109, 10 );
         Text[ en-US ] = "Reason";
     };
@@ -881,8 +895,8 @@ TabPage  RID_PDF_TAB_SIGNING
     Edit ED_SIGN_REASON
     {
         Border = TRUE ;
-        Pos = MAP_APPFONT ( 122, 61 ) ;
-        Size = MAP_APPFONT ( 48 , 12 ) ;
+        Pos = MAP_APPFONT ( 102, 74 ) ;
+        Size = MAP_APPFONT ( 68 , 12 ) ;
     };
 
 };
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index a137cee..30727c6 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -562,6 +562,10 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue
                     rFilterData[ nData ].Value >>= msSignReason;
                 else if ( rFilterData[ nData ].Name == "SignatureContactInfo" )
                     rFilterData[ nData ].Value >>= msSignContact;
+                else if ( rFilterData[ nData ].Name == "SignaturePassword" )
+                    rFilterData[ nData ].Value >>= msSignPassword;
+                else if ( rFilterData[ nData ].Name == "SignatureCertificate" )
+                    rFilterData[ nData ].Value >>= maSignCertificate;
             }
             aContext.URL        = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
 
@@ -794,6 +798,8 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue
             aContext.SignLocation = msSignLocation;
             aContext.SignContact = msSignContact;
             aContext.SignReason = msSignReason;
+            aContext.SignPassword = msSignPassword;
+            aContext.SignCertificate = maSignCertificate;
 
 // all context data set, time to create the printing device
             PDFWriter*          pPDFWriter = new PDFWriter( aContext, xEnc );
diff --git a/filter/source/pdf/pdfexport.hxx b/filter/source/pdf/pdfexport.hxx
index baa996e..3962d1e 100644
--- a/filter/source/pdf/pdfexport.hxx
+++ b/filter/source/pdf/pdfexport.hxx
@@ -122,6 +122,8 @@ private:
     OUString                msSignLocation;
     OUString                msSignContact;
     OUString                msSignReason;
+    OUString                msSignPassword;
+    Reference< security::XCertificate > maSignCertificate;
 
     void                    ImplWriteWatermark( ::vcl::PDFWriter& rWriter, const Size& rPageSize );
 public:
diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx
index 535c2b3..0e93cdd 100644
--- a/vcl/inc/vcl/pdfwriter.hxx
+++ b/vcl/inc/vcl/pdfwriter.hxx
@@ -41,6 +41,7 @@
 
 #include "com/sun/star/io/XOutputStream.hpp"
 #include "com/sun/star/beans/XMaterialHolder.hpp"
+#include "com/sun/star/security/XCertificate.hpp"
 #include "com/sun/star/lang/Locale.hpp"
 
 #include <boost/scoped_ptr.hpp>
@@ -631,8 +632,10 @@ The following structure describes the permissions used in PDF security
 
         bool                            SignPDF;
         rtl::OUString                   SignLocation;
+        rtl::OUString                   SignPassword;
         rtl::OUString                   SignReason;
         rtl::OUString                   SignContact;
+        com::sun::star::uno::Reference< com::sun::star::security::XCertificate> SignCertificate;
 
         com::sun::star::lang::Locale    DocumentLocale; // defines the document default language
         sal_uInt32                      DPIx, DPIy;     // how to handle MapMode( MAP_PIXEL )
@@ -668,7 +671,8 @@ The following structure describes the permissions used in PDF security
                 SignPDF( false ),
                 DPIx( 0 ),
                 DPIy( 0 ),
-                ColorMode( PDFWriter::DrawColor )
+                ColorMode( PDFWriter::DrawColor ),
+                SignCertificate( 0 )
         {}
     };
 
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 6438271..16f2a0d 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6175,6 +6175,8 @@ bool PDFWriterImpl::finalizeSignature()
     }
 
     // 3- create the PKCS#7 object using NSS
+    // use  m_aContext.SignCertificate and m_aContext.SignPassword as certificate and private key password
+    // SignCertificate->getEncoded is DER encoded certificate
 
     // 4- overwrite the PKCS7 content to the m_nSignatureContentOffset
     CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset ) ) );
commit bb1ba4f3b784b1ad8776319d6336dba97e484d59
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jul 7 19:15:17 2012 +0300

    Use new chooseCertificate UNO method to pop up certificate dialog.
    
    Change-Id: I713357547c462cd0164f2aa361c44fca63cce435

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index cc26818..dd9c429 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -42,6 +42,7 @@
 #include "com/sun/star/container/XIndexAccess.hpp"
 #include "com/sun/star/frame/XController.hpp"
 #include "com/sun/star/view/XSelectionSupplier.hpp"
+#include "com/sun/star/security/XDocumentDigitalSignatures.hpp"
 
 #include <boost/shared_ptr.hpp>
 
@@ -1697,19 +1698,20 @@ ImpPDFTabSigningPage::~ImpPDFTabSigningPage()
 
 IMPL_LINK_NOARG( ImpPDFTabSigningPage, ClickmaPbSignSelectCert )
 {
-    // Certificate selection dialog will pop up
-    /*
-    Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
-    Reference< XComponentContext > mxCtx;
 
-    XMLSignatureHelper aSignatureHelper( mxCtx );
-    if ( aSignatureHelper.Init() )
-        xSecEnv = aSignatureHelper.GetSecurityEnvironment();
+    uno::Sequence< uno::Any > aArgs( 2 );
+    aArgs[0] <<= rtl::OUString("1.2");
+    aArgs[1] <<= sal_False;
 
-    SignatureInformations maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
-    CertificateChooser aChooser( this, mxCtx, xSecEnv, maCurrentSignatureInformations );
-    aChooser.Execute();
-    */
+    Reference< security::XDocumentDigitalSignatures > xSigner(
+        comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+            rtl::OUString( "com.sun.star.security.DocumentDigitalSignatures"  ), aArgs ),
+        uno::UNO_QUERY );
+
+    if ( !xSigner.is() )
+        return 0;
+
+    Reference< security::XCertificate > xCert = xSigner->chooseCertificate();
 
     return 0;
 }
commit 786f730ea2608abaafdc656e2181d11e076b6648
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jul 7 19:08:48 2012 +0300

    Add new chooseCertificate method to XDocumentDigitalSignatures UNO interface.
    
    This method shows the certificate choosing dialog previously used in ODF
    signing and returns the selected certificate. For PDF signing support,
    we need to reuse existing CertifacateChooser class of xmlsecurity module.
    So the UNO api of ::com::sun::star::security::XDocumentDigitalSignatures is
    extended.
    
    Change-Id: I09f7d0ee180b16b588798820206780df359d133e

diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
index be75dc1..8e9089e 100644
--- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
+++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
@@ -143,7 +143,9 @@ interface XDocumentDigitalSignatures : com::sun::star::uno::XInterface
     void    addAuthorToTrustedSources( [in] com::sun::star::security::XCertificate Author );
     void    addLocationToTrustedSources( [in] string Location );
 
-
+    /**  This method shows CertificateChooser dialog, used by document and PDF signing
+     */
+    com::sun::star::security::XCertificate chooseCertificate();
 
 } ;
 
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 3282dfe..f52c1a4 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -28,6 +28,7 @@
 
 #include <documentdigitalsignatures.hxx>
 #include <xmlsecurity/digitalsignaturesdialog.hxx>
+#include <xmlsecurity/certificatechooser.hxx>
 #include <xmlsecurity/certificateviewer.hxx>
 #include <xmlsecurity/macrosecurity.hxx>
 #include <xmlsecurity/biginteger.hxx>
@@ -424,6 +425,28 @@ void DocumentDigitalSignatures::showCertificate(
     return bFound;
 }
 
+Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificate() throw (RuntimeException)
+{
+    Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
+
+    XMLSignatureHelper aSignatureHelper( mxCtx );
+    if ( aSignatureHelper.Init() )
+        xSecEnv = aSignatureHelper.GetSecurityEnvironment();
+
+    CertificateChooser aChooser( NULL, mxCtx, xSecEnv, aSignatureHelper.GetSignatureInformations());
+
+    if (aChooser.Execute() != RET_OK)
+        return Reference< css::security::XCertificate >(0);
+
+    Reference< css::security::XCertificate > xCert = aChooser.GetSelectedCertificate();
+
+    if ( !xCert.is() )
+        return Reference< css::security::XCertificate >(0);
+
+    return xCert;
+}
+
+
 ::sal_Bool DocumentDigitalSignatures::isLocationTrusted( const ::rtl::OUString& Location ) throw (RuntimeException)
 {
     sal_Bool bFound = sal_False;
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index 3525370..a16ee9a 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -94,6 +94,7 @@ public:
     void SAL_CALL addAuthorToTrustedSources( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& Author ) throw (::com::sun::star::uno::RuntimeException);
     void SAL_CALL addLocationToTrustedSources( const ::rtl::OUString& Location ) throw (::com::sun::star::uno::RuntimeException);
 
+    ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL chooseCertificate( ) throw (::com::sun::star::uno::RuntimeException);
 };
 
 com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL DocumentDigitalSignatures_CreateInstance(
commit 64f614d93e0ff2b719e8dd360c0ed684569439bc
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sun Jul 1 11:35:12 2012 +0300

    Add CertificateChooser code in comment.
    
    When I solve #include "xmlsecurity/..." problem, I will use that code.
    
    Change-Id: Ia119557d90ba231d848b7eaac41249a8acd897a2

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 1ca8a9a..cc26818 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -33,6 +33,7 @@
 #include "vcl/msgbox.hxx"
 #include "sfx2/passwd.hxx"
 #include "svtools/miscopt.hxx"
+//#include "xmlsecurity/certificatechooser.hxx"
 
 #include "comphelper/storagehelper.hxx"
 
@@ -1697,6 +1698,19 @@ ImpPDFTabSigningPage::~ImpPDFTabSigningPage()
 IMPL_LINK_NOARG( ImpPDFTabSigningPage, ClickmaPbSignSelectCert )
 {
     // Certificate selection dialog will pop up
+    /*
+    Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
+    Reference< XComponentContext > mxCtx;
+
+    XMLSignatureHelper aSignatureHelper( mxCtx );
+    if ( aSignatureHelper.Init() )
+        xSecEnv = aSignatureHelper.GetSecurityEnvironment();
+
+    SignatureInformations maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
+    CertificateChooser aChooser( this, mxCtx, xSecEnv, maCurrentSignatureInformations );
+    aChooser.Execute();
+    */
+
     return 0;
 }
 
commit 7a2a0dc0327b130da93ab52151a1aa1da1d4ac34
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sun Jul 1 00:33:03 2012 +0300

    Make PDF Signing GUI operative.
    
    Now, PDFWriterContext is used for signing information. GUI elements are
    recorded to PDFWriterContext and used during signing process. Sign PDF
    checkbox and Location/Contact Info/Reason boxes are all working now.
    
    Change-Id: I1d0cb53323707efa7e460431dd1519bcd34e8b29

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 6740143..1ca8a9a 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -127,10 +127,7 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
     mbConvertOOoTargets( sal_False ),
     mbExportBmkToPDFDestination( sal_False ),
 
-    mbSignPDF( sal_False ),
-    msSignLocation ( ' ' ),
-    msSignContact( ' ' ),
-    msSignReason( ' ' )
+    mbSignPDF( sal_False )
 
 {
     FreeResource();
@@ -462,15 +459,15 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
     }
 
     aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureLocation" ) );
-    aRet[ nLength - nElementAdded ].Value <<= OUString( msSignLocation );
+    aRet[ nLength - nElementAdded ].Value <<= msSignLocation;
     nElementAdded--;
 
     aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureReason" ) );
-    aRet[ nLength - nElementAdded ].Value <<= OUString( msSignReason );
+    aRet[ nLength - nElementAdded ].Value <<= msSignReason;
     nElementAdded--;
 
     aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureContactInfo" ) );
-    aRet[ nLength - nElementAdded ].Value <<= OUString( msSignContact );
+    aRet[ nLength - nElementAdded ].Value <<= msSignContact;
     nElementAdded--;
 
     return aRet;
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index f227c14..b83343b 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -151,9 +151,9 @@ protected:
     sal_Bool                    mbExportBmkToPDFDestination;
 
     sal_Bool                    mbSignPDF;
-    String                      msSignLocation;
-    String                      msSignContact;
-    String                      msSignReason;
+    ::rtl::OUString             msSignLocation;
+    ::rtl::OUString             msSignContact;
+    ::rtl::OUString             msSignReason;
 
     ::rtl::OUString             maWatermarkText;
 
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index db93010..a137cee 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -554,6 +554,14 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue
                     rFilterData[ nData ].Value >>= mbExportHiddenSlides;
                 else if ( rFilterData[ nData ].Name == "OpenBookmarkLevels" )
                     rFilterData[ nData ].Value >>= mnOpenBookmarkLevels;
+                else if ( rFilterData[ nData ].Name == "SignPDF" )
+                    rFilterData[ nData ].Value >>= mbSignPDF;
+                else if ( rFilterData[ nData ].Name == "SignatureLocation" )
+                    rFilterData[ nData ].Value >>= msSignLocation;
+                else if ( rFilterData[ nData ].Name == "SignatureReason" )
+                    rFilterData[ nData ].Value >>= msSignReason;
+                else if ( rFilterData[ nData ].Name == "SignatureContactInfo" )
+                    rFilterData[ nData ].Value >>= msSignContact;
             }
             aContext.URL        = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
 
@@ -781,6 +789,12 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue
                     aContext.ForcePDFAction = sal_False;
                 }
             }
+
+            aContext.SignPDF = mbSignPDF;
+            aContext.SignLocation = msSignLocation;
+            aContext.SignContact = msSignContact;
+            aContext.SignReason = msSignReason;
+
 // all context data set, time to create the printing device
             PDFWriter*          pPDFWriter = new PDFWriter( aContext, xEnc );
             OutputDevice*       pOut = pPDFWriter->GetReferenceDevice();
diff --git a/filter/source/pdf/pdfexport.hxx b/filter/source/pdf/pdfexport.hxx
index 3374d0a..baa996e 100644
--- a/filter/source/pdf/pdfexport.hxx
+++ b/filter/source/pdf/pdfexport.hxx
@@ -117,6 +117,12 @@ private:
     sal_Bool                mbExportBmkToDest;
     sal_Bool                ImplExportPage( ::vcl::PDFWriter& rWriter, ::vcl::PDFExtOutDevData& rPDFExtOutDevData,
                                                 const GDIMetaFile& rMtf );
+
+    sal_Bool                mbSignPDF;
+    OUString                msSignLocation;
+    OUString                msSignContact;
+    OUString                msSignReason;
+
     void                    ImplWriteWatermark( ::vcl::PDFWriter& rWriter, const Size& rPageSize );
 public:
 
diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx
index 8ffab09..535c2b3 100644
--- a/vcl/inc/vcl/pdfwriter.hxx
+++ b/vcl/inc/vcl/pdfwriter.hxx
@@ -629,6 +629,11 @@ The following structure describes the permissions used in PDF security
         PDFWriter::PDFEncryptionProperties  Encryption;
         PDFWriter::PDFDocInfo           DocumentInfo;
 
+        bool                            SignPDF;
+        rtl::OUString                   SignLocation;
+        rtl::OUString                   SignReason;
+        rtl::OUString                   SignContact;
+
         com::sun::star::lang::Locale    DocumentLocale; // defines the document default language
         sal_uInt32                      DPIx, DPIy;     // how to handle MapMode( MAP_PIXEL )
                                                         // 0 here specifies a default handling
@@ -660,6 +665,7 @@ The following structure describes the permissions used in PDF security
                 InitialPage( 1 ),
                 OpenBookmarkLevels( -1 ),
                 Encryption(),
+                SignPDF( false ),
                 DPIx( 0 ),
                 DPIy( 0 ),
                 ColorMode( PDFWriter::DrawColor )
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index f12f973..6438271 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -138,6 +138,11 @@ void doTestCode()
     aContext.DocumentInfo.Title = OUString( "PDF export test document"  );
     aContext.DocumentInfo.Producer = OUString( "VCL"  );
 
+    aContext.SignPDF        = true;
+    aContext.SignLocation   = OUString( "Burdur" );
+    aContext.SignReason     = OUString( "Some valid reason to sign" );
+    aContext.SignContact    = OUString( "signer at example.com" );
+
     com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > xEnc;
     PDFWriter aWriter( aContext, xEnc );
     aWriter.NewPage( 595, 842 );
@@ -524,11 +529,6 @@ void doTestCode()
 
     aWriter.EndStructureElement(); // close document
 
-    // sign the document
-    PDFWriter::SignatureWidget aSignature;
-    aSignature.Name = OUString("Signature1");
-    aWriter.CreateControl( aSignature, 0);
-
     aWriter.Emit();
 }
 #endif
@@ -6099,13 +6099,13 @@ bool PDFWriterImpl::emitSignature()
     OStringBuffer aContentFiller( MAX_SIGNATURE_CONTENT_LENGTH );
     comphelper::string::padToLength(aContentFiller, MAX_SIGNATURE_CONTENT_LENGTH, '0');
     aLine.append( aContentFiller.makeStringAndClear() );
-    aLine.append( ">\n/Type/Sig/SubFilter/adbe.pkcs7.sha1/Location()"
-                  "/Name ");
+    aLine.append( ">\n/Type/Sig/SubFilter/adbe.pkcs7.sha1");
 
     if( m_aContext.DocumentInfo.Author.Len() )
+    {
+        aLine.append( "/Name" );
         appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Author, m_nSignatureObject, aLine );
-    else
-        aLine.append("()");
+    }
 
     aLine.append( " /M ");
     appendLiteralStringEncrypt( m_aCreationDateString, m_nSignatureObject, aLine );
@@ -6124,8 +6124,28 @@ bool PDFWriterImpl::emitSignature()
     OStringBuffer aByteRangeFiller( 100  );
     comphelper::string::padToLength(aByteRangeFiller, 100, ' ');
     aLine.append( aByteRangeFiller.makeStringAndClear() );
-    aLine.append("  /Filter/Adobe.PPKMS/Reason()>>"
-                 "\nendobj\n\n" );
+    aLine.append("  /Filter/Adobe.PPKMS");
+
+    //emit reason, location and contactinfo
+    if ( !m_aContext.SignReason.isEmpty() )
+    {
+        aLine.append("/Reason");
+        appendUnicodeTextStringEncrypt( m_aContext.SignReason, m_nSignatureObject, aLine );
+    }
+
+    if ( !m_aContext.SignLocation.isEmpty() )
+    {
+        aLine.append("/Location");
+        appendUnicodeTextStringEncrypt( m_aContext.SignLocation, m_nSignatureObject, aLine );
+    }
+
+    if ( !m_aContext.SignContact.isEmpty() )
+    {
+        aLine.append("/ContactInfo");
+        appendUnicodeTextStringEncrypt( m_aContext.SignContact, m_nSignatureObject, aLine );
+    }
+
+    aLine.append(" >>\nendobj\n\n" );
 
     if (!writeBuffer( aLine.getStr(), aLine.getLength() ))
         return false;
@@ -6946,6 +6966,14 @@ bool PDFWriterImpl::emit()
     // needed for widget tab order
     sortWidgets();
 
+    if( m_aContext.SignPDF )
+    {
+        // sign the document
+        PDFWriter::SignatureWidget aSignature;
+        aSignature.Name = OUString("Signature1");
+        createControl( aSignature, 0 );
+    }
+
     // emit additional streams
     CHECK_RETURN( emitAdditionalStreams() );
 
commit 863cf84802ad387899f1d337fe20d907edfdc1a5
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jun 30 17:41:32 2012 +0300

    Show signing GUI in experimentalmode only.
    
    Change-Id: I5e4481d75eca357235eadc99bac170dec488045f

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 259b958..6740143 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -32,6 +32,7 @@
 #include "vcl/svapp.hxx"
 #include "vcl/msgbox.hxx"
 #include "sfx2/passwd.hxx"
+#include "svtools/miscopt.hxx"
 
 #include "comphelper/storagehelper.hxx"
 
@@ -260,6 +261,11 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
     AddTabPage( RID_PDF_TAB_VPREFER, ImpPDFTabViewerPage::Create, 0 );
     AddTabPage( RID_PDF_TAB_OPNFTR, ImpPDFTabOpnFtrPage::Create, 0 );
 
+//remove tabpage if experimentalmode is not set
+    SvtMiscOptions aMiscOptions;
+    if (!aMiscOptions.IsExperimentalMode())
+        RemoveTabPage( RID_PDF_TAB_SIGNING );
+
 //last queued is the first to be displayed (or so it seems..)
     AddTabPage( RID_PDF_TAB_GENER, ImpPDFTabGeneralPage::Create, 0 );
 
@@ -294,7 +300,11 @@ ImpPDFTabDialog::~ImpPDFTabDialog()
     RemoveTabPage( RID_PDF_TAB_OPNFTR );
     RemoveTabPage( RID_PDF_TAB_LINKS );
     RemoveTabPage( RID_PDF_TAB_SECURITY );
-    RemoveTabPage( RID_PDF_TAB_SIGNING );
+
+//remove tabpage if experimentalmode is set
+    SvtMiscOptions aMiscOptions;
+    if (aMiscOptions.IsExperimentalMode())
+        RemoveTabPage( RID_PDF_TAB_SIGNING );
 }
 
 // -----------------------------------------------------------------------------
commit a4ca3ebfabf09d82eabbe9c0ab46884d6d677db2
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sun Jun 24 17:42:30 2012 +0300

    Add certificate selection button and its click handler.
    
    Change-Id: I3f2fff0a3c5cfb77de0ecd11832345b6e162816b

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 4e4b04a..259b958 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -1674,9 +1674,12 @@ ImpPDFTabSigningPage::ImpPDFTabSigningPage( Window* pParent,
     maFtSignContactInfo( this, PDFFilterResId( FT_SIGN_CONTACT ) ),
     maEdSignContactInfo( this, PDFFilterResId( ED_SIGN_CONTACT ) ),
     maFtSignReason( this, PDFFilterResId( FT_SIGN_REASON ) ),
-    maEdSignReason( this, PDFFilterResId( ED_SIGN_REASON ) )
+    maEdSignReason( this, PDFFilterResId( ED_SIGN_REASON ) ),
+    maPbSignSelectCert( this, PDFFilterResId( BTN_SIGN_SELECT_CERT ) )
 {
     FreeResource();
+
+    maPbSignSelectCert.SetClickHdl( LINK( this, ImpPDFTabSigningPage, ClickmaPbSignSelectCert ) );
 }
 
 // -----------------------------------------------------------------------------
@@ -1684,6 +1687,12 @@ ImpPDFTabSigningPage::~ImpPDFTabSigningPage()
 {
 }
 
+IMPL_LINK_NOARG( ImpPDFTabSigningPage, ClickmaPbSignSelectCert )
+{
+    // Certificate selection dialog will pop up
+    return 0;
+}
+
 // -----------------------------------------------------------------------------
 SfxTabPage*  ImpPDFTabSigningPage::Create( Window* pParent,
                                           const SfxItemSet& rAttrSet)
@@ -1709,6 +1718,7 @@ void ImpPDFTabSigningPage::SetFilterConfigItem( const  ImpPDFTabDialog* paParent
     maEdSignLocation.Enable( false );
     maEdSignContactInfo.Enable( false );
     maEdSignReason.Enable( false );
+    maPbSignSelectCert.Enable( false );
 
     if (paParent->mbSignPDF)
     {
@@ -1725,6 +1735,7 @@ IMPL_LINK_NOARG(ImpPDFTabSigningPage, ToggleSignPDFHdl)
     maEdSignLocation.Enable( maCbSignPDF.IsChecked() );
     maEdSignContactInfo.Enable( maCbSignPDF.IsChecked() );
     maEdSignReason.Enable( maCbSignPDF.IsChecked() );
+    maPbSignSelectCert.Enable( maCbSignPDF.IsChecked() );
 
     return 0;
 }
diff --git a/filter/source/pdf/impdialog.hrc b/filter/source/pdf/impdialog.hrc
index ea5cade..e446302 100644
--- a/filter/source/pdf/impdialog.hrc
+++ b/filter/source/pdf/impdialog.hrc
@@ -208,4 +208,4 @@
 #define ED_SIGN_CONTACT      174
 #define FT_SIGN_REASON       175
 #define ED_SIGN_REASON       176
-
+#define BTN_SIGN_SELECT_CERT 177
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index 87327a0..f227c14 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -447,8 +447,10 @@ class ImpPDFTabSigningPage : public SfxTabPage
     Edit                        maEdSignContactInfo;
     FixedText                   maFtSignReason;
     Edit                        maEdSignReason;
+    PushButton                  maPbSignSelectCert;
 
     DECL_LINK( ToggleSignPDFHdl, void* );
+    DECL_LINK( ClickmaPbSignSelectCert, void* );
 
 public:
     ImpPDFTabSigningPage( Window* pParent,
diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src
index 92bf696..b099a53 100644
--- a/filter/source/pdf/impdialog.src
+++ b/filter/source/pdf/impdialog.src
@@ -834,9 +834,18 @@ TabPage  RID_PDF_TAB_SIGNING
         Text[ en-US ] = "Sign PDF file" ;
     };
 
+    PushButton BTN_SIGN_SELECT_CERT
+    {
+        TabStop = TRUE ;
+        Disable = TRUE ;
+        Pos = MAP_APPFONT ( 12, 17 ) ;
+        Size = MAP_APPFONT ( 120 , 13 ) ;
+        Text[ en-US ] = "Select c~ertificate...";
+    };
+
     FixedText FT_SIGN_LOCATION
     {
-        Pos = MAP_APPFONT( 12, 15 );
+        Pos = MAP_APPFONT( 12, 35 );
         Size = MAP_APPFONT( 109, 10 );
         Text[ en-US ] = "Location";
     };
@@ -844,13 +853,13 @@ TabPage  RID_PDF_TAB_SIGNING
     Edit ED_SIGN_LOCATION
     {
         Border = TRUE ;
-        Pos = MAP_APPFONT ( 122, 15 ) ;
+        Pos = MAP_APPFONT ( 122, 35 ) ;
         Size = MAP_APPFONT ( 48 , 12 ) ;
     };
 
     FixedText FT_SIGN_CONTACT
     {
-        Pos = MAP_APPFONT( 12, 28 );
+        Pos = MAP_APPFONT( 12, 48 );
         Size = MAP_APPFONT( 109, 10 );
         Text[ en-US ] = "Contact Information";
     };
@@ -858,13 +867,13 @@ TabPage  RID_PDF_TAB_SIGNING
     Edit ED_SIGN_CONTACT
     {
         Border = TRUE ;
-        Pos = MAP_APPFONT ( 122, 28 ) ;
+        Pos = MAP_APPFONT ( 122, 48 ) ;
         Size = MAP_APPFONT ( 48 , 12 ) ;
     };
 
     FixedText FT_SIGN_REASON
     {
-        Pos = MAP_APPFONT( 12, 41 );
+        Pos = MAP_APPFONT( 12, 61 );
         Size = MAP_APPFONT( 109, 10 );
         Text[ en-US ] = "Reason";
     };
@@ -872,7 +881,7 @@ TabPage  RID_PDF_TAB_SIGNING
     Edit ED_SIGN_REASON
     {
         Border = TRUE ;
-        Pos = MAP_APPFONT ( 122, 41 ) ;
+        Pos = MAP_APPFONT ( 122, 61 ) ;
         Size = MAP_APPFONT ( 48 , 12 ) ;
     };
 
commit 2a537c6d96bac3ef0661bf59375e4061342c0aca
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sun Jun 24 16:25:39 2012 +0300

    Add a simple GUI for digital signatures.
    
    Right now, there is no certificate selection and password
    edit but this GUI will make things easier to test. If Sign PDF
    checkbox is checked, I will create the necessary data in PDF file
    with a garbage PKCS7 object, for now.
    
    Change-Id: Ib9f0b33d3be31cb3eb8acb12a6aa2e37f2d3beeb

diff --git a/filter/inc/filter.hrc b/filter/inc/filter.hrc
index 8c50b5a..8a18d6f 100644
--- a/filter/inc/filter.hrc
+++ b/filter/inc/filter.hrc
@@ -59,6 +59,7 @@
 #define HID_FILTER_PDF_USER_INTERFACE "HID_FILTER_PDF_USER_INTERFACE"
 #define HID_FILTER_PDF_SECURITY       "HID_FILTER_PDF_SECURITY"
 #define HID_FILTER_PDF_LINKS          "HID_FILTER_PDF_LINKS"
+#define HID_FILTER_PDF_SIGNING        "HID_FILTER_PDF_SIGNING"
 
 #endif
 
diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 03de749..4e4b04a 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -124,7 +124,13 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
     mbExportRelativeFsysLinks( sal_False ),
     mnViewPDFMode( 0 ),
     mbConvertOOoTargets( sal_False ),
-    mbExportBmkToPDFDestination( sal_False )
+    mbExportBmkToPDFDestination( sal_False ),
+
+    mbSignPDF( sal_False ),
+    msSignLocation ( ' ' ),
+    msSignContact( ' ' ),
+    msSignReason( ' ' )
+
 {
     FreeResource();
 // check for selection
@@ -241,7 +247,14 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
     mbConvertOOoTargets = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ), sal_False );
     mbExportBmkToPDFDestination = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ), sal_False );
 
+//prepare values for digital signatures
+    mbSignPDF = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignPDF" ) ), sal_False );
+    //msSignLocation = maConfigItem.ReadString( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureLocation" ) ), "" );
+    //msSignContact = maConfigItem.ReadString( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureContactInfo" ) ), "" );
+    //msSignReason = maConfigItem.ReadString( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureReason" ) ), "" );
+
 //queue the tab pages for later creation (created when first shown)
+    AddTabPage( RID_PDF_TAB_SIGNING, ImpPDFTabSigningPage::Create, 0 );
     AddTabPage( RID_PDF_TAB_SECURITY, ImpPDFTabSecurityPage::Create, 0 );
     AddTabPage( RID_PDF_TAB_LINKS, ImpPDFTabLinksPage::Create, 0 );
     AddTabPage( RID_PDF_TAB_VPREFER, ImpPDFTabViewerPage::Create, 0 );
@@ -281,6 +294,7 @@ ImpPDFTabDialog::~ImpPDFTabDialog()
     RemoveTabPage( RID_PDF_TAB_OPNFTR );
     RemoveTabPage( RID_PDF_TAB_LINKS );
     RemoveTabPage( RID_PDF_TAB_SECURITY );
+    RemoveTabPage( RID_PDF_TAB_SIGNING );
 }
 
 // -----------------------------------------------------------------------------
@@ -304,6 +318,9 @@ void ImpPDFTabDialog::PageCreated( sal_uInt16 _nId,
     case RID_PDF_TAB_SECURITY:
         ( ( ImpPDFTabSecurityPage* )&_rPage )->SetFilterConfigItem( this );
         break;
+    case RID_PDF_TAB_SIGNING:
+        ( ( ImpPDFTabSigningPage* )&_rPage )->SetFilterConfigItem( this );
+        break;
     }
 }
 
@@ -329,6 +346,8 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
         ( ( ImpPDFTabLinksPage* )GetTabPage( RID_PDF_TAB_LINKS ) )->GetFilterConfigItem( this );
     if( GetTabPage( RID_PDF_TAB_SECURITY ) )
         ( ( ImpPDFTabSecurityPage* )GetTabPage( RID_PDF_TAB_SECURITY ) )->GetFilterConfigItem( this );
+    if( GetTabPage( RID_PDF_TAB_SIGNING ) )
+        ( ( ImpPDFTabSigningPage* )GetTabPage( RID_PDF_TAB_SIGNING ) )->GetFilterConfigItem( this );
 
 //prepare the items to be returned
     maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "UseLosslessCompression" ) ), mbUseLosslessCompression );
@@ -379,6 +398,8 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
     maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ), mbConvertOOoTargets );
     maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ), mbExportBmkToPDFDestination );
 
+    maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignPDF" ) ), mbSignPDF );
+
     maConfigItem.WriteInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ), mnPrint );
     maConfigItem.WriteInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ), mnChangesAllowed );
     maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableCopyingOfContent" ) ), mbCanCopyOrExtract );
@@ -386,7 +407,7 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
 
     Sequence< PropertyValue > aRet( maConfigItem.GetFilterData() );
 
-    int nElementAdded = 6;
+    int nElementAdded = 9;
 
     aRet.realloc( aRet.getLength() + nElementAdded );
 
@@ -421,13 +442,27 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
     {
         aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
         aRet[ nLength - nElementAdded ].Value <<= OUString( msPageRange );
+        nElementAdded--;
     }
     else if( mbSelectionIsChecked )
     {
         aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Selection" ) );
         aRet[ nLength - nElementAdded ].Value <<= maSelection;
+        nElementAdded--;
     }
 
+    aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureLocation" ) );
+    aRet[ nLength - nElementAdded ].Value <<= OUString( msSignLocation );
+    nElementAdded--;
+
+    aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureReason" ) );
+    aRet[ nLength - nElementAdded ].Value <<= OUString( msSignReason );
+    nElementAdded--;
+
+    aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureContactInfo" ) );
+    aRet[ nLength - nElementAdded ].Value <<= OUString( msSignContact );
+    nElementAdded--;
+
     return aRet;
 }
 
@@ -1626,4 +1661,72 @@ IMPL_LINK_NOARG(ImplErrorDialog, SelectHdl)
     return 0;
 }
 
+////////////////////////////////////////////////////////
+// The digital signatures tab page
+// -----------------------------------------------------------------------------
+ImpPDFTabSigningPage::ImpPDFTabSigningPage( Window* pParent,
+                                              const SfxItemSet& rCoreSet ) :
+    SfxTabPage( pParent, PDFFilterResId( RID_PDF_TAB_SIGNING ), rCoreSet ),
+
+    maCbSignPDF( this, PDFFilterResId( CB_SIGN_PDF ) ),
+    maFtSignLocation( this, PDFFilterResId( FT_SIGN_LOCATION ) ),
+    maEdSignLocation( this, PDFFilterResId( ED_SIGN_LOCATION ) ),
+    maFtSignContactInfo( this, PDFFilterResId( FT_SIGN_CONTACT ) ),
+    maEdSignContactInfo( this, PDFFilterResId( ED_SIGN_CONTACT ) ),
+    maFtSignReason( this, PDFFilterResId( FT_SIGN_REASON ) ),
+    maEdSignReason( this, PDFFilterResId( ED_SIGN_REASON ) )
+{
+    FreeResource();
+}
+
+// -----------------------------------------------------------------------------
+ImpPDFTabSigningPage::~ImpPDFTabSigningPage()
+{
+}
+
+// -----------------------------------------------------------------------------
+SfxTabPage*  ImpPDFTabSigningPage::Create( Window* pParent,
+                                          const SfxItemSet& rAttrSet)
+{
+    return ( new  ImpPDFTabSigningPage( pParent, rAttrSet ) );
+}
+
+// -----------------------------------------------------------------------------
+void ImpPDFTabSigningPage::GetFilterConfigItem( ImpPDFTabDialog* paParent  )
+{
+    paParent->mbSignPDF = maCbSignPDF.IsChecked();
+    paParent->msSignLocation = maEdSignLocation.GetText();
+    paParent->msSignContact = maEdSignContactInfo.GetText();
+    paParent->msSignReason = maEdSignReason.GetText();
+
+}
+
+// -----------------------------------------------------------------------------
+void ImpPDFTabSigningPage::SetFilterConfigItem( const  ImpPDFTabDialog* paParent )
+{
+
+    maCbSignPDF.SetToggleHdl( LINK( this, ImpPDFTabSigningPage, ToggleSignPDFHdl ) );
+    maEdSignLocation.Enable( false );
+    maEdSignContactInfo.Enable( false );
+    maEdSignReason.Enable( false );
+
+    if (paParent->mbSignPDF)
+    {
+        maCbSignPDF.Check();
+        maEdSignLocation.SetText(paParent->msSignLocation);
+        maEdSignContactInfo.SetText(paParent->msSignContact);
+        maEdSignReason.SetText(paParent->msSignReason);
+    }
+}
+
+// -----------------------------------------------------------------------------
+IMPL_LINK_NOARG(ImpPDFTabSigningPage, ToggleSignPDFHdl)
+{
+    maEdSignLocation.Enable( maCbSignPDF.IsChecked() );
+    maEdSignContactInfo.Enable( maCbSignPDF.IsChecked() );
+    maEdSignReason.Enable( maCbSignPDF.IsChecked() );
+
+    return 0;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/pdf/impdialog.hrc b/filter/source/pdf/impdialog.hrc
index 25c46ce..ea5cade 100644
--- a/filter/source/pdf/impdialog.hrc
+++ b/filter/source/pdf/impdialog.hrc
@@ -33,6 +33,7 @@
 #define RID_PDF_TAB_OPNFTR          (RID_PDF_DIALOG_START +   3)
 #define RID_PDF_TAB_SECURITY        (RID_PDF_DIALOG_START +   4)
 #define RID_PDF_TAB_LINKS           (RID_PDF_DIALOG_START +   12)
+#define RID_PDF_TAB_SIGNING         (RID_PDF_DIALOG_START +   13)
 #define RID_PDF_WARNPDFAPASSWORD    (RID_PDF_DIALOG_START +   6)
 
 //strings
@@ -198,3 +199,13 @@
 #define FL_INITVIEW_VERTICAL 158
 #define FL_VPREFER_VERTICAL  158
 #define FL_SECURITY_VERTICAL 160
+
+//controls for digital signatures tab page
+#define CB_SIGN_PDF          170
+#define FT_SIGN_LOCATION     171
+#define ED_SIGN_LOCATION     172
+#define FT_SIGN_CONTACT      173
+#define ED_SIGN_CONTACT      174
+#define FT_SIGN_REASON       175
+#define ED_SIGN_REASON       176
+
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index f3330c0..87327a0 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -149,6 +149,12 @@ protected:
     sal_Int32                   mnViewPDFMode;
     sal_Bool                    mbConvertOOoTargets;
     sal_Bool                    mbExportBmkToPDFDestination;
+
+    sal_Bool                    mbSignPDF;
+    String                      msSignLocation;
+    String                      msSignContact;
+    String                      msSignReason;
+
     ::rtl::OUString             maWatermarkText;
 
 public:
@@ -158,6 +164,7 @@ public:
     friend class                ImpPDFTabOpnFtrPage;
     friend class                ImpPDFTabSecurityPage;
     friend class                ImpPDFTabLinksPage;
+    friend class                ImpPDFTabSigningPage;
 
     ImpPDFTabDialog( Window* pParent,
                      Sequence< PropertyValue >& rFilterData,
@@ -430,6 +437,31 @@ public:
     void    ImplPDFALinkControl( sal_Bool bEnableLaunch );
 };
 
+//class to implement the digital signing
+class ImpPDFTabSigningPage : public SfxTabPage
+{
+    CheckBox                    maCbSignPDF;
+    FixedText                   maFtSignLocation;
+    Edit                        maEdSignLocation;
+    FixedText                   maFtSignContactInfo;
+    Edit                        maEdSignContactInfo;
+    FixedText                   maFtSignReason;
+    Edit                        maEdSignReason;
+
+    DECL_LINK( ToggleSignPDFHdl, void* );
+
+public:
+    ImpPDFTabSigningPage( Window* pParent,
+                          const SfxItemSet& rSet );
+
+    ~ImpPDFTabSigningPage();
+    static SfxTabPage*      Create( Window* pParent,
+                                    const SfxItemSet& rAttrSet );
+
+    void    GetFilterConfigItem( ImpPDFTabDialog* paParent);
+    void    SetFilterConfigItem( const ImpPDFTabDialog* paParent );
+};
+
 #endif // IMPDIALOG_HXX
 
 
diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src
index 8c73d20..92bf696 100644
--- a/filter/source/pdf/impdialog.src
+++ b/filter/source/pdf/impdialog.src
@@ -817,6 +817,68 @@ TabPage  RID_PDF_TAB_SECURITY
 };
 
 //----------------------------------------------------------
+//tab page for PDF Export, digital signatures
+TabPage  RID_PDF_TAB_SIGNING
+{
+    HelpId = HID_FILTER_PDF_SIGNING ;
+    Text [ en-US ] = "Digital Signatures";
+    TAB_PDF_SIZE;
+    Hide = TRUE;
+
+    CheckBox CB_SIGN_PDF
+    {
+        Pos = MAP_APPFONT ( 6 , 3 ) ;
+        Size = MAP_APPFONT ( 164 , 16 ) ;
+        TabStop = TRUE ;
+        WordBreak = TRUE ;
+        Text[ en-US ] = "Sign PDF file" ;
+    };
+
+    FixedText FT_SIGN_LOCATION
+    {
+        Pos = MAP_APPFONT( 12, 15 );
+        Size = MAP_APPFONT( 109, 10 );
+        Text[ en-US ] = "Location";
+    };
+
+    Edit ED_SIGN_LOCATION
+    {
+        Border = TRUE ;
+        Pos = MAP_APPFONT ( 122, 15 ) ;
+        Size = MAP_APPFONT ( 48 , 12 ) ;
+    };
+
+    FixedText FT_SIGN_CONTACT
+    {
+        Pos = MAP_APPFONT( 12, 28 );
+        Size = MAP_APPFONT( 109, 10 );
+        Text[ en-US ] = "Contact Information";
+    };
+
+    Edit ED_SIGN_CONTACT
+    {
+        Border = TRUE ;
+        Pos = MAP_APPFONT ( 122, 28 ) ;
+        Size = MAP_APPFONT ( 48 , 12 ) ;
+    };
+
+    FixedText FT_SIGN_REASON
+    {
+        Pos = MAP_APPFONT( 12, 41 );
+        Size = MAP_APPFONT( 109, 10 );
+        Text[ en-US ] = "Reason";
+    };
+
+    Edit ED_SIGN_REASON
+    {
+        Border = TRUE ;
+        Pos = MAP_APPFONT ( 122, 41 ) ;
+        Size = MAP_APPFONT ( 48 , 12 ) ;
+    };
+
+};
+
+//----------------------------------------------------------
 //tab page for PDF Export, links management
 TabPage  RID_PDF_TAB_LINKS
 {
@@ -930,6 +992,11 @@ TabDialog  RID_PDF_EXPORT_DLG
                 Identifier = RID_PDF_TAB_SECURITY;
                 Text [ en-US ] = "Security";
             };
+            PageItem
+            {
+                Identifier = RID_PDF_TAB_SIGNING;
+                Text [ en-US ] = "Digital Signatures";
+            };
         };
     };
 };
commit 1d546e142274f9f1f1bbc60f095b4b7c7493e469
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jun 23 20:30:47 2012 +0300

    Use /Rect [0, 0, 0, 0] if signature is not visible.
    
    Change-Id: I271b882d95d6e0bc7b5831add67046e7f476c7dd

diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx
index 99f99d6..8ffab09 100644
--- a/vcl/inc/vcl/pdfwriter.hxx
+++ b/vcl/inc/vcl/pdfwriter.hxx
@@ -452,12 +452,18 @@ public:
 
     struct SignatureWidget: public AnyWidget
     {
+        // Use Sig prefix for members to avoid conflict with
+        // the Location member of the AnyWidget which spcifies the coordinates
+        // of the signature
+
         rtl::OUString                    SigLocation;
         rtl::OUString                    SigReason;
         rtl::OUString                    SigContactInfo;
+        bool                             SigHidden;
 
         SignatureWidget()
-                : AnyWidget( vcl::PDFWriter::Signature )
+                : AnyWidget( vcl::PDFWriter::Signature ),
+                  SigHidden( true )
         {}
 
         virtual AnyWidget* Clone() const
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 5e271ec..f12f973 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -527,7 +527,6 @@ void doTestCode()
     // sign the document
     PDFWriter::SignatureWidget aSignature;
     aSignature.Name = OUString("Signature1");
-    aSignature.Location = Rectangle( Point( 0, 0 ), Size( 0, 0 ) );
     aWriter.CreateControl( aSignature, 0);
 
     aWriter.Emit();
@@ -11699,13 +11698,14 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
     if( nPageNr < 0 || nPageNr >= (sal_Int32)m_aPages.size() )
         return -1;
 
+    bool sigHidden;
     sal_Int32 nNewWidget = m_aWidgets.size();
     m_aWidgets.push_back( PDFWidget() );
 
     m_aWidgets.back().m_nObject         = createObject();
-    m_aWidgets.back().m_aRect               = rControl.Location;
-    m_aWidgets.back().m_nPage               = nPageNr;
-    m_aWidgets.back().m_eType               = rControl.getType();
+    m_aWidgets.back().m_aRect           = rControl.Location;
+    m_aWidgets.back().m_nPage           = nPageNr;
+    m_aWidgets.back().m_eType           = rControl.getType();
 
     sal_Int32 nRadioGroupWidget = -1;
     // for unknown reasons the radio buttons of a radio group must not have a
@@ -11865,7 +11865,12 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
     }
     else if( rControl.getType() == PDFWriter::Signature)
     {
-        //const PDFWriter::SignatureWidget& rSig = static_cast<const PDFWriter::SignatureWidget&>(rControl);
+        const PDFWriter::SignatureWidget& rSig = static_cast<const PDFWriter::SignatureWidget&>(rControl);
+        sigHidden = rSig.SigHidden;
+
+        if ( sigHidden )
+            rNewWidget.m_aRect = Rectangle(0, 0, 0, 0);
+
         m_nSignatureObject = createObject();
         rNewWidget.m_aValue = OUString::valueOf( m_nSignatureObject );
         rNewWidget.m_aValue += OUString(" 0 R");
@@ -11874,9 +11879,15 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
         rNewWidget.m_aAppearances[ "N" ][ "Standard" ] = new SvMemoryStream();
     }
 
-    // convert to default user space now, since the mapmode may change
-    // note: create default appearances before m_aRect gets transformed
-    m_aPages[ nPageNr ].convertRect( rNewWidget.m_aRect );
+
+    // if control is a hidden signature, do not convert coordinates since we
+    // need /Rect [ 0 0 0 0 ]
+    if ( ! ( ( rControl.getType() == PDFWriter::Signature ) && ( sigHidden ) ) )
+    {
+        // convert to default user space now, since the mapmode may change
+        // note: create default appearances before m_aRect gets transformed
+        m_aPages[ nPageNr ].convertRect( rNewWidget.m_aRect );
+    }
 
     // insert widget to page's annotation list
     m_aPages[ nPageNr ].m_aAnnotations.push_back( rNewWidget.m_nObject );
commit 77d41a25fe7afc31045ea6a39cb7bfb6c74d85fa
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jun 23 15:43:14 2012 +0300

    /NeedAppearances must not be used if PDF is signed.
    
    Change-Id: Ie9d98d555e807de4d20a122a005e75106e039305

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index c0cf798..5e271ec 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6048,7 +6048,8 @@ bool PDFWriterImpl::emitCatalog()
         aLine.append( "/DR " );
         aLine.append( getResourceDictObj() );
         aLine.append( " 0 R" );
-        if( m_bIsPDF_A1 )
+        // /NeedAppearances must not be used if PDF is signed
+        if( m_bIsPDF_A1 || ( m_nSignatureObject != -1 ) )
             aLine.append( ">>\n" );
         else
             aLine.append( "/NeedAppearances true>>\n" );
commit 92cc6c3788376ff28a22e29975499c3414d642b6
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Sat Jun 23 14:18:10 2012 +0300

    Check the return values of osl_getFilePos and osl_setFilePos.
    
    Change-Id: I42d62ae69d37f35b6c0b1a325abc9943e664dd45

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 6746d4b..c0cf798 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6090,7 +6090,7 @@ bool PDFWriterImpl::emitSignature()
                  "/DigestValue(aa)/TransformMethod/DocMDP>>]/Contents <" );
 
     sal_uInt64 nOffset = ~0U;
-    oslFileError aError = osl_getFilePos( m_aFile, &nOffset );
+    CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nOffset ) ) );
     DBG_ASSERT( aError == osl_File_E_None, "could not get file position" );
 
     m_nSignatureContentOffset = nOffset + aLine.getLength();
@@ -6137,34 +6137,31 @@ bool PDFWriterImpl::finalizeSignature()
 {
     // 1- calculate last ByteRange value
     sal_uInt64 nOffset = ~0U;
-    oslFileError aError = osl_getFilePos( m_aFile, &nOffset );
-
-    if ( aError != osl_File_E_None )
-        return false;
+    CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nOffset ) ) );
 
     sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH) - 1;
 
     // 2- overwrite the value to the m_nSignatureLastByteRangeNoOffset position
     sal_uInt64 nWritten = 0;
-    osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureLastByteRangeNoOffset );
+    CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureLastByteRangeNoOffset ) ) );
     OStringBuffer aByteRangeNo( 256 );
     aByteRangeNo.append( nLastByteRangeNo, 10);
     aByteRangeNo.append( " ]" );
 
     if( osl_writeFile( m_aFile, aByteRangeNo.getStr(), aByteRangeNo.getLength(), &nWritten ) != osl_File_E_None )
     {
-        osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset );
+        CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset ) ) );
         return false;
     }
 
     // 3- create the PKCS#7 object using NSS
 
     // 4- overwrite the PKCS7 content to the m_nSignatureContentOffset
-    osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset );
+    CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset ) ) );
     // osl_writeFile()
 
     // revert the file position back
-    osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset );
+    CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset ) ) );
     return true;
 }
 
commit 9ad3203bc1585085c70b026465de1fdc27d1a3a2
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Wed Jun 20 15:46:13 2012 +0300

    Fix the calculation of ByteRange values.
    
    Change-Id: I1d386f381871da7e73cd9efc30ccb71081d24bbc

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index cc65911..6746d4b 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6111,9 +6111,9 @@ bool PDFWriterImpl::emitSignature()
     appendLiteralStringEncrypt( m_aCreationDateString, m_nSignatureObject, aLine );
 
     aLine.append( " /ByteRange [ 0 ");
-    aLine.append( m_nSignatureContentOffset, 10 );
+    aLine.append( m_nSignatureContentOffset - 1, 10 );
     aLine.append( " " );
-    aLine.append( m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH, 10 );
+    aLine.append( m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1, 10 );
     aLine.append( " " );
 
     m_nSignatureLastByteRangeNoOffset = nOffset + aLine.getLength();
@@ -6142,7 +6142,7 @@ bool PDFWriterImpl::finalizeSignature()
     if ( aError != osl_File_E_None )
         return false;
 
-    sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH);
+    sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH) - 1;
 
     // 2- overwrite the value to the m_nSignatureLastByteRangeNoOffset position
     sal_uInt64 nWritten = 0;
commit 4ef8a04b6a11bed9f83685242672492c6d723d9d
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Wed Jun 20 15:10:48 2012 +0300

    Add a fake appearance dictionary to Sig object.
    
    Change-Id: Ibd8f6232b0121de6951e27ec82851ea719a2ddc2

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 9e0dbf9..cc65911 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -11872,6 +11872,8 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
         rNewWidget.m_aValue = OUString::valueOf( m_nSignatureObject );
         rNewWidget.m_aValue += OUString(" 0 R");
         //createDefaultSignatureAppearance( rNewWidget, rSig );
+        // let's add a fake appearance
+        rNewWidget.m_aAppearances[ "N" ][ "Standard" ] = new SvMemoryStream();
     }
 
     // convert to default user space now, since the mapmode may change
commit 35373f0ef4b60f5d50b53949db083f33b78974de
Author: Gökçen Eraslan <gokcen.eraslan at gmail.com>
Date:   Tue Jun 19 17:18:52 2012 +0300

    Add initial support for PDF signing.
    
    PDF signing has still some missing parts like PKCS7 object creation
    and GUI stuff (like certificate selection). But this basically
    implements the skeleton of the Signature structure.
    
    Change-Id: Ic0c7e4a1b0f79791aec1cc682dfa85ed163330eb

diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx
index cb6d271..99f99d6 100644
--- a/vcl/inc/vcl/pdfwriter.hxx
+++ b/vcl/inc/vcl/pdfwriter.hxx
@@ -197,7 +197,8 @@ public:
 
     enum WidgetType
     {
-        PushButton, RadioButton, CheckBox, Edit, ListBox, ComboBox, Hierarchy
+        PushButton, RadioButton, CheckBox, Edit, ListBox, ComboBox, Hierarchy,
+        Signature
     };
 
     enum WidgetState
@@ -449,6 +450,22 @@ public:
         }
     };
 
+    struct SignatureWidget: public AnyWidget
+    {
+        rtl::OUString                    SigLocation;
+        rtl::OUString                    SigReason;
+        rtl::OUString                    SigContactInfo;
+
+        SignatureWidget()
+                : AnyWidget( vcl::PDFWriter::Signature )
+        {}
+
+        virtual AnyWidget* Clone() const
+        {
+            return new SignatureWidget( *this );
+        }
+    };
+
     enum ExportDataFormat { HTML, XML, FDF, PDF };
 // see 3.6.1 of PDF 1.4 ref for details, used for 8.1 PDF v 1.4 ref also
 // These emuns are treated as integer while reading/writing to configuration
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 72201ba..9e0dbf9 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -74,6 +74,7 @@
 #include <lcms2.h>
 
 #include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
 
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/util/URLTransformer.hpp>
@@ -97,6 +98,8 @@ using ::rtl::OUStringBuffer;
 #define DEBUG_DISABLE_PDFCOMPRESSION // also do not compress streams
 #endif
 
+#define MAX_SIGNATURE_CONTENT_LENGTH 0x4000
+
 #ifdef DO_TEST_PDF
 class PDFTestOutputStream : public PDFOutputStream
 {
@@ -520,6 +523,13 @@ void doTestCode()
     aWriter.CreateOutlineItem( nPage2OL, OUString( "Dest 1"  ), nFirstDest );
 
     aWriter.EndStructureElement(); // close document
+
+    // sign the document
+    PDFWriter::SignatureWidget aSignature;
+    aSignature.Name = OUString("Signature1");
+    aSignature.Location = Rectangle( Point( 0, 0 ), Size( 0, 0 ) );
+    aWriter.CreateControl( aSignature, 0);
+
     aWriter.Emit();
 }
 #endif
@@ -1755,6 +1765,9 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal
         m_eInheritedOrientation( PDFWriter::Portrait ),
         m_nCurrentPage( -1 ),
         m_nResourceDict( -1 ),
+        m_nSignatureObject( -1 ),
+        m_nSignatureContentOffset( 0 ),
+        m_nSignatureLastByteRangeNoOffset( 0 ),
         m_nFontDictObject( -1 ),
         m_pCodec( NULL ),
         m_aDocDigest( rtl_digest_createMD5() ),
@@ -5452,15 +5465,29 @@ bool PDFWriterImpl::emitWidgetAnnotations()
             // emit widget annotation only for terminal fields
             if( rWidget.m_aKids.empty() )
             {
-                aLine.append( "/Type/Annot/Subtype/Widget/F 4\n"
-                              "/Rect[" );
-                appendFixedInt( rWidget.m_aRect.Left()-1, aLine );
+                int iRectMargin;
+
+                aLine.append( "/Type/Annot/Subtype/Widget/F " );
+
+                if (rWidget.m_eType == PDFWriter::Signature)
+                {
+                    aLine.append( "132\n" ); // Print & Locked
+                    iRectMargin = 0;
+                }
+                else
+                {
+                    aLine.append( "4\n" );
+                    iRectMargin = 1;
+                }
+
+                aLine.append("/Rect[" );
+                appendFixedInt( rWidget.m_aRect.Left()-iRectMargin, aLine );
                 aLine.append( ' ' );
-                appendFixedInt( rWidget.m_aRect.Top()+1, aLine );
+                appendFixedInt( rWidget.m_aRect.Top()+iRectMargin, aLine );
                 aLine.append( ' ' );
-                appendFixedInt( rWidget.m_aRect.Right()+1, aLine );
+                appendFixedInt( rWidget.m_aRect.Right()+iRectMargin, aLine );
                 aLine.append( ' ' );
-                appendFixedInt( rWidget.m_aRect.Bottom()-1, aLine );
+                appendFixedInt( rWidget.m_aRect.Bottom()-iRectMargin, aLine );
                 aLine.append( "]\n" );
             }
             aLine.append( "/FT/" );
@@ -5515,6 +5542,10 @@ bool PDFWriterImpl::emitWidgetAnnotations()
                     aLine.append( "Tx" );
                     appendUnicodeTextStringEncrypt( rWidget.m_aValue, rWidget.m_nObject, aValue );
                     break;
+                case PDFWriter::Signature:
+                    aLine.append( "Sig" );
+                    aValue.append(OUStringToOString(rWidget.m_aValue, RTL_TEXTENCODING_ASCII_US));
+                    break;
                 case PDFWriter::Hierarchy: // make the compiler happy
                     break;
             }
@@ -5877,6 +5908,14 @@ bool PDFWriterImpl::emitCatalog()
     }
     else
         aInitPageRef.append( "0" );
+
+    if (m_nSignatureObject != -1) // Document will be signed
+    {
+        aLine.append("/Perms<</DocMDP ");
+        aLine.append(m_nSignatureObject);
+        aLine.append(" 0 R>>");
+    }
+
     switch( m_aContext.PDFDocumentAction )
     {
     case PDFWriter::ActionDefault :     //do nothing, this is the Acrobat default
@@ -6001,7 +6040,12 @@ bool PDFWriterImpl::emitCatalog()
                 aLine.append( (nOut++ % 5)==4 ? " 0 R\n" : " 0 R " );
             }
         }
-        aLine.append( "\n]/DR " );
+        aLine.append( "\n]" );
+
+        if (m_nSignatureObject != -1)
+            aLine.append( "/SigFlags 3");
+
+        aLine.append( "/DR " );
         aLine.append( getResourceDictObj() );
         aLine.append( " 0 R" );
         if( m_bIsPDF_A1 )
@@ -6031,6 +6075,99 @@ bool PDFWriterImpl::emitCatalog()
     return true;
 }
 
+bool PDFWriterImpl::emitSignature()
+{
+    if( !updateObject( m_nSignatureObject ) )
+        return false;
+
+    OStringBuffer aLine( 0x5000 );
+    aLine.append( m_nSignatureObject );
+    aLine.append( " 0 obj\n" );
+    aLine.append("<</Reference[<</Data ");
+    aLine.append( m_nCatalogObject );
+    aLine.append(" 0 R/Type/SigRef/TransformParams<</Type/TransformParams"
+                 "/V/1.2/P 1>>/DigestMethod/MD5/DigestLocation[0 0]"
+                 "/DigestValue(aa)/TransformMethod/DocMDP>>]/Contents <" );
+
+    sal_uInt64 nOffset = ~0U;
+    oslFileError aError = osl_getFilePos( m_aFile, &nOffset );
+    DBG_ASSERT( aError == osl_File_E_None, "could not get file position" );
+
+    m_nSignatureContentOffset = nOffset + aLine.getLength();
+
+    // reserve some space for the PKCS#7 object
+    OStringBuffer aContentFiller( MAX_SIGNATURE_CONTENT_LENGTH );
+    comphelper::string::padToLength(aContentFiller, MAX_SIGNATURE_CONTENT_LENGTH, '0');
+    aLine.append( aContentFiller.makeStringAndClear() );
+    aLine.append( ">\n/Type/Sig/SubFilter/adbe.pkcs7.sha1/Location()"
+                  "/Name ");
+
+    if( m_aContext.DocumentInfo.Author.Len() )
+        appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Author, m_nSignatureObject, aLine );
+    else
+        aLine.append("()");
+
+    aLine.append( " /M ");
+    appendLiteralStringEncrypt( m_aCreationDateString, m_nSignatureObject, aLine );
+
+    aLine.append( " /ByteRange [ 0 ");
+    aLine.append( m_nSignatureContentOffset, 10 );
+    aLine.append( " " );
+    aLine.append( m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH, 10 );
+    aLine.append( " " );
+
+    m_nSignatureLastByteRangeNoOffset = nOffset + aLine.getLength();
+
+    // mark the last ByteRange no and add some space. Now, we don't know
+    // how many bytes we need for this ByteRange value
+    // The real value will be overwritten in the finalizeSignature method
+    OStringBuffer aByteRangeFiller( 100  );
+    comphelper::string::padToLength(aByteRangeFiller, 100, ' ');
+    aLine.append( aByteRangeFiller.makeStringAndClear() );
+    aLine.append("  /Filter/Adobe.PPKMS/Reason()>>"
+                 "\nendobj\n\n" );
+
+    if (!writeBuffer( aLine.getStr(), aLine.getLength() ))
+        return false;
+
+    return true;
+}
+
+bool PDFWriterImpl::finalizeSignature()
+{
+    // 1- calculate last ByteRange value
+    sal_uInt64 nOffset = ~0U;
+    oslFileError aError = osl_getFilePos( m_aFile, &nOffset );
+
+    if ( aError != osl_File_E_None )
+        return false;
+
+    sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH);
+
+    // 2- overwrite the value to the m_nSignatureLastByteRangeNoOffset position
+    sal_uInt64 nWritten = 0;
+    osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureLastByteRangeNoOffset );
+    OStringBuffer aByteRangeNo( 256 );
+    aByteRangeNo.append( nLastByteRangeNo, 10);
+    aByteRangeNo.append( " ]" );
+
+    if( osl_writeFile( m_aFile, aByteRangeNo.getStr(), aByteRangeNo.getLength(), &nWritten ) != osl_File_E_None )
+    {
+        osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset );
+        return false;
+    }
+
+    // 3- create the PKCS#7 object using NSS
+
+    // 4- overwrite the PKCS7 content to the m_nSignatureContentOffset
+    osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset );
+    // osl_writeFile()
+
+    // revert the file position back
+    osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset );
+    return true;
+}
+
 sal_Int32 PDFWriterImpl::emitInfoDict( )
 {
     sal_Int32 nObject = createObject();
@@ -6818,9 +6955,15 @@ bool PDFWriterImpl::emit()
     // emit catalog
     CHECK_RETURN( emitCatalog() );
 
+    if (m_nSignatureObject != -1) // if document is signed, emit sigdict
+        CHECK_RETURN( emitSignature() );
+
     // emit trailer
     CHECK_RETURN( emitTrailer() );
 
+    if (m_nSignatureObject != -1) // finalize the signature
+        CHECK_RETURN( finalizeSignature() );
+
     osl_closeFile( m_aFile );
     m_bOpen = false;
 
@@ -11722,6 +11865,14 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
 
         createDefaultEditAppearance( rNewWidget, rEdit );
     }
+    else if( rControl.getType() == PDFWriter::Signature)
+    {
+        //const PDFWriter::SignatureWidget& rSig = static_cast<const PDFWriter::SignatureWidget&>(rControl);
+        m_nSignatureObject = createObject();
+        rNewWidget.m_aValue = OUString::valueOf( m_nSignatureObject );
+        rNewWidget.m_aValue += OUString(" 0 R");
+        //createDefaultSignatureAppearance( rNewWidget, rSig );
+    }
 
     // convert to default user space now, since the mapmode may change
     // note: create default appearances before m_aRect gets transformed
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 8e1ba1d..ac94275 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -678,6 +678,10 @@ private:
     sal_Int32                           m_nCurrentPage;
 
     sal_Int32                           m_nCatalogObject;
+    // object number of the main signature dictionary
+    sal_Int32                           m_nSignatureObject;
+    sal_Int64                           m_nSignatureContentOffset;
+    sal_Int64                           m_nSignatureLastByteRangeNoOffset;
     sal_Int32                           m_nResourceDict;
     ResourceDict                        m_aGlobalResourceDict;
     sal_Int32                           m_nFontDictObject;
@@ -950,6 +954,11 @@ i12626
     sal_Int32 emitStructParentTree( sal_Int32 nTreeObject );
     // writes page tree and catalog
     bool emitCatalog();
+    // writes signature dictionary object
+    bool emitSignature();
+    // creates a PKCS7 object using the ByteRange and overwrite /Contents
+    // of the signature dictionary
+    bool finalizeSignature();
     // writes xref and trailer
     bool emitTrailer();
     // emit additional streams collected; also create there object numbers


More information about the Libreoffice-commits mailing list