summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Behrens <Thorsten.Behrens@CIB.de>2017-05-21 14:28:57 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-06-21 23:14:49 +0200
commit3e3b37ca4cbc881628a71715b67ac172018cf9f2 (patch)
tree5f16855d11f1a2910e2f4fbb08078c2aff4c5275
parent814dbf3624b9e8608882b003d96dfb51fa3634fc (diff)
gpg4libre: backport OpenPGP signing from master
This squashes the following commits: - gpg4libre: share static xmlsec lib between nss and gpg - gpg4libre: fix gpg signature generation - gpg4libre: initial GPG signature validation - gpg4libre: Make signature dialog work with two signing services - gpg4libre: Having this dllpublic should be fine now since it's in inc/ - gpg4libre: fix build, explicit ctor call - gpg4libre: now use the gpg security env - gpg4libre: [API-CHANGE] add certificate kind (X509 vs. OpenPGP) - gpg4libre: List both (x509 and gpg) existing signatures - gpg4libre: Init xmlsec in one place before creating the gpg/x509 services - gpg4libre: write PGPData info, get more metadata out for gpg key - gpg4libre: Fixup unit tests, now that SecurityContext is needed - gpg4libre: Make viewing signatures work for gpg signatures - gpg4libre: some code improvements, add metadata for OpenPGP keys - gpg4libre: make signature impl swappable in-situ during validation - gpg4libre: actually take key from user selection - gpg4libre: fix build for windows and mac Change-Id: I3e36b22cefba4c6195bcf8b85b3f7a2cc101b845 Reviewed-on: https://gerrit.libreoffice.org/39076 Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de> Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de> Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r--include/sal/log-areas.dox1
-rw-r--r--offapi/UnoApi_offapi.mk1
-rw-r--r--offapi/com/sun/star/security/CertificateKind.idl33
-rw-r--r--offapi/com/sun/star/security/XCertificate.idl8
-rw-r--r--postprocess/Rdb_services.mk3
-rw-r--r--xmlsecurity/Library_xmlsecurity.mk6
-rw-r--r--xmlsecurity/Library_xsec_gpg.mk75
-rw-r--r--xmlsecurity/Library_xsec_xmlsec.mk20
-rw-r--r--xmlsecurity/Module_xmlsecurity.mk6
-rw-r--r--xmlsecurity/inc/certificatechooser.hxx8
-rw-r--r--xmlsecurity/inc/digitalsignaturesdialog.hxx4
-rw-r--r--xmlsecurity/inc/documentsignaturemanager.hxx6
-rw-r--r--xmlsecurity/inc/framework/signatureverifierimpl.hxx3
-rw-r--r--xmlsecurity/inc/gpg/SEInitializer.hxx5
-rw-r--r--xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx (renamed from xmlsecurity/source/gpg/xmlsignature_gpgimpl.hxx)1
-rw-r--r--xmlsecurity/inc/sigstruct.hxx4
-rw-r--r--xmlsecurity/inc/xmlsec/xmlsec_init.hxx20
-rw-r--r--xmlsecurity/inc/xmlsec/xmlstreamio.hxx8
-rw-r--r--xmlsecurity/inc/xmlsignaturehelper.hxx3
-rw-r--r--xmlsecurity/inc/xsecctl.hxx8
-rw-r--r--xmlsecurity/qa/unit/signing/signing.cxx12
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.cxx15
-rw-r--r--xmlsecurity/source/dialogs/certificatechooser.cxx19
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx96
-rw-r--r--xmlsecurity/source/gpg/CertificateImpl.cxx57
-rw-r--r--xmlsecurity/source/gpg/CertificateImpl.hxx5
-rw-r--r--xmlsecurity/source/gpg/SEInitializer.cxx7
-rw-r--r--xmlsecurity/source/gpg/SecurityEnvironment.cxx49
-rw-r--r--xmlsecurity/source/gpg/SecurityEnvironment.hxx5
-rw-r--r--xmlsecurity/source/gpg/XMLSecurityContext.cxx20
-rw-r--r--xmlsecurity/source/gpg/XMLSecurityContext.hxx10
-rw-r--r--xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx203
-rw-r--r--xmlsecurity/source/helper/documentsignaturehelper.cxx3
-rw-r--r--xmlsecurity/source/helper/documentsignaturemanager.cxx128
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx10
-rw-r--r--xmlsecurity/source/helper/xsecctl.cxx91
-rw-r--r--xmlsecurity/source/helper/xsecparser.cxx36
-rw-r--r--xmlsecurity/source/helper/xsecparser.hxx4
-rw-r--r--xmlsecurity/source/helper/xsecsign.cxx23
-rw-r--r--xmlsecurity/source/helper/xsecverify.cxx46
-rw-r--r--xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx5
-rw-r--r--xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx3
-rw-r--r--xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx5
-rw-r--r--xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx2
-rw-r--r--xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx23
-rw-r--r--xmlsecurity/source/xmlsec/xmlsec_init.cxx47
-rw-r--r--xmlsecurity/source/xmlsec/xmlstreamio.cxx4
-rw-r--r--xmlsecurity/source/xmlsec/xsec_xmlsec.cxx13
-rw-r--r--xmlsecurity/util/xsec_gpg.component25
49 files changed, 825 insertions, 364 deletions
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index 8acbf3f62a0f..4da0c8b533fc 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -526,6 +526,7 @@ certain functionality.
@li @c xmlsecurity.helper
@li @c xmlsecurity.pdfio - signing of existing PDF
@li @c xmlsecurity.xmlsec - xmlsec wrapper
+@li @c xmlsecurity.xmlsec.gpg - gpg xmlsec component
@section xmlscript
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 0e0a6cad8962..f0e03f2808e1 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -3316,6 +3316,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/security,\
CertificateCharacters \
CertificateContainerStatus \
CertificateException \
+ CertificateKind \
CertificateValidity \
CryptographyException \
DocumentSignatureInformation \
diff --git a/offapi/com/sun/star/security/CertificateKind.idl b/offapi/com/sun/star/security/CertificateKind.idl
new file mode 100644
index 000000000000..b1ae35e87ded
--- /dev/null
+++ b/offapi/com/sun/star/security/CertificateKind.idl
@@ -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 __com_sun_star_security_CertificateKind_idl_
+#define __com_sun_star_security_CertificateKind_idl_
+
+module com { module sun { module star { module security {
+
+/**
+ * Enum definition of a certificate kind ( X509, OpenPGP )
+ */
+enum CertificateKind
+{
+ /** X.509 format of a certificate
+ */
+ X509,
+
+ /** OpenPGP format of a certificate
+ */
+ OPENPGP
+};
+
+} ; } ; } ; } ;
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/security/XCertificate.idl b/offapi/com/sun/star/security/XCertificate.idl
index 22f7c6a4a1be..6feaa409ccf2 100644
--- a/offapi/com/sun/star/security/XCertificate.idl
+++ b/offapi/com/sun/star/security/XCertificate.idl
@@ -23,13 +23,14 @@
#include <com/sun/star/uno/XInterface.idl>
#include <com/sun/star/util/DateTime.idl>
#include <com/sun/star/security/XCertificateExtension.idl>
+#include <com/sun/star/security/CertificateKind.idl>
module com { module sun { module star { module security {
/**
* Interface of a PKI Certificate
*
- * <p>This interface represents a x509 certificate.</p>
+ * <p>This interface represents a certificate (X.509 or OpenPGP) .</p>
*/
interface XCertificate : com::sun::star::uno::XInterface
{
@@ -109,6 +110,11 @@ interface XCertificate : com::sun::star::uno::XInterface
[attribute, readonly] sequence< byte > MD5Thumbprint;
/**
+ * the kind of certificate, X.509 or OpenPGP
+ */
+ [attribute, readonly] com::sun::star::security::CertificateKind CertificateKind;
+
+ /**
* Find a extension with a object identifier.
*/
XCertificateExtension findCertificateExtension( [in]sequence< byte > oid ) ;
diff --git a/postprocess/Rdb_services.mk b/postprocess/Rdb_services.mk
index cd7a10cadd64..ce8649ed7f7e 100644
--- a/postprocess/Rdb_services.mk
+++ b/postprocess/Rdb_services.mk
@@ -109,9 +109,6 @@ $(eval $(call gb_Rdb_add_components,services,\
xmloff/util/xo \
xmlscript/util/xmlscript \
$(if $(ENABLE_NSS), \
- $(if $(filter-out WNT MACOSX ANDROID IOS,$(OS)), \
- xmlsecurity/util/xsec_gpg \
- ) \
xmlsecurity/util/xmlsecurity \
xmlsecurity/util/xsec_xmlsec$(if $(filter WNT,$(OS)),.windows)) \
$(if $(ENABLE_COINMP), \
diff --git a/xmlsecurity/Library_xmlsecurity.mk b/xmlsecurity/Library_xmlsecurity.mk
index a0fe40a5a033..77d3bd81dc3b 100644
--- a/xmlsecurity/Library_xmlsecurity.mk
+++ b/xmlsecurity/Library_xmlsecurity.mk
@@ -45,12 +45,6 @@ $(eval $(call gb_Library_use_libraries,xmlsecurity,\
xsec_xmlsec \
))
-ifneq ($(filter-out WNT MACOSX ANDROID IOS,$(OS)),)
-$(eval $(call gb_Library_use_libraries,xmlsecurity,\
- xsec_gpg \
-))
-endif
-
$(eval $(call gb_Library_add_exception_objects,xmlsecurity,\
xmlsecurity/source/component/certificatecontainer \
xmlsecurity/source/component/documentdigitalsignatures \
diff --git a/xmlsecurity/Library_xsec_gpg.mk b/xmlsecurity/Library_xsec_gpg.mk
deleted file mode 100644
index 5c21173f94b8..000000000000
--- a/xmlsecurity/Library_xsec_gpg.mk
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# 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/.
-#
-
-$(eval $(call gb_Library_Library,xsec_gpg))
-
-$(eval $(call gb_Library_set_componentfile,xsec_gpg,xmlsecurity/util/xsec_gpg))
-
-$(eval $(call gb_Library_set_include,xsec_gpg,\
- $$(INCLUDE) \
- -I$(SRCDIR)/xmlsecurity/inc \
- -I$(SRCDIR)/xmlsecurity/source/gpg \
- -I$(call gb_UnpackedTarball_get_dir,xmlsec/include \
-)))
-
-$(eval $(call gb_Library_add_defs,xsec_gpg,\
- -DXMLSEC_NO_XSLT \
- -DXMLSEC_CRYPTO_NSS \
- -DXSECGPG_DLLIMPLEMENTATION \
-))
-
-$(eval $(call gb_Library_use_custom_headers,xsec_gpg,\
- officecfg/registry \
-))
-
-$(eval $(call gb_Library_use_sdk_api,xsec_gpg))
-
-$(eval $(call gb_Library_set_precompiled_header,xsec_gpg,$(SRCDIR)/xmlsecurity/inc/pch/precompiled_xsec_gpg))
-
-$(eval $(call gb_Library_use_packages,xsec_gpg,\
- xmlsec \
-))
-$(eval $(call gb_Library_use_externals,xsec_gpg,\
- boost_headers \
- libxml2 \
- nss3 \
- gpgmepp))
-
-$(eval $(call gb_Library_use_libraries,xsec_gpg,\
- comphelper \
- cppu \
- cppuhelper \
- sal \
- svl \
- tl \
- xo \
- xsec_xmlsec \
-))
-
-$(eval $(call gb_Library_add_defs,xsec_gpg,\
- -DXMLSEC_CRYPTO_NSS \
-))
-$(eval $(call gb_Library_add_libs,xsec_gpg,\
- $(call gb_UnpackedTarball_get_dir,xmlsec)/src/nss/.libs/libxmlsec1-nss.a \
- $(call gb_UnpackedTarball_get_dir,xmlsec)/src/.libs/libxmlsec1.a \
-))
-
-$(eval $(call gb_Library_add_exception_objects,xsec_gpg,\
- xmlsecurity/source/gpg/CertificateImpl \
- xmlsecurity/source/gpg/CipherContext \
- xmlsecurity/source/gpg/DigestContext \
- xmlsecurity/source/gpg/GpgComponentFactory \
- xmlsecurity/source/gpg/SecurityEnvironment \
- xmlsecurity/source/gpg/SEInitializer \
- xmlsecurity/source/gpg/XMLEncryption \
- xmlsecurity/source/gpg/XMLSecurityContext \
- xmlsecurity/source/gpg/xmlsignature_gpgimpl \
-))
-
-# vim: set noet sw=4 ts=4:
diff --git a/xmlsecurity/Library_xsec_xmlsec.mk b/xmlsecurity/Library_xsec_xmlsec.mk
index db161c13995f..639fe55f5add 100644
--- a/xmlsecurity/Library_xsec_xmlsec.mk
+++ b/xmlsecurity/Library_xsec_xmlsec.mk
@@ -18,6 +18,7 @@ endif
$(eval $(call gb_Library_set_include,xsec_xmlsec,\
$$(INCLUDE) \
-I$(SRCDIR)/xmlsecurity/inc \
+ -I$(SRCDIR)/xmlsecurity/source/gpg \
-I$(SRCDIR)/xmlsecurity/source/xmlsec \
-I$(call gb_UnpackedTarball_get_dir,xmlsec/include) \
))
@@ -53,6 +54,11 @@ $(eval $(call gb_Library_use_externals,xsec_xmlsec,\
libxml2 \
nss3 \
))
+ifneq ($(filter-out WNT MACOSX ANDROID IOS,$(OS)),)
+$(eval $(call gb_Library_use_externals,xsec_xmlsec,\
+ gpgmepp \
+))
+endif
$(eval $(call gb_Library_add_exception_objects,xsec_xmlsec,\
xmlsecurity/source/xmlsec/biginteger \
@@ -62,6 +68,7 @@ $(eval $(call gb_Library_add_exception_objects,xsec_xmlsec,\
xmlsecurity/source/xmlsec/serialnumberadapter \
xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl \
xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl \
+ xmlsecurity/source/xmlsec/xmlsec_init \
xmlsecurity/source/xmlsec/xmlstreamio \
xmlsecurity/source/xmlsec/xsec_xmlsec \
xmlsecurity/source/xmlsec/nss/ciphercontext \
@@ -70,6 +77,19 @@ $(eval $(call gb_Library_add_exception_objects,xsec_xmlsec,\
xmlsecurity/source/xmlsec/nss/xsec_nss \
))
+ifneq ($(filter-out WNT MACOSX ANDROID IOS,$(OS)),)
+$(eval $(call gb_Library_add_exception_objects,xsec_xmlsec,\
+ xmlsecurity/source/gpg/CertificateImpl \
+ xmlsecurity/source/gpg/CipherContext \
+ xmlsecurity/source/gpg/DigestContext \
+ xmlsecurity/source/gpg/SecurityEnvironment \
+ xmlsecurity/source/gpg/SEInitializer \
+ xmlsecurity/source/gpg/XMLEncryption \
+ xmlsecurity/source/gpg/XMLSecurityContext \
+ xmlsecurity/source/gpg/xmlsignature_gpgimpl \
+))
+endif
+
ifeq ($(OS),WNT)
$(eval $(call gb_Library_add_defs,xsec_xmlsec,\
diff --git a/xmlsecurity/Module_xmlsecurity.mk b/xmlsecurity/Module_xmlsecurity.mk
index d3fafeb7e4ec..b14729ffc405 100644
--- a/xmlsecurity/Module_xmlsecurity.mk
+++ b/xmlsecurity/Module_xmlsecurity.mk
@@ -19,12 +19,6 @@ $(eval $(call gb_Module_add_targets,xmlsecurity,\
Library_xsec_xmlsec \
))
-ifneq ($(filter-out WNT MACOSX ANDROID IOS,$(OS)),)
-$(eval $(call gb_Module_add_targets,xmlsecurity,\
- Library_xsec_gpg \
-))
-endif
-
$(eval $(call gb_Module_add_slowcheck_targets,xmlsecurity,\
CppunitTest_xmlsecurity_signing \
CppunitTest_xmlsecurity_pdfsigning \
diff --git a/xmlsecurity/inc/certificatechooser.hxx b/xmlsecurity/inc/certificatechooser.hxx
index d5881eb5b837..264b740dd448 100644
--- a/xmlsecurity/inc/certificatechooser.hxx
+++ b/xmlsecurity/inc/certificatechooser.hxx
@@ -24,6 +24,8 @@
#include <vcl/dialog.hxx>
#include <vcl/fixed.hxx>
#include <vcl/button.hxx>
+#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
+#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <sigstruct.hxx>
@@ -43,6 +45,7 @@ class HeaderBar;
struct UserData
{
css::uno::Reference<css::security::XCertificate> xCertificate;
+ css::uno::Reference<css::xml::crypto::XXMLSecurityContext> xSecurityContext;
css::uno::Reference<css::xml::crypto::XSecurityEnvironment> xSecurityEnvironment;
};
@@ -50,7 +53,7 @@ class CertificateChooser : public ModalDialog
{
private:
css::uno::Reference< css::uno::XComponentContext > mxCtx;
- std::vector< css::uno::Reference< css::xml::crypto::XSecurityEnvironment > > mxSecurityEnvironments;
+ std::vector< css::uno::Reference< css::xml::crypto::XXMLSecurityContext > > mxSecurityContexts;
std::vector<std::shared_ptr<UserData>> mvUserData;
VclPtr<SvSimpleTable> m_pCertLB;
@@ -72,13 +75,14 @@ private:
public:
CertificateChooser(vcl::Window* pParent,
css::uno::Reference< css::uno::XComponentContext>& rxCtx,
- std::vector< css::uno::Reference< css::xml::crypto::XSecurityEnvironment > >& rxSecurityEnvironments);
+ std::vector< css::uno::Reference< css::xml::crypto::XXMLSecurityContext > >& rxSecurityContexts);
virtual ~CertificateChooser() override;
virtual void dispose() override;
short Execute() override;
css::uno::Reference< css::security::XCertificate > GetSelectedCertificate();
+ css::uno::Reference< css::xml::crypto::XXMLSecurityContext > GetSelectedSecurityContext();
/// Gets the description string provided when selecting the certificate.
OUString GetDescription();
diff --git a/xmlsecurity/inc/digitalsignaturesdialog.hxx b/xmlsecurity/inc/digitalsignaturesdialog.hxx
index 44cf85da7d50..e49419e57a4a 100644
--- a/xmlsecurity/inc/digitalsignaturesdialog.hxx
+++ b/xmlsecurity/inc/digitalsignaturesdialog.hxx
@@ -101,6 +101,10 @@ private:
void ImplFillSignaturesBox();
void ImplShowSignaturesDetails();
+ css::uno::Reference<css::security::XCertificate> getCertificate(const SignatureInformation& rInfo);
+ css::uno::Reference<css::xml::crypto::XSecurityEnvironment> getSecurityEnvironmentForCertificate(
+ css::uno::Reference<css::security::XCertificate> xCert);
+
//Checks if adding is allowed.
//See the spec at specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
//(6.6.2)Behaviour with regard to ODF 1.2
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index 2039b7fe778f..eed54a5a32c7 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -61,7 +61,9 @@ public:
bool isXML(const OUString& rURI);
SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 eStreamMode, bool bTempStream);
/// Add a new signature, using xCert as a signing certificate, and rDescription as description.
- bool add(const css::uno::Reference<css::security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant);
+ bool add(const css::uno::Reference<css::security::XCertificate>& xCert,
+ const css::uno::Reference<css::xml::crypto::XXMLSecurityContext> xSecurityContext,
+ const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant);
/// Remove signature at nPosition.
void remove(sal_uInt16 nPosition);
/// Read signatures from either a temp stream or the real storage.
@@ -79,6 +81,8 @@ public:
/// Get the security environment.
css::uno::Reference<css::xml::crypto::XSecurityEnvironment> getSecurityEnvironment();
css::uno::Reference<css::xml::crypto::XSecurityEnvironment> getGpgSecurityEnvironment();
+ css::uno::Reference<css::xml::crypto::XXMLSecurityContext> getSecurityContext();
+ css::uno::Reference<css::xml::crypto::XXMLSecurityContext> getGpgSecurityContext();
};
#endif // INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREMANAGER_HXX
diff --git a/xmlsecurity/inc/framework/signatureverifierimpl.hxx b/xmlsecurity/inc/framework/signatureverifierimpl.hxx
index 8c20c8385de9..592e4740c714 100644
--- a/xmlsecurity/inc/framework/signatureverifierimpl.hxx
+++ b/xmlsecurity/inc/framework/signatureverifierimpl.hxx
@@ -76,6 +76,9 @@ public:
virtual OUString SAL_CALL getImplementationName( ) override;
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ void updateSignature( const css::uno::Reference< css::xml::crypto::XXMLSignature >& xSignature,
+ const css::uno::Reference< css::xml::crypto::XXMLSecurityContext >& xContext ) { m_xXMLSignature = xSignature; m_xXMLSecurityContext = xContext; }
};
/// @throws css::uno::RuntimeException
diff --git a/xmlsecurity/inc/gpg/SEInitializer.hxx b/xmlsecurity/inc/gpg/SEInitializer.hxx
index d4f375bfd41c..db73d621f7be 100644
--- a/xmlsecurity/inc/gpg/SEInitializer.hxx
+++ b/xmlsecurity/inc/gpg/SEInitializer.hxx
@@ -22,11 +22,8 @@
class XSECGPG_DLLPUBLIC SEInitializerGpg : public cppu::WeakImplHelper< css::xml::crypto::XSEInitializer >
{
-protected:
- css::uno::Reference< css::uno::XComponentContext > m_xContext;
-
public:
- explicit SEInitializerGpg(const css::uno::Reference<css::uno::XComponentContext > &rxContext);
+ SEInitializerGpg();
virtual ~SEInitializerGpg() override;
/* XSEInitializer */
diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.hxx b/xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx
index 96dfa0c39f3e..913053b7a4f0 100644
--- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.hxx
+++ b/xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx
@@ -36,7 +36,6 @@
#include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp>
#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
-// TODO: hack, remove dllpublic again...
class XSECGPG_DLLPUBLIC XMLSignature_GpgImpl : public ::cppu::WeakImplHelper<
css::xml::crypto::XXMLSignature ,
css::lang::XServiceInfo >
diff --git a/xmlsecurity/inc/sigstruct.hxx b/xmlsecurity/inc/sigstruct.hxx
index 479ba3d8f745..68e64176206b 100644
--- a/xmlsecurity/inc/sigstruct.hxx
+++ b/xmlsecurity/inc/sigstruct.hxx
@@ -74,6 +74,10 @@ struct SignatureInformation
OUString ouX509IssuerName;
OUString ouX509SerialNumber;
OUString ouX509Certificate;
+
+ OUString ouGpgKeyID;
+ OUString ouGpgCertificate;
+
OUString ouSignatureValue;
css::util::DateTime stDateTime;
diff --git a/xmlsecurity/inc/xmlsec/xmlsec_init.hxx b/xmlsecurity/inc/xmlsec/xmlsec_init.hxx
new file mode 100644
index 000000000000..6dc4de2a63cf
--- /dev/null
+++ b/xmlsecurity/inc/xmlsec/xmlsec_init.hxx
@@ -0,0 +1,20 @@
+/* -*- 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_SOURCE_XMLSEC_XMLSEC_INIT_HXX
+#define INCLUDED_XMLSECURITY_SOURCE_XMLSEC_XMLSEC_INIT_HXX
+
+#include <xsecxmlsecdllapi.h>
+
+XSECXMLSEC_DLLPUBLIC void initXmlSec();
+XSECXMLSEC_DLLPUBLIC void deInitXmlSec();
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/xmlsec/xmlstreamio.hxx b/xmlsecurity/inc/xmlsec/xmlstreamio.hxx
index 55001cbd3ead..9483fdb25475 100644
--- a/xmlsecurity/inc/xmlsec/xmlstreamio.hxx
+++ b/xmlsecurity/inc/xmlsec/xmlstreamio.hxx
@@ -25,13 +25,11 @@
#include <xsecxmlsecdllapi.h>
-int xmlEnableStreamInputCallbacks() ;
-void xmlDisableStreamInputCallbacks() ;
-
+XSECXMLSEC_DLLPUBLIC int xmlEnableStreamInputCallbacks() ;
+XSECXMLSEC_DLLPUBLIC void xmlDisableStreamInputCallbacks() ;
XSECXMLSEC_DLLPUBLIC int xmlRegisterStreamInputCallbacks(
css::uno::Reference< css::xml::crypto::XUriBinding >& aUriBinding
-) ;
-
+);
XSECXMLSEC_DLLPUBLIC int xmlUnregisterStreamInputCallbacks() ;
#endif // INCLUDED_XMLSECURITY_SOURCE_XMLSEC_XMLSTREAMIO_HXX
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index df77db92b7a8..261a4792cd61 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -154,6 +154,9 @@ public:
void AddEncapsulatedX509Certificate(const OUString& ouEncapsulatedX509Certificate);
+ void SetGpgCertificate(sal_Int32 nSecurityId, const OUString& ouGpgCertDigest,
+ const OUString& ouGpgCert);
+
void SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const tools::Time& rTime );
void SetDescription(sal_Int32 nSecurityId, const OUString& rDescription);
diff --git a/xmlsecurity/inc/xsecctl.hxx b/xmlsecurity/inc/xsecctl.hxx
index b7ee1f8310b9..a38c1cbf8e3d 100644
--- a/xmlsecurity/inc/xsecctl.hxx
+++ b/xmlsecurity/inc/xsecctl.hxx
@@ -292,6 +292,7 @@ private:
* For signature verification
*/
void addSignature();
+ void switchGpgSignature();
void addReference(
const OUString& ouUri,
sal_Int32 nDigestID );
@@ -306,6 +307,8 @@ private:
void setX509Certificate( OUString& ouX509Certificate );
void setSignatureValue( OUString& ouSignatureValue );
void setDigestValue( sal_Int32 nDigestID, OUString& ouDigestValue );
+ void setGpgKeyID( OUString& ouKeyID );
+ void setGpgCertificate( OUString& ouGpgCert );
void setDate( OUString& ouDate );
void setDescription(const OUString& rDescription);
@@ -382,6 +385,11 @@ public:
void addEncapsulatedX509Certificate(const OUString& rEncapsulatedX509Certificate);
+ void setGpgCertificate(
+ sal_Int32 nSecurityId,
+ const OUString& ouCertDigest,
+ const OUString& ouCert);
+
void setDate(
sal_Int32 nSecurityId,
const css::util::DateTime& rDateTime );
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index f8fe7b55123d..2b6e60e7c0bd 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -56,6 +56,8 @@ class SigningTest : public test::BootstrapFixture, public unotest::MacrosTest, p
{
uno::Reference<uno::XComponentContext> mxComponentContext;
uno::Reference<lang::XComponent> mxComponent;
+ uno::Reference<xml::crypto::XSEInitializer> mxSEInitializer;
+ uno::Reference<xml::crypto::XXMLSecurityContext> mxSecurityContext;
public:
SigningTest();
@@ -135,6 +137,8 @@ void SigningTest::setUp()
mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
mxDesktop.set(frame::Desktop::create(mxComponentContext));
+ mxSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext);
+ mxSecurityContext = mxSEInitializer->createSecurityContext(OUString());
#ifndef _WIN32
// Set up cert8.db in workdir/CppunitTest/
@@ -214,7 +218,7 @@ void SigningTest::testDescription()
return;
OUString aDescription("SigningTest::testDescription");
sal_Int32 nSecurityId;
- aManager.add(xCertificate, aDescription, nSecurityId, false);
+ aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, false);
// Read back the signature and make sure that the description survives the roundtrip.
aManager.read(/*bUseTempStream=*/true);
@@ -248,7 +252,7 @@ void SigningTest::testOOXMLDescription()
return;
OUString aDescription("SigningTest::testDescription");
sal_Int32 nSecurityId;
- aManager.add(xCertificate, aDescription, nSecurityId, false);
+ aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, false);
// Read back the signature and make sure that the description survives the roundtrip.
aManager.read(/*bUseTempStream=*/true);
@@ -281,7 +285,7 @@ void SigningTest::testOOXMLAppend()
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
- aManager.add(xCertificate, OUString(), nSecurityId, false);
+ aManager.add(xCertificate, mxSecurityContext, OUString(), nSecurityId, false);
// Read back the signatures and make sure that we have the expected amount.
aManager.read(/*bUseTempStream=*/true);
@@ -586,7 +590,7 @@ void SigningTest::testXAdES()
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
- aManager.add(xCertificate, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true);
+ aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId, /*bAdESCompliant=*/true);
// Write to storage.
aManager.read(/*bUseTempStream=*/true);
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 4dfa87edeeda..518b4acb1c93 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -307,6 +307,7 @@ DocumentDigitalSignatures::ImplVerifySignatures(
rSignatureHelper.EndMission();
uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = aSignatureManager.getSecurityEnvironment();
+ uno::Reference<xml::crypto::XSecurityEnvironment> xGpgSecEnv = aSignatureManager.getGpgSecurityEnvironment();
SignatureInformations aSignInfos = rSignatureHelper.GetSignatureInformations();
int nInfos = aSignInfos.size();
@@ -359,7 +360,11 @@ DocumentDigitalSignatures::ImplVerifySignatures(
{
//We should always be able to get the certificates because it is contained in the document,
//unless the document is damaged so that signature xml file could not be parsed.
- rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
+ rSigInfo.CertificateStatus =
+ xGpgSecEnv->verifyCertificate(rSigInfo.Signer,
+ Sequence<Reference<css::security::XCertificate> >());
+ // well - except for gpg signatures ...
+ //rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
}
rSigInfo.SignatureIsValid = ( rInfo.nStatus == css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );
@@ -447,16 +452,16 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificate(OUString& rDescription)
{
- std::vector< Reference< css::xml::crypto::XSecurityEnvironment > > xSecEnvs;
+ std::vector< Reference< css::xml::crypto::XXMLSecurityContext > > xSecContexts;
DocumentSignatureMode eMode{};
DocumentSignatureManager aSignatureManager(mxCtx, eMode);
if (aSignatureManager.init()) {
- xSecEnvs.push_back(aSignatureManager.getSecurityEnvironment());
- xSecEnvs.push_back(aSignatureManager.getGpgSecurityEnvironment());
+ xSecContexts.push_back(aSignatureManager.getSecurityContext());
+ xSecContexts.push_back(aSignatureManager.getGpgSecurityContext());
}
- ScopedVclPtrInstance< CertificateChooser > aChooser(nullptr, mxCtx, xSecEnvs);
+ ScopedVclPtrInstance< CertificateChooser > aChooser(nullptr, mxCtx, xSecContexts);
if (aChooser->Execute() != RET_OK)
return Reference< css::security::XCertificate >(nullptr);
diff --git a/xmlsecurity/source/dialogs/certificatechooser.cxx b/xmlsecurity/source/dialogs/certificatechooser.cxx
index 3cf2b5e5af86..726b4038aa96 100644
--- a/xmlsecurity/source/dialogs/certificatechooser.cxx
+++ b/xmlsecurity/source/dialogs/certificatechooser.cxx
@@ -36,7 +36,7 @@ using namespace css;
CertificateChooser::CertificateChooser(vcl::Window* _pParent,
uno::Reference<uno::XComponentContext>& _rxCtx,
- std::vector< css::uno::Reference< css::xml::crypto::XSecurityEnvironment > >& rxSecurityEnvironments)
+ std::vector< css::uno::Reference< css::xml::crypto::XXMLSecurityContext > >& rxSecurityContexts)
: ModalDialog(_pParent, "SelectCertificateDialog", "xmlsec/ui/selectcertificatedialog.ui"),
mvUserData()
{
@@ -61,7 +61,7 @@ CertificateChooser::CertificateChooser(vcl::Window* _pParent,
m_pViewBtn->SetClickHdl( LINK( this, CertificateChooser, ViewButtonHdl ) );
mxCtx = _rxCtx;
- mxSecurityEnvironments = rxSecurityEnvironments;
+ mxSecurityContexts = rxSecurityContexts;
mbInitialized = false;
// disable buttons
@@ -150,8 +150,9 @@ void CertificateChooser::ImplInitialize()
if ( mbInitialized )
return;
- for (auto &secEnvironment : mxSecurityEnvironments)
+ for (auto &secContext : mxSecurityContexts)
{
+ auto secEnvironment = secContext->getSecurityEnvironment();
if (!secEnvironment.is())
continue;
@@ -183,6 +184,7 @@ void CertificateChooser::ImplInitialize()
{
std::shared_ptr<UserData> userData = std::make_shared<UserData>();
userData->xCertificate = xCerts[ nC ];
+ userData->xSecurityContext = secContext;
userData->xSecurityEnvironment = secEnvironment;
mvUserData.push_back(userData);
SvTreeListEntry* pEntry = m_pCertLB->InsertEntry( XmlSec::GetContentPart( xCerts[ nC ]->getSubjectName() )
@@ -210,6 +212,17 @@ uno::Reference< css::security::XCertificate > CertificateChooser::GetSelectedCer
return xCert;
}
+uno::Reference<xml::crypto::XXMLSecurityContext> CertificateChooser::GetSelectedSecurityContext()
+{
+ SvTreeListEntry* pSel = m_pCertLB->FirstSelected();
+ if( !pSel )
+ return uno::Reference<xml::crypto::XXMLSecurityContext>();
+
+ UserData* userData = static_cast<UserData*>(pSel->GetUserData());
+ uno::Reference<xml::crypto::XXMLSecurityContext> xCert = userData->xSecurityContext;
+ return xCert;
+}
+
OUString CertificateChooser::GetDescription()
{
return m_pDescriptionED->GetText();
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index f691ab063157..a9fbe930b30d 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -32,6 +32,7 @@
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/security/CertificateValidity.hpp>
#include <com/sun/star/packages/WrongPasswordException.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
#include <com/sun/star/packages/manifest/ManifestReader.hpp>
@@ -386,15 +387,16 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
return;
try
{
- std::vector<uno::Reference<xml::crypto::XSecurityEnvironment>> xSecEnvs;
- xSecEnvs.push_back(maSignatureManager.getSecurityEnvironment());
- xSecEnvs.push_back(maSignatureManager.getGpgSecurityEnvironment());
+ std::vector<uno::Reference<xml::crypto::XXMLSecurityContext>> xSecContexts;
+ xSecContexts.push_back(maSignatureManager.getSecurityContext());
+ xSecContexts.push_back(maSignatureManager.getGpgSecurityContext());
- ScopedVclPtrInstance< CertificateChooser > aChooser( this, mxCtx, xSecEnvs );
+ ScopedVclPtrInstance< CertificateChooser > aChooser( this, mxCtx, xSecContexts );
if ( aChooser->Execute() == RET_OK )
{
sal_Int32 nSecurityId;
- if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
+ if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetSelectedSecurityContext(),
+ aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
return;
mbSignaturesChanged = true;
@@ -499,10 +501,6 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
{
m_pSignaturesLB->Clear();
- uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
-
- uno::Reference< css::security::XCertificate > xCert;
-
size_t nInfos = maSignatureManager.maCurrentSignatureInformations.size();
size_t nValidSigs = 0, nValidCerts = 0;
bool bAllNewSignatures = true;
@@ -518,26 +516,9 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
aElementsToBeVerified = DocumentSignatureHelper::CreateElementList(maSignatureManager.mxStore, maSignatureManager.meSignatureMode, mode);
const SignatureInformation& rInfo = maSignatureManager.maCurrentSignatureInformations[n];
- //First we try to get the certificate which is embedded in the XML Signature
- if (!rInfo.ouX509Certificate.isEmpty())
- xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
- else {
- //There must be an embedded certificate because we use it to get the
- //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
- //because it could be modified by an attacker. The issuer is displayed
- //in the digital signature dialog.
- //Comparing the X509IssuerName with the one from the X509Certificate in order
- //to find out if the X509IssuerName was modified does not work. See #i62684
- SAL_WARN( "xmlsecurity.dialogs", "Could not find embedded certificate!");
- }
-
- //In case there is no embedded certificate we try to get it from a local store
- //Todo: This probably could be removed, see above.
- if (!xCert.is())
- xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
-
- SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Certificate not found and can't be created!" );
+ uno::Reference< css::security::XCertificate > xCert = getCertificate(rInfo);
+ // TODO - should use pgpdata from info provider?
OUString aSubject;
OUString aIssuer;
OUString aDateTimeStr;
@@ -550,8 +531,8 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
{
//check the validity of the cert
try {
- sal_Int32 certResult = xSecEnv->verifyCertificate(xCert,
- Sequence<css::uno::Reference<css::security::XCertificate> >());
+ sal_Int32 certResult = getSecurityEnvironmentForCertificate(xCert)->verifyCertificate(xCert,
+ Sequence<uno::Reference<security::XCertificate> >());
bCertValid = certResult == css::security::CertificateValidity::VALID;
if ( bCertValid )
@@ -664,6 +645,46 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
SignatureHighlightHdl( nullptr );
}
+uno::Reference<security::XCertificate> DigitalSignaturesDialog::getCertificate(const SignatureInformation& rInfo)
+{
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
+ uno::Reference<xml::crypto::XSecurityEnvironment> xGpgSecEnv = maSignatureManager.getGpgSecurityEnvironment();
+ uno::Reference<security::XCertificate> xCert;
+
+ //First we try to get the certificate which is embedded in the XML Signature
+ if (!rInfo.ouX509Certificate.isEmpty())
+ xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
+ else {
+ //There must be an embedded certificate because we use it to get the
+ //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
+ //because it could be modified by an attacker. The issuer is displayed
+ //in the digital signature dialog.
+ //Comparing the X509IssuerName with the one from the X509Certificate in order
+ //to find out if the X509IssuerName was modified does not work. See #i62684
+ SAL_WARN( "xmlsecurity.dialogs", "Could not find embedded certificate!");
+ }
+
+ //In case there is no embedded certificate we try to get it from a local store
+ if (!xCert.is())
+ xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
+ if (!xCert.is())
+ xCert = xGpgSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
+
+ SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Certificate not found and can't be created!" );
+
+ return xCert;
+}
+
+uno::Reference<xml::crypto::XSecurityEnvironment> DigitalSignaturesDialog::getSecurityEnvironmentForCertificate(uno::Reference<security::XCertificate> xCert)
+{
+ if (xCert->getCertificateKind() == CertificateKind_OPENPGP)
+ return maSignatureManager.getGpgSecurityEnvironment();
+ else if (xCert->getCertificateKind() == CertificateKind_X509)
+ return maSignatureManager.getSecurityEnvironment();
+
+ throw RuntimeException("Unknown certificate kind");
+}
+
//If bUseTempStream is true then the temporary signature stream is used.
//Otherwise the real signature stream is used.
void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature)
@@ -678,19 +699,12 @@ void DigitalSignaturesDialog::ImplShowSignaturesDetails()
{
sal_uInt16 nSelected = (sal_uInt16) reinterpret_cast<sal_uIntPtr>( m_pSignaturesLB->FirstSelected()->GetUserData() );
const SignatureInformation& rInfo = maSignatureManager.maCurrentSignatureInformations[ nSelected ];
- uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
- // Use Certificate from doc, not from key store
- uno::Reference< css::security::XCertificate > xCert;
- if (!rInfo.ouX509Certificate.isEmpty())
- xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
- //fallback if no certificate is embedded, get if from store
- if (!xCert.is())
- xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
-
- SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Error getting Certificate!" );
+ uno::Reference<security::XCertificate> xCert = getCertificate(rInfo);
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = getSecurityEnvironmentForCertificate(xCert);
+
if ( xCert.is() )
{
- ScopedVclPtrInstance<CertificateViewer> aViewer(this, maSignatureManager.getSecurityEnvironment(), xCert, false);
+ ScopedVclPtrInstance<CertificateViewer> aViewer(this, xSecEnv, xCert, false);
aViewer->Execute();
}
}
diff --git a/xmlsecurity/source/gpg/CertificateImpl.cxx b/xmlsecurity/source/gpg/CertificateImpl.cxx
index a00b0336fee1..e40f59323a04 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -10,16 +10,21 @@
#include "CertificateImpl.hxx"
#include <comphelper/servicehelper.hxx>
+#include <comphelper/sequence.hxx>
#include <com/sun/star/security/KeyUsage.hpp>
+#include <gpgme.h>
+#include <context.h>
+#include <data.h>
+
using namespace css;
using namespace css::uno;
using namespace css::security;
using namespace css::util;
CertificateImpl::CertificateImpl() :
- m_pKey(nullptr)
+ m_pKey()
{
}
@@ -35,8 +40,10 @@ sal_Int16 SAL_CALL CertificateImpl::getVersion()
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSerialNumber()
{
- // Empty for gpg
- return Sequence< sal_Int8 > ();
+ // This is mapped to the fingerprint for gpg
+ const char* keyId = m_pKey.primaryFingerprint();
+ return comphelper::arrayToSequence<sal_Int8>(
+ keyId, strlen(keyId));
}
OUString SAL_CALL CertificateImpl::getIssuerName()
@@ -113,8 +120,8 @@ Reference< XCertificateExtension > SAL_CALL CertificateImpl::findCertificateExte
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getEncoded()
{
- // Empty for gpg
- return Sequence< sal_Int8 > ();
+ // Export key to base64Empty for gpg
+ return m_aBits;
}
OUString SAL_CALL CertificateImpl::getSubjectPublicKeyAlgorithm()
@@ -146,20 +153,31 @@ OUString SAL_CALL CertificateImpl::getSignatureAlgorithm()
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSHA1Thumbprint()
{
- // Empty for gpg
- return Sequence< sal_Int8 > ();
+ // This is mapped to the short keyID for gpg
+ const char* keyId = m_pKey.shortKeyID();
+ return comphelper::arrayToSequence<sal_Int8>(
+ keyId, strlen(keyId));
}
uno::Sequence<sal_Int8> CertificateImpl::getSHA256Thumbprint()
{
- // Empty for gpg
- return Sequence< sal_Int8 > ();
+ // This is mapped to the long keyID for gpg
+ const char* keyId = m_pKey.keyID();
+ return comphelper::arrayToSequence<sal_Int8>(
+ keyId, strlen(keyId));
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
{
- // Empty for gpg
- return Sequence< sal_Int8 > ();
+ // This is mapped to the short keyID for gpg
+ const char* keyId = m_pKey.shortKeyID();
+ return comphelper::arrayToSequence<sal_Int8>(
+ keyId, strlen(keyId));
+}
+
+CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
+{
+ return CertificateKind_OPENPGP;
}
sal_Int32 SAL_CALL CertificateImpl::getCertificateUsage()
@@ -187,9 +205,24 @@ const Sequence< sal_Int8>& CertificateImpl::getUnoTunnelId() {
return CertificateImplUnoTunnelId::get().getSeq();
}
-void CertificateImpl::setCertificate(GpgME::Key key)
+void CertificateImpl::setCertificate(GpgME::Context* ctx, const GpgME::Key& key)
{
m_pKey = key;
+
+ // extract key data, store into m_aBits
+ GpgME::Data data_out;
+ ctx->exportPublicKeys(key.keyID(), data_out);
+
+ assert(data_out.seek(0,SEEK_SET) == 0);
+ int len=0, curr=0; char buf;
+ while( (curr=data_out.read(&buf, 1)) )
+ len += curr;
+
+ // write bits to sequence of bytes
+ m_aBits.realloc(len);
+ assert(data_out.seek(0,SEEK_SET) == 0);
+ if( data_out.read(m_aBits.getArray(), len) != len )
+ throw RuntimeException("The GpgME library failed to read the key");
}
const GpgME::Key* CertificateImpl::getCertificate() const
diff --git a/xmlsecurity/source/gpg/CertificateImpl.hxx b/xmlsecurity/source/gpg/CertificateImpl.hxx
index cf9ab06c181f..9db3ab85de14 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.hxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.hxx
@@ -23,6 +23,7 @@
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/uno/SecurityException.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
#include <com/sun/star/security/XCertificate.hpp>
#include <key.h>
@@ -33,6 +34,7 @@ class CertificateImpl : public cppu::WeakImplHelper< css::security::XCertificate
{
private:
GpgME::Key m_pKey;
+ css::uno::Sequence< sal_Int8 > m_aBits;
public:
CertificateImpl();
@@ -77,9 +79,10 @@ public:
/// @see xmlsecurity::Certificate::getSHA256Thumbprint().
virtual css::uno::Sequence<sal_Int8> getSHA256Thumbprint() override;
+ virtual css::security::CertificateKind getCertificateKind() override;
// Helper methods
- void setCertificate(GpgME::Key key);
+ void setCertificate(GpgME::Context* ctx, const GpgME::Key& key);
const GpgME::Key* getCertificate() const;
} ;
diff --git a/xmlsecurity/source/gpg/SEInitializer.cxx b/xmlsecurity/source/gpg/SEInitializer.cxx
index af02de9d7ece..919161d86554 100644
--- a/xmlsecurity/source/gpg/SEInitializer.cxx
+++ b/xmlsecurity/source/gpg/SEInitializer.cxx
@@ -11,6 +11,8 @@
#include "SecurityEnvironment.hxx"
#include "XMLSecurityContext.hxx"
+#include <gpgme.h>
+#include <context.h>
using namespace css;
using namespace css::lang;
@@ -18,9 +20,10 @@ using namespace css::uno;
using namespace css::xml::crypto;
-SEInitializerGpg::SEInitializerGpg( const css::uno::Reference< css::uno::XComponentContext > &rxContext )
+SEInitializerGpg::SEInitializerGpg()
{
- m_xContext = rxContext;
+ // Also init GpgME while we're at it
+ GpgME::initializeLibrary();
}
SEInitializerGpg::~SEInitializerGpg()
diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.cxx b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
index 323e267af6b0..2b8a2d567afd 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.cxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
@@ -14,8 +14,6 @@
#include <comphelper/servicehelper.hxx>
#include <list>
-#include <gpgme.h>
-#include <context.h>
#include <key.h>
#include <keylistresult.h>
@@ -26,6 +24,13 @@ using namespace css::lang;
SecurityEnvironmentGpg::SecurityEnvironmentGpg()
{
+ GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
+ if (err)
+ throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
+
+ m_ctx.reset( GpgME::Context::createForProtocol(GpgME::OpenPGP) );
+ if (m_ctx == nullptr)
+ throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
}
SecurityEnvironmentGpg::~SecurityEnvironmentGpg()
@@ -59,31 +64,22 @@ OUString SecurityEnvironmentGpg::getSecurityEnvironmentInformation()
Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertificates()
{
- GpgME::initializeLibrary();
- GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
- if (err)
- throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
- GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
- if (ctx == nullptr)
- throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
CertificateImpl* xCert;
std::list< CertificateImpl* > certsList;
- ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
- err = ctx->startKeyListing("", true);
+ m_ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
+ GpgME::Error err = m_ctx->startKeyListing("", true);
while (!err) {
- GpgME::Key k = ctx->nextKey(err);
+ GpgME::Key k = m_ctx->nextKey(err);
if (err)
break;
if (!k.isInvalid()) {
xCert = new CertificateImpl();
- xCert->setCertificate(k);
+ xCert->setCertificate(m_ctx.get(),k);
certsList.push_back(xCert);
}
}
- ctx->endKeyListing();
+ m_ctx->endKeyListing();
Sequence< Reference< XCertificate > > xCertificateSequence(certsList.size());
std::list< CertificateImpl* >::iterator xcertIt;
@@ -94,8 +90,27 @@ Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertif
return xCertificateSequence;
}
-Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString& /*issuerName*/, const Sequence< sal_Int8 >& /*serialNumber*/ )
+Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& /*serialNumber*/ )
{
+ CertificateImpl* xCert=nullptr;
+ std::list< CertificateImpl* > certsList;
+
+ m_ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
+ OString ostr = OUStringToOString( issuerName , RTL_TEXTENCODING_UTF8 );
+ GpgME::Error err = m_ctx->startKeyListing(ostr.getStr(), true);
+ while (!err) {
+ GpgME::Key k = m_ctx->nextKey(err);
+ if (err)
+ break;
+ if (!k.isInvalid()) {
+ xCert = new CertificateImpl();
+ xCert->setCertificate(m_ctx.get(), k);
+ m_ctx->endKeyListing();
+ return xCert;
+ }
+ }
+ m_ctx->endKeyListing();
+
return nullptr;
}
diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.hxx b/xmlsecurity/source/gpg/SecurityEnvironment.hxx
index 51a263fa5e5d..66d79bb8643e 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.hxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.hxx
@@ -24,10 +24,14 @@
#include <com/sun/star/security/CertificateValidity.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <gpgme.h>
+#include <context.h>
class SecurityEnvironmentGpg : public cppu::WeakImplHelper< css::xml::crypto::XSecurityEnvironment,
css::lang::XUnoTunnel >
{
+ std::unique_ptr<GpgME::Context> m_ctx;
+
public:
SecurityEnvironmentGpg();
virtual ~SecurityEnvironmentGpg() override;
@@ -61,6 +65,7 @@ public:
virtual css::uno::Reference< css::security::XCertificate > SAL_CALL createCertificateFromAscii(
const OUString& asciiCertificate ) override;
+ GpgME::Context& getGpgContext() { return *m_ctx.get(); }
} ;
#endif // INCLUDED_XMLSECURITY_SOURCE_GPG_SECURITYENVIRONMENT_HXX
diff --git a/xmlsecurity/source/gpg/XMLSecurityContext.cxx b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
index a05ea7e40c55..0919f4dbc2b6 100644
--- a/xmlsecurity/source/gpg/XMLSecurityContext.cxx
+++ b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
@@ -10,6 +10,11 @@
#include "XMLSecurityContext.hxx"
#include "SecurityEnvironment.hxx"
+#include <cppuhelper/supportsservice.hxx>
+
+#include "xmlsec/xmlstreamio.hxx"
+#include "xmlsec-wrapper.h"
+
using namespace css::uno;
using namespace css::lang;
using namespace css::xml::crypto;
@@ -65,4 +70,19 @@ void SAL_CALL XMLSecurityContextGpg::setDefaultSecurityEnvironmentIndex(sal_Int3
m_nDefaultEnvIndex = nDefaultEnvIndex;
}
+/* XServiceInfo */
+OUString SAL_CALL XMLSecurityContextGpg::getImplementationName() {
+ return OUString("com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl");
+}
+
+/* XServiceInfo */
+sal_Bool SAL_CALL XMLSecurityContextGpg::supportsService( const OUString& serviceName) {
+ return cppu::supportsService(this, serviceName);
+}
+
+/* XServiceInfo */
+Sequence< OUString > SAL_CALL XMLSecurityContextGpg::getSupportedServiceNames() {
+ return { OUString("com.sun.star.xml.crypto.XMLSecurityContext") };
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/gpg/XMLSecurityContext.hxx b/xmlsecurity/source/gpg/XMLSecurityContext.hxx
index 3402d33aa9cd..4355cc0ce67a 100644
--- a/xmlsecurity/source/gpg/XMLSecurityContext.hxx
+++ b/xmlsecurity/source/gpg/XMLSecurityContext.hxx
@@ -26,7 +26,8 @@
#include <vector>
-class XMLSecurityContextGpg : public cppu::WeakImplHelper< css::xml::crypto::XXMLSecurityContext >
+class XMLSecurityContextGpg : public cppu::WeakImplHelper< css::xml::crypto::XXMLSecurityContext,
+ css::lang::XServiceInfo>
{
private:
std::vector< css::uno::Reference< css::xml::crypto::XSecurityEnvironment > > m_vSecurityEnvironments;
@@ -50,6 +51,13 @@ public:
virtual sal_Int32 SAL_CALL getDefaultSecurityEnvironmentIndex() override;
virtual void SAL_CALL setDefaultSecurityEnvironmentIndex( sal_Int32 nDefaultEnvIndex ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override ;
+
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override ;
+
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override ;
} ;
#endif // INCLUDED_XMLSECURITY_SOURCE_GPG_XMLSECURITYCONTEXT_HXX
diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
index 4f4ff7956750..40248ee3a9e8 100644
--- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
+++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
@@ -19,7 +19,7 @@
#include <sal/config.h>
#include <rtl/uuid.h>
-#include "xmlsignature_gpgimpl.hxx"
+#include "gpg/xmlsignature_gpgimpl.hxx"
#include <gpgme.h>
#include <context.h>
@@ -98,8 +98,6 @@ SAL_CALL XMLSignature_GpgImpl::generate(
if( pSecEnv == nullptr )
throw RuntimeException() ;
- // TODO figure out key from pSecEnv!
- // unclear how/where that is transported in nss impl...
setErrorRecorder();
//Create Signature context
@@ -110,6 +108,13 @@ SAL_CALL XMLSignature_GpgImpl::generate(
return aTemplate;
}
+ // set intended operation to sign - several asserts inside libxmlsec
+ // wanting that for digest / transforms
+ pDsigCtx->operation = xmlSecTransformOperationSign;
+
+ // we default to SHA512 for all digests - nss crypto does not have it...
+ //pDsigCtx->defDigestMethodId = xmlSecTransformSha512Id;
+
// Calculate digest for all references
xmlNodePtr cur = xmlSecGetNextElementNode(pNode->children);
if( cur != nullptr )
@@ -151,27 +156,42 @@ SAL_CALL XMLSignature_GpgImpl::generate(
// get me a digestible buffer from the signature template!
// -------------------------------------------------------
- // run the transformations
+ // run the transformations over SignedInfo element (first child of
+ // pNode)
xmlSecNodeSetPtr nodeset = nullptr;
- nodeset = xmlSecNodeSetGetChildren(pNode->doc, pNode, 1, 0);
+ cur = xmlSecGetNextElementNode(pNode->children);
+ // TODO assert that...
+ nodeset = xmlSecNodeSetGetChildren(pNode->doc, cur, 1, 0);
if(nodeset == nullptr)
throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
if( xmlSecTransformCtxXmlExecute(&(pDsigCtx->transformCtx), nodeset) < 0 )
throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
- //Sign the template via gpgme
- GpgME::initializeLibrary();
- if( GpgME::checkEngine(GpgME::OpenPGP) )
+ // now extract the keyid from PGPData
+ // walk xml tree to PGPData node - go to children, first is
+ // SignedInfo, 2nd is signaturevalue, 3rd is KeyInfo
+ // 1st child is PGPData, 1st grandchild is PGPKeyID
+ cur = xmlSecGetNextElementNode(pNode->children);
+ // TODO error handling
+ cur = xmlSecGetNextElementNode(cur->next);
+ cur = xmlSecGetNextElementNode(cur->next);
+ cur = xmlSecGetNextElementNode(cur->children);
+ // check that this is now PGPData
+ if(!xmlSecCheckNodeName(cur, xmlSecNamePGPData, xmlSecDSigNs))
throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
- GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
- if( ctx == nullptr )
+ // check that this is now PGPKeyID
+ cur = xmlSecGetNextElementNode(cur->children);
+ static const xmlChar xmlSecNodePGPKeyID[] = "PGPKeyID";
+ if(!xmlSecCheckNodeName(cur, xmlSecNodePGPKeyID, xmlSecDSigNs))
throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
- ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
+ GpgME::Context& rCtx=pSecEnv->getGpgContext();
+ rCtx.setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
GpgME::Error err;
- if( ctx->addSigningKey(ctx->key("0x909BE2575CEDBEA3", err, true)) )
+ if( rCtx.addSigningKey(
+ rCtx.key(
+ reinterpret_cast<char*>(xmlNodeGetContent(cur)), err, true)) )
throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
// good, ctx is setup now, let's sign the lot
@@ -180,17 +200,18 @@ SAL_CALL XMLSignature_GpgImpl::generate(
xmlSecBufferGetSize(pDsigCtx->transformCtx.result), false);
GpgME::Data data_out;
- GpgME::SigningResult sign_res=ctx->sign(data_in, data_out,
- GpgME::Clearsigned);
- // TODO: needs some error handling
- data_out.seek(0,SEEK_SET);
+ SAL_INFO("xmlsecurity.xmlsec.gpg", "Generating signature for: " << xmlSecBufferGetData(pDsigCtx->transformCtx.result));
+
+ GpgME::SigningResult sign_res=rCtx.sign(data_in, data_out,
+ GpgME::Detached);
+ assert(data_out.seek(0,SEEK_SET) == 0);
int len=0, curr=0; char buf;
while( (curr=data_out.read(&buf, 1)) )
len += curr;
// write signed data to xml
std::vector<unsigned char> buf2(len);
- data_out.seek(0,SEEK_SET);
+ assert(data_out.seek(0,SEEK_SET) == 0);
if( data_out.read(&buf2[0], len) != len )
throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
@@ -199,8 +220,11 @@ SAL_CALL XMLSignature_GpgImpl::generate(
cur = xmlSecGetNextElementNode(pNode->children);
cur = xmlSecGetNextElementNode(cur->next);
+ // TODO some assert would be good...
xmlNodeSetContentLen(cur, &buf2[0], len);
+ aTemplate->setStatus(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
+
// done
xmlSecDSigCtxDestroy( pDsigCtx ) ;
@@ -218,11 +242,8 @@ SAL_CALL XMLSignature_GpgImpl::validate(
const Reference< XXMLSignatureTemplate >& aTemplate ,
const Reference< XXMLSecurityContext >& aSecurityCtx
) {
- xmlSecKeysMngrPtr pMngr = nullptr ;
xmlSecDSigCtxPtr pDsigCtx = nullptr ;
xmlNodePtr pNode = nullptr ;
- //sal_Bool valid ;
- (void)pMngr; (void)pDsigCtx; (void)pNode;
if( !aTemplate.is() )
throw RuntimeException() ;
@@ -259,72 +280,130 @@ SAL_CALL XMLSignature_GpgImpl::validate(
{
Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
- //Get Keys Manager
- Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY_THROW ) ;
-#if 0
- SecurityEnvironment_NssImpl* pSecEnv =
- reinterpret_cast<SecurityEnvironment_NssImpl*>(
- sal::static_int_cast<sal_uIntPtr>(
- xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() )));
+ SecurityEnvironmentGpg* pSecEnv =
+ dynamic_cast<SecurityEnvironmentGpg*>(aEnvironment.get());
if( pSecEnv == nullptr )
throw RuntimeException() ;
- pMngr = pSecEnv->createKeysManager();
- if( !pMngr ) {
- throw RuntimeException() ;
- }
+ // TODO figure out key from pSecEnv!
+ // unclear how/where that is transported in nss impl...
//Create Signature context
- pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
+ pDsigCtx = xmlSecDSigCtxCreate( nullptr ) ;
if( pDsigCtx == nullptr )
{
- SecurityEnvironment_NssImpl::destroyKeysManager( pMngr );
- //throw XMLSignatureException() ;
clearErrorRecorder();
return aTemplate;
}
- //Verify signature
- int rs = xmlSecDSigCtxVerify( pDsigCtx , pNode );
+ // set intended operation to verify - several asserts inside libxmlsec
+ // wanting that for digest / transforms
+ pDsigCtx->operation = xmlSecTransformOperationVerify;
- // Also verify manifest: this is empty for ODF, but contains everything (except signature metadata) for OOXML.
- xmlSecSize nReferenceCount = xmlSecPtrListGetSize(&pDsigCtx->manifestReferences);
- // Require that all manifest references are also good.
- xmlSecSize nReferenceGood = 0;
- for (xmlSecSize nReference = 0; nReference < nReferenceCount; ++nReference)
- {
- xmlSecDSigReferenceCtxPtr pReference = static_cast<xmlSecDSigReferenceCtxPtr>(xmlSecPtrListGetItem(&pDsigCtx->manifestReferences, nReference));
- if (pReference)
- {
- if (pReference->status == xmlSecDSigStatusSucceeded)
- ++nReferenceGood;
- }
- }
+ // reset status - to be set later
+ pDsigCtx->status = xmlSecDSigStatusUnknown;
+
+ // get me a digestible buffer from the SignatureInfo node!
+ // -------------------------------------------------------
+
+ // run the transformations - first child node is required to
+ // be SignatureInfo
+ xmlSecNodeSetPtr nodeset = nullptr;
+ xmlNodePtr cur = xmlSecGetNextElementNode(pNode->children);
+ // TODO assert that...
+ nodeset = xmlSecNodeSetGetChildren(pNode->doc, cur, 1, 0);
+ if(nodeset == nullptr)
+ throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
+
+ // TODO assert we really have the SignatureInfo here?
+ if( xmlSecTransformCtxXmlExecute(&(pDsigCtx->transformCtx), nodeset) < 0 )
+ throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
- if (rs == 0 && pDsigCtx->status == xmlSecDSigStatusSucceeded && nReferenceCount == nReferenceGood)
+ // Validate the template via gpgme
+ GpgME::Context& rCtx=pSecEnv->getGpgContext();
+
+ GpgME::Data data_text(
+ reinterpret_cast<char*>(xmlSecBufferGetData(pDsigCtx->transformCtx.result)),
+ xmlSecBufferGetSize(pDsigCtx->transformCtx.result), false);
+
+ SAL_INFO("xmlsecurity.xmlsec.gpg", "Validating SignatureInfo: " << xmlSecBufferGetData(pDsigCtx->transformCtx.result));
+
+ // walk xml tree to sign value node - go to children, first is
+ // SignedInfo, 2nd is signaturevalue
+ cur = xmlSecGetNextElementNode(pNode->children);
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ // TODO some assert would be good that cur is actually SignatureValue
+ xmlChar* pSignatureValue=xmlNodeGetContent(cur);
+ GpgME::Data data_signature(
+ reinterpret_cast<char*>(pSignatureValue),
+ xmlStrlen(pSignatureValue), false);
+
+ GpgME::VerificationResult verify_res=rCtx.verifyDetachedSignature(
+ data_signature, data_text);
+
+ xmlFree(pSignatureValue);
+
+ // TODO: needs some more error handling, needs checking _all_ signatures
+ if( verify_res.isNull() ||
+ verify_res.numSignatures() == 0 ||
+ verify_res.signature(0).validity() < GpgME::Signature::Full )
{
- aTemplate->setStatus(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
- xmlSecDSigCtxDestroy( pDsigCtx ) ;
- SecurityEnvironment_NssImpl::destroyKeysManager( pMngr );
- break;
+ clearErrorRecorder();
+ return aTemplate;
}
- else
+
+ // now verify digest for all references
+ cur = xmlSecGetNextElementNode(pNode->children);
+ if( cur != nullptr )
+ cur = xmlSecGetNextElementNode(cur->children);
+ while( cur != nullptr )
{
- aTemplate->setStatus(css::xml::crypto::SecurityOperationStatus_UNKNOWN);
+ // some of those children I suppose should be reference elements
+ if( xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs) )
+ {
+ xmlSecDSigReferenceCtxPtr pDsigRefCtx =
+ xmlSecDSigReferenceCtxCreate(pDsigCtx,
+ xmlSecDSigReferenceOriginSignedInfo);
+ if(pDsigRefCtx == nullptr)
+ throw RuntimeException();
+
+ // add this one to the list
+ if( xmlSecPtrListAdd(&(pDsigCtx->signedInfoReferences),
+ pDsigRefCtx) < 0 )
+ {
+ // TODO resource handling
+ xmlSecDSigReferenceCtxDestroy(pDsigRefCtx);
+ throw RuntimeException();
+ }
+
+ if( xmlSecDSigReferenceCtxProcessNode(pDsigRefCtx, cur) < 0 )
+ throw RuntimeException();
+
+ // final check - all good?
+ if(pDsigRefCtx->status != xmlSecDSigStatusSucceeded)
+ {
+ pDsigCtx->status = xmlSecDSigStatusInvalid;
+ return aTemplate; // TODO - harder error?
+ }
+ }
+
+ cur = xmlSecGetNextElementNode(cur->next);
}
+
+ // TODO - also verify manifest (only relevant for ooxml)?
+ aTemplate->setStatus(css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED);
+
+ // done
xmlSecDSigCtxDestroy( pDsigCtx ) ;
- SecurityEnvironment_NssImpl::destroyKeysManager( pMngr );
-#endif
}
-
//Unregistered the stream/URI binding
if( xUriBinding.is() )
xmlUnregisterStreamInputCallbacks() ;
- //return valid ;
clearErrorRecorder();
- return aTemplate;
+ return aTemplate ;
}
/* XServiceInfo */
diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx
index 96f78aaa6c80..1d8d1c0d72cb 100644
--- a/xmlsecurity/source/helper/documentsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx
@@ -554,7 +554,8 @@ void DocumentSignatureHelper::writeSignedProperties(
writeDigestMethod(xDocumentHandler);
xDocumentHandler->startElement("DigestValue", uno::Reference<xml::sax::XAttributeList>(new SvXMLAttributeList()));
- assert(!signatureInfo.ouCertDigest.isEmpty());
+ // TODO: this is empty for gpg signatures currently
+ //assert(!signatureInfo.ouCertDigest.isEmpty());
xDocumentHandler->characters(signatureInfo.ouCertDigest);
xDocumentHandler->endElement("DigestValue");
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index f2a155b4db8d..ded3de8d9960 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -26,6 +26,7 @@
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
#include <comphelper/storagehelper.hxx>
#include <rtl/ustrbuf.hxx>
@@ -37,7 +38,10 @@
#include <certificate.hxx>
#include <biginteger.hxx>
+#include <xmlsec/xmlsec_init.hxx>
+
using namespace css;
+namespace cssu = com::sun::star::uno;
DocumentSignatureManager::DocumentSignatureManager(const uno::Reference<uno::XComponentContext>& xContext, DocumentSignatureMode eMode)
: mxContext(xContext),
@@ -46,7 +50,10 @@ DocumentSignatureManager::DocumentSignatureManager(const uno::Reference<uno::XCo
{
}
-DocumentSignatureManager::~DocumentSignatureManager() = default;
+DocumentSignatureManager::~DocumentSignatureManager()
+{
+ deInitXmlSec();
+}
bool DocumentSignatureManager::init()
{
@@ -54,9 +61,12 @@ bool DocumentSignatureManager::init()
SAL_WARN_IF(mxSecurityContext.is(), "xmlsecurity.helper", "DocumentSignatureManager::Init - mxSecurityContext already set!");
SAL_WARN_IF(mxGpgSEInitializer.is(), "xmlsecurity.helper", "DocumentSignatureManager::Init - mxGpgSEInitializer already set!");
+ // xmlsec is needed by both services, so init before those
+ initXmlSec();
+
mxSEInitializer = xml::crypto::SEInitializer::create(mxContext);
#if !defined(MACOSX) && !defined(WNT)
- mxGpgSEInitializer.set(new SEInitializerGpg(mxContext));
+ mxGpgSEInitializer.set(new SEInitializerGpg());
#endif
if (mxSEInitializer.is())
@@ -243,7 +253,11 @@ SignatureStreamHelper DocumentSignatureManager::ImplOpenSignatureStream(sal_Int3
return aHelper;
}
-bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant)
+bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>& xCert,
+ const uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext,
+ const OUString& rDescription,
+ sal_Int32& nSecurityId,
+ bool bAdESCompliant)
{
if (!xCert.is())
{
@@ -251,57 +265,94 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>&
return false;
}
- OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber());
- if (aCertSerial.isEmpty())
- {
- SAL_WARN("xmlsecurity.helper", "Error in Certificate, problem with serial number!");
- return false;
- }
-
- if (!mxStore.is())
+ // GPG or X509 key?
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xSecurityContext, cssu::UNO_QUERY );
+ if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
{
- // Something not ZIP based, try PDF.
- nSecurityId = getPDFSignatureHelper().GetNewSecurityId();
- getPDFSignatureHelper().SetX509Certificate(xCert);
- getPDFSignatureHelper().SetDescription(rDescription);
- uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
- if (!getPDFSignatureHelper().Sign(xInputStream, bAdESCompliant))
+ // GPG keys only really have PGPKeyId and PGPKeyPacket
+ // TODO: prevent selection of gpg keys for pdfs and ooxml early on!
+ if (!mxStore.is())
{
- SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
+ SAL_WARN("xmlsecurity.helper", "cannot sign pdfs with GPG keys");
return false;
}
- return true;
- }
- maSignatureHelper.StartMission(mxSecurityContext);
+ maSignatureHelper.StartMission(xSecurityContext);
- nSecurityId = maSignatureHelper.GetNewSecurityId();
+ nSecurityId = maSignatureHelper.GetNewSecurityId();
- OUStringBuffer aStrBuffer;
- sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
+ OUStringBuffer aStrBuffer;
+ sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
- OUString aCertDigest;
- if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
- {
- OUStringBuffer aBuffer;
- sax::Converter::encodeBase64(aBuffer, pCertificate->getSHA256Thumbprint());
- aCertDigest = aBuffer.makeStringAndClear();
+ OUString aKeyId;
+ if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
+ {
+ OUStringBuffer aBuffer;
+ sax::Converter::encodeBase64(aBuffer, pCertificate->getSHA256Thumbprint());
+ aKeyId = aBuffer.makeStringAndClear();
+ }
+ else
+ SAL_WARN("xmlsecurity.helper", "XCertificate implementation without an xmlsecurity::Certificate one");
+
+ maSignatureHelper.SetGpgCertificate(nSecurityId, aKeyId, aStrBuffer.makeStringAndClear());
}
else
- SAL_WARN("xmlsecurity.helper", "XCertificate implementation without an xmlsecurity::Certificate one");
+ {
+ OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber());
+ if (aCertSerial.isEmpty())
+ {
+ SAL_WARN("xmlsecurity.helper", "Error in Certificate, problem with serial number!");
+ return false;
+ }
- maSignatureHelper.SetX509Certificate(nSecurityId, xCert->getIssuerName(), aCertSerial, aStrBuffer.makeStringAndClear(), aCertDigest);
+ if (!mxStore.is())
+ {
+ // Something not ZIP based, try PDF.
+ nSecurityId = getPDFSignatureHelper().GetNewSecurityId();
+ getPDFSignatureHelper().SetX509Certificate(xCert);
+ getPDFSignatureHelper().SetDescription(rDescription);
+ uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
+ if (!getPDFSignatureHelper().Sign(xInputStream, bAdESCompliant))
+ {
+ SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
+ return false;
+ }
+ return true;
+ }
+
+ maSignatureHelper.StartMission(xSecurityContext);
+
+ nSecurityId = maSignatureHelper.GetNewSecurityId();
+
+ OUStringBuffer aStrBuffer;
+ sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
+
+ OUString aCertDigest;
+ if (auto pCertificate = dynamic_cast<xmlsecurity::Certificate*>(xCert.get()))
+ {
+ OUStringBuffer aBuffer;
+ sax::Converter::encodeBase64(aBuffer, pCertificate->getSHA256Thumbprint());
+ aCertDigest = aBuffer.makeStringAndClear();
+ }
+ else
+ SAL_WARN("xmlsecurity.helper", "XCertificate implementation without an xmlsecurity::Certificate one");
+
+ maSignatureHelper.SetX509Certificate(nSecurityId, xCert->getIssuerName(), aCertSerial, aStrBuffer.makeStringAndClear(), aCertDigest);
- uno::Sequence< uno::Reference< security::XCertificate > > aCertPath = getSecurityEnvironment()->buildCertificatePath(xCert);
+ }
+
+ uno::Sequence< uno::Reference< security::XCertificate > > aCertPath = xSecurityContext->getSecurityEnvironment()->buildCertificatePath(xCert);
const uno::Reference< security::XCertificate >* pCertPath = aCertPath.getConstArray();
sal_Int32 nCnt = aCertPath.getLength();
+ OUStringBuffer aStrBuffer;
for (int i = 0; i < nCnt; i++)
{
sax::Converter::encodeBase64(aStrBuffer, pCertPath[i]->getEncoded());
maSignatureHelper.AddEncapsulatedX509Certificate(aStrBuffer.makeStringAndClear());
}
+
std::vector< OUString > aElements = DocumentSignatureHelper::CreateElementList(mxStore, meSignatureMode, DocumentSignatureAlgorithm::OOo3_2);
DocumentSignatureHelper::AppendContentTypes(mxStore, aElements);
@@ -521,4 +572,15 @@ uno::Reference<xml::crypto::XSecurityEnvironment> DocumentSignatureManager::getG
return mxGpgSecurityContext.is() ? mxGpgSecurityContext->getSecurityEnvironment() : uno::Reference<xml::crypto::XSecurityEnvironment>();
}
+uno::Reference<xml::crypto::XXMLSecurityContext> DocumentSignatureManager::getSecurityContext()
+{
+ return mxSecurityContext;
+}
+
+uno::Reference<xml::crypto::XXMLSecurityContext> DocumentSignatureManager::getGpgSecurityContext()
+{
+ return mxGpgSecurityContext;
+}
+
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index df8af13653b2..6242518ce4e1 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -123,6 +123,16 @@ void XMLSignatureHelper::AddEncapsulatedX509Certificate(const OUString& ouEncaps
mpXSecController->addEncapsulatedX509Certificate(ouEncapsulatedX509Certificate);
}
+void XMLSignatureHelper::SetGpgCertificate(sal_Int32 nSecurityId,
+ const OUString& ouGpgCertDigest,
+ const OUString& ouGpgCert)
+{
+ mpXSecController->setGpgCertificate(
+ nSecurityId,
+ ouGpgCertDigest,
+ ouGpgCert);
+}
+
void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const ::Date& rDate, const tools::Time& rTime )
{
css::util::DateTime stDateTime = ::DateTime(rDate, rTime).GetUNODateTime();
diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx
index e28f8bd8f901..ffadd0584692 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -22,6 +22,9 @@
#include "documentsignaturehelper.hxx"
#include "framework/saxeventkeeperimpl.hxx"
#include "xmlsec/xmldocumentwrapper_xmlsecimpl.hxx"
+#if !defined(MACOSX) && !defined(WNT)
+# include "gpg/xmlsignature_gpgimpl.hxx"
+#endif
#include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
@@ -124,9 +127,13 @@ void XSecController::createXSecComponent( )
cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
- m_xXMLSignature.set(
- xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx ),
- cssu::UNO_QUERY );
+#if !defined(MACOSX) && !defined(WNT)
+ uno::Reference< lang::XServiceInfo > xServiceInfo( m_xSecurityContext, cssu::UNO_QUERY );
+ if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
+ m_xXMLSignature.set(new XMLSignature_GpgImpl());
+ else // xmlsec or mscrypt
+#endif
+ m_xXMLSignature.set(xMCF->createInstanceWithContext("com.sun.star.xml.crypto.XMLSignature", mxCtx), cssu::UNO_QUERY);
bool bSuccess = m_xXMLSignature.is();
if ( bSuccess )
@@ -716,43 +723,73 @@ void XSecController::exportSignature(
"KeyInfo",
cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
{
- /* Write X509Data element */
- xDocumentHandler->startElement(
- "X509Data",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ // GPG or X509 key?
+ if (!signatureInfo.ouGpgCertificate.isEmpty())
{
- /* Write X509IssuerSerial element */
+ /* Write PGPData element */
xDocumentHandler->startElement(
- "X509IssuerSerial",
+ "PGPData",
cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
{
- /* Write X509IssuerName element */
+ /* Write keyid element */
xDocumentHandler->startElement(
- "X509IssuerName",
+ "PGPKeyID",
cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouX509IssuerName );
- xDocumentHandler->endElement( "X509IssuerName" );
+ xDocumentHandler->characters( signatureInfo.ouCertDigest );
+ xDocumentHandler->endElement( "PGPKeyID" );
- /* Write X509SerialNumber element */
- xDocumentHandler->startElement(
- "X509SerialNumber",
- cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouX509SerialNumber );
- xDocumentHandler->endElement( "X509SerialNumber" );
+ /* Write PGPKeyPacket element */
+ if (!signatureInfo.ouGpgCertificate.isEmpty())
+ {
+ xDocumentHandler->startElement(
+ "PGPKeyPacket",
+ cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters( signatureInfo.ouGpgCertificate );
+ xDocumentHandler->endElement( "PGPKeyPacket" );
+ }
}
- xDocumentHandler->endElement( "X509IssuerSerial" );
-
- /* Write X509Certificate element */
- if (!signatureInfo.ouX509Certificate.isEmpty())
+ xDocumentHandler->endElement( "PGPData" );
+ }
+ else
+ {
+ /* Write X509Data element */
+ xDocumentHandler->startElement(
+ "X509Data",
+ cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
{
+ /* Write X509IssuerSerial element */
xDocumentHandler->startElement(
- "X509Certificate",
+ "X509IssuerSerial",
cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
- xDocumentHandler->characters( signatureInfo.ouX509Certificate );
- xDocumentHandler->endElement( "X509Certificate" );
+ {
+ /* Write X509IssuerName element */
+ xDocumentHandler->startElement(
+ "X509IssuerName",
+ cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters( signatureInfo.ouX509IssuerName );
+ xDocumentHandler->endElement( "X509IssuerName" );
+
+ /* Write X509SerialNumber element */
+ xDocumentHandler->startElement(
+ "X509SerialNumber",
+ cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters( signatureInfo.ouX509SerialNumber );
+ xDocumentHandler->endElement( "X509SerialNumber" );
+ }
+ xDocumentHandler->endElement( "X509IssuerSerial" );
+
+ /* Write X509Certificate element */
+ if (!signatureInfo.ouX509Certificate.isEmpty())
+ {
+ xDocumentHandler->startElement(
+ "X509Certificate",
+ cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
+ xDocumentHandler->characters( signatureInfo.ouX509Certificate );
+ xDocumentHandler->endElement( "X509Certificate" );
+ }
}
+ xDocumentHandler->endElement( "X509Data" );
}
- xDocumentHandler->endElement( "X509Data" );
}
xDocumentHandler->endElement( "KeyInfo" );
diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx
index 6e6bfc45c426..6c402e73e0cb 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -35,6 +35,8 @@ XSecParser::XSecParser(XMLSignatureHelper& rXMLSignatureHelper,
: m_bInX509IssuerName(false)
, m_bInX509SerialNumber(false)
, m_bInX509Certificate(false)
+ , m_bInGpgCertificate(false)
+ , m_bInGpgKeyID(false)
, m_bInCertDigest(false)
, m_bInEncapsulatedX509Certificate(false)
, m_bInSigningTime(false)
@@ -70,6 +72,8 @@ void SAL_CALL XSecParser::startDocument( )
m_bInX509IssuerName = false;
m_bInX509SerialNumber = false;
m_bInX509Certificate = false;
+ m_bInGpgCertificate = false;
+ m_bInGpgKeyID = false;
m_bInSignatureValue = false;
m_bInDigestValue = false;
m_bInDate = false;
@@ -176,6 +180,20 @@ void SAL_CALL XSecParser::startElement(
m_ouX509Certificate.clear();
m_bInX509Certificate = true;
}
+ else if (aName == "PGPData")
+ {
+ m_pXSecController->switchGpgSignature();
+ }
+ else if (aName == "PGPKeyID")
+ {
+ m_ouGpgKeyID.clear();
+ m_bInGpgKeyID = true;
+ }
+ else if (aName == "PGPKeyPacket")
+ {
+ m_ouGpgCertificate.clear();
+ m_bInGpgCertificate = true;
+ }
else if (aName == "SignatureValue")
{
m_ouSignatureValue.clear();
@@ -289,6 +307,16 @@ void SAL_CALL XSecParser::endElement( const OUString& aName )
m_pXSecController->setX509Certificate( m_ouX509Certificate );
m_bInX509Certificate = false;
}
+ else if (aName == "PGPKeyID")
+ {
+ m_pXSecController->setGpgKeyID( m_ouGpgKeyID );
+ m_bInGpgKeyID = false;
+ }
+ else if (aName == "PGPKeyPacket")
+ {
+ m_pXSecController->setGpgCertificate( m_ouGpgCertificate );
+ m_bInGpgCertificate = false;
+ }
else if (aName == "xd:CertDigest")
{
m_pXSecController->setCertDigest( m_ouCertDigest );
@@ -352,6 +380,14 @@ void SAL_CALL XSecParser::characters( const OUString& aChars )
{
m_ouX509Certificate += aChars;
}
+ else if (m_bInGpgCertificate)
+ {
+ m_ouGpgCertificate += aChars;
+ }
+ else if (m_bInGpgKeyID)
+ {
+ m_ouGpgKeyID += aChars;
+ }
else if (m_bInSignatureValue)
{
m_ouSignatureValue += aChars;
diff --git a/xmlsecurity/source/helper/xsecparser.hxx b/xmlsecurity/source/helper/xsecparser.hxx
index 1fc01b74123e..dd4d0c83c1e6 100644
--- a/xmlsecurity/source/helper/xsecparser.hxx
+++ b/xmlsecurity/source/helper/xsecparser.hxx
@@ -57,6 +57,8 @@ private:
OUString m_ouX509IssuerName;
OUString m_ouX509SerialNumber;
OUString m_ouX509Certificate;
+ OUString m_ouGpgCertificate;
+ OUString m_ouGpgKeyID;
OUString m_ouCertDigest;
OUString m_ouEncapsulatedX509Certificate;
OUString m_ouDigestValue;
@@ -71,6 +73,8 @@ private:
bool m_bInX509IssuerName;
bool m_bInX509SerialNumber;
bool m_bInX509Certificate;
+ bool m_bInGpgCertificate;
+ bool m_bInGpgKeyID;
bool m_bInCertDigest;
bool m_bInEncapsulatedX509Certificate;
bool m_bInSigningTime;
diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx
index 092b8fb001e6..452613b4d10b 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -239,6 +239,29 @@ void XSecController::setX509Certificate(
}
}
+void XSecController::setGpgCertificate(
+ sal_Int32 nSecurityId,
+ const OUString& ouCertDigest,
+ const OUString& ouCert)
+{
+ int index = findSignatureInfor( nSecurityId );
+
+ if ( index == -1 )
+ {
+ InternalSignatureInformation isi(nSecurityId, nullptr);
+ isi.signatureInfor.ouGpgCertificate = ouCert;
+ isi.signatureInfor.ouCertDigest = ouCertDigest;
+ m_vInternalSignatureInformations.push_back( isi );
+ }
+ else
+ {
+ SignatureInformation &si
+ = m_vInternalSignatureInformations[index].signatureInfor;
+ si.ouGpgCertificate = ouCert;
+ si.ouCertDigest = ouCertDigest;
+ }
+}
+
void XSecController::setDate(
sal_Int32 nSecurityId,
const css::util::DateTime& rDateTime )
diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index 138a0026928a..ab2a8dec6100 100644
--- a/xmlsecurity/source/helper/xsecverify.cxx
+++ b/xmlsecurity/source/helper/xsecverify.cxx
@@ -23,12 +23,15 @@
#include "ooxmlsecparser.hxx"
#include "framework/signatureverifierimpl.hxx"
#include "framework/saxeventkeeperimpl.hxx"
+#include "gpg/xmlsignature_gpgimpl.hxx"
+#include "gpg/SEInitializer.hxx"
#include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
#include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
#include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
+#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/embed/StorageFormats.hpp>
#include <sal/log.hxx>
@@ -105,6 +108,27 @@ void XSecController::addSignature()
m_vInternalSignatureInformations.push_back( isi );
}
+void XSecController::switchGpgSignature()
+{
+#if !defined(MACOSX) && !defined(WNT)
+ // swap signature verifier for the Gpg one
+ m_xXMLSignature.set(new XMLSignature_GpgImpl());
+ if (!m_vInternalSignatureInformations.empty())
+ {
+ SignatureVerifierImpl* pImpl=
+ dynamic_cast<SignatureVerifierImpl*>(
+ m_vInternalSignatureInformations.back().xReferenceResolvedListener.get());
+ if (pImpl)
+ {
+ css::uno::Reference<css::xml::crypto::XSEInitializer> xGpgSEInitializer(
+ new SEInitializerGpg());
+ pImpl->updateSignature(new XMLSignature_GpgImpl(),
+ xGpgSEInitializer->createSecurityContext(OUString()));
+ }
+ }
+#endif
+}
+
void XSecController::addReference( const OUString& ouUri, sal_Int32 nDigestID )
{
if (m_vInternalSignatureInformations.empty())
@@ -246,6 +270,28 @@ void XSecController::setDigestValue( sal_Int32 nDigestID, OUString& ouDigestValu
reference.ouDigestValue = ouDigestValue;
}
+void XSecController::setGpgKeyID( OUString& ouKeyID )
+{
+ if (m_vInternalSignatureInformations.empty())
+ {
+ SAL_INFO("xmlsecurity.helper","XSecController::setGpgKeyID: no signature");
+ return;
+ }
+ InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
+ isi.signatureInfor.ouGpgKeyID = ouKeyID;
+}
+
+void XSecController::setGpgCertificate( OUString& ouGpgCert )
+{
+ if (m_vInternalSignatureInformations.empty())
+ {
+ SAL_INFO("xmlsecurity.helper","XSecController::setGpgCertificate: no signature");
+ return;
+ }
+ InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
+ isi.signatureInfor.ouGpgCertificate = ouGpgCert;
+}
+
void XSecController::setDate( OUString& ouDate )
{
if (m_vInternalSignatureInformations.empty())
diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
index 8ae78b105403..35b3835a2afe 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
@@ -594,6 +594,11 @@ css::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getMD5Thumb
return getThumbprint(m_pCertContext, CERT_MD5_HASH_PROP_ID);
}
+CertificateKind SAL_CALL X509Certificate_MSCryptImpl::getCertificateKind()
+{
+ return CertificateKind_X509;
+}
+
sal_Int32 SAL_CALL X509Certificate_MSCryptImpl::getCertificateUsage( )
{
sal_Int32 usage =
diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx
index f7ba8a21a3fc..ce63a8acc170 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx
@@ -35,6 +35,7 @@
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/uno/SecurityException.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
#include <com/sun/star/security/XCertificate.hpp>
#include <certificate.hxx>
@@ -67,6 +68,8 @@ class X509Certificate_MSCryptImpl : public ::cppu::WeakImplHelper<
virtual OUString SAL_CALL getSignatureAlgorithm() override;
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSHA1Thumbprint() override;
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getMD5Thumbprint() override;
+ virtual css::security::CertificateKind SAL_CALL getCertificateKind() override;
+
virtual sal_Int32 SAL_CALL getCertificateUsage( ) override;
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
index cc93f1be46b7..079be582e02b 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
@@ -455,6 +455,11 @@ css::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getMD5Thumbprin
return getThumbprint(m_pCert, SEC_OID_MD5);
}
+CertificateKind SAL_CALL X509Certificate_NssImpl::getCertificateKind()
+{
+ return CertificateKind_X509;
+}
+
sal_Int32 SAL_CALL X509Certificate_NssImpl::getCertificateUsage( )
{
SECStatus rv;
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
index 08e9cf1185e7..58759673935b 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
@@ -27,6 +27,7 @@
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/uno/SecurityException.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
#include <com/sun/star/security/XCertificate.hpp>
#include <certificate.hxx>
@@ -72,6 +73,7 @@ class X509Certificate_NssImpl : public ::cppu::WeakImplHelper<
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSHA1Thumbprint() override ;
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getMD5Thumbprint() override ;
+ virtual css::security::CertificateKind SAL_CALL getCertificateKind() override;
virtual sal_Int32 SAL_CALL getCertificateUsage( ) override ;
diff --git a/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx
index 6b7a78b1e6a1..371a27f3d090 100644
--- a/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx
@@ -22,9 +22,6 @@
#include "securityenvironment_nssimpl.hxx"
#include "xmlsecuritycontext_nssimpl.hxx"
-#include "xmlsec/xmlstreamio.hxx"
-
-#include "xmlsec-wrapper.h"
using namespace ::com::sun::star::uno ;
using namespace ::com::sun::star::lang ;
@@ -37,30 +34,10 @@ using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
XMLSecurityContext_NssImpl::XMLSecurityContext_NssImpl()
: m_nDefaultEnvIndex(-1)
{
- //Init xmlsec library
- if( xmlSecInit() < 0 ) {
- throw RuntimeException() ;
- }
-
- //Init xmlsec crypto engine library
- if( xmlSecCryptoInit() < 0 ) {
- xmlSecShutdown() ;
- throw RuntimeException() ;
- }
-
- //Enable external stream handlers
- if( xmlEnableStreamInputCallbacks() < 0 ) {
- xmlSecCryptoShutdown() ;
- xmlSecShutdown() ;
- throw RuntimeException() ;
- }
}
XMLSecurityContext_NssImpl::~XMLSecurityContext_NssImpl()
{
- xmlDisableStreamInputCallbacks() ;
- xmlSecCryptoShutdown() ;
- xmlSecShutdown() ;
}
sal_Int32 SAL_CALL XMLSecurityContext_NssImpl::addSecurityEnvironment(
diff --git a/xmlsecurity/source/xmlsec/xmlsec_init.cxx b/xmlsecurity/source/xmlsec/xmlsec_init.cxx
new file mode 100644
index 000000000000..9b2fe90f87c2
--- /dev/null
+++ b/xmlsecurity/source/xmlsec/xmlsec_init.cxx
@@ -0,0 +1,47 @@
+/* -*- 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 "xmlsec/xmlsec_init.hxx"
+
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#include "xmlsec/xmlstreamio.hxx"
+#include "xmlsec-wrapper.h"
+
+using namespace css::uno;
+
+XSECXMLSEC_DLLPUBLIC void initXmlSec()
+{
+ //Init xmlsec library
+ if( xmlSecInit() < 0 ) {
+ throw RuntimeException() ;
+ }
+
+ //Init xmlsec crypto engine library
+ if( xmlSecCryptoInit() < 0 ) {
+ xmlSecShutdown() ;
+ throw RuntimeException() ;
+ }
+
+ //Enable external stream handlers
+ if( xmlEnableStreamInputCallbacks() < 0 ) {
+ xmlSecCryptoShutdown() ;
+ xmlSecShutdown() ;
+ throw RuntimeException() ;
+ }
+}
+
+XSECXMLSEC_DLLPUBLIC void deInitXmlSec()
+{
+ xmlDisableStreamInputCallbacks();
+ xmlSecCryptoShutdown();
+ xmlSecShutdown();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/xmlstreamio.cxx b/xmlsecurity/source/xmlsec/xmlstreamio.cxx
index 6faf711c181b..32d86269cd7e 100644
--- a/xmlsecurity/source/xmlsec/xmlstreamio.cxx
+++ b/xmlsecurity/source/xmlsec/xmlstreamio.cxx
@@ -145,7 +145,7 @@ int xmlStreamClose( void * context )
return 0 ;
}
-int xmlEnableStreamInputCallbacks()
+XSECXMLSEC_DLLPUBLIC int xmlEnableStreamInputCallbacks()
{
if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) {
@@ -210,7 +210,7 @@ XSECXMLSEC_DLLPUBLIC int xmlUnregisterStreamInputCallbacks()
return 0 ;
}
-void xmlDisableStreamInputCallbacks() {
+XSECXMLSEC_DLLPUBLIC void xmlDisableStreamInputCallbacks() {
xmlUnregisterStreamInputCallbacks() ;
enableXmlStreamIO &= ~XMLSTREAMIO_INITIALIZED ;
}
diff --git a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
index 99738064c09f..b480b90a9235 100644
--- a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
+++ b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
@@ -27,6 +27,10 @@
#include "xmlsec/xmldocumentwrapper_xmlsecimpl.hxx"
#include "xsec_xmlsec.hxx"
+#if !defined(MACOSX) && !defined(WNT)
+# include "gpg/xmlsignature_gpgimpl.hxx"
+#endif
+
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
@@ -40,7 +44,14 @@ SAL_DLLPUBLIC_EXPORT void* SAL_CALL xsec_xmlsec_component_getFactory( const sal_
Reference< XInterface > xFactory ;
if( pImplName != nullptr ) {
- if( XMLElementWrapper_XmlSecImpl_getImplementationName().equalsAscii( pImplName ) )
+#if !defined(MACOSX) && !defined(WNT)
+ if( XMLSignature_GpgImpl::impl_getImplementationName().equalsAscii( pImplName ) )
+ {
+ xFactory = XMLSignature_GpgImpl::impl_createFactory( static_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+ }
+ else
+#endif
+ if( XMLElementWrapper_XmlSecImpl_getImplementationName().equalsAscii( pImplName ) )
{
xFactory = cppu::createSingleComponentFactory(
XMLElementWrapper_XmlSecImpl_createInstance,
diff --git a/xmlsecurity/util/xsec_gpg.component b/xmlsecurity/util/xsec_gpg.component
deleted file mode 100644
index bf24f36953ca..000000000000
--- a/xmlsecurity/util/xsec_gpg.component
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * 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/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- -->
-
-<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
- prefix="xsec_gpg" xmlns="http://openoffice.org/2010/uno-components">
- <implementation name="com.sun.star.xml.security.bridge.xmlsec.XMLSignature_GpgImpl">
- <service name="com.sun.star.xml.crypto.XMLSignature2"/>
- </implementation>
-</component>