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)