summaryrefslogtreecommitdiffstats
path: root/certmanager/lib/cryptplugwrapper.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /certmanager/lib/cryptplugwrapper.cpp
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'certmanager/lib/cryptplugwrapper.cpp')
-rw-r--r--certmanager/lib/cryptplugwrapper.cpp850
1 files changed, 850 insertions, 0 deletions
diff --git a/certmanager/lib/cryptplugwrapper.cpp b/certmanager/lib/cryptplugwrapper.cpp
new file mode 100644
index 000000000..ce883d79f
--- /dev/null
+++ b/certmanager/lib/cryptplugwrapper.cpp
@@ -0,0 +1,850 @@
+/**
+ * cryptplugwrapper.cpp
+ *
+ * Copyright (c) 2001 Karl-Heinz Zimmer, Klaraelvdalens Datakonsult AB
+ *
+ * This CRYPTPLUG wrapper implementation is based on cryptplug.h by
+ * Karl-Heinz Zimmer which is based on 'The Aegypten Plugin API' as
+ * specified by Matthias Kalle Dalheimer, Klaraelvdalens Datakonsult AB,
+ * see file mua-integration.sgml located on Aegypten CVS:
+ * http://www.gnupg.org/aegypten/development.en.html
+ *
+ * purpose: Wrap up all Aegypten Plugin API functions in one C++ class
+ * for usage by KDE programs, e.g. KMail (or KMime, resp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cryptplugwrapper.h"
+#include "cryptplug.h"
+
+#include <backends/qgpgme/qgpgmekeylistjob.h>
+#include <backends/qgpgme/qgpgmeencryptjob.h>
+#include <backends/qgpgme/qgpgmedecryptjob.h>
+#include <backends/qgpgme/qgpgmesignjob.h>
+#include <backends/qgpgme/qgpgmeverifydetachedjob.h>
+#include <backends/qgpgme/qgpgmeverifyopaquejob.h>
+#include <backends/qgpgme/qgpgmekeygenerationjob.h>
+#include <backends/qgpgme/qgpgmeimportjob.h>
+#include <backends/qgpgme/qgpgmeexportjob.h>
+#include <backends/qgpgme/qgpgmesecretkeyexportjob.h>
+#include <backends/qgpgme/qgpgmedownloadjob.h>
+#include <backends/qgpgme/qgpgmedeletejob.h>
+#include <backends/qgpgme/qgpgmesignencryptjob.h>
+#include <backends/qgpgme/qgpgmedecryptverifyjob.h>
+#include <backends/qgpgme/qgpgmecryptoconfig.h>
+#include <backends/qgpgme/qgpgmerefreshkeysjob.h>
+
+// qgpgme
+#include <qgpgme/dataprovider.h>
+
+// gpgme++
+#include <gpgmepp/data.h>
+#include <gpgmepp/importresult.h>
+#include <gpgmepp/keygenerationresult.h>
+
+// kde
+#include <kdebug.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kconfig.h>
+
+// other
+#include <memory>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+
+
+/*
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This file's source comments - as well as those in interface file *
+ * cryptplugwrapper.h - are optimized for processing by Doxygen. *
+ * *
+ * To obtain best results please get an updated version of Doxygen, *
+ * for sources and binaries goto http://www.doxygen.org/index.html *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ */
+
+
+
+/*! \file cryptplugwrapper.cpp
+ \brief C++ wrapper for the CRYPTPLUG library API.
+
+ This CRYPTPLUG wrapper implementation is based on cryptplug.h by
+ Karl-Heinz Zimmer which is based on 'The Aegypten Plugin API' as
+ specified by Matthias Kalle Dalheimer, Klaraelvdalens Datakonsult AB,
+ see file mua-integration.sgml located on Aegypten CVS:
+ http://www.gnupg.org/aegypten/development.en.html
+
+ purpose: Wrap up all Aegypten Plugin API functions in one C++ class
+ for usage by KDE programs, e.g. KMail (or KMime, resp.)
+
+ CRYPTPLUG is an independent cryptography plug-in API
+ developed for Sphinx-enabeling KMail and Mutt.
+
+ CRYPTPLUG was designed for the Aegypten project, but it may
+ be used by 3rd party developers as well to design pluggable
+ crypto backends for the above mentioned MUAs.
+
+ \note All string parameters appearing in this API are to be
+ interpreted as UTF-8 encoded.
+
+ \see cryptplugwrapper.h
+*/
+
+
+// a little helper class for reordering of DN attributes
+class DNBeautifier {
+public:
+ enum UnknownAttrsHandling { unknownAttrsHide,
+ unknownAttrsPrefix,
+ unknownAttrsPostfix,
+ unknownAttrsInfix };
+ // infix: at the position of "_X_", if any, else Postfix
+
+ DNBeautifier()
+ {
+ // the attrOrder is defaulted to an empty string automatically
+ _unknownAttrsHandling = unknownAttrsInfix;
+ _unknownAttrsHandlingChar = "INFIX";
+ }
+ DNBeautifier( KConfig* config,
+ const QString& cfgGroup,
+ const QString& cfgAttributeOrderEntry,
+ const QString& cfgUnknownAttrsEntry,
+ const QStringList& fallbackAttrOrder = QStringList(),
+ UnknownAttrsHandling fallbackUnknowAttrsHandling = unknownAttrsInfix )
+ {
+ _unknownAttrsHandling = unknownAttrsInfix;
+ _unknownAttrsHandlingChar = "INFIX";
+ if( config ){
+ const QString oldGroup( config->group() );
+ config->setGroup( cfgGroup ); // e.g. "General"
+ _attrOrder =
+ config->readListEntry( cfgAttributeOrderEntry ); // e.g. "DNAttributeOrder"
+ _unknownAttrsHandlingChar =
+ config->readEntry( cfgUnknownAttrsEntry ).upper().latin1(); // e.g. "DNUnknownAttributes"
+ config->setGroup( oldGroup );
+ if( _unknownAttrsHandlingChar == "HIDE" )
+ _unknownAttrsHandling = unknownAttrsHide;
+ else if( _unknownAttrsHandlingChar == "PREFIX" )
+ _unknownAttrsHandling = unknownAttrsPrefix;
+ else if( _unknownAttrsHandlingChar == "POSTFIX" )
+ _unknownAttrsHandling = unknownAttrsPostfix;
+ else if( _unknownAttrsHandlingChar == "INFIX" )
+ _unknownAttrsHandling = unknownAttrsInfix;
+ else
+ _unknownAttrsHandlingChar = "INFIX";
+ }
+ if( _attrOrder.isEmpty() && ! fallbackAttrOrder.isEmpty() )
+ _attrOrder = fallbackAttrOrder;
+
+ if( _attrOrder.isEmpty() ){
+ _attrOrderChar = 0;
+ }else{
+ _attrOrderChar = new char*[ _attrOrder.count()+1 ];
+ int i=0;
+ for( QStringList::ConstIterator itOrder = _attrOrder.begin();
+ itOrder != _attrOrder.end();
+ ++itOrder ){
+ _attrOrderChar[ i ] = (char*)malloc( ((*itOrder).length()+1)*sizeof(char) );
+ strcpy( _attrOrderChar[ i ], (*itOrder).latin1() );
+ ++i;
+ }
+ _attrOrderChar[ i ] = NULL;
+ }
+ }
+ ~DNBeautifier()
+ {
+ int i=0;
+ for( QStringList::ConstIterator itOrder = _attrOrder.begin();
+ itOrder != _attrOrder.end();
+ ++itOrder ){
+ free( _attrOrderChar[ i ] );
+ ++i;
+ }
+ delete[] _attrOrderChar;
+ }
+
+ QStringList attrOrder() const
+ {
+ return _attrOrder;
+ }
+ char** attrOrderChar()
+ {
+ return _attrOrderChar;
+ }
+
+ UnknownAttrsHandling unknownAttrsHandling() const
+ {
+ return _unknownAttrsHandling;
+ }
+ const char* unknownAttrsHandlingChar() const
+ {
+ return _unknownAttrsHandlingChar;
+ }
+
+ QValueList< QPair<QString,QString> > reorder( const QValueList< QPair<QString,QString> > & dn ) const
+ {
+ return reorder( dn, _attrOrder, _unknownAttrsHandling );
+ }
+
+
+ static QValueList< QPair<QString,QString> > reorder(
+ const QValueList< QPair<QString,QString> > & dn,
+ QStringList attrOrder,
+ UnknownAttrsHandling unknownAttrsHandling )
+ {
+ if( !attrOrder.isEmpty() ){
+ QPtrList< QPair<QString,QString> > unknownEntries;
+ QValueList< QPair<QString,QString> > dnNew;
+
+ QPair<QString,QString>* unknownEntry;
+ QStringList::ConstIterator itOrder;
+ QValueList< QPair<QString,QString> >::ConstIterator itDN;
+ bool bFound;
+
+ if( unknownAttrsHandling != unknownAttrsHide ){
+ // find all unknown entries in their order of appearance
+ for( itDN = dn.begin(); itDN != dn.end(); ++itDN ){
+ bFound = false;
+ for( itOrder = attrOrder.begin(); itOrder != attrOrder.end(); ++itOrder ){
+ if( (*itOrder) == (*itDN).first ){
+ bFound = true;
+ break;
+ }
+ }
+ if( !bFound )
+ unknownEntries.append( &(*itDN) );
+ }
+ }
+
+ // prepend the unknown attrs (if desired)
+ if( unknownAttrsHandling == unknownAttrsPrefix ){
+ for( unknownEntry = unknownEntries.first(); unknownEntry; unknownEntry = unknownEntries.next() ){
+ dnNew << *unknownEntry;
+ }
+ }
+
+ // process the known attrs in the desired order
+ bool b_X_declared = false;
+ for( itOrder = attrOrder.begin(); itOrder != attrOrder.end(); ++itOrder ){
+ if( (*itOrder) == "_X_" ){
+ b_X_declared = true;
+ // insert the unknown attrs (if desired)
+ if( unknownAttrsHandling == unknownAttrsInfix ){
+ for( unknownEntry = unknownEntries.first(); unknownEntry; unknownEntry = unknownEntries.next() ){
+ dnNew << *unknownEntry;
+ }
+ }
+ }else{
+ for( itDN = dn.begin(); itDN != dn.end(); ++itDN ){
+ if( (*itOrder) == (*itDN).first ){
+ dnNew << *itDN;
+ //kdDebug(5150) << QString((*itDN).first) <<" = " << QString((*itDN).second) << endl;;
+ }
+ }
+ }
+ }
+
+ // append the unknown attrs (if desired)
+ if( unknownAttrsHandling == unknownAttrsPostfix ||
+ ( unknownAttrsHandling == unknownAttrsInfix && ! b_X_declared ) ){
+ for( unknownEntry = unknownEntries.first(); unknownEntry; unknownEntry = unknownEntries.next() ){
+ dnNew << *unknownEntry;
+ }
+ }
+
+ return dnNew;
+ }
+ return dn;
+ }
+
+private:
+ QStringList _attrOrder;
+ char** _attrOrderChar;
+ UnknownAttrsHandling _unknownAttrsHandling;
+ QCString _unknownAttrsHandlingChar;
+};
+
+
+
+/* special helper class to be used by signing/encrypting functions *******/
+
+
+
+StructuringInfoWrapper::StructuringInfoWrapper( CryptPlugWrapper* wrapper )
+ : _initDone( false ), _wrapper( wrapper )
+{
+ initMe();
+}
+StructuringInfoWrapper::~StructuringInfoWrapper()
+{
+ freeMe();
+}
+void StructuringInfoWrapper::reset()
+{
+ freeMe();
+ initMe();
+}
+void StructuringInfoWrapper::initMe()
+{
+ if ( _wrapper && _wrapper->cryptPlug() ) {
+ _wrapper->cryptPlug()->init_StructuringInfo( &data );
+ _initDone = true;
+ }
+}
+void StructuringInfoWrapper::freeMe()
+{
+ if( _wrapper && _wrapper->cryptPlug() && _initDone ) {
+ _wrapper->cryptPlug()->free_StructuringInfo( &data );
+ _initDone = false;
+ }
+}
+
+class CryptPlugWrapper::Config {
+public:
+ Config( gpgme_protocol_t proto );
+ ~Config();
+
+ const char* signatureKeyCertificate;
+ SignatureAlgorithm signatureAlgorithm;
+ SignatureCompoundMode signatureCompoundMode;
+ SendCertificates sendCertificates;
+ bool saveSentSignatures;
+ bool warnNoCertificate;
+ bool signatureUseCRLs;
+ EncryptionAlgorithm encryptionAlgorithm;
+ EncryptEmail encryptEmail;
+ bool saveMessagesEncrypted;
+ bool encryptionUseCRLs;
+ bool encryptionCRLExpiryNearWarning;
+ int encryptionCRLNearExpiryInterval;
+ CertificateSource certificateSource;
+ bool warnSendUnsigned;
+ bool signatureCertificateExpiryNearWarning;
+ int signatureCertificateExpiryNearInterval;
+ bool cACertificateExpiryNearWarning;
+ int cACertificateExpiryNearInterval;
+ bool rootCertificateExpiryNearWarning;
+ int rootCertificateExpiryNearInterval;
+ bool warnSendUnencrypted;
+ bool checkCertificatePath;
+ bool receiverCertificateExpiryNearWarning;
+ int receiverCertificateExpiryNearWarningInterval;
+ bool certificateInChainExpiryNearWarning;
+ int certificateInChainExpiryNearWarningInterval;
+ bool receiverEmailAddressNotInCertificateWarning;
+ const char* libVersion; /* a statically allocated string with the GPGME Version used */
+};
+
+static const int NEAR_EXPIRY = 14;
+
+CryptPlugWrapper::Config::Config( gpgme_protocol_t proto )
+{
+ signatureAlgorithm = SignAlg_SHA1;
+ if ( proto == GPGME_PROTOCOL_CMS )
+ signatureCompoundMode = SignatureCompoundMode_Opaque;
+ else
+ signatureCompoundMode = SignatureCompoundMode_Detached;
+ sendCertificates = SendCert_SendChainWithRoot;
+ saveSentSignatures = true;
+ warnNoCertificate = true;
+ signatureUseCRLs = true;
+ encryptionAlgorithm = EncryptAlg_RSA;
+ encryptEmail = EncryptEmail_Ask;
+ saveMessagesEncrypted = true;
+ encryptionUseCRLs = true;
+ encryptionCRLExpiryNearWarning = false;
+ encryptionCRLNearExpiryInterval = NEAR_EXPIRY;
+ certificateSource = CertSrc_Server;
+ warnSendUnsigned = true;
+ signatureCertificateExpiryNearWarning = true;
+ signatureCertificateExpiryNearInterval = NEAR_EXPIRY;
+ cACertificateExpiryNearWarning = true;
+ cACertificateExpiryNearInterval = NEAR_EXPIRY;
+ rootCertificateExpiryNearWarning = true;
+ rootCertificateExpiryNearInterval = NEAR_EXPIRY;
+ warnSendUnencrypted = false;
+ checkCertificatePath = true;
+ receiverCertificateExpiryNearWarning = true;
+ receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY;
+ certificateInChainExpiryNearWarning = true;
+ certificateInChainExpiryNearWarningInterval = NEAR_EXPIRY;
+ receiverEmailAddressNotInCertificateWarning = true;
+ libVersion = gpgme_check_version (NULL);
+}
+
+CryptPlugWrapper::Config::~Config() {
+}
+
+/* Some multi purpose functions ******************************************/
+
+QString CryptPlugWrapper::errorIdToText( int errId, bool & isPassphraseError ) {
+ const GpgME::Error err( errId );
+ isPassphraseError = err.isCanceled()
+ || gpgme_err_code( errId ) == GPG_ERR_NO_SECKEY ; // FIXME: more?
+ return QString::fromLocal8Bit( err.asString() );
+}
+
+/* some special functions ************************************************/
+
+
+CryptPlugWrapper::CryptPlugWrapper( const QString& name,
+ const QString& libName,
+ const QString& update,
+ bool active )
+ : Kleo::CryptoBackend::Protocol(),
+ _name( name ),
+ _libName( libName ),
+ _updateURL( update ),
+ _active( active ),
+ _initStatus( InitStatus_undef ),
+ _cp( 0 ),
+ _config( 0 ),
+ _cryptoConfig( 0 )
+{
+ const bool ok = initialize( 0, 0 );
+ assert( ok );
+}
+
+
+CryptPlugWrapper::~CryptPlugWrapper()
+{
+ deinitialize();
+}
+
+
+void CryptPlugWrapper::setActive( bool active )
+{
+ _active = active;
+}
+
+
+bool CryptPlugWrapper::active() const
+{
+ return _active;
+}
+
+
+
+bool CryptPlugWrapper::setLibName( const QString& libName )
+{
+ bool bOk = ! _cp; // Changing the lib name is only allowed
+ if( bOk ) // when either no initialization took
+ _libName = libName; // place or 'deinitialize()' has been
+ return bOk; // called afterwards.
+}
+
+QString CryptPlugWrapper::libName() const
+{
+ return _libName;
+}
+
+QString CryptPlugWrapper::protocol() const
+{
+ if ( _libName.contains( "smime" ) )
+ return "SMIME";
+ if ( _libName.contains( "openpgp" ) )
+ return "OpenPGP";
+ return QString::null;
+}
+
+void CryptPlugWrapper::setDisplayName( const QString& name )
+{
+ _name = name;
+}
+
+
+QString CryptPlugWrapper::displayName() const
+{
+ if ( !_name.isEmpty() )
+ return _name;
+ if ( _libName.contains( "smime" ) )
+ return "gpgsm";
+ if ( _libName.contains( "openpgp" ) )
+ return "gpg";
+ return i18n("(Unknown Protocol)");
+}
+
+bool CryptPlugWrapper::initialize( InitStatus* initStatus, QString* errorMsg )
+{
+ if ( _cp )
+ return true;
+
+ _initStatus = InitStatus_undef;
+ /* make sure we have a lib name */
+ if ( _libName.isEmpty() ) {
+ _initStatus = InitStatus_NoLibName;
+ kdDebug(5150) << "No library name was given.\n" << endl;
+ } else {
+ if ( _libName.contains( "smime" ) ) {
+ _cp = new SMIMECryptPlug();
+ _config = new Config( GPGME_PROTOCOL_CMS );
+ } else if ( _libName.contains( "openpgp" ) ) {
+ _cp = new OpenPGPCryptPlug();
+ _config = new Config( GPGME_PROTOCOL_OpenPGP );
+ } else {
+ _cp = 0;
+ _config = 0;
+ }
+
+ if ( !_cp ) {
+ _initStatus = InitStatus_LoadError;
+ kdDebug(5150) << "Couldn't create '" << _libName.latin1() << "'" << endl;
+ } else {
+ /* now call the init function */
+ if( !_cp->initialize() ) {
+ _initStatus = InitStatus_InitError;
+ kdDebug(5150) << "Error while executing function 'initialize' on plugin " << _libName << endl;
+ _lastError = i18n("Error while initializing plugin \"%1\"").arg( _libName );
+ if ( errorMsg )
+ *errorMsg = _lastError;
+ delete _cp; _cp = 0;
+ delete _config; _config = 0;
+ } else {
+ _initStatus = InitStatus_Ok;
+ }
+ }
+ }
+ if( initStatus )
+ *initStatus = _initStatus;
+ return _initStatus == InitStatus_Ok;
+}
+
+
+
+void CryptPlugWrapper::deinitialize()
+{
+ delete _cp; _cp = 0;
+ delete _config; _config = 0;
+ delete _cryptoConfig; _cryptoConfig = 0;
+}
+
+
+CryptPlugWrapper::InitStatus CryptPlugWrapper::initStatus( QString* errorMsg ) const
+{
+ if( errorMsg )
+ *errorMsg = _lastError;
+ return _initStatus;
+}
+
+
+bool CryptPlugWrapper::hasFeature( Feature flag )
+{
+ return _cp && _cp->hasFeature( flag );
+}
+
+
+/* normal functions ******************************************************/
+
+bool CryptPlugWrapper::checkMessageSignature( char** cleartext,
+ const char* signaturetext,
+ bool signatureIsBinary,
+ int signatureLen,
+ CryptPlug::SignatureMetaData* sigmeta )
+{
+ DNBeautifier dnBeautifier( kapp->config(),
+ "DN",
+ "AttributeOrder",
+ "UnknownAttributes" );
+ return _cp && _cp->checkMessageSignature( cleartext,
+ signaturetext,
+ signatureIsBinary,
+ signatureLen,
+ sigmeta,
+ dnBeautifier.attrOrderChar(),
+ dnBeautifier.unknownAttrsHandlingChar() );
+}
+
+
+bool CryptPlugWrapper::decryptMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ char** cleartext,
+ const char* certificate,
+ int* errId,
+ char** errTxt )
+{
+ return _cp && _cp->decryptMessage( ciphertext, cipherIsBinary, cipherLen,
+ (const char**)cleartext, certificate, errId, errTxt );
+}
+
+
+bool CryptPlugWrapper::decryptAndCheckMessage(
+ const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ char** cleartext,
+ const char* certificate,
+ bool* signatureFound,
+ CryptPlug::SignatureMetaData* sigmeta,
+ int* errId,
+ char** errTxt )
+{
+ DNBeautifier dnBeautifier( kapp->config(),
+ "DN",
+ "AttributeOrder",
+ "UnknownAttributes" );
+ return _cp && _cp->decryptAndCheckMessage( ciphertext,
+ cipherIsBinary,
+ cipherLen,
+ (const char**)cleartext,
+ certificate,
+ signatureFound,
+ sigmeta,
+ errId,
+ errTxt,
+ dnBeautifier.attrOrderChar(),
+ dnBeautifier.unknownAttrsHandlingChar() );
+}
+
+
+
+
+void CryptPlugWrapper::freeSignatureMetaData( CryptPlug::SignatureMetaData* sigmeta )
+{
+ if ( !sigmeta )
+ return;
+ free( sigmeta->status );
+ for( int i = 0; i < sigmeta->extended_info_count; ++i ) {
+ free( sigmeta->extended_info[i].creation_time );
+ free( (void*)sigmeta->extended_info[i].status_text );
+ free( (void*)sigmeta->extended_info[i].keyid );
+ free( (void*)sigmeta->extended_info[i].fingerprint );
+ free( (void*)sigmeta->extended_info[i].algo );
+ free( (void*)sigmeta->extended_info[i].userid );
+ free( (void*)sigmeta->extended_info[i].name );
+ free( (void*)sigmeta->extended_info[i].comment );
+ if( sigmeta->extended_info[i].emailCount ){
+ for( int j=0; j < sigmeta->extended_info[i].emailCount; ++j)
+ if( sigmeta->extended_info[i].emailList[j] )
+ free( (void*)sigmeta->extended_info[i].emailList[j] );
+ free( (void*)sigmeta->extended_info[i].emailList );
+ }
+ }
+ free( sigmeta->extended_info );
+}
+
+GpgME::ImportResult CryptPlugWrapper::importCertificate( const char* data, size_t length )
+{
+ if ( !_cp )
+ return GpgME::ImportResult();
+
+
+ return _cp->importCertificateFromMem( data, length );
+}
+
+Kleo::KeyListJob * CryptPlugWrapper::keyListJob( bool remote, bool includeSigs, bool validate ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ unsigned int mode = context->keyListMode();
+ if ( remote ) {
+ mode |= GpgME::Context::Extern;
+ mode &= ~GpgME::Context::Local;
+ } else {
+ mode |= GpgME::Context::Local;
+ mode &= ~GpgME::Context::Extern;
+ }
+ if ( includeSigs ) mode |= GpgME::Context::Signatures;
+ if ( validate ) mode |= GpgME::Context::Validate;
+ context->setKeyListMode( mode );
+ return new Kleo::QGpgMEKeyListJob( context );
+}
+
+Kleo::EncryptJob * CryptPlugWrapper::encryptJob( bool armor, bool textmode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ context->setTextMode( textmode );
+ return new Kleo::QGpgMEEncryptJob( context );
+}
+
+Kleo::DecryptJob * CryptPlugWrapper::decryptJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEDecryptJob( context );
+}
+
+Kleo::SignJob * CryptPlugWrapper::signJob( bool armor, bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMESignJob( context );
+}
+
+Kleo::VerifyDetachedJob * CryptPlugWrapper::verifyDetachedJob( bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMEVerifyDetachedJob( context );
+}
+
+Kleo::VerifyOpaqueJob * CryptPlugWrapper::verifyOpaqueJob( bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMEVerifyOpaqueJob( context );
+}
+
+Kleo::KeyGenerationJob * CryptPlugWrapper::keyGenerationJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEKeyGenerationJob( context );
+}
+
+Kleo::ImportJob * CryptPlugWrapper::importJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEImportJob( context );
+}
+
+Kleo::ExportJob * CryptPlugWrapper::publicKeyExportJob( bool armor ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ return new Kleo::QGpgMEExportJob( context );
+}
+
+Kleo::ExportJob * CryptPlugWrapper::secretKeyExportJob( bool armor, const QString& charset ) const {
+ if ( !_cp || _cp->mProtocol != GpgME::Context::CMS ) // fixme: add support for gpg, too
+ return 0;
+
+ // this operation is not supported by gpgme, so we have to call gpgsm ourselves:
+ return new Kleo::QGpgMESecretKeyExportJob( armor, charset );
+}
+
+Kleo::RefreshKeysJob * CryptPlugWrapper::refreshKeysJob() const {
+ if ( !_cp || _cp->mProtocol != GpgME::Context::CMS ) // fixme: add support for gpg, too
+ return 0;
+
+ // this operation is not supported by gpgme, so we have to call gpgsm ourselves:
+ return new Kleo::QGpgMERefreshKeysJob();
+}
+
+Kleo::DownloadJob * CryptPlugWrapper::downloadJob( bool armor ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ // this is the hackish interface for downloading from keyserers currently:
+ context->setKeyListMode( GpgME::Context::Extern );
+
+ return new Kleo::QGpgMEDownloadJob( context );
+}
+
+Kleo::DeleteJob * CryptPlugWrapper::deleteJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEDeleteJob( context );
+}
+
+Kleo::SignEncryptJob * CryptPlugWrapper::signEncryptJob( bool armor, bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMESignEncryptJob( context );
+}
+
+Kleo::DecryptVerifyJob * CryptPlugWrapper::decryptVerifyJob( bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMEDecryptVerifyJob( context );
+}