diff options
author | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-06-21 16:54:52 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-06-21 22:16:56 +0200 |
commit | 4ddb2f716fa5501271bfb2d270a56562ddb5051d (patch) | |
tree | c59899614a26083e43cb34eb2cef1fdd304455fb /xmlsecurity/source | |
parent | c88063e80d464af195afe88d558a44ef77d69f4a (diff) |
gpg4libre: some code improvements, add metadata for OpenPGP keys
Change-Id: I1beb692b9a9a34b5f0cf743ba9e4a145ac582184
Diffstat (limited to 'xmlsecurity/source')
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 1 | ||||
-rw-r--r-- | xmlsecurity/source/gpg/CertificateImpl.cxx | 10 | ||||
-rw-r--r-- | xmlsecurity/source/gpg/SEInitializer.cxx | 5 | ||||
-rw-r--r-- | xmlsecurity/source/gpg/SecurityEnvironment.cxx | 54 | ||||
-rw-r--r-- | xmlsecurity/source/gpg/SecurityEnvironment.hxx | 5 | ||||
-rw-r--r-- | xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx | 42 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecctl.cxx | 2 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecparser.cxx | 32 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecparser.hxx | 4 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecverify.cxx | 22 |
10 files changed, 100 insertions, 77 deletions
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()) |