[Libreoffice-commits] core.git: Branch 'feature/cib_contract891c' - 7 commits - configure.ac include/tools include/vcl include/xmlsecurity sal/osl sfx2/source tools/source vcl/Library_vcl.mk vcl/qa vcl/source xmlsecurity/Library_xmlsecurity.mk xmlsecurity/qa xmlsecurity/source xmlsecurity/uiconfig xmlsecurity/workben
Samuel Mehrbrodt (via logerrit)
logerrit at kemper.freedesktop.org
Thu Oct 1 08:54:07 UTC 2020
Rebased ref, commits from common ancestor:
commit e951f98ef5d713a130b8c1ef28bff79de8278f51
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
AuthorDate: Tue Sep 29 09:22:04 2020 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:30 2020 +0200
Release 5.4.11
Change-Id: I94f4cb91b1cf92722ff43d3561ba0cf2405a6a29
diff --git a/configure.ac b/configure.ac
index 83fe089baf59..af7fc01b8195 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@ dnl in order to create a configure script.
# several non-alphanumeric characters, those are split off and used only for the
# ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea.
-AC_INIT([LibreOffice],[5.4.10.0],[],[],[http://documentfoundation.org/])
+AC_INIT([LibreOffice],[5.4.11.0],[],[],[http://documentfoundation.org/])
AC_PREREQ([2.59])
commit f1682f0f324c4298ef1a5d33c3c68b6a8471f3ae
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Sep 4 17:17:48 2020 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:30 2020 +0200
xmlsecurity: pdf incremental updates that are non-commenting are invalid
I.e. it's OK to add incremental updates for annotation/commenting
purposes and that doesn't invalite existing signatures. Everything else
does.
(cherry picked from commit 61834cd574568613f0b0a2ee099a60fa5a8d9804)
Conflicts:
include/vcl/filter/PDFiumLibrary.hxx
vcl/source/pdf/PDFiumLibrary.cxx
Conflicts:
xmlsecurity/qa/unit/signing/signing.cxx
Change-Id: I4607c242b3c6f6b01517b02407e9e7a095e2e069
diff --git a/include/tools/stream.hxx b/include/tools/stream.hxx
index 0bc3766807fa..608f7f0adde0 100644
--- a/include/tools/stream.hxx
+++ b/include/tools/stream.hxx
@@ -257,6 +257,7 @@ public:
SvStream& WriteOString(const OString& rStr)
{ return WriteCharPtr(rStr.getStr()); }
SvStream& WriteStream( SvStream& rStream );
+ sal_uInt64 WriteStream( SvStream& rStream, sal_uInt64 nSize );
SvStream& WriteBool( bool b )
{ return WriteUChar(static_cast<unsigned char>(b)); }
diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx
index b9bceabb8acf..ffc70874c19b 100644
--- a/include/vcl/filter/PDFiumLibrary.hxx
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -17,11 +17,16 @@
#include <memory>
#include <rtl/instance.hxx>
#include <vcl/dllapi.h>
+#include <vcl/checksum.hxx>
+
+#include <fpdf_doc.h>
namespace vcl
{
namespace pdf
{
+class PDFiumDocument;
+
class VCL_DLLPUBLIC PDFium final
{
private:
@@ -33,6 +38,49 @@ public:
~PDFium();
};
+class VCL_DLLPUBLIC PDFiumPage final
+{
+private:
+ FPDF_PAGE mpPage;
+
+private:
+ PDFiumPage(const PDFiumPage&) = delete;
+ PDFiumPage& operator=(const PDFiumPage&) = delete;
+
+public:
+ PDFiumPage(FPDF_PAGE pPage)
+ : mpPage(pPage)
+ {
+ }
+
+ ~PDFiumPage()
+ {
+ if (mpPage)
+ FPDF_ClosePage(mpPage);
+ }
+
+ /// Get bitmap checksum of the page, without annotations/commenting.
+ BitmapChecksum getChecksum();
+};
+
+class VCL_DLLPUBLIC PDFiumDocument final
+{
+private:
+ FPDF_DOCUMENT mpPdfDocument;
+
+private:
+ PDFiumDocument(const PDFiumDocument&) = delete;
+ PDFiumDocument& operator=(const PDFiumDocument&) = delete;
+
+public:
+ PDFiumDocument(FPDF_DOCUMENT pPdfDocument);
+ ~PDFiumDocument();
+
+ int getPageCount();
+
+ std::unique_ptr<PDFiumPage> openPage(int nIndex);
+};
+
struct PDFiumLibrary : public rtl::StaticWithInit<std::shared_ptr<PDFium>, PDFiumLibrary>
{
std::shared_ptr<PDFium> operator()() { return std::make_shared<PDFium>(); }
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
index 488348719892..b83729e35fbf 100644
--- a/tools/source/stream/stream.cxx
+++ b/tools/source/stream/stream.cxx
@@ -1176,6 +1176,27 @@ SvStream& SvStream::WriteStream( SvStream& rStream )
return *this;
}
+sal_uInt64 SvStream::WriteStream( SvStream& rStream, sal_uInt64 nSize )
+{
+ const sal_uInt32 cBufLen = 0x8000;
+ std::unique_ptr<char[]> pBuf( new char[ cBufLen ] );
+ sal_uInt32 nCurBufLen = cBufLen;
+ sal_uInt32 nCount;
+ sal_uInt64 nWriteSize = nSize;
+
+ do {
+ if ( nSize >= nCurBufLen )
+ nWriteSize -= nCurBufLen;
+ else
+ nCurBufLen = nWriteSize;
+ nCount = rStream.ReadBytes( pBuf.get(), nCurBufLen );
+ WriteBytes( pBuf.get(), nCount );
+ }
+ while( nWriteSize && nCount == nCurBufLen );
+
+ return nSize - nWriteSize;
+}
+
OUString SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet )
{
// read UTF-16 string directly from stream ?
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index 5f487b15f48b..38eb88a99db0 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -15,6 +15,10 @@
#include <vcl/filter/PDFiumLibrary.hxx>
#include <fpdf_doc.h>
+#include <o3tl/make_unique.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapaccess.hxx>
+
namespace vcl
{
namespace pdf
@@ -31,6 +35,57 @@ PDFium::PDFium()
PDFium::~PDFium() { FPDF_DestroyLibrary(); }
+PDFiumDocument::PDFiumDocument(FPDF_DOCUMENT pPdfDocument)
+ : mpPdfDocument(pPdfDocument)
+{
+}
+
+PDFiumDocument::~PDFiumDocument()
+{
+ if (mpPdfDocument)
+ FPDF_CloseDocument(mpPdfDocument);
+}
+
+std::unique_ptr<PDFiumPage> PDFiumDocument::openPage(int nIndex)
+{
+ std::unique_ptr<PDFiumPage> pPDFiumPage;
+ FPDF_PAGE pPage = FPDF_LoadPage(mpPdfDocument, nIndex);
+ if (pPage)
+ {
+ pPDFiumPage = o3tl::make_unique<PDFiumPage>(pPage);
+ }
+ return pPDFiumPage;
+}
+
+int PDFiumDocument::getPageCount() { return FPDF_GetPageCount(mpPdfDocument); }
+
+BitmapChecksum PDFiumPage::getChecksum()
+{
+ size_t nPageWidth = FPDF_GetPageWidth(mpPage);
+ size_t nPageHeight = FPDF_GetPageHeight(mpPage);
+ FPDF_BITMAP pPdfBitmap = FPDFBitmap_Create(nPageWidth, nPageHeight, /*alpha=*/1);
+ if (!pPdfBitmap)
+ {
+ return 0;
+ }
+
+ // Intentionally not using FPDF_ANNOT here, annotations/commenting is OK to not affect the
+ // checksum, signature verification wants this.
+ FPDF_RenderPageBitmap(pPdfBitmap, mpPage, /*start_x=*/0, /*start_y=*/0, nPageWidth, nPageHeight,
+ /*rotate=*/0, /*flags=*/0);
+ Bitmap aBitmap(Size(nPageWidth, nPageHeight), 24);
+ {
+ Bitmap::ScopedWriteAccess pWriteAccess(aBitmap);
+ const auto pPdfBuffer = static_cast<const sal_uInt8*>(FPDFBitmap_GetBuffer(pPdfBitmap));
+ const int nStride = FPDFBitmap_GetStride(pPdfBitmap);
+ for (size_t nRow = 0; nRow < nPageHeight; ++nRow)
+ {
+ const sal_uInt8* pPdfLine = pPdfBuffer + (nStride * nRow);
+ pWriteAccess->CopyScanline(nRow, pPdfLine, ScanlineFormat::N32BitTcBgra, nStride);
+ }
+ }
+ return aBitmap.GetChecksum();
+}
}
} // end vcl::pdf
diff --git a/xmlsecurity/Library_xmlsecurity.mk b/xmlsecurity/Library_xmlsecurity.mk
index 77d3bd81dc3b..85950d1dcd4b 100644
--- a/xmlsecurity/Library_xmlsecurity.mk
+++ b/xmlsecurity/Library_xmlsecurity.mk
@@ -20,7 +20,10 @@ $(eval $(call gb_Library_add_defs,xmlsecurity,\
-DXMLSECURITY_DLLIMPLEMENTATION \
))
-$(eval $(call gb_Library_use_externals,xmlsecurity,boost_headers))
+$(eval $(call gb_Library_use_externals,xmlsecurity,\
+ boost_headers \
+ $(if $(filter PDFIUM,$(BUILD_TYPE)),pdfium) \
+))
$(eval $(call gb_Library_set_precompiled_header,xmlsecurity,$(SRCDIR)/xmlsecurity/inc/pch/precompiled_xmlsecurity))
diff --git a/xmlsecurity/qa/unit/signing/data/hide-and-replace-shadow-file-signed-2.pdf b/xmlsecurity/qa/unit/signing/data/hide-and-replace-shadow-file-signed-2.pdf
new file mode 100644
index 000000000000..f2b1a71096b2
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/hide-and-replace-shadow-file-signed-2.pdf differ
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index 2b6e60e7c0bd..29e35738c62b 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -88,6 +88,8 @@ public:
void testPDFGood();
/// Test a typical PDF where the signature is bad.
void testPDFBad();
+ /// Test a maliciously manipulated signed pdf
+ void testPDFHideAndReplace();
/// Test a typical PDF which is not signed.
void testPDFNo();
#endif
@@ -113,6 +115,7 @@ public:
#if HAVE_FEATURE_PDFIMPORT
CPPUNIT_TEST(testPDFGood);
CPPUNIT_TEST(testPDFBad);
+ CPPUNIT_TEST(testPDFHideAndReplace);
CPPUNIT_TEST(testPDFNo);
#endif
CPPUNIT_TEST(test96097Calc);
@@ -458,6 +461,22 @@ void SigningTest::testPDFBad()
CPPUNIT_ASSERT_EQUAL(static_cast<int>(SignatureState::BROKEN), static_cast<int>(pObjectShell->GetDocumentSignatureState()));
}
+void SigningTest::testPDFHideAndReplace()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY)
+ + "hide-and-replace-shadow-file-signed-2.pdf");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2 (BROKEN)
+ // - Actual : 6 (NOTVALIDATED_PARTIAL_OK)
+ // i.e. a non-commenting update after a signature was not marked as invalid.
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(SignatureState::BROKEN),
+ static_cast<int>(pObjectShell->GetDocumentSignatureState()));
+}
+
void SigningTest::testPDFNo()
{
createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY) + "no.pdf");
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 5cec868a012b..edcb72d9a9ad 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -21,11 +21,15 @@
#include <filter/msfilter/mscodec.hxx>
#include <rtl/character.hxx>
#include <rtl/strbuf.hxx>
+#include <config_features.h>
+
+#include <vcl/filter/PDFiumLibrary.hxx>
#include <rtl/string.hxx>
#include <sal/log.hxx>
#include <sal/types.h>
#include <sax/tools/converter.hxx>
#include <tools/zcodec.hxx>
+#include <tools/stream.hxx>
#include <unotools/calendarwrapper.hxx>
#include <unotools/datetime.hxx>
#include <vcl/pdfwriter.hxx>
@@ -49,6 +53,8 @@
#include <comphelper/windowserrorstring.hxx>
#endif
+#include <vcl/bitmap.hxx>
+
using namespace com::sun::star;
namespace
@@ -392,6 +398,66 @@ bool VerifyNonDetachedSignature(SvStream& rStream, std::vector<std::pair<size_t,
return false;
}
#endif
+
+/// Collects the checksum of each page of one version of the PDF.
+void AnalyizeSignatureStream(SvMemoryStream& rStream, std::vector<BitmapChecksum>& rPageChecksums)
+{
+#if HAVE_FEATURE_PDFIUM
+ auto pPdfium = vcl::pdf::PDFiumLibrary::get();
+ vcl::pdf::PDFiumDocument aPdfDocument(
+ FPDF_LoadMemDocument(rStream.GetData(), rStream.GetSize(), /*password=*/nullptr));
+
+ int nPageCount = aPdfDocument.getPageCount();
+ for (int nPage = 0; nPage < nPageCount; ++nPage)
+ {
+ std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage(aPdfDocument.openPage(nPage));
+ if (!pPdfPage)
+ {
+ return;
+ }
+
+ BitmapChecksum nPageChecksum = pPdfPage->getChecksum();
+ rPageChecksums.push_back(nPageChecksum);
+ }
+#else
+ (void)rStream;
+#endif
+}
+
+/**
+ * Checks if incremental updates after singing performed valid modifications only.
+ * Annotations/commenting is OK, other changes are not.
+ */
+bool IsValidSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature)
+{
+ size_t nSignatureEOF = 0;
+ if (!GetEOFOfSignature(pSignature, nSignatureEOF))
+ {
+ return false;
+ }
+
+ SvMemoryStream aSignatureStream;
+ sal_uInt64 nPos = rStream.Tell();
+ rStream.Seek(0);
+ aSignatureStream.WriteStream(rStream, nSignatureEOF);
+ rStream.Seek(nPos);
+ aSignatureStream.Seek(0);
+ std::vector<BitmapChecksum> aSignedPages;
+ AnalyizeSignatureStream(aSignatureStream, aSignedPages);
+
+ SvMemoryStream aFullStream;
+ nPos = rStream.Tell();
+ rStream.Seek(0);
+ aFullStream.WriteStream(rStream);
+ rStream.Seek(nPos);
+ aFullStream.Seek(0);
+ std::vector<BitmapChecksum> aAllPages;
+ AnalyizeSignatureStream(aFullStream, aAllPages);
+
+ // Fail if any page looks different after signing and at the end. Annotations/commenting doesn't
+ // count, though.
+ return aSignedPages == aAllPages;
+}
}
bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature,
@@ -499,6 +565,12 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
}
rInformation.bPartialDocumentSignature = !IsCompleteSignature(rStream, rDocument, pSignature);
+ if (!IsValidSignature(rStream, pSignature))
+ {
+ SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: invalid incremental update detected");
+ return false;
+ }
+
// At this point there is no obviously missing info to validate the
// signature.
std::vector<unsigned char> aSignature = vcl::filter::PDFDocument::DecodeHexString(pContents);
diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx
index ea48350246a6..d0b5405b015b 100644
--- a/xmlsecurity/workben/pdfverify.cxx
+++ b/xmlsecurity/workben/pdfverify.cxx
@@ -20,6 +20,7 @@
#include <vcl/pngwrite.hxx>
#include <vcl/svapp.hxx>
#include <vcl/graphicfilter.hxx>
+#include <comphelper/scopeguard.hxx>
#include <xmlsecurity/pdfio/pdfdocument.hxx>
@@ -72,11 +73,11 @@ int pdfVerify(int nArgc, char** pArgv)
uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xMultiComponentFactory, uno::UNO_QUERY);
comphelper::setProcessServiceFactory(xMultiServiceFactory);
+ InitVCL();
+ comphelper::ScopeGuard g([] { DeInitVCL(); });
if (nArgc > 3 && OString(pArgv[3]) == "-p")
{
- InitVCL();
generatePreview(pArgv[1], pArgv[2]);
- DeInitVCL();
return 0;
}
commit 9c886e422f3065133695f89712ca6729e86d460d
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jul 24 11:29:27 2020 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:30 2020 +0200
xmlsecurity: detect unsigned incremental update between signatures
(cherry picked from commit 7468d5df5ec79783eae84b62bdc5ecf12f0ca255)
Conflicts:
vcl/source/filter/ipdf/pdfdocument.cxx
xmlsecurity/source/pdfio/pdfdocument.cxx
Change-Id: I269ed858852ee7d1275adf340c8cc1565fc30693
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99480
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
diff --git a/include/vcl/filter/pdfdocument.hxx b/include/vcl/filter/pdfdocument.hxx
index 9297ef4a9e5e..6c247fefcd72 100644
--- a/include/vcl/filter/pdfdocument.hxx
+++ b/include/vcl/filter/pdfdocument.hxx
@@ -379,6 +379,8 @@ public:
std::vector<PDFObjectElement*> GetSignatureWidgets();
/// Remove the nth signature from read document in the edit buffer.
bool RemoveSignature(size_t nPosition);
+ /// Get byte offsets of the end of incremental updates.
+ const std::vector<size_t>& GetEOFs() const;
//@}
};
diff --git a/include/xmlsecurity/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx
index 6f3b0f263add..2d652397aad2 100644
--- a/include/xmlsecurity/pdfio/pdfdocument.hxx
+++ b/include/xmlsecurity/pdfio/pdfdocument.hxx
@@ -29,7 +29,7 @@ namespace pdfio
* @param bLast If this is the last signature in the file, so it covers the whole file physically.
* @return If we can determinate a result.
*/
-XMLSECURITY_DLLPUBLIC bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, SignatureInformation& rInformation, bool bLast);
+XMLSECURITY_DLLPUBLIC bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, SignatureInformation& rInformation, vcl::filter::PDFDocument& rDocument);
} // namespace pdfio
} // namespace xmlsecurity
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index 2c4c9288a32c..b01ad824a2c5 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -160,6 +160,8 @@ bool PDFDocument::RemoveSignature(size_t nPosition)
return m_aEditBuffer.good();
}
+const std::vector<size_t>& PDFDocument::GetEOFs() const { return m_aEOFs; }
+
sal_uInt32 PDFDocument::GetNextSignature()
{
sal_uInt32 nRet = 0;
@@ -1969,7 +1971,16 @@ bool PDFCommentElement::Read(SvStream& rStream)
m_aComment = aBuf.makeStringAndClear();
if (m_aComment.startsWith("%%EOF"))
- m_rDoc.PushBackEOF(rStream.Tell());
+ {
+ sal_uInt64 nPos = rStream.Tell();
+ if (ch == '\r')
+ {
+ // If the comment ends with a \r\n, count the \n as well to match Adobe Acrobat
+ // behavior.
+ nPos += 1;
+ }
+ m_rDoc.PushBackEOF(nPos);
+ }
SAL_INFO("vcl.filter", "PDFCommentElement::Read: m_aComment is '" << m_aComment << "'");
return true;
diff --git a/xmlsecurity/qa/unit/pdfsigning/data/partial-in-between.pdf b/xmlsecurity/qa/unit/pdfsigning/data/partial-in-between.pdf
new file mode 100644
index 000000000000..211a111cb394
Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/partial-in-between.pdf differ
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
index 55289fc05176..f0c45d0d7b63 100644
--- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
+++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
@@ -66,6 +66,7 @@ public:
void testPDFPAdESGood();
/// Test a valid signature that does not cover the whole file.
void testPartial();
+ void testPartialInBetween();
/// Test writing a PAdES signature.
void testSigningCertificateAttribute();
/// Test that we accept files which are supposed to be good.
@@ -87,6 +88,7 @@ public:
CPPUNIT_TEST(testPDF14LOWin);
CPPUNIT_TEST(testPDFPAdESGood);
CPPUNIT_TEST(testPartial);
+ CPPUNIT_TEST(testPartialInBetween);
CPPUNIT_TEST(testSigningCertificateAttribute);
CPPUNIT_TEST(testGood);
CPPUNIT_TEST(testTokenize);
@@ -132,8 +134,8 @@ std::vector<SignatureInformation> PDFSigningTest::verify(const OUString& rURL, s
for (size_t i = 0; i < aSignatures.size(); ++i)
{
SignatureInformation aInfo(i);
- bool bLast = i == aSignatures.size() - 1;
- CPPUNIT_ASSERT(xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, bLast));
+ CPPUNIT_ASSERT(
+ xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, aVerifyDocument));
aRet.push_back(aInfo);
if (!rExpectedSubFilter.isEmpty())
@@ -235,7 +237,8 @@ void PDFSigningTest::testPDFRemove()
std::vector<vcl::filter::PDFObjectElement*> aSignatures = aDocument.GetSignatureWidgets();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aSignatures.size());
SignatureInformation aInfo(0);
- CPPUNIT_ASSERT(xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[0], aInfo, /*bLast=*/true));
+ CPPUNIT_ASSERT(
+ xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[0], aInfo, aDocument));
}
// Remove the signature and write out the result as remove.pdf.
@@ -452,6 +455,18 @@ void PDFSigningTest::testUnknownSubFilter()
CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), rInformations.size());
}
+void PDFSigningTest::testPartialInBetween()
+{
+ std::vector<SignatureInformation> aInfos
+ = verify(m_directories.getURLFromSrc(DATA_DIRECTORY) + "partial-in-between.pdf", 2,
+ /*rExpectedSubFilter=*/OString());
+ CPPUNIT_ASSERT(!aInfos.empty());
+ SignatureInformation& rInformation = aInfos[0];
+ // Without the accompanying fix in place, this test would have failed, as unsigned incremental
+ // update between two signatures were not detected.
+ CPPUNIT_ASSERT(rInformation.bPartialDocumentSignature);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(PDFSigningTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
index 9bb6e59d0380..884974f4d17a 100644
--- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
@@ -52,8 +52,7 @@ bool PDFSignatureHelper::ReadAndVerifySignature(const uno::Reference<io::XInputS
{
SignatureInformation aInfo(i);
- bool bLast = i == aSignatures.size() - 1;
- if (!xmlsecurity::pdfio::ValidateSignature(*pStream, aSignatures[i], aInfo, bLast))
+ if (!xmlsecurity::pdfio::ValidateSignature(*pStream, aSignatures[i], aInfo, aDocument))
SAL_WARN("xmlsecurity.helper", "failed to determine digest match");
m_aSignatureInfos.push_back(aInfo);
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 5420196df7d8..5cec868a012b 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -51,6 +51,118 @@
using namespace com::sun::star;
+namespace
+{
+/// Turns an array of floats into offset + length pairs.
+bool GetByteRangesFromPDF(vcl::filter::PDFArrayElement& rArray,
+ std::vector<std::pair<size_t, size_t>>& rByteRanges)
+{
+ size_t nByteRangeOffset = 0;
+ const std::vector<vcl::filter::PDFElement*>& rByteRangeElements = rArray.GetElements();
+ for (size_t i = 0; i < rByteRangeElements.size(); ++i)
+ {
+ auto pNumber = dynamic_cast<vcl::filter::PDFNumberElement*>(rByteRangeElements[i]);
+ if (!pNumber)
+ {
+ SAL_WARN("xmlsecurity.pdfio",
+ "ValidateSignature: signature offset and length has to be a number");
+ return false;
+ }
+
+ if (i % 2 == 0)
+ {
+ nByteRangeOffset = pNumber->GetValue();
+ continue;
+ }
+ size_t nByteRangeLength = pNumber->GetValue();
+ rByteRanges.emplace_back(nByteRangeOffset, nByteRangeLength);
+ }
+
+ return true;
+}
+
+/// Determines the last position that is covered by a signature.
+bool GetEOFOfSignature(vcl::filter::PDFObjectElement* pSignature, size_t& rEOF)
+{
+ vcl::filter::PDFObjectElement* pValue = pSignature->LookupObject("V");
+ if (!pValue)
+ {
+ return false;
+ }
+
+ auto pByteRange = dynamic_cast<vcl::filter::PDFArrayElement*>(pValue->Lookup("ByteRange"));
+ if (!pByteRange || pByteRange->GetElements().size() < 2)
+ {
+ return false;
+ }
+
+ std::vector<std::pair<size_t, size_t>> aByteRanges;
+ if (!GetByteRangesFromPDF(*pByteRange, aByteRanges))
+ {
+ return false;
+ }
+
+ rEOF = aByteRanges[1].first + aByteRanges[1].second;
+ return true;
+}
+
+/// Checks if there are unsigned incremental updates between the signatures or after the last one.
+bool IsCompleteSignature(SvStream& rStream, vcl::filter::PDFDocument& rDocument,
+ vcl::filter::PDFObjectElement* pSignature)
+{
+ std::set<size_t> aSignedEOFs;
+ for (const auto& i : rDocument.GetSignatureWidgets())
+ {
+ size_t nEOF = 0;
+ if (!GetEOFOfSignature(i, nEOF))
+ {
+ return false;
+ }
+
+ aSignedEOFs.insert(nEOF);
+ }
+
+ size_t nSignatureEOF = 0;
+ if (!GetEOFOfSignature(pSignature, nSignatureEOF))
+ {
+ return false;
+ }
+
+ const std::vector<size_t>& rAllEOFs = rDocument.GetEOFs();
+ bool bFoundOwn = false;
+ for (const auto& rEOF : rAllEOFs)
+ {
+ if (rEOF == nSignatureEOF)
+ {
+ bFoundOwn = true;
+ continue;
+ }
+
+ if (!bFoundOwn)
+ {
+ continue;
+ }
+
+ if (aSignedEOFs.find(rEOF) == aSignedEOFs.end())
+ {
+ // Unsigned incremental update found.
+ return false;
+ }
+ }
+
+ // Make sure we find the incremental update of the signature itself.
+ if (!bFoundOwn)
+ {
+ return false;
+ }
+
+ // No additional content after the last incremental update.
+ rStream.Seek(STREAM_SEEK_TO_END);
+ size_t nFileEnd = rStream.Tell();
+ return std::find(rAllEOFs.begin(), rAllEOFs.end(), nFileEnd) != rAllEOFs.end();
+}
+}
+
namespace xmlsecurity
{
namespace pdfio
@@ -282,7 +394,8 @@ bool VerifyNonDetachedSignature(SvStream& rStream, std::vector<std::pair<size_t,
#endif
}
-bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, SignatureInformation& rInformation, bool bLast)
+bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature,
+ SignatureInformation& rInformation, vcl::filter::PDFDocument& rDocument)
{
vcl::filter::PDFObjectElement* pValue = pSignature->LookupObject("V");
if (!pValue)
@@ -361,24 +474,9 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
// Build a list of offset-length pairs, representing the signed bytes.
std::vector<std::pair<size_t, size_t>> aByteRanges;
- size_t nByteRangeOffset = 0;
- const std::vector<vcl::filter::PDFElement*>& rByteRangeElements = pByteRange->GetElements();
- for (size_t i = 0; i < rByteRangeElements.size(); ++i)
+ if (!GetByteRangesFromPDF(*pByteRange, aByteRanges))
{
- auto pNumber = dynamic_cast<vcl::filter::PDFNumberElement*>(rByteRangeElements[i]);
- if (!pNumber)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: signature offset and length has to be a number");
- return false;
- }
-
- if (i % 2 == 0)
- {
- nByteRangeOffset = pNumber->GetValue();
- continue;
- }
- size_t nByteRangeLength = pNumber->GetValue();
- aByteRanges.push_back(std::make_pair(nByteRangeOffset, nByteRangeLength));
+ return false;
}
// Detect if the byte ranges don't cover everything, but the signature itself.
@@ -399,11 +497,7 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: second range start is not the end of the signature");
return false;
}
- rStream.Seek(STREAM_SEEK_TO_END);
- size_t nFileEnd = rStream.Tell();
- if (bLast && (aByteRanges[1].first + aByteRanges[1].second) != nFileEnd)
- // Second range end is not the end of the file.
- rInformation.bPartialDocumentSignature = true;
+ rInformation.bPartialDocumentSignature = !IsCompleteSignature(rStream, rDocument, pSignature);
// At this point there is no obviously missing info to validate the
// signature.
diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx
index 7b64e42c2a49..ea48350246a6 100644
--- a/xmlsecurity/workben/pdfverify.cxx
+++ b/xmlsecurity/workben/pdfverify.cxx
@@ -149,8 +149,8 @@ int pdfVerify(int nArgc, char** pArgv)
for (size_t i = 0; i < aSignatures.size(); ++i)
{
SignatureInformation aInfo(i);
- bool bLast = i == aSignatures.size() - 1;
- if (!xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo, bLast))
+ if (!xmlsecurity::pdfio::ValidateSignature(aStream, aSignatures[i], aInfo,
+ aDocument))
{
SAL_WARN("xmlsecurity.pdfio", "failed to determine digest match");
return 1;
@@ -158,6 +158,8 @@ int pdfVerify(int nArgc, char** pArgv)
bool bSuccess = aInfo.nStatus == xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
std::cerr << "signature #" << i << ": digest match? " << bSuccess << std::endl;
+ std::cerr << "signature #" << i << ": partial? " << aInfo.bPartialDocumentSignature
+ << std::endl;
}
}
commit 1df20c2c15f1fdb698ffe6af21b1e127fd01b248
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun May 31 11:50:20 2020 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:30 2020 +0200
pdfium: only init pdfium library once and destroy on LO exit
With more and more usage of PDFium, it is hard to keep track of
the life-time of the PDFium library, so it can happen that a
FPDF_DestroyLibrary happens when we still have another instance
where PDFium is still use. The result of this is a crash. To
prevent this, just initialize the library once and delete, when
on LO exit.
This can be improved in the future to only keep the library
active when in actual use.
[ Leaving out the vector graphic search bits, the motivation is to just
have this in libreoffice-7-0, so that recent pdf sig verify improvements
can be backported. ]
(cherry picked from commit 067a8a954c8e1d8d6465a4ab5fb61e93f16c26c2)
Conflicts:
vcl/source/graphic/VectorGraphicSearch.cxx
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102317
Tested-by: Miklos Vajna <vmiklos at collabora.com>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
(cherry picked from commit b7de766b4dc5b4810277069bcf53a9f3737e87da)
Conflicts:
svx/source/svdraw/svdpdf.cxx
svx/source/svdraw/svdpdf.hxx
vcl/Library_vcl.mk
vcl/qa/cppunit/pdfexport/pdfexport.cxx
vcl/source/filter/ipdf/pdfread.cxx
(cherry picked from commit 12025e528ef50af9e3176a19465f860723e30871)
Change-Id: I5c7e5de7f8b97d10efb394c67c7a61b976c8d57c
diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx
new file mode 100644
index 000000000000..b9bceabb8acf
--- /dev/null
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <config_features.h>
+
+#if HAVE_FEATURE_PDFIUM
+
+#include <memory>
+#include <rtl/instance.hxx>
+#include <vcl/dllapi.h>
+
+namespace vcl
+{
+namespace pdf
+{
+class VCL_DLLPUBLIC PDFium final
+{
+private:
+ PDFium(const PDFium&) = delete;
+ PDFium& operator=(const PDFium&) = delete;
+
+public:
+ PDFium();
+ ~PDFium();
+};
+
+struct PDFiumLibrary : public rtl::StaticWithInit<std::shared_ptr<PDFium>, PDFiumLibrary>
+{
+ std::shared_ptr<PDFium> operator()() { return std::make_shared<PDFium>(); }
+};
+}
+} // namespace vcl::pdf
+
+#endif // HAVE_FEATURE_PDFIUM
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a0113a2e85d4..af4b5f897e64 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -304,6 +304,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/wall \
vcl/source/gdi/scrptrun \
vcl/source/gdi/CommonSalLayout \
+ vcl/source/pdf/PDFiumLibrary \
vcl/source/bitmap/bitmapfilter \
vcl/source/bitmap/bitmapscalesuper \
vcl/source/bitmap/BitmapScaleConvolution \
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 1a88b97e5364..ce5b28ffe705 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -28,6 +28,8 @@
#include <fpdfview.h>
#endif
+#include <vcl/filter/PDFiumLibrary.hxx>
+
using namespace ::com::sun::star;
namespace
@@ -43,6 +45,7 @@ class PdfExportTest : public test::BootstrapFixture, public unotest::MacrosTest
#if HAVE_FEATURE_PDFIUM
FPDF_PAGE mpPdfPage = nullptr;
FPDF_DOCUMENT mpPdfDocument = nullptr;
+ std::shared_ptr<vcl::pdf::PDFium> mpPDFium;
#endif
public:
@@ -97,12 +100,7 @@ void PdfExportTest::setUp()
mxDesktop.set(frame::Desktop::create(mxComponentContext));
#if HAVE_FEATURE_PDFIUM
- FPDF_LIBRARY_CONFIG config;
- config.version = 2;
- config.m_pUserFontPaths = nullptr;
- config.m_pIsolate = nullptr;
- config.m_v8EmbedderSlot = 0;
- FPDF_InitLibraryWithConfig(&config);
+ mpPDFium = vcl::pdf::PDFiumLibrary::get();
#endif
}
@@ -111,7 +109,6 @@ void PdfExportTest::tearDown()
#if HAVE_FEATURE_PDFIUM
FPDF_ClosePage(mpPdfPage);
FPDF_CloseDocument(mpPdfDocument);
- FPDF_DestroyLibrary();
#endif
if (mxComponent.is())
diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index f1a7e2b52a17..85a31fe27ebd 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -19,6 +19,8 @@
#include <vcl/bitmapaccess.hxx>
+#include <vcl/filter/PDFiumLibrary.hxx>
+
using namespace com::sun::star;
namespace
@@ -58,12 +60,7 @@ double pointToPixel(double fPoint)
/// Does PDF to bitmap conversion using pdfium.
bool generatePreview(SvStream& rStream, Graphic& rGraphic)
{
- FPDF_LIBRARY_CONFIG aConfig;
- aConfig.version = 2;
- aConfig.m_pUserFontPaths = nullptr;
- aConfig.m_pIsolate = nullptr;
- aConfig.m_v8EmbedderSlot = 0;
- FPDF_InitLibraryWithConfig(&aConfig);
+ auto pPdfium = vcl::pdf::PDFiumLibrary::get();
// Read input into a buffer.
SvMemoryStream aInBuffer;
@@ -108,7 +105,6 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
FPDFBitmap_Destroy(pPdfBitmap);
FPDF_ClosePage(pPdfPage);
FPDF_CloseDocument(pPdfDocument);
- FPDF_DestroyLibrary();
return true;
}
@@ -145,13 +141,8 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
rOutStream.WriteStream(rInStream);
else
{
- // Downconvert to PDF-1.4.
- FPDF_LIBRARY_CONFIG aConfig;
- aConfig.version = 2;
- aConfig.m_pUserFontPaths = nullptr;
- aConfig.m_pIsolate = nullptr;
- aConfig.m_v8EmbedderSlot = 0;
- FPDF_InitLibraryWithConfig(&aConfig);
+ // Downconvert to PDF-1.5.
+ auto pPdfium = vcl::pdf::PDFiumLibrary::get();
// Read input into a buffer.
SvMemoryStream aInBuffer;
@@ -168,7 +159,6 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
return false;
FPDF_CloseDocument(pPdfDocument);
- FPDF_DestroyLibrary();
aWriter.m_aStream.Seek(STREAM_SEEK_TO_BEGIN);
rOutStream.WriteStream(aWriter.m_aStream);
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
new file mode 100644
index 000000000000..5f487b15f48b
--- /dev/null
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <config_features.h>
+
+#if HAVE_FEATURE_PDFIUM
+
+#include <vcl/filter/PDFiumLibrary.hxx>
+#include <fpdf_doc.h>
+
+namespace vcl
+{
+namespace pdf
+{
+PDFium::PDFium()
+{
+ FPDF_LIBRARY_CONFIG aConfig;
+ aConfig.version = 2;
+ aConfig.m_pUserFontPaths = nullptr;
+ aConfig.m_pIsolate = nullptr;
+ aConfig.m_v8EmbedderSlot = 0;
+ FPDF_InitLibraryWithConfig(&aConfig);
+}
+
+PDFium::~PDFium() { FPDF_DestroyLibrary(); }
+
+}
+} // end vcl::pdf
+
+#endif // HAVE_FEATURE_PDFIUM
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 58899f8e976a6cc2f715c7a5d8f268c4e375a676
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Sep 2 12:37:18 2020 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:30 2020 +0200
xmlsecurity: avoid saying OK when the signature is partial
That's reserved for valid signatures (digest match, certificate
validates and the signature covers the whole document).
Also avoid "invalid" in the dialog when the digest matches and the
signature is just incomplete.
This now uses wording which is closer to Acrobat and also uses the same
wording on the infobar and in the dialog.
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101926
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102188
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 46efad443472679b93b282c8e08b807d7e8f1a78)
Conflicts:
xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
Change-Id: I26e4781d555b65cf29aa8df2232e286917235dc1
diff --git a/sfx2/source/view/view.src b/sfx2/source/view/view.src
index 94f8a5ecbd1f..f42bedaefb68 100644
--- a/sfx2/source/view/view.src
+++ b/sfx2/source/view/view.src
@@ -144,12 +144,12 @@ String STR_SIGNATURE_INVALID
String STR_SIGNATURE_NOTVALIDATED
{
- Text[ en-US ] = "The signature is OK, but the certificate could not be validated.";
+ Text[ en-US ] = "At least one signature has problems: the certificate could not be validated.";
};
String STR_SIGNATURE_PARTIAL_OK
{
- Text[ en-US ] = "The signature is OK, but the document is only partially signed.";
+ Text[ en-US ] = "At least one signature has problems: the document is only partially signed.";
};
String STR_SIGNATURE_OK
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 3ca748019cf7..2eeaef132adb 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -518,6 +518,7 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
size_t nInfos = maSignatureManager.maCurrentSignatureInformations.size();
size_t nValidSigs = 0, nValidCerts = 0;
bool bAllNewSignatures = true;
+ bool bSomePartial = false;
if( nInfos )
{
@@ -595,7 +596,7 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
{
if (maSignatureManager.mxStore.is())
{
- // XML based.
+ // ZIP based.
bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
aElementsToBeVerified, rInfo, mode);
}
@@ -607,6 +608,10 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
if( bSigValid )
nValidSigs++;
+ else
+ {
+ bSomePartial = true;
+ }
}
Image aImage;
@@ -660,8 +665,8 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
bool bShowInvalidState = nInfos && !bAllSigsValid;
- m_pSigsInvalidImg->Show( bShowInvalidState );
- m_pSigsInvalidFI->Show( bShowInvalidState );
+ m_pSigsInvalidImg->Show( bShowInvalidState && !bSomePartial);
+ m_pSigsInvalidFI->Show( bShowInvalidState && !bSomePartial);
bool bShowNotValidatedState = nInfos && bAllSigsValid && !bAllCertsValid;
@@ -670,8 +675,8 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
//bAllNewSignatures is always true if we are not in document mode
bool bShowOldSignature = nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures;
- m_pSigsOldSignatureImg->Show(bShowOldSignature);
- m_pSigsOldSignatureFI->Show(bShowOldSignature);
+ m_pSigsOldSignatureImg->Show(bShowOldSignature || bSomePartial);
+ m_pSigsOldSignatureFI->Show(bShowOldSignature || bSomePartial);
SignatureHighlightHdl( nullptr );
}
diff --git a/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui b/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui
index 487bebdf8764..330a0f27bff0 100644
--- a/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui
+++ b/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui
@@ -297,7 +297,7 @@
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
- <property name="label" translatable="yes">Not all parts of the document are signed</property>
+ <property name="label" translatable="yes">At least one signature has problems: the document is only partially signed.</property>
<property name="xalign">0</property>
</object>
<packing>
@@ -310,7 +310,7 @@
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
- <property name="label" translatable="yes">Certificate could not be validated</property>
+ <property name="label" translatable="yes">At least one signature has problems: the certificate could not be validated.</property>
<property name="xalign">0</property>
</object>
<packing>
commit b621713c819bd3f50cacbc910d3039ede0c085d4
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Aug 31 13:34:17 2020 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:30 2020 +0200
xmlsecurity: fix infobar vs signature dialog inconsistency
The infobar mentioned if a signature is partial, but the dialog just has
a bool UI for signatures. Then present "good, but partial" as "bad".
(cherry picked from commit 3ba1144cb96c710e665ffb3ada26fb6a48a03472)
Change-Id: I698190aa77702000b11d635bd038d9c9a91614ac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101844
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 8696c20cbf5c816ded9fee469616cb693b4572b0)
Conflicts:
xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 5a49151608d3..3ca748019cf7 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -593,8 +593,17 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
if ( bSigValid )
{
- bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
- aElementsToBeVerified, rInfo, mode);
+ if (maSignatureManager.mxStore.is())
+ {
+ // XML based.
+ bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
+ aElementsToBeVerified, rInfo, mode);
+ }
+ else
+ {
+ // Assume PDF.
+ bSigValid = !rInfo.bPartialDocumentSignature;
+ }
if( bSigValid )
nValidSigs++;
commit 50d32ee1590dff9da8073fe047b930203d804549
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Tue Apr 16 22:08:42 2019 +0200
Commit: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
CommitDate: Thu Oct 1 10:53:27 2020 +0200
tdf#124776: don't use SearchPathW to get full path of executable
... use GetModuleFileNameW() for that.
We call SetDllDirectoryW and SetSearchPathMode to improve security of
the process, and exclude some paths (including current directory) from
search when using API that looks for binaries whose names are not fully
qualified.
So the sequence is this:
1. Program is started using relative executable path like
"instdir\program\soffice";
2. sal_detail_initialize is called, which calls the two mentioned
hardening functions;
3. sal_detail_initialize calls osl_setCommandArgs, which in turn calls
osl_createCommandArgs_Impl;
4. The latter uses SearchPathW with empty path and first program arg
"instdir\program\soffice" to find fully qualified program path.
That now naturally fails, because current path is not searched.
But to find the process name, we need no search: we can simply use
GetModuleFileNameW() with NULL passed as module handle. Let's use that.
Note that we can't use _wpgmptr/_get_wpgmptr, because we don't use wide
entry point like wmain.
LHM-Stuff
---------
Dieser Patch löst das Problem wenn Symbols eingeschaltet ist, danach
konnte LO nicht mit scalc.exe, swriter.exe, .. gestartet werden den es
ist damit abgestürzt. (Dumpfile war im LO-Verzeichnis)
Reviewed-on: https://gerrit.libreoffice.org/70844
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
(cherry picked from commit c650217cc543080928a26de4bfc07ebb0be5c6ca)
Change-Id: I7a0013a0505f7bdd38164b09b045bfade9686664
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89689
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sal/osl/w32/process.cxx b/sal/osl/w32/process.cxx
index 6d86ae58bad8..eda1e300a588 100644
--- a/sal/osl/w32/process.cxx
+++ b/sal/osl/w32/process.cxx
@@ -350,10 +350,8 @@ static rtl_uString ** osl_createCommandArgs_Impl (int argc, char **)
{
/* Ensure absolute path */
::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
- DWORD dwResult = 0;
-
- dwResult = SearchPath (
- nullptr, reinterpret_cast<LPCWSTR>(ppArgs[0]->buffer), L".exe", aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), nullptr);
+ DWORD dwResult
+ = GetModuleFileNameW(nullptr, SAL_W(aBuffer), aBuffer.getBufSizeInSymbols());
if ((0 < dwResult) && (dwResult < aBuffer.getBufSizeInSymbols()))
{
/* Replace argv[0] with its absolute path */
More information about the Libreoffice-commits
mailing list