4
This file is part of libkleopatra, the KDE keymanagement library
5
Copyright (c) 2004 Klarälvdalens Datakonsult AB
8
Copyright (C) 2001,2002 the KPGP authors
9
See file libkdenetwork/AUTHORS.kpgp for details
11
Libkleopatra is free software; you can redistribute it and/or
12
modify it under the terms of the GNU General Public License as
13
published by the Free Software Foundation; either version 2 of the
14
License, or (at your option) any later version.
16
Libkleopatra is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
General Public License for more details.
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software
23
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
In addition, as a special exception, the copyright holders give
26
permission to link the code of this program with any edition of
27
the Qt library by Trolltech AS, Norway (or with modified versions
28
of Qt that use the same license as Qt), and distribute linked
29
combinations including the two. You must obey the GNU General
30
Public License in all respects for all of the code used other than
31
Qt. If you modify this file, you may extend this exception to
32
your version of the file, but you are not obligated to do so. If
33
you do not wish to do so, delete this exception statement from
37
#ifndef __KLEO_KEYRESOLVER_H__
38
#define __KLEO_KEYRESOLVER_H__
40
#include "libkleo/ui/keyapprovaldialog.h"
41
#include "kleo/enum.h"
43
#include <libkpgp/kpgp.h> // for Kpgp::Result
44
#include <gpgme++/key.h>
58
\short A class to resolve signing/encryption keys w.r.t. per-recipient preferences
60
\section Step 1: Set the information needed
62
The constructor takes some basic options as arguments, such as
63
whether or not encryption was actually requested. Recipient and
64
sender information is then set by using \c
65
setEncryptToSelfKeys(), \c setSigningKeys(), \c
66
setPrimaryRecipients() (To/Cc) and \c setSecondaryRecipients()
69
\section Step 2: Lookup and check per-recipient crypto preferences / Opportunistic Encryption
71
First, \c checkSigningPreferences() goes through all recipient's
72
signing perferences, to determine whether or not to sign. It also
73
takes into account the available signing keys and whether or not
74
the user explicitly requested signing.
76
\c checkEncryptionPreferences() does the same for encryption
77
preferences. If opportunistic encryption is enabled, recipients
78
without encryption preferences set are treated as if they had a
79
preference of \c AskWheneverPossible.
81
In both cases an Action code is returned, with the following
84
<dl><dt>Conflict</dt><dd>A conflict was detected. E.g. one
85
recipient's preference was set to "always encrypt", while another
86
one's preference was set to "never encrypt". You should ask the
87
user what to do.</dd></dt>
89
<dt>DoIt, DontDoIt</dt><dd>Do/Don't sign/encrypt</dd>
91
<dt>Ask</dt><dd>(Some) crypto preferences request to prompt the
94
<dt>Impossible</dt><dd>Signing or encryption is impossible,
95
e.g. due to missing keys or unsupported formats.</dd> </dl>
97
\section Step 3: Resolve all keys.
99
In case signing or encryption was implicitly or explicitly
100
requested by the user, \c resolveAllKeys() tries to find signing
101
keys for each required format, as well as encryption keys for all
102
recipients (incl. the sender, if encrypt-to-self is set).
104
\section Step 4: Get signing keys.
106
If, after key resolving, signing is still requested and
107
apparently possible, you can get the result of all this by
108
iterating over the available message formats and retrieving the
109
set of signing keys to use with a call to \c signingKeys().
111
\section Step 5: Get encrytion key sets.
113
If after key resolving, encryption is still requested and
114
apparently possible, you can get the result of all this by
115
calling \c encryptionItems() with the current message format at
116
hand as its argument.
118
This will return a list of recipient-list/key-list pairs that
119
each describe a copy of the (possibly signed) message to be
120
encrypted independantly.
122
Note that it's only necessary to sign the message once for each
123
message format, although it might be necessary to create more
124
than one message when encrypting. This is because encryption
125
allows the recipients to learn about the other recipients the
126
message was encrypted to, so each secondary (BCC) recipient need
127
a copy of it's own to hide the other secondary recipients.
132
KeyResolver( bool encToSelf, bool showApproval, bool oppEncryption,
134
int encrKeyNearExpiryThresholdDays,
135
int signKeyNearExpiryThresholdDays,
136
int encrRootCertNearExpiryThresholdDays,
137
int signRootCertNearExpiryThresholdDays,
138
int encrChainCertNearExpiryThresholdDays,
139
int signChainCertNearExpiryThresholdDays );
143
struct Item : public KeyApprovalDialog::Item {
145
: KeyApprovalDialog::Item(),
146
signPref( UnknownSigningPreference ),
147
format( AutoFormat ),
149
Item( const QString & a,
150
EncryptionPreference e, SigningPreference s,
151
CryptoMessageFormat f )
152
: KeyApprovalDialog::Item( a, std::vector<GpgME::Key>(), e ),
153
signPref( s ), format( f ), needKeys( true ) {}
154
Item( const QString & a, const std::vector<GpgME::Key> & k,
155
EncryptionPreference e, SigningPreference s,
156
CryptoMessageFormat f )
157
: KeyApprovalDialog::Item( a, k, e ),
158
signPref( s ), format( f ), needKeys( false ) {}
160
SigningPreference signPref;
161
CryptoMessageFormat format;
167
Set the fingerprints of keys to be used for encrypting to
168
self. Also looks them up and complains if they're not usable or
171
Kpgp::Result setEncryptToSelfKeys( const QStringList & fingerprints );
173
Set the fingerprints of keys to be used for signing. Also
174
looks them up and complains if they're not usable or found.
176
Kpgp::Result setSigningKeys( const QStringList & fingerprints );
178
Set the list of primary (To/CC) recipient addresses. Also looks
179
up possible keys, but doesn't interact with the user.
181
void setPrimaryRecipients( const QStringList & addresses );
183
Set the list of secondary (BCC) recipient addresses. Also looks
184
up possible keys, but doesn't interact with the user.
186
void setSecondaryRecipients( const QStringList & addresses );
190
Determine whether to sign or not, depending on the
191
per-recipient signing preferences, as well as the availability
192
of usable signing keys.
194
Action checkSigningPreferences( bool signingRequested ) const;
196
Determine whether to encrypt or not, depending on the
197
per-recipient encryption preferences, as well as the availability
198
of usable encryption keys.
200
Action checkEncryptionPreferences( bool encryptionRequested ) const;
203
Queries the user for missing keys and displays a key approval
206
Kpgp::Result resolveAllKeys( bool& signingRequested, bool& encryptionRequested );
209
@return the signing keys to use (if any) for the given message
212
std::vector<GpgME::Key> signingKeys( CryptoMessageFormat f ) const;
216
SplitInfo( const QStringList & r ) : recipients( r ) {}
217
SplitInfo( const QStringList & r, const std::vector<GpgME::Key> & k )
218
: recipients( r ), keys( k ) {}
219
QStringList recipients;
220
std::vector<GpgME::Key> keys;
222
/** @return the found distinct sets of items for format \a f. The
223
returned vector will contain more than one item only if
224
secondary recipients have been specified.
226
std::vector<SplitInfo> encryptionItems( CryptoMessageFormat f ) const;
230
std::vector<Item> getEncryptionItems( const QStringList & recipients );
231
std::vector<GpgME::Key> getEncryptionKeys( const QString & recipient, bool quiet ) const;
233
Kpgp::Result showKeyApprovalDialog();
235
bool encryptionPossible() const;
236
bool signingPossible() const;
237
Kpgp::Result resolveEncryptionKeys( bool signingRequested );
238
Kpgp::Result resolveSigningKeysForEncryption();
239
Kpgp::Result resolveSigningKeysForSigningOnly();
240
Kpgp::Result checkKeyNearExpiry( const GpgME::Key & key,
241
const char * dontAskAgainName, bool mine,
242
bool sign, bool ca=false, int recurse_limit=100,
243
const GpgME::Key & orig_key=GpgME::Key::null ) const;
244
void collapseAllSplitInfos();
245
void addToAllSplitInfos( const std::vector<GpgME::Key> & keys, unsigned int formats );
246
void addKeys( const std::vector<Item> & items, CryptoMessageFormat f );
247
void addKeys( const std::vector<Item> & items );
248
QStringList allRecipients() const;
249
std::vector<GpgME::Key> signingKeysFor( CryptoMessageFormat f ) const;
250
std::vector<GpgME::Key> encryptToSelfKeysFor( CryptoMessageFormat f ) const;
252
std::vector<GpgME::Key> lookup( const QStringList & patterns, bool secret=false ) const;
254
bool haveTrustedEncryptionKey( const QString & person ) const;
256
std::vector<GpgME::Key> selectKeys( const QString & person, const QString & msg,
257
const std::vector<GpgME::Key> & selectedKeys=std::vector<GpgME::Key>() ) const;
259
QStringList keysForAddress( const QString & address ) const;
260
void setKeysForAddress( const QString & address, const QStringList& pgpKeyFingerprints, const QStringList& smimeCertFingerprints ) const;
262
bool encryptToSelf() const { return mEncryptToSelf; }
263
bool showApprovalDialog() const { return mShowApprovalDialog; }
265
int encryptKeyNearExpiryWarningThresholdInDays() const {
266
return mEncryptKeyNearExpiryWarningThreshold;
268
int signingKeyNearExpiryWarningThresholdInDays() const {
269
return mSigningKeyNearExpiryWarningThreshold;
272
int encryptRootCertNearExpiryWarningThresholdInDays() const {
273
return mEncryptRootCertNearExpiryWarningThreshold;
275
int signingRootCertNearExpiryWarningThresholdInDays() const {
276
return mSigningRootCertNearExpiryWarningThreshold;
279
int encryptChainCertNearExpiryWarningThresholdInDays() const {
280
return mEncryptChainCertNearExpiryWarningThreshold;
282
int signingChainCertNearExpiryWarningThresholdInDays() const {
283
return mSigningChainCertNearExpiryWarningThreshold;
286
struct ContactPreferences {
287
ContactPreferences();
288
Kleo::EncryptionPreference encryptionPreference;
289
Kleo::SigningPreference signingPreference;
290
Kleo::CryptoMessageFormat cryptoMessageFormat;
291
QStringList pgpKeyFingerprints;
292
QStringList smimeCertFingerprints;
295
ContactPreferences lookupContactPreferences( const QString& address ) const;
296
void writeCustomContactProperties( KABC::Addressee &contact, const ContactPreferences& pref ) const;
297
void saveContactPreference( const QString& email, const ContactPreferences& pref ) const;
300
class EncryptionPreferenceCounter;
301
friend class ::Kleo::KeyResolver::EncryptionPreferenceCounter;
302
class SigningPreferenceCounter;
303
friend class ::Kleo::KeyResolver::SigningPreferenceCounter;
309
const bool mShowApprovalDialog : 1;
310
const bool mOpportunisticEncyption : 1;
311
const unsigned int mCryptoMessageFormats;
313
const int mEncryptKeyNearExpiryWarningThreshold;
314
const int mSigningKeyNearExpiryWarningThreshold;
315
const int mEncryptRootCertNearExpiryWarningThreshold;
316
const int mSigningRootCertNearExpiryWarningThreshold;
317
const int mEncryptChainCertNearExpiryWarningThreshold;
318
const int mSigningChainCertNearExpiryWarningThreshold;
323
#endif // __KLEO_KEYRESOLVER_H__