00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "keyresolver.h"
00038
00039 #include "kcursorsaver.h"
00040 #include "kleo_util.h"
00041
00042 #include <kpimutils/email.h>
00043 #include "libkleo/ui/keyselectiondialog.h"
00044 #include "kleo/cryptobackendfactory.h"
00045 #include "kleo/keylistjob.h"
00046 #include "kleo/dn.h"
00047
00048 #include <gpgme++/key.h>
00049 #include <gpgme++/keylistresult.h>
00050
00051 #include <kabc/stdaddressbook.h>
00052 #include <klocale.h>
00053 #include <kdebug.h>
00054 #include <kinputdialog.h>
00055 #include <kmessagebox.h>
00056
00057 #include <QStringList>
00058 #include <time.h>
00059
00060 #include <algorithm>
00061 #include <memory>
00062 #include <iterator>
00063 #include <functional>
00064 #include <map>
00065 #include <set>
00066 #include <iostream>
00067 #include <cassert>
00068
00069
00070
00071
00072
00073
00074 static inline bool EmptyKeyList( const Kleo::KeyApprovalDialog::Item & item ) {
00075 return item.keys.empty();
00076 }
00077
00078 static inline QString ItemDotAddress( const Kleo::KeyResolver::Item & item ) {
00079 return item.address;
00080 }
00081
00082 static inline bool ApprovalNeeded( const Kleo::KeyResolver::Item & item ) {
00083 return item.pref == Kleo::UnknownPreference || item.pref == Kleo::NeverEncrypt || item.keys.empty() ;
00084 }
00085
00086 static inline Kleo::KeyResolver::Item
00087 CopyKeysAndEncryptionPreferences( const Kleo::KeyResolver::Item & oldItem,
00088 const Kleo::KeyApprovalDialog::Item & newItem ) {
00089 return Kleo::KeyResolver::Item( oldItem.address, newItem.keys, newItem.pref, oldItem.signPref, oldItem.format );
00090 }
00091
00092 static inline bool ByKeyID( const GpgME::Key & left, const GpgME::Key & right ) {
00093 return qstrcmp( left.keyID(), right.keyID() ) < 0 ;
00094 }
00095
00096 static inline bool WithRespectToKeyID( const GpgME::Key & left, const GpgME::Key & right ) {
00097 return qstrcmp( left.keyID(), right.keyID() ) == 0 ;
00098 }
00099
00100 static bool ValidTrustedOpenPGPEncryptionKey( const GpgME::Key & key ) {
00101 if ( key.protocol() != GpgME::OpenPGP ) {
00102 return false;
00103 }
00104 #if 0
00105 if ( key.isRevoked() )
00106 kWarning(5006) <<" is revoked";
00107 if ( key.isExpired() )
00108 kWarning(5006) <<" is expired";
00109 if ( key.isDisabled() )
00110 kWarning(5006) <<" is disabled";
00111 if ( !key.canEncrypt() )
00112 kWarning(5006) <<" can't encrypt";
00113 #endif
00114 if ( key.isRevoked() || key.isExpired() || key.isDisabled() || !key.canEncrypt() )
00115 return false;
00116 const std::vector<GpgME::UserID> uids = key.userIDs();
00117 for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it ) {
00118 if ( !it->isRevoked() && it->validity() != GpgME::UserID::Marginal )
00119 return true;
00120 #if 0
00121 else
00122 if ( it->isRevoked() )
00123 kWarning(5006) <<"a userid is revoked";
00124 else
00125 kWarning(5006) <<"bad validity" << it->validity();
00126 #endif
00127 }
00128 return false;
00129 }
00130
00131 static bool ValidTrustedSMIMEEncryptionKey( const GpgME::Key & key ) {
00132 if ( key.protocol() != GpgME::CMS )
00133 return false;
00134 if ( key.isRevoked() || key.isExpired() || key.isDisabled() || !key.canEncrypt() )
00135 return false;
00136 return true;
00137 }
00138
00139 static inline bool ValidTrustedEncryptionKey( const GpgME::Key & key ) {
00140 switch ( key.protocol() ) {
00141 case GpgME::OpenPGP:
00142 return ValidTrustedOpenPGPEncryptionKey( key );
00143 case GpgME::CMS:
00144 return ValidTrustedSMIMEEncryptionKey( key );
00145 default:
00146 return false;
00147 }
00148 }
00149
00150 static inline bool ValidSigningKey( const GpgME::Key & key ) {
00151 if ( key.isRevoked() || key.isExpired() || key.isDisabled() || !key.canSign() )
00152 return false;
00153 return key.hasSecret();
00154 }
00155
00156 static inline bool ValidOpenPGPSigningKey( const GpgME::Key & key ) {
00157 return key.protocol() == GpgME::OpenPGP && ValidSigningKey( key );
00158 }
00159
00160 static inline bool ValidSMIMESigningKey( const GpgME::Key & key ) {
00161 return key.protocol() == GpgME::CMS && ValidSigningKey( key );
00162 }
00163
00164 static inline bool NotValidTrustedOpenPGPEncryptionKey( const GpgME::Key & key ) {
00165 return !ValidTrustedOpenPGPEncryptionKey( key );
00166 }
00167
00168 static inline bool NotValidTrustedSMIMEEncryptionKey( const GpgME::Key & key ) {
00169 return !ValidTrustedSMIMEEncryptionKey( key );
00170 }
00171
00172 static inline bool NotValidTrustedEncryptionKey( const GpgME::Key & key ) {
00173 return !ValidTrustedEncryptionKey( key );
00174 }
00175
00176 static inline bool NotValidSigningKey( const GpgME::Key & key ) {
00177 return !ValidSigningKey( key );
00178 }
00179
00180 static inline bool NotValidOpenPGPSigningKey( const GpgME::Key & key ) {
00181 return !ValidOpenPGPSigningKey( key );
00182 }
00183
00184 static inline bool NotValidSMIMESigningKey( const GpgME::Key & key ) {
00185 return !ValidSMIMESigningKey( key );
00186 }
00187
00188 static QStringList keysAsStrings( const std::vector<GpgME::Key>& keys ) {
00189 QStringList strings;
00190 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it ) {
00191 assert( !(*it).userID(0).isNull() );
00192 QString keyLabel = QString::fromUtf8( (*it).userID(0).email() );
00193 if ( keyLabel.isEmpty() )
00194 keyLabel = QString::fromUtf8( (*it).userID(0).name() );
00195 if ( keyLabel.isEmpty() )
00196 keyLabel = QString::fromUtf8( (*it).userID(0).id() );
00197 strings.append( keyLabel );
00198 }
00199 return strings;
00200 }
00201
00202 static inline std::vector<GpgME::Key> TrustedOrConfirmed( const std::vector<GpgME::Key> & keys ) {
00203
00204 std::vector<GpgME::Key> fishies;
00205 std::vector<GpgME::Key> ickies;
00206 std::vector<GpgME::Key>::const_iterator it = keys.begin();
00207 const std::vector<GpgME::Key>::const_iterator end = keys.end();
00208 for ( ; it != end ; ++it ) {
00209 const GpgME::Key key = *it;
00210 assert( ValidTrustedEncryptionKey( key ) );
00211 const std::vector<GpgME::UserID> uids = key.userIDs();
00212 for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it ) {
00213 if ( !it->isRevoked() && it->validity() == GpgME::UserID::Marginal ) {
00214 fishies.push_back( key );
00215 break;
00216 }
00217 if ( !it->isRevoked() && it->validity() < GpgME::UserID::Never ) {
00218 ickies.push_back( key );
00219 break;
00220 }
00221 }
00222 }
00223
00224 if ( fishies.empty() && ickies.empty() )
00225 return keys;
00226
00227
00228 QString msg = i18n("One or more of your configured OpenPGP encryption "
00229 "keys or S/MIME certificates is not fully trusted "
00230 "for encryption.");
00231
00232 if ( !fishies.empty() ) {
00233
00234 msg += i18n( "\nThe following keys are only marginally trusted: \n");
00235 msg += keysAsStrings( fishies ).join(",");
00236 }
00237 if ( !ickies.empty() ) {
00238 msg += i18n( "\nThe following keys or certificates have unknown trust level: \n");
00239 msg += keysAsStrings( ickies ).join(",");
00240 }
00241
00242 if( KMessageBox::warningContinueCancel( 0, msg, i18n("Not Fully Trusted Encryption Keys"),
00243 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
00244 "not fully trusted encryption key warning" )
00245 == KMessageBox::Continue )
00246 return keys;
00247 else
00248 return std::vector<GpgME::Key>();
00249 }
00250
00251 namespace {
00252 struct IsNotForFormat : public std::unary_function<GpgME::Key,bool> {
00253 IsNotForFormat( Kleo::CryptoMessageFormat f ) : format( f ) {}
00254
00255 bool operator()( const GpgME::Key & key ) const {
00256 return
00257 ( isOpenPGP( format ) && key.protocol() != GpgME::OpenPGP ) ||
00258 ( isSMIME( format ) && key.protocol() != GpgME::CMS );
00259 }
00260
00261 const Kleo::CryptoMessageFormat format;
00262 };
00263 }
00264
00265
00266
00267 class Kleo::KeyResolver::SigningPreferenceCounter : public std::unary_function<Kleo::KeyResolver::Item,void> {
00268 public:
00269 SigningPreferenceCounter()
00270 : mTotal( 0 ),
00271 mUnknownSigningPreference( 0 ),
00272 mNeverSign( 0 ),
00273 mAlwaysSign( 0 ),
00274 mAlwaysSignIfPossible( 0 ),
00275 mAlwaysAskForSigning( 0 ),
00276 mAskSigningWheneverPossible( 0 )
00277 {
00278
00279 }
00280 void operator()( const Kleo::KeyResolver::Item & item );
00281 #define make_int_accessor(x) unsigned int num##x() const { return m##x; }
00282 make_int_accessor(UnknownSigningPreference)
00283 make_int_accessor(NeverSign)
00284 make_int_accessor(AlwaysSign)
00285 make_int_accessor(AlwaysSignIfPossible)
00286 make_int_accessor(AlwaysAskForSigning)
00287 make_int_accessor(AskSigningWheneverPossible)
00288 make_int_accessor(Total)
00289 #undef make_int_accessor
00290 private:
00291 unsigned int mTotal;
00292 unsigned int mUnknownSigningPreference, mNeverSign, mAlwaysSign,
00293 mAlwaysSignIfPossible, mAlwaysAskForSigning, mAskSigningWheneverPossible;
00294 };
00295
00296 void Kleo::KeyResolver::SigningPreferenceCounter::operator()( const Kleo::KeyResolver::Item & item ) {
00297 switch ( item.signPref ) {
00298 #define CASE(x) case x: ++m##x; break
00299 CASE(UnknownSigningPreference);
00300 CASE(NeverSign);
00301 CASE(AlwaysSign);
00302 CASE(AlwaysSignIfPossible);
00303 CASE(AlwaysAskForSigning);
00304 CASE(AskSigningWheneverPossible);
00305 #undef CASE
00306 }
00307 ++mTotal;
00308 }
00309
00310
00311
00312 class Kleo::KeyResolver::EncryptionPreferenceCounter : public std::unary_function<Item,void> {
00313 const Kleo::KeyResolver * _this;
00314 public:
00315 EncryptionPreferenceCounter( const Kleo::KeyResolver * kr, EncryptionPreference defaultPreference )
00316 : _this( kr ),
00317 mDefaultPreference( defaultPreference ),
00318 mTotal( 0 ),
00319 mNoKey( 0 ),
00320 mNeverEncrypt( 0 ),
00321 mUnknownPreference( 0 ),
00322 mAlwaysEncrypt( 0 ),
00323 mAlwaysEncryptIfPossible( 0 ),
00324 mAlwaysAskForEncryption( 0 ),
00325 mAskWheneverPossible( 0 )
00326 {
00327
00328 }
00329 void operator()( Item & item );
00330
00331 #define make_int_accessor(x) unsigned int num##x() const { return m##x; }
00332 make_int_accessor(NoKey)
00333 make_int_accessor(NeverEncrypt)
00334 make_int_accessor(UnknownPreference)
00335 make_int_accessor(AlwaysEncrypt)
00336 make_int_accessor(AlwaysEncryptIfPossible)
00337 make_int_accessor(AlwaysAskForEncryption)
00338 make_int_accessor(AskWheneverPossible)
00339 make_int_accessor(Total)
00340 #undef make_int_accessor
00341 private:
00342 EncryptionPreference mDefaultPreference;
00343 unsigned int mTotal;
00344 unsigned int mNoKey;
00345 unsigned int mNeverEncrypt, mUnknownPreference, mAlwaysEncrypt,
00346 mAlwaysEncryptIfPossible, mAlwaysAskForEncryption, mAskWheneverPossible;
00347 };
00348
00349 void Kleo::KeyResolver::EncryptionPreferenceCounter::operator()( Item & item ) {
00350 if ( item.needKeys )
00351 item.keys = _this->getEncryptionKeys( item.address, true );
00352 if ( item.keys.empty() ) {
00353 ++mNoKey;
00354 return;
00355 }
00356 switch ( !item.pref ? mDefaultPreference : item.pref ) {
00357 #define CASE(x) case Kleo::x: ++m##x; break
00358 CASE(NeverEncrypt);
00359 CASE(UnknownPreference);
00360 CASE(AlwaysEncrypt);
00361 CASE(AlwaysEncryptIfPossible);
00362 CASE(AlwaysAskForEncryption);
00363 CASE(AskWheneverPossible);
00364 #undef CASE
00365 }
00366 ++mTotal;
00367 }
00368
00369 namespace {
00370
00371 class FormatPreferenceCounterBase : public std::unary_function<Kleo::KeyResolver::Item,void> {
00372 public:
00373 FormatPreferenceCounterBase()
00374 : mTotal( 0 ),
00375 mInlineOpenPGP( 0 ),
00376 mOpenPGPMIME( 0 ),
00377 mSMIME( 0 ),
00378 mSMIMEOpaque( 0 )
00379 {
00380
00381 }
00382
00383 #define make_int_accessor(x) unsigned int num##x() const { return m##x; }
00384 make_int_accessor(Total)
00385 make_int_accessor(InlineOpenPGP)
00386 make_int_accessor(OpenPGPMIME)
00387 make_int_accessor(SMIME)
00388 make_int_accessor(SMIMEOpaque)
00389 #undef make_int_accessor
00390
00391 unsigned int numOf( Kleo::CryptoMessageFormat f ) const {
00392 switch ( f ) {
00393 #define CASE(x) case Kleo::x##Format: return m##x
00394 CASE(InlineOpenPGP);
00395 CASE(OpenPGPMIME);
00396 CASE(SMIME);
00397 CASE(SMIMEOpaque);
00398 #undef CASE
00399 default: return 0;
00400 }
00401 }
00402
00403 protected:
00404 unsigned int mTotal;
00405 unsigned int mInlineOpenPGP, mOpenPGPMIME, mSMIME, mSMIMEOpaque;
00406 };
00407
00408 class EncryptionFormatPreferenceCounter : public FormatPreferenceCounterBase {
00409 public:
00410 EncryptionFormatPreferenceCounter() : FormatPreferenceCounterBase() {}
00411 void operator()( const Kleo::KeyResolver::Item & item );
00412 };
00413
00414 class SigningFormatPreferenceCounter : public FormatPreferenceCounterBase {
00415 public:
00416 SigningFormatPreferenceCounter() : FormatPreferenceCounterBase() {}
00417 void operator()( const Kleo::KeyResolver::Item & item );
00418 };
00419
00420 #define CASE(x) if ( item.format & Kleo::x##Format ) ++m##x;
00421 void EncryptionFormatPreferenceCounter::operator()( const Kleo::KeyResolver::Item & item ) {
00422 if ( item.format & (Kleo::InlineOpenPGPFormat|Kleo::OpenPGPMIMEFormat) &&
00423 std::find_if( item.keys.begin(), item.keys.end(),
00424 ValidTrustedOpenPGPEncryptionKey ) != item.keys.end() ) {
00425 CASE(OpenPGPMIME);
00426 CASE(InlineOpenPGP);
00427 }
00428 if ( item.format & (Kleo::SMIMEFormat|Kleo::SMIMEOpaqueFormat) &&
00429 std::find_if( item.keys.begin(), item.keys.end(),
00430 ValidTrustedSMIMEEncryptionKey ) != item.keys.end() ) {
00431 CASE(SMIME);
00432 CASE(SMIMEOpaque);
00433 }
00434 ++mTotal;
00435 }
00436
00437 void SigningFormatPreferenceCounter::operator()( const Kleo::KeyResolver::Item & item ) {
00438 CASE(InlineOpenPGP);
00439 CASE(OpenPGPMIME);
00440 CASE(SMIME);
00441 CASE(SMIMEOpaque);
00442 ++mTotal;
00443 }
00444 #undef CASE
00445
00446 }
00447
00448 static QString canonicalAddress( const QString & _address ) {
00449 const QString address = KPIMUtils::extractEmailAddress( _address );
00450 if ( !address.contains('@') ) {
00451
00452
00453 return address + "@localdomain";
00454 }
00455 else
00456 return address;
00457 }
00458
00459
00460 struct FormatInfo {
00461 std::vector<Kleo::KeyResolver::SplitInfo> splitInfos;
00462 std::vector<GpgME::Key> signKeys;
00463 };
00464
00465 struct Kleo::KeyResolver::Private {
00466 std::set<QByteArray> alreadyWarnedFingerprints;
00467
00468 std::vector<GpgME::Key> mOpenPGPSigningKeys;
00469 std::vector<GpgME::Key> mSMIMESigningKeys;
00470
00471 std::vector<GpgME::Key> mOpenPGPEncryptToSelfKeys;
00472 std::vector<GpgME::Key> mSMIMEEncryptToSelfKeys;
00473
00474 std::vector<Item> mPrimaryEncryptionKeys;
00475 std::vector<Item> mSecondaryEncryptionKeys;
00476
00477 std::map<CryptoMessageFormat,FormatInfo> mFormatInfoMap;
00478
00479
00480 typedef std::map<QString, ContactPreferences> ContactPreferencesMap;
00481 ContactPreferencesMap mContactPreferencesMap;
00482 };
00483
00484
00485 Kleo::KeyResolver::KeyResolver( bool encToSelf, bool showApproval, bool oppEncryption,
00486 unsigned int f,
00487 int encrWarnThresholdKey, int signWarnThresholdKey,
00488 int encrWarnThresholdRootCert, int signWarnThresholdRootCert,
00489 int encrWarnThresholdChainCert, int signWarnThresholdChainCert )
00490 : mEncryptToSelf( encToSelf ),
00491 mShowApprovalDialog( showApproval ),
00492 mOpportunisticEncyption( oppEncryption ),
00493 mCryptoMessageFormats( f ),
00494 mEncryptKeyNearExpiryWarningThreshold( encrWarnThresholdKey ),
00495 mSigningKeyNearExpiryWarningThreshold( signWarnThresholdKey ),
00496 mEncryptRootCertNearExpiryWarningThreshold( encrWarnThresholdRootCert ),
00497 mSigningRootCertNearExpiryWarningThreshold( signWarnThresholdRootCert ),
00498 mEncryptChainCertNearExpiryWarningThreshold( encrWarnThresholdChainCert ),
00499 mSigningChainCertNearExpiryWarningThreshold( signWarnThresholdChainCert )
00500 {
00501 d = new Private();
00502 }
00503
00504 Kleo::KeyResolver::~KeyResolver() {
00505 delete d; d = 0;
00506 }
00507
00508 Kpgp::Result Kleo::KeyResolver::checkKeyNearExpiry( const GpgME::Key & key, const char * dontAskAgainName,
00509 bool mine, bool sign, bool ca,
00510 int recur_limit, const GpgME::Key & orig ) const
00511 {
00512 if ( recur_limit <= 0 ) {
00513 kDebug(5006) << "Key chain too long (>100 certs)";
00514 return Kpgp::Ok;
00515 }
00516 const GpgME::Subkey subkey = key.subkey(0);
00517 if ( d->alreadyWarnedFingerprints.count( subkey.fingerprint() ) )
00518 return Kpgp::Ok;
00519 d->alreadyWarnedFingerprints.insert( subkey.fingerprint() );
00520
00521 if ( subkey.neverExpires() )
00522 return Kpgp::Ok;
00523 static const double secsPerDay = 24 * 60 * 60;
00524 const int daysTillExpiry =
00525 1 + int( ::difftime( subkey.expirationTime(), time(0) ) / secsPerDay );
00526 kDebug(5006) <<"Key 0x" << key.shortKeyID() <<"expires in less than"
00527 << daysTillExpiry << "days";
00528 const int threshold =
00529 ca
00530 ? ( key.isRoot()
00531 ? ( sign
00532 ? signingRootCertNearExpiryWarningThresholdInDays()
00533 : encryptRootCertNearExpiryWarningThresholdInDays() )
00534 : ( sign
00535 ? signingChainCertNearExpiryWarningThresholdInDays()
00536 : encryptChainCertNearExpiryWarningThresholdInDays() ) )
00537 : ( sign
00538 ? signingKeyNearExpiryWarningThresholdInDays()
00539 : encryptKeyNearExpiryWarningThresholdInDays() );
00540 if ( threshold > -1 && daysTillExpiry <= threshold ) {
00541 const QString msg =
00542 key.protocol() == GpgME::OpenPGP
00543 ? ( mine ? sign
00544 ? ki18np("<p>Your OpenPGP signing key</p><p align=\"center\"><b>%2</b> (KeyID 0x%3)</p>"
00545 "<p>expires in less than a day.</p>",
00546 "<p>Your OpenPGP signing key</p><p align=\"center\"><b>%2</b> (KeyID 0x%3)</p>"
00547 "<p>expires in less than %1 days.</p>")
00548 : ki18np("<p>Your OpenPGP encryption key</p><p align=\"center\"><b>%2</b> (KeyID 0x%3)</p>"
00549 "<p>expires in less than a day.</p>",
00550 "<p>Your OpenPGP encryption key</p><p align=\"center\"><b>%2</b> (KeyID 0x%3)</p>"
00551 "<p>expires in less than %1 days.</p>")
00552 : ki18np("<p>The OpenPGP key for</p><p align=\"center\"><b>%2</b> (KeyID 0x%3)</p>"
00553 "<p>expires in less than a day.</p>",
00554 "<p>The OpenPGP key for</p><p align=\"center\"><b>%2</b> (KeyID 0x%3)</p>"
00555 "<p>expires in less than %1 days.</p>") )
00556 .subs( daysTillExpiry )
00557 .subs( QString::fromUtf8( key.userID(0).id() ) )
00558 .subs( key.shortKeyID() )
00559 .toString()
00560 : ( ca
00561 ? ( key.isRoot()
00562 ? ( mine ? sign
00563 ? ki18np("<p>The root certificate</p><p align=\"center\"><b>%4</b></p>"
00564 "<p>for your S/MIME signing certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00565 "<p>expires in less than a day.</p>",
00566 "<p>The root certificate</p><p align=\"center\"><b>%4</b></p>"
00567 "<p>for your S/MIME signing certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00568 "<p>expires in less than %1 days.</p>")
00569 : ki18np("<p>The root certificate</p><p align=\"center\"><b>%4</b></p>"
00570 "<p>for your S/MIME encryption certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00571 "<p>expires in less than a day.</p>",
00572 "<p>The root certificate</p><p align=\"center\"><b>%4</b></p>"
00573 "<p>for your S/MIME encryption certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00574 "<p>expires in less than %1 days.</p>")
00575 : ki18np("<p>The root certificate</p><p align=\"center\"><b>%4</b></p>"
00576 "<p>for S/MIME certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00577 "<p>expires in less than a day.</p>",
00578 "<p>The root certificate</p><p align=\"center\"><b>%4</b></p>"
00579 "<p>for S/MIME certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00580 "<p>expires in less than %1 days.</p>") )
00581 : ( mine ? sign
00582 ? ki18np("<p>The intermediate CA certificate</p><p align=\"center\"><b>%4</b></p>"
00583 "<p>for your S/MIME signing certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00584 "<p>expires in less than a day.</p>",
00585 "<p>The intermediate CA certificate</p><p align=\"center\"><b>%4</b></p>"
00586 "<p>for your S/MIME signing certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00587 "<p>expires in less than %1 days.</p>")
00588 : ki18np("<p>The intermediate CA certificate</p><p align=\"center\"><b>%4</b></p>"
00589 "<p>for your S/MIME encryption certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00590 "<p>expires in less than a day.</p>",
00591 "<p>The intermediate CA certificate</p><p align=\"center\"><b>%4</b></p>"
00592 "<p>for your S/MIME encryption certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00593 "<p>expires in less than %1 days.</p>")
00594 : ki18np("<p>The intermediate CA certificate</p><p align=\"center\"><b>%4</b></p>"
00595 "<p>for S/MIME certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00596 "<p>expires in less than a day.</p>",
00597 "<p>The intermediate CA certificate</p><p align=\"center\"><b>%4</b></p>"
00598 "<p>for S/MIME certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00599 "<p>expires in less than %1 days.</p>") ) )
00600 .subs( daysTillExpiry )
00601 .subs( Kleo::DN( orig.userID(0).id() ).prettyDN() )
00602 .subs( orig.issuerSerial() )
00603 .subs( Kleo::DN( key.userID(0).id() ).prettyDN() )
00604 .toString()
00605 : ( mine ? sign
00606 ? ki18np("<p>Your S/MIME signing certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00607 "<p>expires in less than a day.</p>",
00608 "<p>Your S/MIME signing certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00609 "<p>expires in less than %1 days.</p>")
00610 : ki18np("<p>Your S/MIME encryption certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00611 "<p>expires in less than a day.</p>",
00612 "<p>Your S/MIME encryption certificate</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00613 "<p>expires in less than %1 days.</p>")
00614 : ki18np("<p>The S/MIME certificate for</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00615 "<p>expires in less than a day.</p>",
00616 "<p>The S/MIME certificate for</p><p align=\"center\"><b>%2</b> (serial number %3)</p>"
00617 "<p>expires in less than %1 days.</p>" ) )
00618 .subs( daysTillExpiry )
00619 .subs( Kleo::DN( key.userID(0).id() ).prettyDN() )
00620 .subs( key.issuerSerial() )
00621 .toString() );
00622 if ( KMessageBox::warningContinueCancel( 0, msg,
00623 key.protocol() == GpgME::OpenPGP
00624 ? i18n("OpenPGP Key Expires Soon" )
00625 : i18n("S/MIME Certificate Expires Soon" ),
00626 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
00627 dontAskAgainName )
00628 == KMessageBox::Cancel )
00629 return Kpgp::Canceled;
00630 }
00631 if ( key.isRoot() )
00632 return Kpgp::Ok;
00633 else if ( const char * chain_id = key.chainID() ) {
00634 const std::vector<GpgME::Key> issuer = lookup( QStringList( chain_id ), false );
00635 if ( issuer.empty() )
00636 return Kpgp::Ok;
00637 else
00638 return checkKeyNearExpiry( issuer.front(), dontAskAgainName, mine, sign,
00639 true, recur_limit-1, ca ? orig : key );
00640 }
00641 return Kpgp::Ok;
00642 }
00643
00644 Kpgp::Result Kleo::KeyResolver::setEncryptToSelfKeys( const QStringList & fingerprints ) {
00645 if ( !encryptToSelf() )
00646 return Kpgp::Ok;
00647
00648 std::vector<GpgME::Key> keys = lookup( fingerprints );
00649 std::remove_copy_if( keys.begin(), keys.end(),
00650 std::back_inserter( d->mOpenPGPEncryptToSelfKeys ),
00651 NotValidTrustedOpenPGPEncryptionKey );
00652 std::remove_copy_if( keys.begin(), keys.end(),
00653 std::back_inserter( d->mSMIMEEncryptToSelfKeys ),
00654 NotValidTrustedSMIMEEncryptionKey );
00655
00656 if ( d->mOpenPGPEncryptToSelfKeys.size() + d->mSMIMEEncryptToSelfKeys.size()
00657 < keys.size() ) {
00658
00659 const QString msg = i18n("One or more of your configured OpenPGP encryption "
00660 "keys or S/MIME certificates is not usable for "
00661 "encryption. Please reconfigure your encryption keys "
00662 "and certificates for this identity in the identity "
00663 "configuration dialog.\n"
00664 "If you choose to continue, and the keys are needed "
00665 "later on, you will be prompted to specify the keys "
00666 "to use.");
00667 return KMessageBox::warningContinueCancel( 0, msg, i18n("Unusable Encryption Keys"),
00668 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
00669 "unusable own encryption key warning" )
00670 == KMessageBox::Continue ? Kpgp::Ok : Kpgp::Canceled ;
00671 }
00672
00673
00674
00675 for ( std::vector<GpgME::Key>::const_iterator it = d->mOpenPGPEncryptToSelfKeys.begin() ; it != d->mOpenPGPEncryptToSelfKeys.end() ; ++it ) {
00676 const Kpgp::Result r = checkKeyNearExpiry( *it, "own encryption key expires soon warning",
00677 true, false );
00678 if ( r != Kpgp::Ok )
00679 return r;
00680 }
00681
00682 for ( std::vector<GpgME::Key>::const_iterator it = d->mSMIMEEncryptToSelfKeys.begin() ; it != d->mSMIMEEncryptToSelfKeys.end() ; ++it ) {
00683 const Kpgp::Result r = checkKeyNearExpiry( *it, "own encryption key expires soon warning",
00684 true, false );
00685 if ( r != Kpgp::Ok )
00686 return r;
00687 }
00688
00689 return Kpgp::Ok;
00690 }
00691
00692 Kpgp::Result Kleo::KeyResolver::setSigningKeys( const QStringList & fingerprints ) {
00693 std::vector<GpgME::Key> keys = lookup( fingerprints, true );
00694 std::remove_copy_if( keys.begin(), keys.end(),
00695 std::back_inserter( d->mOpenPGPSigningKeys ),
00696 NotValidOpenPGPSigningKey );
00697 std::remove_copy_if( keys.begin(), keys.end(),
00698 std::back_inserter( d->mSMIMESigningKeys ),
00699 NotValidSMIMESigningKey );
00700
00701 if ( d->mOpenPGPSigningKeys.size() + d->mSMIMESigningKeys.size() < keys.size() ) {
00702
00703 const QString msg = i18n("One or more of your configured OpenPGP signing keys "
00704 "or S/MIME signing certificates is not usable for "
00705 "signing. Please reconfigure your signing keys "
00706 "and certificates for this identity in the identity "
00707 "configuration dialog.\n"
00708 "If you choose to continue, and the keys are needed "
00709 "later on, you will be prompted to specify the keys "
00710 "to use.");
00711 return KMessageBox::warningContinueCancel( 0, msg, i18n("Unusable Signing Keys"),
00712 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
00713 "unusable signing key warning" )
00714 == KMessageBox::Continue ? Kpgp::Ok : Kpgp::Canceled ;
00715 }
00716
00717
00718
00719 for ( std::vector<GpgME::Key>::const_iterator it = d->mOpenPGPSigningKeys.begin() ; it != d->mOpenPGPSigningKeys.end() ; ++it ) {
00720 const Kpgp::Result r = checkKeyNearExpiry( *it, "signing key expires soon warning",
00721 true, true );
00722 if ( r != Kpgp::Ok )
00723 return r;
00724 }
00725
00726 for ( std::vector<GpgME::Key>::const_iterator it = d->mSMIMESigningKeys.begin() ; it != d->mSMIMESigningKeys.end() ; ++it ) {
00727 const Kpgp::Result r = checkKeyNearExpiry( *it, "signing key expires soon warning",
00728 true, true );
00729 if ( r != Kpgp::Ok )
00730 return r;
00731 }
00732
00733 return Kpgp::Ok;
00734 }
00735
00736 void Kleo::KeyResolver::setPrimaryRecipients( const QStringList & addresses ) {
00737 d->mPrimaryEncryptionKeys = getEncryptionItems( addresses );
00738 }
00739
00740 void Kleo::KeyResolver::setSecondaryRecipients( const QStringList & addresses ) {
00741 d->mSecondaryEncryptionKeys = getEncryptionItems( addresses );
00742 }
00743
00744 std::vector<Kleo::KeyResolver::Item> Kleo::KeyResolver::getEncryptionItems( const QStringList & addresses ) {
00745 std::vector<Item> items;
00746 items.reserve( addresses.size() );
00747 for ( QStringList::const_iterator it = addresses.begin() ; it != addresses.end() ; ++it ) {
00748 QString addr = canonicalAddress( *it ).toLower();
00749 const ContactPreferences pref = lookupContactPreferences( addr );
00750
00751 items.push_back( Item( *it,
00752 pref.encryptionPreference,
00753 pref.signingPreference,
00754 pref.cryptoMessageFormat ) );
00755 }
00756 return items;
00757 }
00758
00759 static Kleo::Action action( bool doit, bool ask, bool donot, bool requested ) {
00760 if ( requested && !donot )
00761 return Kleo::DoIt;
00762 if ( doit && !ask && !donot )
00763 return Kleo::DoIt;
00764 if ( !doit && ask && !donot )
00765 return Kleo::Ask;
00766 if ( !doit && !ask && donot )
00767 return requested ? Kleo::Conflict : Kleo::DontDoIt ;
00768 if ( !doit && !ask && !donot )
00769 return Kleo::DontDoIt ;
00770 return Kleo::Conflict;
00771 }
00772
00773 Kleo::Action Kleo::KeyResolver::checkSigningPreferences( bool signingRequested ) const {
00774
00775 if ( signingRequested && d->mOpenPGPSigningKeys.empty() && d->mSMIMESigningKeys.empty() )
00776 return Impossible;
00777
00778 SigningPreferenceCounter count;
00779 count = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
00780 count );
00781 count = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
00782 count );
00783
00784 unsigned int sign = count.numAlwaysSign();
00785 unsigned int ask = count.numAlwaysAskForSigning();
00786 const unsigned int dontSign = count.numNeverSign();
00787 if ( signingPossible() ) {
00788 sign += count.numAlwaysSignIfPossible();
00789 ask += count.numAskSigningWheneverPossible();
00790 }
00791
00792 return action( sign, ask, dontSign, signingRequested );
00793 }
00794
00795 bool Kleo::KeyResolver::signingPossible() const {
00796 return !d->mOpenPGPSigningKeys.empty() || !d->mSMIMESigningKeys.empty() ;
00797 }
00798
00799 Kleo::Action Kleo::KeyResolver::checkEncryptionPreferences( bool encryptionRequested ) const {
00800
00801 if ( d->mPrimaryEncryptionKeys.empty() && d->mSecondaryEncryptionKeys.empty() )
00802 return DontDoIt;
00803
00804 if ( encryptionRequested && encryptToSelf() &&
00805 d->mOpenPGPEncryptToSelfKeys.empty() && d->mSMIMEEncryptToSelfKeys.empty() )
00806 return Impossible;
00807
00808 EncryptionPreferenceCounter count( this, mOpportunisticEncyption ? AskWheneverPossible : UnknownPreference );
00809 count = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
00810 count );
00811 count = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
00812 count );
00813
00814 unsigned int encrypt = count.numAlwaysEncrypt();
00815 unsigned int ask = count.numAlwaysAskForEncryption();
00816 const unsigned int dontEncrypt = count.numNeverEncrypt() + count.numNoKey();
00817 if ( encryptionPossible() ) {
00818 encrypt += count.numAlwaysEncryptIfPossible();
00819 ask += count.numAskWheneverPossible();
00820 }
00821
00822 const Action act = action( encrypt, ask, dontEncrypt, encryptionRequested );
00823 if ( act != Ask ||
00824 std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
00825 std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
00826 EncryptionPreferenceCounter( this, UnknownPreference ) ) ).numAlwaysAskForEncryption() )
00827 return act;
00828 else
00829 return AskOpportunistic;
00830 }
00831
00832 bool Kleo::KeyResolver::encryptionPossible() const {
00833 return std::find_if( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
00834 EmptyKeyList ) == d->mPrimaryEncryptionKeys.end()
00835 && std::find_if( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
00836 EmptyKeyList ) == d->mSecondaryEncryptionKeys.end() ;
00837 }
00838
00839 Kpgp::Result Kleo::KeyResolver::resolveAllKeys( bool& signingRequested, bool& encryptionRequested ) {
00840 if ( !encryptionRequested && !signingRequested ) {
00841
00842
00843 dump();
00844 d->mFormatInfoMap[OpenPGPMIMEFormat].splitInfos.push_back( SplitInfo( allRecipients() ) );
00845 dump();
00846 return Kpgp::Ok;
00847 }
00848 Kpgp::Result result = Kpgp::Ok;
00849 if ( encryptionRequested )
00850 result = resolveEncryptionKeys( signingRequested );
00851 if ( result != Kpgp::Ok )
00852 return result;
00853 if ( signingRequested )
00854 if ( encryptionRequested )
00855 result = resolveSigningKeysForEncryption();
00856 else {
00857 result = resolveSigningKeysForSigningOnly();
00858 if ( result == Kpgp::Failure ) {
00859 signingRequested = false;
00860 return Kpgp::Ok;
00861 }
00862 }
00863 return result;
00864 }
00865
00866 Kpgp::Result Kleo::KeyResolver::resolveEncryptionKeys( bool signingRequested ) {
00867
00868
00869
00870
00871 for ( std::vector<Item>::iterator it = d->mPrimaryEncryptionKeys.begin() ; it != d->mPrimaryEncryptionKeys.end() ; ++it ) {
00872 if ( !it->needKeys )
00873 continue;
00874 it->keys = getEncryptionKeys( it->address, false );
00875 if ( it->keys.empty() )
00876 return Kpgp::Canceled;
00877 QString addr = canonicalAddress( it->address ).toLower();
00878 const ContactPreferences pref = lookupContactPreferences( addr );
00879 it->pref = pref.encryptionPreference;
00880 it->signPref = pref.signingPreference;
00881 it->format = pref.cryptoMessageFormat;
00882 }
00883
00884 for ( std::vector<Item>::iterator it = d->mSecondaryEncryptionKeys.begin() ; it != d->mSecondaryEncryptionKeys.end() ; ++it ) {
00885 if ( !it->needKeys )
00886 continue;
00887 it->keys = getEncryptionKeys( it->address, false );
00888 if ( it->keys.empty() )
00889 return Kpgp::Canceled;
00890 QString addr = canonicalAddress( it->address ).toLower();
00891 const ContactPreferences pref = lookupContactPreferences( addr );
00892 it->pref = pref.encryptionPreference;
00893 it->signPref = pref.signingPreference;
00894 it->format = pref.cryptoMessageFormat;
00895 }
00896
00897
00898
00899 const Kpgp::Result res = showKeyApprovalDialog();
00900 if ( res != Kpgp::Ok )
00901 return res;
00902
00903
00904
00905
00906
00907
00908
00909
00910 const EncryptionFormatPreferenceCounter primaryCount
00911 = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
00912 EncryptionFormatPreferenceCounter() );
00913
00914 CryptoMessageFormat commonFormat = AutoFormat;
00915 for ( unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
00916 if ( !( concreteCryptoMessageFormats[i] & mCryptoMessageFormats ) )
00917 continue;
00918 if ( signingRequested && signingKeysFor( concreteCryptoMessageFormats[i] ).empty() )
00919 continue;
00920 if ( encryptToSelf() && encryptToSelfKeysFor( concreteCryptoMessageFormats[i] ).empty() )
00921 continue;
00922 if ( primaryCount.numOf( concreteCryptoMessageFormats[i] ) == primaryCount.numTotal() ) {
00923 commonFormat = concreteCryptoMessageFormats[i];
00924 break;
00925 }
00926 }
00927 if ( commonFormat != AutoFormat )
00928 addKeys( d->mPrimaryEncryptionKeys, commonFormat );
00929 else
00930 addKeys( d->mPrimaryEncryptionKeys );
00931
00932 collapseAllSplitInfos();
00933
00934
00935
00936
00937 const EncryptionFormatPreferenceCounter secondaryCount
00938 = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
00939 EncryptionFormatPreferenceCounter() );
00940
00941 if ( commonFormat != AutoFormat &&
00942 secondaryCount.numOf( commonFormat ) == secondaryCount.numTotal() )
00943 addKeys( d->mSecondaryEncryptionKeys, commonFormat );
00944 else
00945 addKeys( d->mSecondaryEncryptionKeys );
00946
00947
00948
00949 for ( unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
00950 const std::vector<SplitInfo> si_list = encryptionItems( concreteCryptoMessageFormats[i] );
00951 for ( std::vector<SplitInfo>::const_iterator sit = si_list.begin() ; sit != si_list.end() ; ++sit )
00952 for ( std::vector<GpgME::Key>::const_iterator kit = sit->keys.begin() ; kit != sit->keys.end() ; ++kit ) {
00953 const Kpgp::Result r = checkKeyNearExpiry( *kit, "other encryption key near expiry warning",
00954 false, false );
00955 if ( r != Kpgp::Ok )
00956 return r;
00957 }
00958 }
00959
00960
00961
00962 if ( !encryptToSelf() )
00963 return Kpgp::Ok;
00964
00965
00966
00967 if ( !encryptionItems( InlineOpenPGPFormat ).empty() ||
00968 !encryptionItems( OpenPGPMIMEFormat ).empty() ) {
00969
00970 if ( d->mOpenPGPEncryptToSelfKeys.empty() ) {
00971 const QString msg = i18n("Examination of recipient's encryption preferences "
00972 "yielded that the message should be encrypted using "
00973 "OpenPGP, at least for some recipients;\n"
00974 "however, you have not configured valid trusted "
00975 "OpenPGP encryption keys for this identity.\n"
00976 "You may continue without encrypting to yourself, "
00977 "but be aware that you will not be able to read your "
00978 "own messages if you do so.");
00979 if ( KMessageBox::warningContinueCancel( 0, msg,
00980 i18n("Unusable Encryption Keys"),
00981 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
00982 "encrypt-to-self will fail warning" )
00983 == KMessageBox::Cancel )
00984 return Kpgp::Canceled;
00985
00986 }
00987 addToAllSplitInfos( d->mOpenPGPEncryptToSelfKeys,
00988 InlineOpenPGPFormat|OpenPGPMIMEFormat );
00989 }
00990
00991
00992
00993 if ( !encryptionItems( SMIMEFormat ).empty() ||
00994 !encryptionItems( SMIMEOpaqueFormat ).empty() ) {
00995
00996 if ( d->mSMIMEEncryptToSelfKeys.empty() ) {
00997
00998 const QString msg = i18n("Examination of recipient's encryption preferences "
00999 "yielded that the message should be encrypted using "
01000 "S/MIME, at least for some recipients;\n"
01001 "however, you have not configured valid "
01002 "S/MIME encryption certificates for this identity.\n"
01003 "You may continue without encrypting to yourself, "
01004 "but be aware that you will not be able to read your "
01005 "own messages if you do so.");
01006 if ( KMessageBox::warningContinueCancel( 0, msg,
01007 i18n("Unusable Encryption Keys"),
01008 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
01009 "encrypt-to-self will fail warning" )
01010 == KMessageBox::Cancel )
01011 return Kpgp::Canceled;
01012
01013 }
01014 addToAllSplitInfos( d->mSMIMEEncryptToSelfKeys,
01015 SMIMEFormat|SMIMEOpaqueFormat );
01016 }
01017
01018
01019
01020
01021 return Kpgp::Ok;
01022 }
01023
01024 Kpgp::Result Kleo::KeyResolver::resolveSigningKeysForEncryption() {
01025 if ( ( !encryptionItems( InlineOpenPGPFormat ).empty() ||
01026 !encryptionItems( OpenPGPMIMEFormat ).empty() )
01027 && d->mOpenPGPSigningKeys.empty() ) {
01028 const QString msg = i18n("Examination of recipient's signing preferences "
01029 "yielded that the message should be signed using "
01030 "OpenPGP, at least for some recipients;\n"
01031 "however, you have not configured valid "
01032 "OpenPGP signing certificates for this identity.");
01033 if ( KMessageBox::warningContinueCancel( 0, msg,
01034 i18n("Unusable Signing Keys"),
01035 KGuiItem(i18n("Do Not OpenPGP-Sign")),
01036 KStandardGuiItem::cancel(),
01037 "signing will fail warning" )
01038 == KMessageBox::Cancel )
01039 return Kpgp::Canceled;
01040
01041 }
01042 if ( ( !encryptionItems( SMIMEFormat ).empty() ||
01043 !encryptionItems( SMIMEOpaqueFormat ).empty() )
01044 && d->mSMIMESigningKeys.empty() ) {
01045 const QString msg = i18n("Examination of recipient's signing preferences "
01046 "yielded that the message should be signed using "
01047 "S/MIME, at least for some recipients;\n"
01048 "however, you have not configured valid "
01049 "S/MIME signing certificates for this identity.");
01050 if ( KMessageBox::warningContinueCancel( 0, msg,
01051 i18n("Unusable Signing Keys"),
01052 KGuiItem(i18n("Do Not S/MIME-Sign")),
01053 KStandardGuiItem::cancel(),
01054 "signing will fail warning" )
01055 == KMessageBox::Cancel )
01056 return Kpgp::Canceled;
01057
01058 }
01059
01060
01061
01062
01063 for ( std::map<CryptoMessageFormat,FormatInfo>::iterator it = d->mFormatInfoMap.begin() ; it != d->mFormatInfoMap.end() ; ++it )
01064 if ( !it->second.splitInfos.empty() ) {
01065 dump();
01066 it->second.signKeys = signingKeysFor( it->first );
01067 dump();
01068 }
01069
01070 return Kpgp::Ok;
01071 }
01072
01073 Kpgp::Result Kleo::KeyResolver::resolveSigningKeysForSigningOnly() {
01074
01075
01076
01077
01078 SigningFormatPreferenceCounter count;
01079 count = std::for_each( d->mPrimaryEncryptionKeys.begin(), d->mPrimaryEncryptionKeys.end(),
01080 count );
01081 count = std::for_each( d->mSecondaryEncryptionKeys.begin(), d->mSecondaryEncryptionKeys.end(),
01082 count );
01083
01084
01085
01086 CryptoMessageFormat commonFormat = AutoFormat;
01087
01088 for ( unsigned int i = 0 ; i < numConcreteCryptoMessageFormats ; ++i ) {
01089 if ( !(mCryptoMessageFormats & concreteCryptoMessageFormats[i]) )
01090 continue;
01091 if ( signingKeysFor( concreteCryptoMessageFormats[i] ).empty() )
01092 continue;
01093 if ( count.numOf( concreteCryptoMessageFormats[i] ) == count.numTotal() ) {
01094 commonFormat = concreteCryptoMessageFormats[i];
01095 break;
01096 }
01097 }
01098
01099 if ( commonFormat != AutoFormat ) {
01100 dump();
01101 FormatInfo & fi = d->mFormatInfoMap[ commonFormat ];
01102 fi.signKeys = signingKeysFor( commonFormat );
01103 fi.splitInfos.resize( 1 );
01104 fi.splitInfos.front() = SplitInfo( allRecipients() );
01105 dump();
01106 return Kpgp::Ok;
01107 }
01108
01109 const QString msg = i18n("Examination of recipient's signing preferences "
01110 "showed no common type of signature matching your "
01111 "available signing keys.\n"
01112 "Send message without signing?" );
01113 if ( KMessageBox::warningContinueCancel( 0, msg, i18n("No signing possible"),
01114 KStandardGuiItem::cont() )
01115 == KMessageBox::Continue ) {
01116 d->mFormatInfoMap[OpenPGPMIMEFormat].splitInfos.push_back( SplitInfo( allRecipients() ) );
01117 return Kpgp::Failure;
01118 }
01119 return Kpgp::Canceled;
01120 }
01121
01122 std::vector<GpgME::Key> Kleo::KeyResolver::signingKeysFor( CryptoMessageFormat f ) const {
01123 if ( isOpenPGP( f ) )
01124 return d->mOpenPGPSigningKeys;
01125 if ( isSMIME( f ) )
01126 return d->mSMIMESigningKeys;
01127 return std::vector<GpgME::Key>();
01128 }
01129
01130 std::vector<GpgME::Key> Kleo::KeyResolver::encryptToSelfKeysFor( CryptoMessageFormat f ) const {
01131 if ( isOpenPGP( f ) )
01132 return d->mOpenPGPEncryptToSelfKeys;
01133 if ( isSMIME( f ) )
01134 return d->mSMIMEEncryptToSelfKeys;
01135