summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorThorsten Behrens <Thorsten.Behrens@CIB.de>2017-06-21 16:54:52 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-06-21 22:16:56 +0200
commit4ddb2f716fa5501271bfb2d270a56562ddb5051d (patch)
treec59899614a26083e43cb34eb2cef1fdd304455fb /xmlsecurity
parentc88063e80d464af195afe88d558a44ef77d69f4a (diff)
gpg4libre: some code improvements, add metadata for OpenPGP keys
Change-Id: I1beb692b9a9a34b5f0cf743ba9e4a145ac582184
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/sigstruct.hxx1
-rw-r--r--xmlsecurity/inc/xsecctl.hxx2
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx1
-rw-r--r--xmlsecurity/source/gpg/CertificateImpl.cxx10
-rw-r--r--xmlsecurity/source/gpg/SEInitializer.cxx5
-rw-r--r--xmlsecurity/source/gpg/SecurityEnvironment.cxx54
-rw-r--r--xmlsecurity/source/gpg/SecurityEnvironment.hxx5
-rw-r--r--xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx42
-rw-r--r--xmlsecurity/source/helper/xsecctl.cxx2
-rw-r--r--xmlsecurity/source/helper/xsecparser.cxx32
-rw-r--r--xmlsecurity/source/helper/xsecparser.hxx4
-rw-r--r--xmlsecurity/source/helper/xsecverify.cxx22
12 files changed, 103 insertions, 77 deletions
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())