xmlsecurity: add initial PDFSignatureHelper
This splits most of the PDF signature code out of the pdfverify executable, and puts it into the xmlsecurity library instead. The PDFSignatureHelper now attempts to verify PDF signatures, and code in sdext / sfx2 also calls it (even if PDF is not a ZIP-based format). Change-Id: I7b8b3ac9c976e4ea4f3796b1cda07c8a2c97bd02 Reviewed-on: https://gerrit.libreoffice.org/29751 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
This commit is contained in:
parent
3461c9d7a2
commit
0f613adbfa
@ -31,7 +31,7 @@
|
||||
<value>com.sun.star.comp.Writer.XmlFilterAdaptor</value>
|
||||
</prop>
|
||||
<prop oor:name="Flags" oor:type="oor:string-list">
|
||||
<value>3RDPARTYFILTER ALIEN IMPORT PREFERRED</value>
|
||||
<value>3RDPARTYFILTER ALIEN IMPORT PREFERRED SUPPORTSSIGNING</value>
|
||||
</prop>
|
||||
<prop oor:name="Type" oor:type="xs:string">
|
||||
<value>pdf_Portable_Document_Format</value>
|
||||
|
@ -102,6 +102,8 @@
|
||||
#include <sfx2/saveastemplatedlg.hxx>
|
||||
#include <memory>
|
||||
#include <cppuhelper/implbase.hxx>
|
||||
#include <unotools/ucbstreamhelper.hxx>
|
||||
#include <unotools/streamwrap.hxx>
|
||||
|
||||
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<io::XStream> xStream(new utl::OStreamWrapper(*pStream));
|
||||
uno::Reference<io::XInputStream> xInputStream(xStream, uno::UNO_QUERY);
|
||||
aResult = xLocSigner->verifyDocumentContentSignatures(uno::Reference<embed::XStorage>(), xInputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( css::uno::Exception& )
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
70
xmlsecurity/inc/pdfio/pdfdocument.hxx
Normal file
70
xmlsecurity/inc/pdfio/pdfdocument.hxx
Normal file
@ -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 <vector>
|
||||
|
||||
#include <tools/stream.hxx>
|
||||
|
||||
#include <xmlsecuritydllapi.h>
|
||||
|
||||
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<PDFElement> > m_aElements;
|
||||
// List of object offsets we know.
|
||||
std::vector<size_t> 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<PDFElement> >& GetElements();
|
||||
std::vector<PDFObjectElement*> GetPages();
|
||||
|
||||
bool Read(SvStream& rStream);
|
||||
std::vector<PDFObjectElement*> 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: */
|
33
xmlsecurity/inc/pdfsignaturehelper.hxx
Normal file
33
xmlsecurity/inc/pdfsignaturehelper.hxx
Normal file
@ -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 <xmlsecuritydllapi.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <com/sun/star/io/XInputStream.hpp>
|
||||
#include <com/sun/star/security/DocumentSignatureInformation.hpp>
|
||||
|
||||
/// Handles signatures of a PDF file.
|
||||
class XMLSECURITY_DLLPUBLIC PDFSignatureHelper
|
||||
{
|
||||
std::vector<css::security::DocumentSignatureInformation> m_aSignatureInfos;
|
||||
|
||||
public:
|
||||
bool ReadAndVerifySignature(const css::uno::Reference<css::io::XInputStream>& xInputStream);
|
||||
css::uno::Sequence<css::security::DocumentSignatureInformation> GetDocumentSignatureInformations();
|
||||
};
|
||||
|
||||
#endif // INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@ -24,6 +24,7 @@
|
||||
#include <macrosecurity.hxx>
|
||||
#include <biginteger.hxx>
|
||||
#include <global.hrc>
|
||||
#include <pdfsignaturehelper.hxx>
|
||||
|
||||
#include <sax/tools/converter.hxx>
|
||||
|
||||
@ -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<css::security::DocumentSignatureInformation>();
|
||||
}
|
||||
|
65
xmlsecurity/source/helper/pdfsignaturehelper.cxx
Normal file
65
xmlsecurity/source/helper/pdfsignaturehelper.cxx
Normal file
@ -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 <pdfsignaturehelper.hxx>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <comphelper/sequence.hxx>
|
||||
#include <tools/stream.hxx>
|
||||
#include <unotools/ucbstreamhelper.hxx>
|
||||
|
||||
#include <pdfio/pdfdocument.hxx>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
bool PDFSignatureHelper::ReadAndVerifySignature(const uno::Reference<io::XInputStream>& xInputStream)
|
||||
{
|
||||
if (!xInputStream.is())
|
||||
{
|
||||
SAL_WARN("xmlsecurity.helper", "input stream missing");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<SvStream> 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<xmlsecurity::pdfio::PDFObjectElement*> 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<security::DocumentSignatureInformation> PDFSignatureHelper::GetDocumentSignatureInformations()
|
||||
{
|
||||
return comphelper::containerToSequence(m_aSignatureInfos);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
1461
xmlsecurity/source/pdfio/pdfdocument.cxx
Normal file
1461
xmlsecurity/source/pdfio/pdfdocument.cxx
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user