diff --git a/sdext/source/pdfimport/config/pdf_import_filter.xcu b/sdext/source/pdfimport/config/pdf_import_filter.xcu
index d454d6f19ddb..3909f9fc1855 100644
--- a/sdext/source/pdfimport/config/pdf_import_filter.xcu
+++ b/sdext/source/pdfimport/config/pdf_import_filter.xcu
@@ -31,7 +31,7 @@
com.sun.star.comp.Writer.XmlFilterAdaptor
- 3RDPARTYFILTER ALIEN IMPORT PREFERRED
+ 3RDPARTYFILTER ALIEN IMPORT PREFERRED SUPPORTSSIGNING
pdf_Portable_Document_Format
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index 2ba4ffdbe08f..f6243ccf5cf4 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -102,6 +102,8 @@
#include
#include
#include
+#include
+#include
using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
@@ -1291,7 +1293,7 @@ uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnal
uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner;
bool bSupportsSigning = GetMedium() && GetMedium()->GetFilter() && GetMedium()->GetFilter()->GetSupportsSigning();
- if (GetMedium() && !GetMedium()->GetName().isEmpty() && (IsOwnStorageFormat(*GetMedium()) || bSupportsSigning) && GetMedium()->GetStorage().is())
+ if (GetMedium() && !GetMedium()->GetName().isEmpty() && ((IsOwnStorageFormat(*GetMedium()) && GetMedium()->GetStorage().is()) || bSupportsSigning))
{
try
{
@@ -1315,8 +1317,22 @@ uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnal
aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
uno::Reference< io::XInputStream >() );
else
- aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
- uno::Reference< io::XInputStream >() );
+ {
+ if (GetMedium()->GetStorage().is())
+ {
+ // Something ZIP-based.
+ aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
+ uno::Reference< io::XInputStream >() );
+ }
+ else
+ {
+ // Not ZIP-based, e.g. PDF.
+ SvStream* pStream = utl::UcbStreamHelper::CreateStream(GetMedium()->GetName(), StreamMode::READ);
+ uno::Reference xStream(new utl::OStreamWrapper(*pStream));
+ uno::Reference xInputStream(xStream, uno::UNO_QUERY);
+ aResult = xLocSigner->verifyDocumentContentSignatures(uno::Reference(), xInputStream);
+ }
+ }
}
catch( css::uno::Exception& )
{
diff --git a/xmlsecurity/Executable_pdfverify.mk b/xmlsecurity/Executable_pdfverify.mk
index c62698f1c4f9..bc08d5620dcc 100644
--- a/xmlsecurity/Executable_pdfverify.mk
+++ b/xmlsecurity/Executable_pdfverify.mk
@@ -13,29 +13,18 @@ $(eval $(call gb_Executable_use_sdk_api,pdfverify))
$(eval $(call gb_Executable_set_include,pdfverify,\
$$(INCLUDE) \
+ -I$(SRCDIR)/xmlsecurity/inc \
))
$(eval $(call gb_Executable_use_libraries,pdfverify,\
comphelper \
sal \
tl \
+ xmlsecurity \
))
$(eval $(call gb_Executable_add_exception_objects,pdfverify,\
xmlsecurity/source/pdfio/pdfverify \
))
-ifeq ($(OS)-$(COM),WNT-MSC)
-$(eval $(call gb_Executable_add_defs,pdfverify,\
- -DXMLSEC_CRYPTO_MSCRYPTO \
-))
-else
-$(eval $(call gb_Executable_add_defs,pdfverify,\
- -DXMLSEC_CRYPTO_NSS \
-))
-$(eval $(call gb_Executable_use_externals,pdfverify,\
- nss3 \
-))
-endif
-
# vim:set noet sw=4 ts=4:
diff --git a/xmlsecurity/Library_xmlsecurity.mk b/xmlsecurity/Library_xmlsecurity.mk
index 1997010344e9..77368ab39616 100644
--- a/xmlsecurity/Library_xmlsecurity.mk
+++ b/xmlsecurity/Library_xmlsecurity.mk
@@ -57,12 +57,27 @@ $(eval $(call gb_Library_add_exception_objects,xmlsecurity,\
xmlsecurity/source/helper/documentsignaturemanager \
xmlsecurity/source/helper/ooxmlsecparser \
xmlsecurity/source/helper/ooxmlsecexporter \
+ xmlsecurity/source/helper/pdfsignaturehelper \
xmlsecurity/source/helper/xmlsignaturehelper2 \
xmlsecurity/source/helper/xmlsignaturehelper \
xmlsecurity/source/helper/xsecctl \
xmlsecurity/source/helper/xsecparser \
xmlsecurity/source/helper/xsecsign \
xmlsecurity/source/helper/xsecverify \
+ xmlsecurity/source/pdfio/pdfdocument \
))
+ifeq ($(OS)-$(COM),WNT-MSC)
+$(eval $(call gb_Library_add_defs,xmlsecurity,\
+ -DXMLSEC_CRYPTO_MSCRYPTO \
+))
+else
+$(eval $(call gb_Library_add_defs,xmlsecurity,\
+ -DXMLSEC_CRYPTO_NSS \
+))
+$(eval $(call gb_Library_use_externals,xmlsecurity,\
+ nss3 \
+))
+endif
+
# vim: set noet sw=4 ts=4:
diff --git a/xmlsecurity/inc/pdfio/pdfdocument.hxx b/xmlsecurity/inc/pdfio/pdfdocument.hxx
new file mode 100644
index 000000000000..9d072615b599
--- /dev/null
+++ b/xmlsecurity/inc/pdfio/pdfdocument.hxx
@@ -0,0 +1,70 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX
+#define INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX
+
+#include
+
+#include
+
+#include
+
+namespace xmlsecurity
+{
+namespace pdfio
+{
+
+class PDFTrailerElement;
+class PDFObjectElement;
+
+/// A byte range in a PDF file.
+class PDFElement
+{
+public:
+ virtual bool Read(SvStream& rStream) = 0;
+ virtual ~PDFElement() { }
+};
+
+/// In-memory representation of an on-disk PDF document.
+class XMLSECURITY_DLLPUBLIC PDFDocument
+{
+ /// This vector owns all elements.
+ std::vector< std::unique_ptr > m_aElements;
+ // List of object offsets we know.
+ std::vector m_aXRef;
+ PDFTrailerElement* m_pTrailer;
+
+ static int AsHex(char ch);
+
+public:
+ PDFDocument();
+ PDFDocument& operator=(const PDFDocument&) = delete;
+ PDFDocument(const PDFDocument&) = delete;
+ static OString ReadKeyword(SvStream& rStream);
+ static size_t FindStartXRef(SvStream& rStream);
+ void ReadXRef(SvStream& rStream);
+ static void SkipWhitespace(SvStream& rStream);
+ size_t GetObjectOffset(size_t nIndex) const;
+ const std::vector< std::unique_ptr >& GetElements();
+ std::vector GetPages();
+
+ bool Read(SvStream& rStream);
+ std::vector GetSignatureWidgets();
+ /// Return value is about if we can determine a result, bDigestMatch is about the actual result.
+ static bool ValidateSignature(SvStream& rStream, PDFObjectElement* pSignature, bool& bDigestMatch);
+};
+
+} // namespace pdfio
+} // namespace xmlsecurity
+
+#endif // INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/pdfsignaturehelper.hxx b/xmlsecurity/inc/pdfsignaturehelper.hxx
new file mode 100644
index 000000000000..fb928340817d
--- /dev/null
+++ b/xmlsecurity/inc/pdfsignaturehelper.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ *
+ */
+
+#ifndef INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX
+#define INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX
+
+#include
+
+#include
+
+#include
+#include
+
+/// Handles signatures of a PDF file.
+class XMLSECURITY_DLLPUBLIC PDFSignatureHelper
+{
+ std::vector m_aSignatureInfos;
+
+public:
+ bool ReadAndVerifySignature(const css::uno::Reference& xInputStream);
+ css::uno::Sequence GetDocumentSignatureInformations();
+};
+
+#endif // INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index cfa3d247634f..2fa08a442cd3 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
@@ -259,6 +260,14 @@ DocumentDigitalSignatures::ImplVerifySignatures(
{
if (!rxStorage.is())
{
+ if (xSignStream.is())
+ {
+ // Something not ZIP-based, try PDF.
+ PDFSignatureHelper aSignatureHelper;
+ if (aSignatureHelper.ReadAndVerifySignature(xSignStream))
+ return aSignatureHelper.GetDocumentSignatureInformations();
+ }
+
SAL_WARN( "xmlsecurity.comp", "Error, no XStorage provided");
return Sequence();
}
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
new file mode 100644
index 000000000000..d8e6cd5eb6ac
--- /dev/null
+++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
@@ -0,0 +1,65 @@
+/* -*- 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
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+using namespace ::com::sun::star;
+
+bool PDFSignatureHelper::ReadAndVerifySignature(const uno::Reference& xInputStream)
+{
+ if (!xInputStream.is())
+ {
+ SAL_WARN("xmlsecurity.helper", "input stream missing");
+ return false;
+ }
+
+ std::unique_ptr pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
+ xmlsecurity::pdfio::PDFDocument aDocument;
+ if (!aDocument.Read(*pStream))
+ {
+ SAL_WARN("xmlsecurity.helper", "failed to read the document");
+ return false;
+ }
+
+ std::vector aSignatures = aDocument.GetSignatureWidgets();
+ if (aSignatures.empty())
+ return true;
+
+ for (size_t i = 0; i < aSignatures.size(); ++i)
+ {
+ security::DocumentSignatureInformation aInfo;
+
+ bool bDigestMatch;
+ if (!xmlsecurity::pdfio::PDFDocument::ValidateSignature(*pStream, aSignatures[i], bDigestMatch))
+ {
+ SAL_WARN("xmlsecurity.helper", "failed to determine digest match");
+ continue;
+ }
+
+ aInfo.SignatureIsValid = bDigestMatch;
+ m_aSignatureInfos.push_back(aInfo);
+ }
+
+ return true;
+}
+
+uno::Sequence PDFSignatureHelper::GetDocumentSignatureInformations()
+{
+ return comphelper::containerToSequence(m_aSignatureInfos);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
new file mode 100644
index 000000000000..3bd90db5e478
--- /dev/null
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -0,0 +1,1461 @@
+/* -*- 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
+
+#include