|
|
|
/**
|
|
|
|
* 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 <tdeconfig.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( TDEConfig* config,
|
|
|
|
const TQString& cfgGroup,
|
|
|
|
const TQString& cfgAttributeOrderEntry,
|
|
|
|
const TQString& cfgUnknownAttrsEntry,
|
|
|
|
const TQStringList& fallbackAttrOrder = TQStringList(),
|
|
|
|
UnknownAttrsHandling fallbackUnknowAttrsHandling = unknownAttrsInfix )
|
|
|
|
{
|
|
|
|
_unknownAttrsHandling = unknownAttrsInfix;
|
|
|
|
_unknownAttrsHandlingChar = "INFIX";
|
|
|
|
if( config ){
|
|
|
|
const TQString 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( TQStringList::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( TQStringList::ConstIterator itOrder = _attrOrder.begin();
|
|
|
|
itOrder != _attrOrder.end();
|
|
|
|
++itOrder ){
|
|
|
|
free( _attrOrderChar[ i ] );
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
delete[] _attrOrderChar;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList attrOrder() const
|
|
|
|
{
|
|
|
|
return _attrOrder;
|
|
|
|
}
|
|
|
|
char** attrOrderChar()
|
|
|
|
{
|
|
|
|
return _attrOrderChar;
|
|
|
|
}
|
|
|
|
|
|
|
|
UnknownAttrsHandling unknownAttrsHandling() const
|
|
|
|
{
|
|
|
|
return _unknownAttrsHandling;
|
|
|
|
}
|
|
|
|
const char* unknownAttrsHandlingChar() const
|
|
|
|
{
|
|
|
|
return _unknownAttrsHandlingChar;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQValueList< TQPair<TQString,TQString> > reorder( const TQValueList< TQPair<TQString,TQString> > & dn ) const
|
|
|
|
{
|
|
|
|
return reorder( dn, _attrOrder, _unknownAttrsHandling );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static TQValueList< TQPair<TQString,TQString> > reorder(
|
|
|
|
const TQValueList< TQPair<TQString,TQString> > & dn,
|
|
|
|
TQStringList attrOrder,
|
|
|
|
UnknownAttrsHandling unknownAttrsHandling )
|
|
|
|
{
|
|
|
|
if( !attrOrder.isEmpty() ){
|
|
|
|
TQPtrList< TQPair<TQString,TQString> > unknownEntries;
|
|
|
|
TQValueList< TQPair<TQString,TQString> > dnNew;
|
|
|
|
|
|
|
|
TQPair<TQString,TQString>* unknownEntry;
|
|
|
|
TQStringList::ConstIterator itOrder;
|
|
|
|
TQValueList< TQPair<TQString,TQString> >::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) << TQString((*itDN).first) <<" = " << TQString((*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:
|
|
|
|
TQStringList _attrOrder;
|
|
|
|
char** _attrOrderChar;
|
|
|
|
UnknownAttrsHandling _unknownAttrsHandling;
|
|
|
|
TQCString _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 ******************************************/
|
|
|
|
|
|
|
|
TQString 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 TQString::fromLocal8Bit( err.asString() );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* some special functions ************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
CryptPlugWrapper::CryptPlugWrapper( const TQString& name,
|
|
|
|
const TQString& libName,
|
|
|
|
const TQString& update,
|
|
|
|
bool active )
|
|
|
|
: Kleo::CryptoBackend::Protocol(),
|
|
|
|
_name( name ),
|
|
|
|
_libName( libName ),
|
|
|
|
_updateURL( update ),
|
|
|
|
_active( active ),
|
|
|
|
_iniStatus( IniStatus_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 TQString& 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.
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString CryptPlugWrapper::libName() const
|
|
|
|
{
|
|
|
|
return _libName;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString CryptPlugWrapper::protocol() const
|
|
|
|
{
|
|
|
|
if ( _libName.contains( "smime" ) )
|
|
|
|
return "SMIME";
|
|
|
|
if ( _libName.contains( "openpgp" ) )
|
|
|
|
return "OpenPGP";
|
|
|
|
return TQString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CryptPlugWrapper::setDisplayName( const TQString& name )
|
|
|
|
{
|
|
|
|
_name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQString 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( IniStatus* iniStatus, TQString* errorMsg )
|
|
|
|
{
|
|
|
|
if ( _cp )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
_iniStatus = IniStatus_undef;
|
|
|
|
/* make sure we have a lib name */
|
|
|
|
if ( _libName.isEmpty() ) {
|
|
|
|
_iniStatus = IniStatus_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 ) {
|
|
|
|
_iniStatus = IniStatus_LoadError;
|
|
|
|
kdDebug(5150) << "Couldn't create '" << _libName.latin1() << "'" << endl;
|
|
|
|
} else {
|
|
|
|
/* now call the init function */
|
|
|
|
if( !_cp->initialize() ) {
|
|
|
|
_iniStatus = IniStatus_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 {
|
|
|
|
_iniStatus = IniStatus_Ok;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( iniStatus )
|
|
|
|
*iniStatus = _iniStatus;
|
|
|
|
return _iniStatus == IniStatus_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CryptPlugWrapper::deinitialize()
|
|
|
|
{
|
|
|
|
delete _cp; _cp = 0;
|
|
|
|
delete _config; _config = 0;
|
|
|
|
delete _cryptoConfig; _cryptoConfig = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CryptPlugWrapper::IniStatus CryptPlugWrapper::iniStatus( TQString* errorMsg ) const
|
|
|
|
{
|
|
|
|
if( errorMsg )
|
|
|
|
*errorMsg = _lastError;
|
|
|
|
return _iniStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 TQString& 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 );
|
|
|
|
}
|