summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-11-10 11:02:09 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-11-10 16:47:25 +0000
commit3b3fb8cfc8a35eb0fb4da77a8c77aac14d86085c (patch)
tree84d1e83d3a6c346608506a1070123c5d4aa7761b /xmlsecurity
parentc21329fa904b682bde3df1082821df0af7ebbea3 (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.cxx9
-rw-r--r--xmlsecurity/source/pdfio/pdfdocument.cxx28
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");
}