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

Miklos Vajna vmiklos at collabora.co.uk
Thu Nov 10 16:47:55 UTC 2016


 xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx |    9 +++++++-
 xmlsecurity/source/pdfio/pdfdocument.cxx      |   28 ++++++++++++++++++--------
 2 files changed, 28 insertions(+), 9 deletions(-)

New commits:
commit 3b3fb8cfc8a35eb0fb4da77a8c77aac14d86085c
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Nov 10 11:02:09 2016 +0100

    xmlsecurity PDF sign: support non-compressed AcroForm objects
    
    This was the last problem to be able to counter-sign Acrobat-created PDF
    1.6 signatures unlimited number of times.
    
    Change-Id: I24ab80c8516b6fe9c08d57c08907bec70384dc28
    Reviewed-on: https://gerrit.libreoffice.org/30757
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
index 7a8df3f..d052e5f 100644
--- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
+++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
@@ -283,7 +283,14 @@ void PDFSigningTest::testPDF16Add()
     OUString aOutURL = aTargetDir + "add.pdf";
     // This failed: verification broke as incorrect xref stream was written as
     // part of the new signature.
-    sign(aInURL, aOutURL, 1);
+    bool bHadCertificates = sign(aInURL, aOutURL, 1);
+
+    // Sign again.
+    aInURL = aTargetDir + "add.pdf";
+    aOutURL = aTargetDir + "add2.pdf";
+    // This failed as non-compressed AcroForm wasn't handled.
+    if (bHadCertificates)
+        sign(aInURL, aOutURL, 2);
 }
 
 void PDFSigningTest::testPDF14LOWin()
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 2921222..32b19a4 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -600,12 +600,8 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
         m_aEditBuffer.WriteUInt32AsString(nAcroFormId);
         m_aEditBuffer.WriteCharPtr(" 0 obj\n");
 
+        // If this is nullptr, then the AcroForm object is not in an object stream.
         SvMemoryStream* pStreamBuffer = pAcroFormObject->GetStreamBuffer();
-        if (!pStreamBuffer)
-        {
-            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: AcroForm object is not in an object stream");
-            return false;
-        }
 
         if (!pAcroFormObject->Lookup("Fields"))
         {
@@ -624,7 +620,14 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
         sal_uInt64 nFieldsEndOffset = pAcroFormDictionary->GetKeyOffset("Fields") + pAcroFormDictionary->GetKeyValueLength("Fields") - strlen("]");
         // Length of beginning of the object dictionary -> Fields end.
         sal_uInt64 nFieldsBeforeEndLength = nFieldsEndOffset;
-        m_aEditBuffer.WriteBytes(pStreamBuffer->GetData(), nFieldsBeforeEndLength);
+        if (pStreamBuffer)
+            m_aEditBuffer.WriteBytes(pStreamBuffer->GetData(), nFieldsBeforeEndLength);
+        else
+        {
+            nFieldsBeforeEndLength -= pAcroFormObject->GetDictionaryOffset();
+            m_aEditBuffer.WriteCharPtr("<<");
+            m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + pAcroFormObject->GetDictionaryOffset(), nFieldsBeforeEndLength);
+        }
 
         // Append our reference at the end of the Fields array.
         m_aEditBuffer.WriteCharPtr(" ");
@@ -632,8 +635,17 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
         m_aEditBuffer.WriteCharPtr(" 0 R");
 
         // Length of Fields end -> end of the object dictionary.
-        sal_uInt64 nFieldsAfterEndLength = pStreamBuffer->GetSize() - nFieldsEndOffset;
-        m_aEditBuffer.WriteBytes(static_cast<const char*>(pStreamBuffer->GetData()) + nFieldsEndOffset, nFieldsAfterEndLength);
+        if (pStreamBuffer)
+        {
+            sal_uInt64 nFieldsAfterEndLength = pStreamBuffer->GetSize() - nFieldsEndOffset;
+            m_aEditBuffer.WriteBytes(static_cast<const char*>(pStreamBuffer->GetData()) + nFieldsEndOffset, nFieldsAfterEndLength);
+        }
+        else
+        {
+            sal_uInt64 nFieldsAfterEndLength = pAcroFormObject->GetDictionaryOffset() + pAcroFormObject->GetDictionaryLength() - nFieldsEndOffset;
+            m_aEditBuffer.WriteBytes(static_cast<const char*>(m_aEditBuffer.GetData()) + nFieldsEndOffset, nFieldsAfterEndLength);
+            m_aEditBuffer.WriteCharPtr(">>");
+        }
 
         m_aEditBuffer.WriteCharPtr("\nendobj\n\n");
     }


More information about the Libreoffice-commits mailing list