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.behr...@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.behr...@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.behr...@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.behr...@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.mehrbr...@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.behr...@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.behr...@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.mehrbr...@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.mehrbr...@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.behr...@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.behr...@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.behr...@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.mehrbr...@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.mehrbr...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits