[Libreoffice-commits] core.git: include/vcl vcl/source xmlsecurity/qa xmlsecurity/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Nov 4 08:14:48 UTC 2016


 include/vcl/pdfwriter.hxx                     |    3 
 vcl/source/gdi/pdfwriter_impl.cxx             |   85 +++++++++++++++++---------
 vcl/source/gdi/pdfwriter_impl.hxx             |    2 
 xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx |   12 +++
 xmlsecurity/source/pdfio/pdfdocument.cxx      |    6 +
 5 files changed, 77 insertions(+), 31 deletions(-)

New commits:
commit 3e610f8496a0b6ef126426b807e0af366a98b8f3
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Nov 4 09:13:02 2016 +0100

    vcl: extract PDFWriter::GetDateTime() from PDFWriterImpl
    
    And use it in xmlsecurity when signing an existing PDF. This is
    especially important on Windows, where the PKCS#7 blob doesn't have an
    (unsigned) timestamp.
    
    Change-Id: I4051dc19a43f8f8114d9f4d02309f28d6754e9ae

diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 79ac5db..0e059a6 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -1270,6 +1270,9 @@ The following structure describes the permissions used in PDF security
 
     /// Write rString as a PDF hex string into rBuffer.
     static void AppendUnicodeTextString(const OUString& rString, OStringBuffer& rBuffer);
+
+    /// Get current date/time in PDF D:YYYYMMDDHHMMSS form.
+    static OString GetDateTime();
 };
 
 }
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 94c730e..80cb0a0 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -1855,14 +1855,67 @@ PDFWriterImpl::~PDFWriterImpl()
 void PDFWriterImpl::setupDocInfo()
 {
     std::vector< sal_uInt8 > aId;
+    m_aCreationDateString = PDFWriter::GetDateTime();
     computeDocumentIdentifier( aId, m_aContext.DocumentInfo, m_aCreationDateString, m_aCreationMetaDateString );
     if( m_aContext.Encryption.DocumentIdentifier.empty() )
         m_aContext.Encryption.DocumentIdentifier = aId;
 }
 
+OString PDFWriter::GetDateTime()
+{
+    OStringBuffer aRet;
+
+    TimeValue aTVal, aGMT;
+    oslDateTime aDT;
+    osl_getSystemTime(&aGMT);
+    osl_getLocalTimeFromSystemTime(&aGMT, &aTVal);
+    osl_getDateTimeFromTimeValue(&aTVal, &aDT);
+    aRet.append("D:");
+    aRet.append((sal_Char)('0' + ((aDT.Year / 1000) % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Year / 100) % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Year / 10) % 10)));
+    aRet.append((sal_Char)('0' + (aDT.Year % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Month / 10) % 10)));
+    aRet.append((sal_Char)('0' + (aDT.Month % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Day / 10) % 10)));
+    aRet.append((sal_Char)('0' + (aDT.Day % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Hours / 10) % 10)));
+    aRet.append((sal_Char)('0' + (aDT.Hours % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Minutes / 10) % 10)));
+    aRet.append((sal_Char)('0' + (aDT.Minutes % 10)));
+    aRet.append((sal_Char)('0' + ((aDT.Seconds / 10) % 10)));
+    aRet.append((sal_Char)('0' + (aDT.Seconds % 10)));
+
+    sal_uInt32 nDelta = 0;
+    if (aGMT.Seconds > aTVal.Seconds)
+    {
+        aRet.append("-");
+        nDelta = aGMT.Seconds-aTVal.Seconds;
+    }
+    else if (aGMT.Seconds < aTVal.Seconds)
+    {
+        aRet.append("+");
+        nDelta = aTVal.Seconds-aGMT.Seconds;
+    }
+    else
+        aRet.append("Z");
+
+    if (nDelta)
+    {
+        aRet.append((sal_Char)('0' + ((nDelta / 36000) % 10)));
+        aRet.append((sal_Char)('0' + ((nDelta / 3600) % 10)));
+        aRet.append("'");
+        aRet.append((sal_Char)('0' + ((nDelta / 600) % 6)));
+        aRet.append((sal_Char)('0' + ((nDelta / 60) % 10)));
+    }
+    aRet.append( "'" );
+
+    return aRet.makeStringAndClear();
+}
+
 void PDFWriterImpl::computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier,
                                                const vcl::PDFWriter::PDFDocInfo& i_rDocInfo,
-                                               OString& o_rCString1,
+                                               const OString& i_rCString1,
                                                OString& o_rCString2
                                                )
 {
@@ -1889,22 +1942,7 @@ void PDFWriterImpl::computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIden
     osl_getSystemTime( &aGMT );
     osl_getLocalTimeFromSystemTime( &aGMT, &aTVal );
     osl_getDateTimeFromTimeValue( &aTVal, &aDT );
-    OStringBuffer aCreationDateString(64), aCreationMetaDateString(64);
-    aCreationDateString.append( "D:" );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) );
-    aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) );
+    OStringBuffer aCreationMetaDateString(64);
 
     //--> i59651, we fill the Metadata date string as well, if PDF/A is requested
     // according to ISO 19005-1:2005 6.7.3 the date is corrected for
@@ -1935,41 +1973,30 @@ void PDFWriterImpl::computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIden
     sal_uInt32 nDelta = 0;
     if( aGMT.Seconds > aTVal.Seconds )
     {
-        aCreationDateString.append( "-" );
         nDelta = aGMT.Seconds-aTVal.Seconds;
         aCreationMetaDateString.append( "-" );
     }
     else if( aGMT.Seconds < aTVal.Seconds )
     {
-        aCreationDateString.append( "+" );
         nDelta = aTVal.Seconds-aGMT.Seconds;
         aCreationMetaDateString.append( "+" );
     }
     else
     {
-        aCreationDateString.append( "Z" );
         aCreationMetaDateString.append( "Z" );
 
     }
     if( nDelta )
     {
-        aCreationDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) );
-        aCreationDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) );
-        aCreationDateString.append( "'" );
-        aCreationDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) );
-        aCreationDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) );
-
         aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) );
         aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) );
         aCreationMetaDateString.append( ":" );
         aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) );
         aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) );
     }
-    aCreationDateString.append( "'" );
-    aID.append( aCreationDateString.getStr(), aCreationDateString.getLength() );
+    aID.append( i_rCString1.getStr(), i_rCString1.getLength() );
 
     aInfoValuesOut = aID.makeStringAndClear();
-    o_rCString1 = aCreationDateString.makeStringAndClear();
     o_rCString2 = aCreationMetaDateString.makeStringAndClear();
 
     rtlDigest aDigest = rtl_digest_createMD5();
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index a49b620..16f1fbd 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -972,7 +972,7 @@ i12626
 
     static void computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier,
                                            const vcl::PDFWriter::PDFDocInfo& i_rDocInfo,
-                                           OString& o_rCString1,
+                                           const OString& i_rCString1,
                                            OString& o_rCString2
                                           );
     static sal_Int32 computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties,
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
index 49da58a..5a95586 100644
--- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
+++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
@@ -12,6 +12,7 @@
 #include <comphelper/processfactory.hxx>
 #include <osl/file.hxx>
 #include <test/bootstrapfixture.hxx>
+#include <tools/datetime.hxx>
 #include <unotools/streamwrap.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 
@@ -152,7 +153,16 @@ void PDFSigningTest::testPDFAdd()
     OUString aInURL = aSourceDir + "no.pdf";
     OUString aTargetDir = m_directories.getURLFromWorkdir("/CppunitTest/xmlsecurity_pdfsigning.test.user/");
     OUString aOutURL = aTargetDir + "add.pdf";
-    sign(aInURL, aOutURL, 0);
+    bool bHadCertificates = sign(aInURL, aOutURL, 0);
+
+    if (bHadCertificates)
+    {
+        // Make sure the timestamp is correct.
+        std::vector<SignatureInformation> aInfos = verify(aOutURL, 1);
+        DateTime aDateTime(DateTime::SYSTEM);
+        // This was 0 (on Windows), as neither the /M key nor the PKCS#7 blob contained a timestamp.
+        CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(aDateTime.GetYear()), aInfos[0].stDateTime.Year);
+    }
 }
 
 void PDFSigningTest::testPDFAdd2()
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 31ac585..6822e14 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -356,6 +356,12 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
     comphelper::string::padToLength(aContentFiller, MAX_SIGNATURE_CONTENT_LENGTH, '0');
     aSigBuffer.append(aContentFiller.makeStringAndClear());
     aSigBuffer.append(">\n/Type/Sig/SubFilter/adbe.pkcs7.detached");
+
+    // Time of signing.
+    aSigBuffer.append(" /M (");
+    aSigBuffer.append(vcl::PDFWriter::GetDateTime());
+    aSigBuffer.append(")");
+
     // Byte range: we can write offset1-length1 and offset2 right now, will
     // write length2 later.
     aSigBuffer.append(" /ByteRange [ 0 ");


More information about the Libreoffice-commits mailing list