From 3f213154e2d4d9447fff161624196597bb59b9ed Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 8 Nov 2016 15:55:25 +0100 Subject: xmlsecurity PDF sign: handle xref stream when reading trailer Don't give up signing just because PDF 1.4 trailer is missing, provided that PDF 1.5 xref stream is available. Change-Id: I03360d428346537583a4398aa3a94b195b428713 Reviewed-on: https://gerrit.libreoffice.org/30703 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- xmlsecurity/source/pdfio/pdfdocument.cxx | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'xmlsecurity/source') diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx index cd52f8d0eaac..ff8aac99cda9 100644 --- a/xmlsecurity/source/pdfio/pdfdocument.cxx +++ b/xmlsecurity/source/pdfio/pdfdocument.cxx @@ -337,6 +337,7 @@ bool PDFDocument::Sign(const uno::Reference& xCertificat std::vector aSignatures = GetSignatureWidgets(); sal_uInt32 nNextSignature = aSignatures.size() + 1; + m_aEditBuffer.Seek(STREAM_SEEK_TO_END); m_aEditBuffer.WriteCharPtr("\n"); // Write signature object. @@ -478,12 +479,18 @@ bool PDFDocument::Sign(const uno::Reference& xCertificat m_aEditBuffer.WriteCharPtr("\nendobj\n\n"); // Write the updated Catalog object, references nAnnotId. - if (!m_pTrailer) + PDFReferenceElement* pRoot = nullptr; + if (m_pXRefStream) + pRoot = dynamic_cast(m_pXRefStream->Lookup("Root")); + else { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: found no trailer"); - return false; + if (!m_pTrailer) + { + SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: found no trailer"); + return false; + } + pRoot = dynamic_cast(m_pTrailer->Lookup("Root")); } - auto pRoot = dynamic_cast(m_pTrailer->Lookup("Root")); if (!pRoot) { SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: trailer has no root reference"); @@ -577,7 +584,12 @@ bool PDFDocument::Sign(const uno::Reference& xCertificat m_aEditBuffer.WriteCharPtr(" "); m_aEditBuffer.WriteUInt32AsString(pRoot->GetGenerationValue()); m_aEditBuffer.WriteCharPtr(" R\n"); - if (auto pInfo = dynamic_cast(m_pTrailer->Lookup("Info"))) + PDFReferenceElement* pInfo = nullptr; + if (m_pXRefStream) + pInfo = dynamic_cast(m_pXRefStream->Lookup("Info")); + else + pInfo = dynamic_cast(m_pTrailer->Lookup("Info")); + if (pInfo) { m_aEditBuffer.WriteCharPtr("/Info "); m_aEditBuffer.WriteUInt32AsString(pInfo->GetObjectValue()); @@ -585,7 +597,12 @@ bool PDFDocument::Sign(const uno::Reference& xCertificat m_aEditBuffer.WriteUInt32AsString(pInfo->GetGenerationValue()); m_aEditBuffer.WriteCharPtr(" R\n"); } - if (auto pID = dynamic_cast(m_pTrailer->Lookup("ID"))) + PDFArrayElement* pID = nullptr; + if (m_pXRefStream) + pID = dynamic_cast(m_pXRefStream->Lookup("ID")); + else + pID = dynamic_cast(m_pTrailer->Lookup("ID")); + if (pID) { const std::vector& rElements = pID->GetElements(); m_aEditBuffer.WriteCharPtr("/ID [ <"); -- cgit