33 #include <config-kleopatra.h> 
   43 #include <kmime/kmime_header_parsing.h> 
   45 #include <gpgme++/key.h> 
   48 using namespace Kleo::Crypto;
 
   49 using namespace KMime::Types;
 
   50 using namespace GpgME;
 
   51 using namespace boost;
 
   55 static bool operator==( 
const AddrSpec & lhs, 
const AddrSpec & rhs ) {
 
   56     return lhs.localPart == rhs.localPart
 
   57         && lhs.domain == rhs.domain ;
 
   60 static bool operator==( 
const Mailbox & lhs, 
const Mailbox & rhs ) {
 
   61     return lhs.name() == rhs.name()
 
   62         && lhs.addrSpec() == rhs.addrSpec() ;
 
   68     return keys.size() != 1 ;
 
   73 class Sender::Private {
 
   74     friend class ::Kleo::Crypto::Sender;
 
   76     explicit Private( 
const Mailbox & mb )
 
   83         const std::vector<Key> encrypt = 
KeyCache::instance()->findEncryptionKeysByMailbox( mb );
 
   84         kdtools::separate_if( signers,
 
   85                               std::back_inserter( pgpSigners ), std::back_inserter( cmsSigners ),
 
   86                               boost::bind( &Key::protocol, _1 ) == 
OpenPGP );
 
   87         kdtools::separate_if( encrypt,
 
   88                               std::back_inserter( pgpEncryptToSelfKeys ), std::back_inserter( cmsEncryptToSelfKeys ),
 
   89                               boost::bind( &Key::protocol, _1 ) == 
OpenPGP );
 
   93     const Mailbox mailbox;
 
   94     std::vector<Key> pgpSigners, cmsSigners, pgpEncryptToSelfKeys, cmsEncryptToSelfKeys;
 
   95     cached<bool> signingAmbiguous[2], encryptionAmbiguous[2];
 
   96     Key signingKey[2], cmsEncryptionKey;
 
   97     UserID pgpEncryptionUid;
 
  101     : 
d( new Private( mb ) )
 
  106 void Sender::detach() {
 
  107     if ( 
d && !
d.unique() )
 
  108         d.reset( 
new Private( *
d ) );
 
  111 bool Sender::deepEquals( 
const Sender & other )
 const {
 
  112     static const _detail::ByFingerprint<std::equal_to> compare = {};
 
  113     return mailbox() == other.
mailbox()
 
  114         && compare( 
d->signingKey[
CMS],     other.d->signingKey[
CMS]     )
 
  116         && compare( 
d->cmsEncryptionKey, other.d->cmsEncryptionKey )
 
  117         && compare( 
d->pgpEncryptionUid.parent(), other.d->pgpEncryptionUid.parent() )
 
  118         && strcmp( 
d->pgpEncryptionUid.id(), other.d->pgpEncryptionUid.id() ) == 0
 
  119         && kdtools::equal( 
d->pgpSigners, other.d->pgpSigners, compare )
 
  120         && kdtools::equal( 
d->cmsSigners, other.d->cmsSigners, compare )
 
  121         && kdtools::equal( 
d->pgpEncryptToSelfKeys, other.d->pgpEncryptToSelfKeys, compare )
 
  122         && kdtools::equal( 
d->cmsEncryptToSelfKeys, other.d->cmsEncryptToSelfKeys, compare )
 
  126 bool Sender::isSigningAmbiguous( GpgME::Protocol proto )
 const {
 
  127     if ( 
d->signingAmbiguous[proto].dirty() )
 
  128         d->signingAmbiguous[proto] = 
determine_ambiguous( 
d->mailbox, signingCertificateCandidates( proto ) );
 
  129     return d->signingAmbiguous[proto];
 
  132 bool Sender::isEncryptionAmbiguous( GpgME::Protocol proto )
 const {
 
  133     if ( 
d->encryptionAmbiguous[proto].dirty() )
 
  134         d->encryptionAmbiguous[proto] = 
determine_ambiguous( 
d->mailbox, encryptToSelfCertificateCandidates( proto ) );
 
  135     return d->encryptionAmbiguous[proto];
 
  138 const Mailbox & Sender::mailbox()
 const {
 
  142 const std::vector<Key> & Sender::signingCertificateCandidates( GpgME::Protocol proto )
 const {
 
  144         return d->pgpSigners;
 
  146         return d->cmsSigners;
 
  151         proto == 
CMS     ? 
d->cmsSigners :
 
  157 const std::vector<Key> & Sender::encryptToSelfCertificateCandidates( GpgME::Protocol proto )
 const {
 
  159         return d->pgpEncryptToSelfKeys;
 
  161         return d->cmsEncryptToSelfKeys;
 
  165         proto == 
OpenPGP ? 
d->pgpEncryptToSelfKeys :
 
  166         proto == 
CMS     ? 
d->cmsEncryptToSelfKeys :
 
  172 void Sender::setResolvedSigningKey( 
const Key & key ) {
 
  175     const Protocol proto = key.protocol();
 
  178     d->signingKey[proto] = key;
 
  179     d->signingAmbiguous[proto] = 
false;
 
  182 Key Sender::resolvedSigningKey( GpgME::Protocol proto )
 const {
 
  184     return d->signingKey[proto];
 
  187 void Sender::setResolvedEncryptionKey( 
const Key & key ) {
 
  190     const Protocol proto = key.protocol();
 
  194         d->pgpEncryptionUid = key.userID( 0 );
 
  196         d->cmsEncryptionKey = key;
 
  197     d->encryptionAmbiguous[proto] = 
false;
 
  200 Key Sender::resolvedEncryptionKey( GpgME::Protocol proto )
 const {
 
  203         return d->pgpEncryptionUid.parent();
 
  205         return d->cmsEncryptionKey;
 
  208 void Sender::setResolvedOpenPGPEncryptionUserID( 
const UserID & uid ) {
 
  212     d->pgpEncryptionUid = uid;
 
  215 UserID Sender::resolvedOpenPGPEncryptionUserID()
 const {
 
  216     return d->pgpEncryptionUid;
 
const KMime::Types::Mailbox & mailbox() const 
static bool operator==(const Mailbox &lhs, const Mailbox &rhs)
#define kleo_assert_fail(cond)
#define kleo_assert(cond)
static boost::shared_ptr< const KeyCache > instance()
static bool determine_ambiguous(const Mailbox &mb, const std::vector< Key > &keys)