diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-11-10 11:02:09 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-11-10 16:47:25 +0000 |
commit | 3b3fb8cfc8a35eb0fb4da77a8c77aac14d86085c (patch) | |
tree | 84d1e83d3a6c346608506a1070123c5d4aa7761b /xmlsecurity | |
parent | c21329fa904b682bde3df1082821df0af7ebbea3 (diff) |
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@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'xmlsecurity')
-rw-r--r-- | xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx | 9 | ||||
-rw-r--r-- | xmlsecurity/source/pdfio/pdfdocument.cxx | 28 |
2 files changed, 28 insertions, 9 deletions
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx index 7a8df3f4236e..d052e5f451dc 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 29212224ced6..32b19a4883a4 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"); } |