[Libreoffice-commits] core.git: 17 commits - include/sal offapi/com offapi/UnoApi_offapi.mk postprocess/Rdb_services.mk xmlsecurity/inc xmlsecurity/Library_xmlsecurity.mk xmlsecurity/Library_xsec_gpg.mk xmlsecurity/Library_xsec_xmlsec.mk xmlsecurity/Module_xmlsecurity.mk xmlsecurity/qa xmlsecurity/source xmlsecurity/util

Thorsten Behrens Thorsten.Behrens at CIB.de
Wed Jun 21 20:20:29 UTC 2017


 include/sal/log-areas.dox                                         |    1 
 offapi/UnoApi_offapi.mk                                           |    1 
 offapi/com/sun/star/security/CertificateKind.idl                  |   33 +
 offapi/com/sun/star/security/XCertificate.idl                     |    8 
 postprocess/Rdb_services.mk                                       |    3 
 xmlsecurity/Library_xmlsecurity.mk                                |    6 
 xmlsecurity/Library_xsec_gpg.mk                                   |   75 ---
 xmlsecurity/Library_xsec_xmlsec.mk                                |   20 
 xmlsecurity/Module_xmlsecurity.mk                                 |    6 
 xmlsecurity/inc/certificatechooser.hxx                            |    8 
 xmlsecurity/inc/digitalsignaturesdialog.hxx                       |    4 
 xmlsecurity/inc/documentsignaturemanager.hxx                      |    6 
 xmlsecurity/inc/framework/signatureverifierimpl.hxx               |    3 
 xmlsecurity/inc/gpg/SEInitializer.hxx                             |    5 
 xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx                      |    1 
 xmlsecurity/inc/sigstruct.hxx                                     |    4 
 xmlsecurity/inc/xmlsec/xmlsec_init.hxx                            |   20 
 xmlsecurity/inc/xmlsec/xmlstreamio.hxx                            |    8 
 xmlsecurity/inc/xmlsignaturehelper.hxx                            |    3 
 xmlsecurity/inc/xsecctl.hxx                                       |    8 
 xmlsecurity/qa/unit/signing/signing.cxx                           |   12 
 xmlsecurity/source/component/documentdigitalsignatures.cxx        |   15 
 xmlsecurity/source/dialogs/certificatechooser.cxx                 |   19 
 xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx            |   96 ++--
 xmlsecurity/source/gpg/CertificateImpl.cxx                        |   57 ++
 xmlsecurity/source/gpg/CertificateImpl.hxx                        |    5 
 xmlsecurity/source/gpg/SEInitializer.cxx                          |    7 
 xmlsecurity/source/gpg/SecurityEnvironment.cxx                    |   49 +-
 xmlsecurity/source/gpg/SecurityEnvironment.hxx                    |    5 
 xmlsecurity/source/gpg/XMLSecurityContext.cxx                     |   20 
 xmlsecurity/source/gpg/XMLSecurityContext.hxx                     |   10 
 xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx                   |  203 ++++++----
 xmlsecurity/source/helper/documentsignaturehelper.cxx             |    3 
 xmlsecurity/source/helper/documentsignaturemanager.cxx            |  128 ++++--
 xmlsecurity/source/helper/xmlsignaturehelper.cxx                  |   10 
 xmlsecurity/source/helper/xsecctl.cxx                             |   91 +++-
 xmlsecurity/source/helper/xsecparser.cxx                          |   36 +
 xmlsecurity/source/helper/xsecparser.hxx                          |    4 
 xmlsecurity/source/helper/xsecsign.cxx                            |   23 +
 xmlsecurity/source/helper/xsecverify.cxx                          |   46 ++
 xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx |    5 
 xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx |    3 
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx         |    5 
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx         |    2 
 xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx      |   23 -
 xmlsecurity/source/xmlsec/xmlsec_init.cxx                         |   47 ++
 xmlsecurity/source/xmlsec/xmlstreamio.cxx                         |    4 
 xmlsecurity/source/xmlsec/xsec_xmlsec.cxx                         |   13 
 xmlsecurity/util/xsec_gpg.component                               |   25 -
 49 files changed, 825 insertions(+), 364 deletions(-)

New commits:
commit f9a14f3d021d78bded54cde0462669ea10d7c546
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Wed Jun 21 21:32:38 2017 +0200

    gpg4libre: fix build for windows and mac
    
    Change-Id: I3e36b22cefba4c6195bcf8b85b3f7a2cc101b845

diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx
index 0df6c08f29ef..795745fe851b 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -22,7 +22,9 @@
 #include "documentsignaturehelper.hxx"
 #include "framework/saxeventkeeperimpl.hxx"
 #include "xmlsec/xmldocumentwrapper_xmlsecimpl.hxx"
-#include "gpg/xmlsignature_gpgimpl.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>
@@ -125,10 +127,12 @@ void XSecController::createXSecComponent( )
 
     cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
 
+#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();
diff --git a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
index da1ecf905d4a..b480b90a9235 100644
--- a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
+++ b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
@@ -26,7 +26,10 @@
 #include "xmlsec/xmlelementwrapper_xmlsecimpl.hxx"
 #include "xmlsec/xmldocumentwrapper_xmlsecimpl.hxx"
 #include "xsec_xmlsec.hxx"
-#include "gpg/xmlsignature_gpgimpl.hxx"
+
+#if !defined(MACOSX) && !defined(WNT)
+# include "gpg/xmlsignature_gpgimpl.hxx"
+#endif
 
 using namespace ::cppu;
 using namespace ::com::sun::star::uno;
@@ -41,11 +44,14 @@ SAL_DLLPUBLIC_EXPORT void* SAL_CALL xsec_xmlsec_component_getFactory( const sal_
     Reference< XInterface > xFactory ;
 
     if( pImplName != nullptr ) {
+#if !defined(MACOSX) && !defined(WNT)
         if( XMLSignature_GpgImpl::impl_getImplementationName().equalsAscii( pImplName ) )
         {
             xFactory = XMLSignature_GpgImpl::impl_createFactory( static_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
         }
-        else if( XMLElementWrapper_XmlSecImpl_getImplementationName().equalsAscii( pImplName ) )
+        else
+#endif
+            if( XMLElementWrapper_XmlSecImpl_getImplementationName().equalsAscii( pImplName ) )
         {
             xFactory = cppu::createSingleComponentFactory(
                 XMLElementWrapper_XmlSecImpl_createInstance,
commit b962b047b08872ec25f339c6ef97dd0b923a2168
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Wed Jun 21 18:53:23 2017 +0200

    gpg4libre: actually take key from user selection
    
    Change-Id: I6b18865913492d41a8e0206a430e267fe78c553a

diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
index 95773b5830a8..40248ee3a9e8 100644
--- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
+++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
@@ -168,10 +168,30 @@ SAL_CALL XMLSignature_GpgImpl::generate(
     if( xmlSecTransformCtxXmlExecute(&(pDsigCtx->transformCtx), nodeset) < 0 )
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
+    // 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.");
+    // 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.");
+
     GpgME::Context& rCtx=pSecEnv->getGpgContext();
     rCtx.setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
     GpgME::Error err;
-    if( rCtx.addSigningKey(rCtx.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
commit ba53bd4e7234c771e6e655a492f0416807669027
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Wed Jun 21 18:00:55 2017 +0200

    gpg4libre: make signature impl swappable in-situ during validation
    
    Sadly we only know whether its a OpenPGP or X509 signature during
    parsing, so we need to switch the implementation mid-way
    
    Change-Id: Ib48a9da0105de62cfecda095df8c154b59ba8c40

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/inc/xsecctl.hxx b/xmlsecurity/inc/xsecctl.hxx
index 3e4037c3ce41..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 );
diff --git a/xmlsecurity/source/gpg/SEInitializer.cxx b/xmlsecurity/source/gpg/SEInitializer.cxx
index 0e4cbd9d8cc8..919161d86554 100644
--- a/xmlsecurity/source/gpg/SEInitializer.cxx
+++ b/xmlsecurity/source/gpg/SEInitializer.cxx
@@ -20,10 +20,8 @@ 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();
 }
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index b2e42076be5e..ded3de8d9960 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -66,7 +66,7 @@ bool DocumentSignatureManager::init()
 
     mxSEInitializer = xml::crypto::SEInitializer::create(mxContext);
 #if !defined(MACOSX) && !defined(WNT)
-    mxGpgSEInitializer.set(new SEInitializerGpg(mxContext));
+    mxGpgSEInitializer.set(new SEInitializerGpg());
 #endif
 
     if (mxSEInitializer.is())
diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx
index 0fb46efb2b67..360d39e326f4 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -178,6 +178,10 @@ 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();
diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index 0e030f37de07..bd9e7dbf7839 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())
commit 4ddb2f716fa5501271bfb2d270a56562ddb5051d
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Wed Jun 21 16:54:52 2017 +0200

    gpg4libre: some code improvements, add metadata for OpenPGP keys
    
    Change-Id: I1beb692b9a9a34b5f0cf743ba9e4a145ac582184

diff --git a/xmlsecurity/inc/sigstruct.hxx b/xmlsecurity/inc/sigstruct.hxx
index c6c706705aba..68e64176206b 100644
--- a/xmlsecurity/inc/sigstruct.hxx
+++ b/xmlsecurity/inc/sigstruct.hxx
@@ -75,6 +75,7 @@ struct SignatureInformation
     OUString ouX509SerialNumber;
     OUString ouX509Certificate;
 
+    OUString ouGpgKeyID;
     OUString ouGpgCertificate;
 
     OUString ouSignatureValue;
diff --git a/xmlsecurity/inc/xsecctl.hxx b/xmlsecurity/inc/xsecctl.hxx
index 02450d1197bd..3e4037c3ce41 100644
--- a/xmlsecurity/inc/xsecctl.hxx
+++ b/xmlsecurity/inc/xsecctl.hxx
@@ -306,6 +306,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);
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index d9f9bba47ec2..a9fbe930b30d 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -518,6 +518,7 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
             const SignatureInformation& rInfo = maSignatureManager.maCurrentSignatureInformations[n];
             uno::Reference< css::security::XCertificate > xCert = getCertificate(rInfo);
 
+            // TODO - should use pgpdata from info provider?
             OUString aSubject;
             OUString aIssuer;
             OUString aDateTimeStr;
diff --git a/xmlsecurity/source/gpg/CertificateImpl.cxx b/xmlsecurity/source/gpg/CertificateImpl.cxx
index c0f48e309c7c..e40f59323a04 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -24,13 +24,12 @@ using namespace css::security;
 using namespace css::util;
 
 CertificateImpl::CertificateImpl() :
-    m_pKey(nullptr)
+    m_pKey()
 {
 }
 
 CertificateImpl::~CertificateImpl()
 {
-    // TODO: cleanup key
 }
 
 //Methods from XCertificateImpl
@@ -214,17 +213,16 @@ void CertificateImpl::setCertificate(GpgME::Context* ctx, const GpgME::Key& key)
     GpgME::Data data_out;
     ctx->exportPublicKeys(key.keyID(), data_out);
 
-    // TODO: needs some error handling
-    data_out.seek(0,SEEK_SET);
+    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);
-    data_out.seek(0,SEEK_SET);
+    assert(data_out.seek(0,SEEK_SET) == 0);
     if( data_out.read(m_aBits.getArray(), len) != len )
-        throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
+        throw RuntimeException("The GpgME library failed to read the key");
 }
 
 const GpgME::Key* CertificateImpl::getCertificate() const
diff --git a/xmlsecurity/source/gpg/SEInitializer.cxx b/xmlsecurity/source/gpg/SEInitializer.cxx
index af02de9d7ece..0e4cbd9d8cc8 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;
@@ -21,6 +23,9 @@ using namespace css::xml::crypto;
 SEInitializerGpg::SEInitializerGpg( const css::uno::Reference< css::uno::XComponentContext > &rxContext )
 {
     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 d120b2a985fa..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,33 +64,22 @@ OUString SecurityEnvironmentGpg::getSecurityEnvironmentInformation()
 
 Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertificates()
 {
-    // TODO: move to central init
-    GpgME::initializeLibrary();
-    GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
-    if (err)
-        throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
-    // TODO: keep that around for SecurityEnvironmentGpg lifetime
-    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(ctx,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;
@@ -98,37 +92,25 @@ Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertif
 
 Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& /*serialNumber*/ )
 {
-    // TODO: move to central init
-    GpgME::initializeLibrary();
-    GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
-    if (err)
-        throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
-    // TODO: keep that around for SecurityEnvironmentGpg lifetime
-    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=nullptr;
     std::list< CertificateImpl* > certsList;
 
-    ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
+    m_ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
     OString ostr = OUStringToOString( issuerName , RTL_TEXTENCODING_UTF8 );
-    err = ctx->startKeyListing(ostr.getStr(), true);
+    GpgME::Error err = m_ctx->startKeyListing(ostr.getStr(), 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(ctx, k);
-            ctx->endKeyListing();
+            xCert->setCertificate(m_ctx.get(), k);
+            m_ctx->endKeyListing();
             return xCert;
         }
     }
-    ctx->endKeyListing();
+    m_ctx->endKeyListing();
 
-    // TODO: cleanup ctx
     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/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
index b9219f0f3281..95773b5830a8 100644
--- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
+++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
@@ -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
@@ -170,20 +168,10 @@ SAL_CALL XMLSignature_GpgImpl::generate(
     if( xmlSecTransformCtxXmlExecute(&(pDsigCtx->transformCtx), nodeset) < 0 )
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
-    //Sign the template via gpgme
-    // TODO move init to central place
-    GpgME::initializeLibrary();
-    if( GpgME::checkEngine(GpgME::OpenPGP) )
-        throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
-    // TODO get ctx from SecurityEnv?
-    GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
-    if( ctx == nullptr )
-        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("0x909BE2575CEDBEA3", err, true)) )
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
     // good, ctx is setup now, let's sign the lot
@@ -194,17 +182,16 @@ SAL_CALL XMLSignature_GpgImpl::generate(
 
     SAL_INFO("xmlsecurity.xmlsec.gpg", "Generating signature for: " << xmlSecBufferGetData(pDsigCtx->transformCtx.result));
 
-    GpgME::SigningResult sign_res=ctx->sign(data_in, data_out,
+    GpgME::SigningResult sign_res=rCtx.sign(data_in, data_out,
                                             GpgME::Detached);
-    // TODO: needs some error handling
-    data_out.seek(0,SEEK_SET);
+    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.");
 
@@ -273,15 +260,11 @@ SAL_CALL XMLSignature_GpgImpl::validate(
     {
         Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);
 
-#if 0
-        //Get Keys Manager
         SecurityEnvironmentGpg* pSecEnv =
             dynamic_cast<SecurityEnvironmentGpg*>(aEnvironment.get());
         if( pSecEnv == nullptr )
             throw RuntimeException() ;
-#endif
 
-        // TODO pSecEnv is still from nss, roll our own impl there
         // TODO figure out key from pSecEnv!
         // unclear how/where that is transported in nss impl...
 
@@ -317,17 +300,8 @@ SAL_CALL XMLSignature_GpgImpl::validate(
             throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
         // Validate the template via gpgme
-        // TODO move init to central place
-        GpgME::initializeLibrary();
-        if( GpgME::checkEngine(GpgME::OpenPGP) )
-            throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
-
-        // TODO get ctx from SecurityEnv?
-        GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
-        if( ctx == nullptr )
-            throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
+        GpgME::Context& rCtx=pSecEnv->getGpgContext();
 
-        // good, ctx is setup now, let's validate the lot
         GpgME::Data data_text(
             reinterpret_cast<char*>(xmlSecBufferGetData(pDsigCtx->transformCtx.result)),
             xmlSecBufferGetSize(pDsigCtx->transformCtx.result), false);
@@ -345,7 +319,7 @@ SAL_CALL XMLSignature_GpgImpl::validate(
             reinterpret_cast<char*>(pSignatureValue),
             xmlStrlen(pSignatureValue), false);
 
-        GpgME::VerificationResult verify_res=ctx->verifyDetachedSignature(
+        GpgME::VerificationResult verify_res=rCtx.verifyDetachedSignature(
             data_signature, data_text);
 
         xmlFree(pSignatureValue);
diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx
index acac83ca2fe3..0df6c08f29ef 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -735,7 +735,7 @@ void XSecController::exportSignature(
                     xDocumentHandler->endElement( "PGPKeyID" );
 
                     /* Write PGPKeyPacket element */
-                    if (!signatureInfo.ouX509Certificate.isEmpty())
+                    if (!signatureInfo.ouGpgCertificate.isEmpty())
                     {
                         xDocumentHandler->startElement(
                             "PGPKeyPacket",
diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx
index 61c2395aae27..0fb46efb2b67 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -34,6 +34,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)
@@ -68,6 +70,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;
@@ -174,6 +178,16 @@ void SAL_CALL XSecParser::startElement(
             m_ouX509Certificate.clear();
             m_bInX509Certificate = true;
         }
+        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();
@@ -287,6 +301,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 );
@@ -350,6 +374,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 dcfbead56a4c..acf9909a2580 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/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index 2dfa54aa5302..0e030f37de07 100644
--- a/xmlsecurity/source/helper/xsecverify.cxx
+++ b/xmlsecurity/source/helper/xsecverify.cxx
@@ -246,6 +246,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())
commit c88063e80d464af195afe88d558a44ef77d69f4a
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Wed Jun 21 16:22:32 2017 +0200

    gpg4libre: Make viewing signatures work for gpg signatures
    
    Change-Id: Ic10846cb87e23ca9ffa0eb0d64c56fcf79c73a9d

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/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index aac3ca15bc30..d9f9bba47ec2 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -501,11 +501,6 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
 {
     m_pSignaturesLB->Clear();
 
-    uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
-    uno::Reference<xml::crypto::XSecurityEnvironment> xGpgSecEnv = maSignatureManager.getGpgSecurityEnvironment();
-
-    uno::Reference< css::security::XCertificate > xCert;
-
     size_t nInfos = maSignatureManager.maCurrentSignatureInformations.size();
     size_t nValidSigs = 0, nValidCerts = 0;
     bool bAllNewSignatures = true;
@@ -521,27 +516,7 @@ 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 ) );
-            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!" );
+            uno::Reference< css::security::XCertificate > xCert = getCertificate(rInfo);
 
             OUString aSubject;
             OUString aIssuer;
@@ -555,13 +530,8 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
             {
                 //check the validity of the cert
                 try {
-                    sal_Int32 certResult;
-                    if (xCert->getCertificateKind() == CertificateKind_OPENPGP)
-                        certResult = xGpgSecEnv->verifyCertificate(xCert,Sequence<css::uno::Reference<css::security::XCertificate> >());
-                    else if (xCert->getCertificateKind() == CertificateKind_X509)
-                        certResult = xSecEnv->verifyCertificate(xCert, Sequence<css::uno::Reference<css::security::XCertificate> >());
-                    else
-                        throw RuntimeException("Unknown certificate kind");
+                    sal_Int32 certResult = getSecurityEnvironmentForCertificate(xCert)->verifyCertificate(xCert,
+                                                                                                          Sequence<uno::Reference<security::XCertificate> >());
 
                     bCertValid = certResult == css::security::CertificateValidity::VALID;
                     if ( bCertValid )
@@ -674,6 +644,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)
@@ -688,19 +698,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();
         }
     }
commit e07085ecf8d4c5337855f45b9736f2d2db0a9002
Author: Katarina Behrens <Katarina.Behrens at cib.de>
Date:   Wed Jun 21 13:34:30 2017 +0200

    gpg4libre: Fixup unit tests, now that SecurityContext is needed
    
    Change-Id: Ifa43fa735c8b0d58ff3d3deca2ad4eca6560494a

diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index 086852e9a56d..95fb711a3596 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -57,6 +57,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();
@@ -136,6 +138,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/
@@ -215,7 +219,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);
@@ -249,7 +253,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);
@@ -282,7 +286,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);
@@ -589,7 +593,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);
commit 891d4b5d91c86951bb06d413808f75a3f4e6cb28
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Tue Jun 20 23:52:18 2017 +0200

    gpg4libre: write PGPData info, get more metadata out for gpg key
    
    Change-Id: Ia560869ec02fca7fe4219136e1fe939e13f1e4c2

diff --git a/xmlsecurity/inc/sigstruct.hxx b/xmlsecurity/inc/sigstruct.hxx
index 479ba3d8f745..c6c706705aba 100644
--- a/xmlsecurity/inc/sigstruct.hxx
+++ b/xmlsecurity/inc/sigstruct.hxx
@@ -74,6 +74,9 @@ struct SignatureInformation
     OUString ouX509IssuerName;
     OUString ouX509SerialNumber;
     OUString ouX509Certificate;
+
+    OUString ouGpgCertificate;
+
     OUString ouSignatureValue;
     css::util::DateTime stDateTime;
 
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index 3d0c91eb7ed8..7a39b6955ca6 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -150,6 +150,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..02450d1197bd 100644
--- a/xmlsecurity/inc/xsecctl.hxx
+++ b/xmlsecurity/inc/xsecctl.hxx
@@ -382,6 +382,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/source/gpg/CertificateImpl.cxx b/xmlsecurity/source/gpg/CertificateImpl.cxx
index 3eabed319b8c..c0f48e309c7c 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -10,9 +10,14 @@
 #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;
@@ -25,6 +30,7 @@ CertificateImpl::CertificateImpl() :
 
 CertificateImpl::~CertificateImpl()
 {
+    // TODO: cleanup key
 }
 
 //Methods from XCertificateImpl
@@ -35,8 +41,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 +121,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 +154,26 @@ 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()
@@ -192,9 +206,25 @@ const Sequence< sal_Int8>& CertificateImpl::getUnoTunnelId() {
     return CertificateImplUnoTunnelId::get().getSeq();
 }
 
-void CertificateImpl::setCertificate(const 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);
+
+    // TODO: needs some error handling
+    data_out.seek(0,SEEK_SET);
+    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);
+    data_out.seek(0,SEEK_SET);
+    if( data_out.read(m_aBits.getArray(), len) != len )
+        throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 }
 
 const GpgME::Key* CertificateImpl::getCertificate() const
diff --git a/xmlsecurity/source/gpg/CertificateImpl.hxx b/xmlsecurity/source/gpg/CertificateImpl.hxx
index 11a862c42b58..9db3ab85de14 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.hxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.hxx
@@ -34,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();
@@ -81,7 +82,7 @@ public:
     virtual css::security::CertificateKind getCertificateKind() override;
 
     // Helper methods
-    void setCertificate(const GpgME::Key& key);
+    void setCertificate(GpgME::Context* ctx, const GpgME::Key& key);
     const GpgME::Key* getCertificate() const;
 } ;
 
diff --git a/xmlsecurity/source/gpg/SecurityEnvironment.cxx b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
index 83e6170a98c1..d120b2a985fa 100644
--- a/xmlsecurity/source/gpg/SecurityEnvironment.cxx
+++ b/xmlsecurity/source/gpg/SecurityEnvironment.cxx
@@ -59,11 +59,13 @@ OUString SecurityEnvironmentGpg::getSecurityEnvironmentInformation()
 
 Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertificates()
 {
+    // TODO: move to central init
     GpgME::initializeLibrary();
     GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
     if (err)
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
+    // TODO: keep that around for SecurityEnvironmentGpg lifetime
     GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
     if (ctx == nullptr)
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
@@ -79,7 +81,7 @@ Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertif
             break;
         if (!k.isInvalid()) {
             xCert = new CertificateImpl();
-            xCert->setCertificate(k);
+            xCert->setCertificate(ctx,k);
             certsList.push_back(xCert);
         }
     }
@@ -96,11 +98,13 @@ Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertif
 
 Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& /*serialNumber*/ )
 {
+    // TODO: move to central init
     GpgME::initializeLibrary();
     GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
     if (err)
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
+    // TODO: keep that around for SecurityEnvironmentGpg lifetime
     GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
     if (ctx == nullptr)
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
@@ -117,13 +121,14 @@ Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString
             break;
         if (!k.isInvalid()) {
             xCert = new CertificateImpl();
-            xCert->setCertificate(k);
+            xCert->setCertificate(ctx, k);
             ctx->endKeyListing();
             return xCert;
         }
     }
     ctx->endKeyListing();
 
+    // TODO: cleanup ctx
     return nullptr;
 }
 
diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
index 686258eeca00..b9219f0f3281 100644
--- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
+++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
@@ -171,10 +171,12 @@ SAL_CALL XMLSignature_GpgImpl::generate(
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
     //Sign the template via gpgme
+    // TODO move init to central place
     GpgME::initializeLibrary();
     if( GpgME::checkEngine(GpgME::OpenPGP) )
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
+    // TODO get ctx from SecurityEnv?
     GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
     if( ctx == nullptr )
         throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
@@ -315,10 +317,12 @@ SAL_CALL XMLSignature_GpgImpl::validate(
             throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
         // Validate the template via gpgme
+        // TODO move init to central place
         GpgME::initializeLibrary();
         if( GpgME::checkEngine(GpgME::OpenPGP) )
             throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
 
+        // TODO get ctx from SecurityEnv?
         GpgME::Context* ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
         if( ctx == nullptr )
             throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 041c3f2a0113..b2e42076be5e 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>
@@ -40,6 +41,7 @@
 #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),
@@ -263,52 +265,87 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>&
         return false;
     }
 
-    // TODO: no serial number currently on gpg keys - better/more
-    // discriminative error handling?
-    OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber());
-    if (aCertSerial.isEmpty())
+    // GPG or X509 key?
+    uno::Reference< lang::XServiceInfo > xServiceInfo( xSecurityContext, cssu::UNO_QUERY );
+    if (xServiceInfo->getImplementationName() == "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
     {
-        SAL_WARN("xmlsecurity.helper", "Error in Certificate, problem with serial number!");
-    }
-
-    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))
+        // 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(xSecurityContext);
+        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;
+        }
+
+        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();
 
-    maSignatureHelper.SetX509Certificate(nSecurityId, xCert->getIssuerName(), aCertSerial, aStrBuffer.makeStringAndClear(), aCertDigest);
+        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 = 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());
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 31de4e897d2d..acac83ca2fe3 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -719,43 +719,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.ouX509Certificate.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/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 )
commit ed92db7a50be36fcfe6e9b316f4b7f7570060c0d
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jun 20 14:49:10 2017 +0200

    gpg4libre: Init xmlsec in one place before creating the gpg/x509 services
    
    Change-Id: I0308d586344b5e52ad327f6650b62ac0eac7ecb9

diff --git a/xmlsecurity/Library_xsec_xmlsec.mk b/xmlsecurity/Library_xsec_xmlsec.mk
index 249523ae1d1e..d35bc848930e 100644
--- a/xmlsecurity/Library_xsec_xmlsec.mk
+++ b/xmlsecurity/Library_xsec_xmlsec.mk
@@ -67,6 +67,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 \
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/source/gpg/XMLSecurityContext.cxx b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
index cfc391f56ec1..0919f4dbc2b6 100644
--- a/xmlsecurity/source/gpg/XMLSecurityContext.cxx
+++ b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
@@ -22,32 +22,10 @@ using namespace css::xml::crypto;
 XMLSecurityContextGpg::XMLSecurityContextGpg()
     : m_nDefaultEnvIndex(-1)
 {
-    // TODO: same code in XMLSecurityContext_NssImpl, not a good idea
-    // prolly to initialize twice ...
-    //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() ;
-    }
 }
 
 XMLSecurityContextGpg::~XMLSecurityContextGpg()
 {
-    xmlDisableStreamInputCallbacks() ;
-    xmlSecCryptoShutdown() ;
-    xmlSecShutdown() ;
 }
 
 sal_Int32 SAL_CALL XMLSecurityContextGpg::addSecurityEnvironment(
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 042b5d7065a8..041c3f2a0113 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -37,6 +37,8 @@
 #include <certificate.hxx>
 #include <biginteger.hxx>
 
+#include <xmlsec/xmlsec_init.hxx>
+
 using namespace css;
 
 DocumentSignatureManager::DocumentSignatureManager(const uno::Reference<uno::XComponentContext>& xContext, DocumentSignatureMode eMode)
@@ -46,7 +48,10 @@ DocumentSignatureManager::DocumentSignatureManager(const uno::Reference<uno::XCo
 {
 }
 
-DocumentSignatureManager::~DocumentSignatureManager() = default;
+DocumentSignatureManager::~DocumentSignatureManager()
+{
+    deInitXmlSec();
+}
 
 bool DocumentSignatureManager::init()
 {
@@ -54,6 +59,9 @@ 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));
diff --git a/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx
index d5ba8a38f949..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,34 +34,10 @@ using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
 XMLSecurityContext_NssImpl::XMLSecurityContext_NssImpl()
     : m_nDefaultEnvIndex(-1)
 {
-#if 0
-    //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() ;
-    }
-#endif
 }
 
 XMLSecurityContext_NssImpl::~XMLSecurityContext_NssImpl()
 {
-#if 0
-    xmlDisableStreamInputCallbacks() ;
-    xmlSecCryptoShutdown() ;
-    xmlSecShutdown() ;
-#endif
 }
 
 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: */
commit e4adff468c8f5e6fbacae0f553d7c154fb95a466
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jun 20 10:58:26 2017 +0200

    gpg4libre: List both (x509 and gpg) existing signatures
    
    Change-Id: I57ae79f7632885bf5c5aadcad3fb5ad4a5a9413d

diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 4dec1d784d17..aac3ca15bc30 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>
@@ -554,9 +555,13 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
             {
                 //check the validity of the cert
                 try {
-                    // TODO: check for both sec envs ...
-                    sal_Int32 certResult = xGpgSecEnv->verifyCertificate(xCert,
-                        Sequence<css::uno::Reference<css::security::XCertificate> >());
+                    sal_Int32 certResult;
+                    if (xCert->getCertificateKind() == CertificateKind_OPENPGP)
+                        certResult = xGpgSecEnv->verifyCertificate(xCert,Sequence<css::uno::Reference<css::security::XCertificate> >());
+                    else if (xCert->getCertificateKind() == CertificateKind_X509)
+                        certResult = xSecEnv->verifyCertificate(xCert, Sequence<css::uno::Reference<css::security::XCertificate> >());
+                    else
+                        throw RuntimeException("Unknown certificate kind");
 
                     bCertValid = certResult == css::security::CertificateValidity::VALID;
                     if ( bCertValid )
commit bb06a106aa92dae05b2d05a46c6c6586e9b84b7c
Author: Katarina Behrens <Katarina.Behrens at cib.de>
Date:   Mon Jun 19 23:36:12 2017 +0200

    gpg4libre: [API-CHANGE] add certificate kind (X509 vs. OpenPGP)
    
    Change-Id: I423bef41f93af9d1b78ee9795be7ec33c3c7ae0c

diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index c947ce392e65..f3e0274777a7 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -3318,6 +3318,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/xmlsecurity/source/gpg/CertificateImpl.cxx b/xmlsecurity/source/gpg/CertificateImpl.cxx
index ba329a3c4e10..3eabed319b8c 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -162,6 +162,11 @@ Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
     return Sequence< sal_Int8 > ();
 }
 
+CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
+{
+    return CertificateKind_OPENPGP;
+}
+
 sal_Int32 SAL_CALL CertificateImpl::getCertificateUsage()
 {
     return KeyUsage::DIGITAL_SIGNATURE | KeyUsage::NON_REPUDIATION  | KeyUsage::KEY_ENCIPHERMENT | KeyUsage::DATA_ENCIPHERMENT;
diff --git a/xmlsecurity/source/gpg/CertificateImpl.hxx b/xmlsecurity/source/gpg/CertificateImpl.hxx
index c22400b865a6..11a862c42b58 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>
@@ -77,6 +78,7 @@ public:
 
     /// @see xmlsecurity::Certificate::getSHA256Thumbprint().
     virtual css::uno::Sequence<sal_Int8> getSHA256Thumbprint() override;
+    virtual css::security::CertificateKind getCertificateKind() override;
 
     // Helper methods
     void setCertificate(const GpgME::Key& key);
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 ;
 
commit d6f8b0348767afea083f24f839b8130897563188
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Mon Jun 19 03:42:15 2017 +0200

    gpg4libre: now use the gpg security env
    
    Change-Id: I84e4d6872aab27f5b11ec727787a2eab80ef6a66

diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
index cef3f8e9501a..686258eeca00 100644
--- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
+++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx
@@ -92,15 +92,12 @@ SAL_CALL XMLSignature_GpgImpl::generate(
             throw RuntimeException() ;
     }
 
-#if 0
     //Get Keys Manager
     SecurityEnvironmentGpg* pSecEnv =
         dynamic_cast<SecurityEnvironmentGpg*>(aEnvironment.get());
     if( pSecEnv == nullptr )
         throw RuntimeException() ;
-#endif
 
-    // TODO pSecEnv is still from nss, roll our own impl there
     // TODO figure out key from pSecEnv!
     // unclear how/where that is transported in nss impl...
     setErrorRecorder();
commit be197b089a15af9a2cbbac5eb4ae3601cebd8f51
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Sat Jun 17 09:56:04 2017 +0200

    gpg4libre: fix build, explicit ctor call
    
    Change-Id: Iec7ca4e37d6f5c4f63aaa22acfa0bdd395747471

diff --git a/xmlsecurity/source/gpg/XMLSecurityContext.cxx b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
index 85888819ea4c..cfc391f56ec1 100644
--- a/xmlsecurity/source/gpg/XMLSecurityContext.cxx
+++ b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
@@ -94,7 +94,7 @@ void SAL_CALL XMLSecurityContextGpg::setDefaultSecurityEnvironmentIndex(sal_Int3
 
 /* XServiceInfo */
 OUString SAL_CALL XMLSecurityContextGpg::getImplementationName() {
-    return "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl";
+    return OUString("com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl");
 }
 
 /* XServiceInfo */
@@ -104,7 +104,7 @@ sal_Bool SAL_CALL XMLSecurityContextGpg::supportsService( const OUString& servic
 
 /* XServiceInfo */
 Sequence< OUString > SAL_CALL XMLSecurityContextGpg::getSupportedServiceNames() {
-    return { "com.sun.star.xml.crypto.XMLSecurityContext" };
+    return { OUString("com.sun.star.xml.crypto.XMLSecurityContext") };
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit b22fb3daf9a4af2991187aa909260ffdb0222f4d
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Fri Jun 16 15:30:30 2017 +0200

    gpg4libre: Having this dllpublic should be fine now since it's in inc/
    
    Change-Id: I79c132e717a62c6274eeafe33d732616cbd6a5a6

diff --git a/xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx b/xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx
index 96dfa0c39f3e..913053b7a4f0 100644
--- a/xmlsecurity/inc/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 >
commit 9b8197ab0de4a264c139546f420c913535d28dcf
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Fri Jun 16 15:24:06 2017 +0200

    gpg4libre: Make signature dialog work with two signing services
    
    Change-Id: I0b47e6dba38222bb6b4f778c4206d3b37bc93089

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/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/source/gpg/xmlsignature_gpgimpl.hxx b/xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx
similarity index 100%
rename from xmlsecurity/source/gpg/xmlsignature_gpgimpl.hxx
rename to xmlsecurity/inc/gpg/xmlsignature_gpgimpl.hxx
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 7d2068d8133b..518b4acb1c93 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -452,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 9c7ff5f6163d..4dec1d784d17 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -386,15 +386,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;
 
diff --git a/xmlsecurity/source/gpg/XMLSecurityContext.cxx b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
index 25621653e721..85888819ea4c 100644
--- a/xmlsecurity/source/gpg/XMLSecurityContext.cxx
+++ b/xmlsecurity/source/gpg/XMLSecurityContext.cxx
@@ -10,6 +10,8 @@
 #include "XMLSecurityContext.hxx"
 #include "SecurityEnvironment.hxx"
 
+#include <cppuhelper/supportsservice.hxx>
+
 #include "xmlsec/xmlstreamio.hxx"
 #include "xmlsec-wrapper.h"
 
@@ -90,4 +92,19 @@ void SAL_CALL XMLSecurityContextGpg::setDefaultSecurityEnvironmentIndex(sal_Int3
     m_nDefaultEnvIndex = nDefaultEnvIndex;
 }
 
+/* XServiceInfo */
+OUString SAL_CALL XMLSecurityContextGpg::getImplementationName() {
+    return "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 { "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 eee8d5f83434..cef3f8e9501a 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>
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index cc4ad6dbf9c8..042b5d7065a8 100644

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list