Messagelib

keyresolver.h
1 /* -*- c++ -*-
2  keyresolver.h
3 
4  This file is part of libkleopatra, the KDE keymanagement library
5  SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
6 
7  Based on kpgp.h
8  Copyright (C) 2001,2002 the KPGP authors
9  See file libkdenetwork/AUTHORS.kpgp for details
10 
11  SPDX-License-Identifier: GPL-2.0-or-later
12 */
13 
14 #pragma once
15 
16 #include "messagecomposer_export.h"
17 #include <Libkleo/Enum>
18 #include <Libkleo/KeyApprovalDialog>
19 
20 #include <gpgme++/key.h>
21 
22 #include <vector>
23 
24 #include <QStringList>
25 #include <QSharedPointer>
26 
27 namespace MessageComposer
28 {
29 class NearExpiryChecker;
30 using NearExpiryCheckerPtr = QSharedPointer<NearExpiryChecker>;
31 }
32 
33 namespace Kleo
34 {
35 enum Result { Failure = 0, Ok = 1, Canceled = 2 };
36 /**
37  \short A class to resolve signing/encryption keys w.r.t. per-recipient preferences
38 
39  \section Step 1: Set the information needed
40 
41  The constructor takes some basic options as arguments, such as
42  whether or not encryption was actually requested. Recipient and
43  sender information is then set by using \c
44  setEncryptToSelfKeys(), \c setSigningKeys(), \c
45  setPrimaryRecipients() (To/Cc) and \c setSecondaryRecipients()
46  (Bcc).
47 
48  \section Step 2: Lookup and check per-recipient crypto preferences / Opportunistic Encryption
49 
50  First, \c checkSigningPreferences() goes through all recipient's
51  signing preferences, to determine whether or not to sign. It also
52  takes into account the available signing keys and whether or not
53  the user explicitly requested signing.
54 
55  \c checkEncryptionPreferences() does the same for encryption
56  preferences. If opportunistic encryption is enabled, recipients
57  without encryption preferences set are treated as if they had a
58  preference of \c AskWheneverPossible.
59 
60  In both cases an Action code is returned, with the following
61  meanings:
62 
63  <dl><dt>Conflict</dt><dd>A conflict was detected. E.g. one
64  recipient's preference was set to "always encrypt", while another
65  one's preference was set to "never encrypt". You should ask the
66  user what to do.</dd></dt>
67 
68  <dt>DoIt, DontDoIt</dt><dd>Do/Don't sign/encrypt</dd>
69 
70  <dt>Ask</dt><dd>(Some) crypto preferences request to prompt the
71  user, so do it.</dd>
72 
73  <dt>Impossible</dt><dd>Signing or encryption is impossible,
74  e.g. due to missing keys or unsupported formats.</dd> </dl>
75 
76  \section Step 3: Resolve all keys.
77 
78  In case signing or encryption was implicitly or explicitly
79  requested by the user, \c resolveAllKeys() tries to find signing
80  keys for each required format, as well as encryption keys for all
81  recipients (incl. the sender, if encrypt-to-self is set).
82 
83  \section Step 4: Get signing keys.
84 
85  If, after key resolving, signing is still requested and
86  apparently possible, you can get the result of all this by
87  iterating over the available message formats and retrieving the
88  set of signing keys to use with a call to \c signingKeys().
89 
90  \section Step 5: Get encryption key sets.
91 
92  If after key resolving, encryption is still requested and
93  apparently possible, you can get the result of all this by
94  calling \c encryptionItems() with the current message format at
95  hand as its argument.
96 
97  This will return a list of recipient-list/key-list pairs that
98  each describe a copy of the (possibly signed) message to be
99  encrypted independently.
100 
101  Note that it's only necessary to sign the message once for each
102  message format, although it might be necessary to create more
103  than one message when encrypting. This is because encryption
104  allows the recipients to learn about the other recipients the
105  message was encrypted to, so each secondary (BCC) recipient need
106  a copy of it's own to hide the other secondary recipients.
107  */
108 
109 class MESSAGECOMPOSER_EXPORT KeyResolver
110 {
111 public:
112  KeyResolver(bool encToSelf,
113  bool showApproval,
114  bool oppEncryption,
115  unsigned int format,
116  const MessageComposer::NearExpiryCheckerPtr &nearExpiryChecker);
117 
118  ~KeyResolver();
119 
120  struct ContactPreferences {
121  ContactPreferences();
122  Kleo::EncryptionPreference encryptionPreference;
123  Kleo::SigningPreference signingPreference;
124  Kleo::CryptoMessageFormat cryptoMessageFormat;
125  QStringList pgpKeyFingerprints;
126  QStringList smimeCertFingerprints;
127  };
128 
129  struct Item : public KeyApprovalDialog::Item {
130  Item()
131  : KeyApprovalDialog::Item()
132  , signPref(UnknownSigningPreference)
133  , format(AutoFormat)
134  , needKeys(true)
135  {
136  }
137 
138  Item(const QString &a, EncryptionPreference e, SigningPreference s, CryptoMessageFormat f)
139  : KeyApprovalDialog::Item(a, std::vector<GpgME::Key>(), e)
140  , signPref(s)
141  , format(f)
142  , needKeys(true)
143  {
144  }
145 
146  Item(const QString &a, const std::vector<GpgME::Key> &k, EncryptionPreference e, SigningPreference s, CryptoMessageFormat f)
147  : KeyApprovalDialog::Item(a, k, e)
148  , signPref(s)
149  , format(f)
150  , needKeys(false)
151  {
152  }
153 
154  SigningPreference signPref;
155  CryptoMessageFormat format;
156  bool needKeys;
157  };
158 
159  /**
160  Set the fingerprints of keys to be used for encrypting to
161  self. Also looks them up and complains if they're not usable or
162  found.
163  */
164  Q_REQUIRED_RESULT Kleo::Result setEncryptToSelfKeys(const QStringList &fingerprints);
165  /**
166  Set the fingerprints of keys to be used for signing. Also
167  looks them up and complains if they're not usable or found.
168  */
169  Q_REQUIRED_RESULT Kleo::Result setSigningKeys(const QStringList &fingerprints);
170  /**
171  Set the list of primary (To/CC) recipient addresses. Also looks
172  up possible keys, but doesn't interact with the user.
173  */
174  void setPrimaryRecipients(const QStringList &addresses);
175  /**
176  Set the list of secondary (BCC) recipient addresses. Also looks
177  up possible keys, but doesn't interact with the user.
178  */
179  void setSecondaryRecipients(const QStringList &addresses);
180 
181  /**
182  Determine whether to sign or not, depending on the
183  per-recipient signing preferences, as well as the availability
184  of usable signing keys.
185  */
186  Q_REQUIRED_RESULT Action checkSigningPreferences(bool signingRequested) const;
187  /**
188  Determine whether to encrypt or not, depending on the
189  per-recipient encryption preferences, as well as the availability
190  of usable encryption keys.
191  */
192  Q_REQUIRED_RESULT Action checkEncryptionPreferences(bool encryptionRequested) const;
193 
194  /**
195  Queries the user for missing keys and displays a key approval
196  dialog if needed.
197  */
198  Q_REQUIRED_RESULT Kleo::Result resolveAllKeys(bool &signingRequested, bool &encryptionRequested);
199 
200  /**
201  @return the signing keys to use (if any) for the given message
202  format.
203  */
204  Q_REQUIRED_RESULT std::vector<GpgME::Key> signingKeys(CryptoMessageFormat f) const;
205 
206  struct SplitInfo {
207  SplitInfo() = default;
208 
209  explicit SplitInfo(const QStringList &r)
210  : recipients(r)
211  {
212  }
213 
214  SplitInfo(const QStringList &r, const std::vector<GpgME::Key> &k)
215  : recipients(r)
216  , keys(k)
217  {
218  }
219 
220  QStringList recipients;
221  std::vector<GpgME::Key> keys;
222  };
223  /** @return the found distinct sets of items for format \a f. The
224  returned vector will contain more than one item only if
225  secondary recipients have been specified.
226  */
227  Q_REQUIRED_RESULT std::vector<SplitInfo> encryptionItems(CryptoMessageFormat f) const;
228 
229  std::vector<GpgME::Key> encryptToSelfKeysFor(CryptoMessageFormat f) const;
230 
231  /** If Autocrypt keys are used to find valid PGP Keys
232  */
233  void setAutocryptEnabled(bool autocryptEnabled);
234 
235  std::map<QByteArray, QString> useAutocrypt() const;
236 
237  /** Disable ContactSearchJob in KeyResolver.
238  A usecase is that ests won't fireup an Akonadi instance only for this feature.
239  @default is true: The ContactSearchJob is executed.
240  */
241  void setAkonadiLookupEnabled(bool akonadiLookupEnabled);
242 
243 private:
244  void dump() const;
245  std::vector<Item> getEncryptionItems(const QStringList &recipients);
246  std::vector<GpgME::Key> getEncryptionKeys(const QString &recipient, bool quiet) const;
247 
248  Kleo::Result showKeyApprovalDialog(bool &finalySendUnencrypted);
249 
250  bool encryptionPossible() const;
251  bool signingPossible() const;
252  Kleo::Result resolveEncryptionKeys(bool signingRequested, bool &finalySendUnencrypted);
253  Kleo::Result resolveSigningKeysForEncryption();
254  Kleo::Result resolveSigningKeysForSigningOnly();
255  void collapseAllSplitInfos();
256  void addToAllSplitInfos(const std::vector<GpgME::Key> &keys, unsigned int formats);
257  void addKeys(const std::vector<Item> &items, CryptoMessageFormat f);
258  void addKeys(const std::vector<Item> &items);
259  QStringList allRecipients() const;
260  std::vector<GpgME::Key> signingKeysFor(CryptoMessageFormat f) const;
261 
262  std::vector<GpgME::Key> lookup(const QStringList &patterns, bool secret = false) const;
263 
264  std::vector<GpgME::Key>
265  selectKeys(const QString &person, const QString &msg, const std::vector<GpgME::Key> &selectedKeys = std::vector<GpgME::Key>()) const;
266 
267  QStringList keysForAddress(const QString &address) const;
268  void setKeysForAddress(const QString &address, const QStringList &pgpKeyFingerprints, const QStringList &smimeCertFingerprints) const;
269 
270  bool encryptToSelf() const;
271  bool showApprovalDialog() const;
272 
273  ContactPreferences lookupContactPreferences(const QString &address) const;
274  void saveContactPreference(const QString &email, const ContactPreferences &pref) const;
275 
276 private:
277  class EncryptionPreferenceCounter;
278  friend class ::Kleo::KeyResolver::EncryptionPreferenceCounter;
279  class SigningPreferenceCounter;
280  friend class ::Kleo::KeyResolver::SigningPreferenceCounter;
281 
282  struct KeyResolverPrivate;
283  std::unique_ptr<KeyResolverPrivate> const d;
284 
285  bool mEncryptToSelf;
286  const bool mShowApprovalDialog : 1;
287  const bool mOpportunisticEncyption : 1;
288  const unsigned int mCryptoMessageFormats;
289 };
290 } // namespace Kleo
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
A class to resolve signing/encryption keys w.r.t.
Definition: keyresolver.h:109
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Tue May 17 2022 04:00:04 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.