Libkleo

defaultkeyfilter.cpp
1 /*
2  defaultkeyfilter.cpp
3 
4  This file is part of libkleopatra, the KDE keymanagement library
5  SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
6 
7  SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
8  SPDX-FileContributor: Intevation GmbH
9 
10  SPDX-License-Identifier: GPL-2.0-or-later
11 */
12 
13 #include <config-libkleo.h>
14 
15 #include "defaultkeyfilter.h"
16 #include "utils/compliance.h"
17 
18 #if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
19 #else
20 #include <libkleo/compat.h>
21 #endif
22 #include <libkleo/compliance.h>
23 #include <libkleo/formatting.h>
24 #include <libkleo/keyhelpers.h>
25 
26 #include <functional>
27 
28 using namespace GpgME;
29 using namespace Kleo;
30 
31 static bool is_card_key(const Key &key)
32 {
33  const std::vector<Subkey> sks = key.subkeys();
34  return std::find_if(sks.begin(), sks.end(), std::mem_fn(&Subkey::isCardKey)) != sks.end();
35 }
36 
37 class DefaultKeyFilter::Private
38 {
39 public:
40  Private()
41  {
42  }
43 
44  QColor mFgColor;
45  QColor mBgColor;
46  QString mName;
47  QString mIcon;
48  QString mId;
49  MatchContexts mMatchContexts = AnyMatchContext;
50  unsigned int mSpecificity = 0;
51  bool mItalic = false;
52  bool mBold = false;
53  bool mStrikeOut = false;
54  bool mUseFullFont = false;
55  QFont mFont;
56 
57  TriState mRevoked = DoesNotMatter;
58  TriState mExpired = DoesNotMatter;
59  TriState mInvalid = DoesNotMatter;
60  TriState mDisabled = DoesNotMatter;
61  TriState mRoot = DoesNotMatter;
62  TriState mCanEncrypt = DoesNotMatter;
63  TriState mCanSign = DoesNotMatter;
64  TriState mCanCertify = DoesNotMatter;
65  TriState mCanAuthenticate = DoesNotMatter;
66  TriState mHasEncrypt = DoesNotMatter;
67  TriState mHasSign = DoesNotMatter;
68  TriState mHasCertify = DoesNotMatter;
69  TriState mHasAuthenticate = DoesNotMatter;
70  TriState mQualified = DoesNotMatter;
71  TriState mCardKey = DoesNotMatter;
72  TriState mHasSecret = DoesNotMatter;
73  TriState mIsOpenPGP = DoesNotMatter;
74  TriState mWasValidated = DoesNotMatter;
75  TriState mIsDeVs = DoesNotMatter;
76  TriState mBad = DoesNotMatter;
77  TriState mValidIfSMIME = DoesNotMatter;
78 
79  LevelState mOwnerTrust = LevelDoesNotMatter;
80  GpgME::Key::OwnerTrust mOwnerTrustReferenceLevel = Key::OwnerTrust::Unknown;
81  LevelState mValidity = LevelDoesNotMatter;
82  GpgME::UserID::Validity mValidityReferenceLevel = UserID::Validity::Unknown;
83 };
84 
85 DefaultKeyFilter::DefaultKeyFilter()
86  : KeyFilter{}
87  , d{new Private}
88 {
89 }
90 
91 DefaultKeyFilter::~DefaultKeyFilter() = default;
92 
93 bool DefaultKeyFilter::matches(const Key &key, MatchContexts contexts) const
94 {
95  if (!(d->mMatchContexts & contexts)) {
96  return false;
97  }
98 #ifdef MATCH
99 #undef MATCH
100 #endif
101 #define MATCH(member, method) \
102  do { \
103  if (member != DoesNotMatter && key.method() != bool(member == Set)) { \
104  return false; \
105  } \
106  } while (false)
107 #define IS_MATCH(what) MATCH(d->m##what, is##what)
108 #define CAN_MATCH(what) MATCH(d->mCan##what, can##what)
109 #if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
110 #define HAS_MATCH(what) MATCH(d->mHas##what, has##what)
111 #else
112 #define HAS_MATCH(what) \
113  do { \
114  if (d->mHas##what != DoesNotMatter && Kleo::keyHas##what(key) != bool(d->mHas##what == Set)) { \
115  return false; \
116  } \
117  } while (false)
118 #endif
119  IS_MATCH(Revoked);
120  IS_MATCH(Expired);
121  IS_MATCH(Invalid);
122  IS_MATCH(Disabled);
123  IS_MATCH(Root);
124  CAN_MATCH(Encrypt);
125  CAN_MATCH(Sign);
126  CAN_MATCH(Certify);
127  CAN_MATCH(Authenticate);
128  HAS_MATCH(Encrypt);
129  HAS_MATCH(Sign);
130  HAS_MATCH(Certify);
131  HAS_MATCH(Authenticate);
132  IS_MATCH(Qualified);
133  if (d->mCardKey != DoesNotMatter) {
134  if ((d->mCardKey == Set && !is_card_key(key)) || (d->mCardKey == NotSet && is_card_key(key))) {
135  return false;
136  }
137  }
138  MATCH(d->mHasSecret, hasSecret);
139 #undef MATCH
140  if (d->mIsOpenPGP != DoesNotMatter && bool(key.protocol() == GpgME::OpenPGP) != bool(d->mIsOpenPGP == Set)) {
141  return false;
142  }
143  if (d->mWasValidated != DoesNotMatter && bool(key.keyListMode() & GpgME::Validate) != bool(d->mWasValidated == Set)) {
144  return false;
145  }
146  if (d->mIsDeVs != DoesNotMatter && bool(DeVSCompliance::keyIsCompliant(key)) != bool(d->mIsDeVs == Set)) {
147  return false;
148  }
149  if (d->mBad != DoesNotMatter &&
150  /* This is similar to GPGME::Key::isBad which was introduced in GPGME 1.13.0 */
151  bool(key.isNull() || key.isRevoked() || key.isExpired() || key.isDisabled() || key.isInvalid()) != bool(d->mBad == Set)) {
152  return false;
153  }
154  const UserID uid = key.userID(0);
155  if ((key.protocol() == GpgME::CMS) //
156  && (d->mValidIfSMIME != DoesNotMatter) //
157  && (bool(uid.validity() >= UserID::Full) != bool(d->mValidIfSMIME == Set))) {
158  return false;
159  }
160  switch (d->mOwnerTrust) {
161  default:
162  case LevelDoesNotMatter:
163  break;
164  case Is:
165  if (key.ownerTrust() != d->mOwnerTrustReferenceLevel) {
166  return false;
167  }
168  break;
169  case IsNot:
170  if (key.ownerTrust() == d->mOwnerTrustReferenceLevel) {
171  return false;
172  }
173  break;
174  case IsAtLeast:
175  if (static_cast<int>(key.ownerTrust()) < static_cast<int>(d->mOwnerTrustReferenceLevel)) {
176  return false;
177  }
178  break;
179  case IsAtMost:
180  if (static_cast<int>(key.ownerTrust()) > static_cast<int>(d->mOwnerTrustReferenceLevel)) {
181  return false;
182  }
183  break;
184  }
185  switch (d->mValidity) {
186  default:
187  case LevelDoesNotMatter:
188  break;
189  case Is:
190  if (uid.validity() != d->mValidityReferenceLevel) {
191  return false;
192  }
193  break;
194  case IsNot:
195  if (uid.validity() == d->mValidityReferenceLevel) {
196  return false;
197  }
198  break;
199  case IsAtLeast:
200  if (static_cast<int>(uid.validity()) < static_cast<int>(d->mValidityReferenceLevel)) {
201  return false;
202  }
203  break;
204  case IsAtMost:
205  if (static_cast<int>(uid.validity()) > static_cast<int>(d->mValidityReferenceLevel)) {
206  return false;
207  }
208  break;
209  }
210  return true;
211 }
212 
213 bool DefaultKeyFilter::matches(const UserID &userID, MatchContexts contexts) const
214 {
215  if (!(d->mMatchContexts & contexts)) {
216  return false;
217  }
218 #ifdef MATCH_KEY
219 #undef MATCH_KEY
220 #endif
221 #define MATCH_KEY(member, method) \
222  do { \
223  if (member != DoesNotMatter && userID.parent().method() != bool(member == Set)) { \
224  return false; \
225  } \
226  } while (false)
227 #define IS_MATCH_KEY(what) MATCH_KEY(d->m##what, is##what)
228 #define CAN_MATCH_KEY(what) MATCH_KEY(d->mCan##what, can##what)
229 #if GPGMEPP_KEY_HAS_HASCERTIFY_SIGN_ENCRYPT_AUTHENTICATE
230 #define HAS_MATCH_KEY(what) MATCH_KEY(d->mHas##what, has##what)
231 #else
232 #define HAS_MATCH_KEY(what) \
233  do { \
234  if (d->mHas##what != DoesNotMatter && Kleo::keyHas##what(userID.parent()) != bool(d->mHas##what == Set)) { \
235  return false; \
236  } \
237  } while (false)
238 #endif
239 
240 #ifdef MATCH
241 #undef MATCH
242 #endif
243 #define MATCH(member, method) \
244  do { \
245  if (member != DoesNotMatter && (userID.parent().method() != bool(member == Set) || userID.method() != bool(member == Set))) { \
246  return false; \
247  } \
248  } while (false)
249 #define IS_MATCH(what) MATCH(d->m##what, is##what)
250  IS_MATCH(Revoked);
251  IS_MATCH_KEY(Expired);
252  // We have to do this manually since there's no UserID::isExpired()
253  if (d->mExpired != DoesNotMatter && (userID.parent().isExpired() != bool(d->mExpired == Set) || isExpired(userID) != bool(d->mExpired == Set))) {
254  return false;
255  }
256  IS_MATCH(Invalid);
257  IS_MATCH_KEY(Disabled);
258  IS_MATCH_KEY(Root);
259  CAN_MATCH_KEY(Encrypt);
260  CAN_MATCH_KEY(Sign);
261  CAN_MATCH_KEY(Certify);
262  CAN_MATCH_KEY(Authenticate);
263  HAS_MATCH_KEY(Encrypt);
264  HAS_MATCH_KEY(Sign);
265  HAS_MATCH_KEY(Certify);
266  HAS_MATCH_KEY(Authenticate);
267  IS_MATCH_KEY(Qualified);
268  if (d->mCardKey != DoesNotMatter) {
269  if ((d->mCardKey == Set && !is_card_key(userID.parent())) || (d->mCardKey == NotSet && is_card_key(userID.parent()))) {
270  return false;
271  }
272  }
273  MATCH_KEY(d->mHasSecret, hasSecret);
274 #undef MATCH
275  if (d->mIsOpenPGP != DoesNotMatter && bool(userID.parent().protocol() == GpgME::OpenPGP) != bool(d->mIsOpenPGP == Set)) {
276  return false;
277  }
278  if (d->mWasValidated != DoesNotMatter && bool(userID.parent().keyListMode() & GpgME::Validate) != bool(d->mWasValidated == Set)) {
279  return false;
280  }
281  if (d->mIsDeVs != DoesNotMatter && bool(DeVSCompliance::userIDIsCompliant(userID)) != bool(d->mIsDeVs == Set)) {
282  return false;
283  }
284  if (d->mBad != DoesNotMatter &&
285  /* This is similar to GPGME::Key::isBad which was introduced in GPGME 1.13.0 */
286  bool(userID.parent().isNull() || userID.isNull() || userID.parent().isRevoked() || userID.isRevoked() || userID.parent().isExpired()
287  || userID.parent().isDisabled() || userID.parent().isInvalid() || userID.isInvalid())
288  != bool(d->mBad == Set)) {
289  return false;
290  }
291  if ((userID.parent().protocol() == GpgME::CMS) //
292  && (d->mValidIfSMIME != DoesNotMatter) //
293  && (bool(userID.validity() >= UserID::Full) != bool(d->mValidIfSMIME == Set))) {
294  return false;
295  }
296  switch (d->mOwnerTrust) {
297  default:
298  case LevelDoesNotMatter:
299  break;
300  case Is:
301  if (userID.parent().ownerTrust() != d->mOwnerTrustReferenceLevel) {
302  return false;
303  }
304  break;
305  case IsNot:
306  if (userID.parent().ownerTrust() == d->mOwnerTrustReferenceLevel) {
307  return false;
308  }
309  break;
310  case IsAtLeast:
311  if (static_cast<int>(userID.parent().ownerTrust()) < static_cast<int>(d->mOwnerTrustReferenceLevel)) {
312  return false;
313  }
314  break;
315  case IsAtMost:
316  if (static_cast<int>(userID.parent().ownerTrust()) > static_cast<int>(d->mOwnerTrustReferenceLevel)) {
317  return false;
318  }
319  break;
320  }
321  switch (d->mValidity) {
322  default:
323  case LevelDoesNotMatter:
324  break;
325  case Is:
326  if (userID.validity() != d->mValidityReferenceLevel) {
327  return false;
328  }
329  break;
330  case IsNot:
331  if (userID.validity() == d->mValidityReferenceLevel) {
332  return false;
333  }
334  break;
335  case IsAtLeast:
336  if (static_cast<int>(userID.validity()) < static_cast<int>(d->mValidityReferenceLevel)) {
337  return false;
338  }
339  break;
340  case IsAtMost:
341  if (static_cast<int>(userID.validity()) > static_cast<int>(d->mValidityReferenceLevel)) {
342  return false;
343  }
344  break;
345  }
346  return true;
347 }
348 
349 KeyFilter::FontDescription DefaultKeyFilter::fontDescription() const
350 {
351  if (d->mUseFullFont) {
352  return FontDescription::create(font(), bold(), italic(), strikeOut());
353  } else {
354  return FontDescription::create(bold(), italic(), strikeOut());
355  }
356 }
357 
358 void DefaultKeyFilter::setFgColor(const QColor &value)
359 {
360  d->mFgColor = value;
361 }
362 
363 void DefaultKeyFilter::setBgColor(const QColor &value)
364 {
365  d->mBgColor = value;
366 }
367 
368 void DefaultKeyFilter::setName(const QString &value)
369 {
370  d->mName = value;
371 }
372 
373 void DefaultKeyFilter::setIcon(const QString &value)
374 {
375  d->mIcon = value;
376 }
377 
378 void DefaultKeyFilter::setId(const QString &value)
379 {
380  d->mId = value;
381 }
382 
383 void DefaultKeyFilter::setMatchContexts(MatchContexts value)
384 {
385  d->mMatchContexts = value;
386 }
387 
388 void DefaultKeyFilter::setSpecificity(unsigned int value)
389 {
390  d->mSpecificity = value;
391 }
392 
393 void DefaultKeyFilter::setItalic(bool value)
394 {
395  d->mItalic = value;
396 }
397 
398 void DefaultKeyFilter::setBold(bool value)
399 {
400  d->mBold = value;
401 }
402 
403 void DefaultKeyFilter::setStrikeOut(bool value)
404 {
405  d->mStrikeOut = value;
406 }
407 
408 void DefaultKeyFilter::setUseFullFont(bool value)
409 {
410  d->mUseFullFont = value;
411 }
412 
413 void DefaultKeyFilter::setFont(const QFont &value)
414 {
415  d->mFont = value;
416 }
417 
418 void DefaultKeyFilter::setRevoked(DefaultKeyFilter::TriState value)
419 {
420  d->mRevoked = value;
421 }
422 
423 void DefaultKeyFilter::setExpired(DefaultKeyFilter::TriState value)
424 {
425  d->mExpired = value;
426 }
427 
428 void DefaultKeyFilter::setInvalid(DefaultKeyFilter::TriState value)
429 {
430  d->mInvalid = value;
431 }
432 
433 void DefaultKeyFilter::setDisabled(DefaultKeyFilter::TriState value)
434 {
435  d->mDisabled = value;
436 }
437 
438 void DefaultKeyFilter::setRoot(DefaultKeyFilter::TriState value)
439 {
440  d->mRoot = value;
441 }
442 
443 void DefaultKeyFilter::setCanEncrypt(DefaultKeyFilter::TriState value)
444 {
445  d->mCanEncrypt = value;
446 }
447 
448 void DefaultKeyFilter::setCanSign(DefaultKeyFilter::TriState value)
449 {
450  d->mCanSign = value;
451 }
452 
453 void DefaultKeyFilter::setCanCertify(DefaultKeyFilter::TriState value)
454 {
455  d->mCanCertify = value;
456 }
457 
458 void DefaultKeyFilter::setCanAuthenticate(DefaultKeyFilter::TriState value)
459 {
460  d->mCanAuthenticate = value;
461 }
462 
463 void DefaultKeyFilter::setHasEncrypt(DefaultKeyFilter::TriState value)
464 {
465  d->mHasEncrypt = value;
466 }
467 
468 void DefaultKeyFilter::setHasSign(DefaultKeyFilter::TriState value)
469 {
470  d->mHasSign = value;
471 }
472 
473 void DefaultKeyFilter::setHasCertify(DefaultKeyFilter::TriState value)
474 {
475  d->mHasCertify = value;
476 }
477 
478 void DefaultKeyFilter::setHasAuthenticate(DefaultKeyFilter::TriState value)
479 {
480  d->mHasAuthenticate = value;
481 }
482 
483 void DefaultKeyFilter::setQualified(DefaultKeyFilter::TriState value)
484 {
485  d->mQualified = value;
486 }
487 
488 void DefaultKeyFilter::setCardKey(DefaultKeyFilter::TriState value)
489 {
490  d->mCardKey = value;
491 }
492 
493 void DefaultKeyFilter::setHasSecret(DefaultKeyFilter::TriState value)
494 {
495  d->mHasSecret = value;
496 }
497 
498 void DefaultKeyFilter::setIsOpenPGP(DefaultKeyFilter::TriState value)
499 {
500  d->mIsOpenPGP = value;
501 }
502 
503 void DefaultKeyFilter::setWasValidated(DefaultKeyFilter::TriState value)
504 {
505  d->mWasValidated = value;
506 }
507 
508 void DefaultKeyFilter::setOwnerTrust(DefaultKeyFilter::LevelState value)
509 {
510  d->mOwnerTrust = value;
511 }
512 
513 void DefaultKeyFilter::setOwnerTrustReferenceLevel(GpgME::Key::OwnerTrust value)
514 {
515  d->mOwnerTrustReferenceLevel = value;
516 }
517 
518 void DefaultKeyFilter::setValidity(DefaultKeyFilter::LevelState value)
519 {
520  d->mValidity = value;
521 }
522 
523 void DefaultKeyFilter::setValidityReferenceLevel(GpgME::UserID::Validity value)
524 {
525  d->mValidityReferenceLevel = value;
526 }
527 
528 void DefaultKeyFilter::setIsDeVs(DefaultKeyFilter::TriState value)
529 {
530  d->mIsDeVs = value;
531 }
532 
533 void DefaultKeyFilter::setIsBad(DefaultKeyFilter::TriState value)
534 {
535  d->mBad = value;
536 }
537 
539 {
540  d->mValidIfSMIME = value;
541 }
542 
543 QColor DefaultKeyFilter::fgColor() const
544 {
545  return d->mFgColor;
546 }
547 
548 QColor DefaultKeyFilter::bgColor() const
549 {
550  return d->mBgColor;
551 }
552 
553 QString DefaultKeyFilter::name() const
554 {
555  return d->mName;
556 }
557 
558 QString DefaultKeyFilter::icon() const
559 {
560  return d->mIcon;
561 }
562 
563 QString DefaultKeyFilter::id() const
564 {
565  return d->mId;
566 }
567 
568 QFont DefaultKeyFilter::font() const
569 {
570  return d->mFont;
571 }
572 
573 KeyFilter::MatchContexts DefaultKeyFilter::availableMatchContexts() const
574 {
575  return d->mMatchContexts;
576 }
577 
578 unsigned int DefaultKeyFilter::specificity() const
579 {
580  return d->mSpecificity;
581 }
582 
583 bool DefaultKeyFilter::italic() const
584 {
585  return d->mItalic;
586 }
587 
588 bool DefaultKeyFilter::bold() const
589 {
590  return d->mBold;
591 }
592 
593 bool DefaultKeyFilter::strikeOut() const
594 {
595  return d->mStrikeOut;
596 }
597 
598 bool DefaultKeyFilter::useFullFont() const
599 {
600  return d->mUseFullFont;
601 }
602 
603 DefaultKeyFilter::TriState DefaultKeyFilter::revoked() const
604 {
605  return d->mRevoked;
606 }
607 
608 DefaultKeyFilter::TriState DefaultKeyFilter::expired() const
609 {
610  return d->mExpired;
611 }
612 
613 DefaultKeyFilter::TriState DefaultKeyFilter::invalid() const
614 {
615  return d->mInvalid;
616 }
617 
618 DefaultKeyFilter::TriState DefaultKeyFilter::disabled() const
619 {
620  return d->mDisabled;
621 }
622 
623 DefaultKeyFilter::TriState DefaultKeyFilter::root() const
624 {
625  return d->mRoot;
626 }
627 
628 DefaultKeyFilter::TriState DefaultKeyFilter::canEncrypt() const
629 {
630  return d->mCanEncrypt;
631 }
632 
633 DefaultKeyFilter::TriState DefaultKeyFilter::canSign() const
634 {
635  return d->mCanSign;
636 }
637 
638 DefaultKeyFilter::TriState DefaultKeyFilter::canCertify() const
639 {
640  return d->mCanCertify;
641 }
642 
643 DefaultKeyFilter::TriState DefaultKeyFilter::canAuthenticate() const
644 {
645  return d->mCanAuthenticate;
646 }
647 
648 DefaultKeyFilter::TriState DefaultKeyFilter::hasEncrypt() const
649 {
650  return d->mHasEncrypt;
651 }
652 
653 DefaultKeyFilter::TriState DefaultKeyFilter::hasSign() const
654 {
655  return d->mHasSign;
656 }
657 
658 DefaultKeyFilter::TriState DefaultKeyFilter::hasCertify() const
659 {
660  return d->mHasCertify;
661 }
662 
663 DefaultKeyFilter::TriState DefaultKeyFilter::hasAuthenticate() const
664 {
665  return d->mHasAuthenticate;
666 }
667 
668 DefaultKeyFilter::TriState DefaultKeyFilter::qualified() const
669 {
670  return d->mQualified;
671 }
672 
673 DefaultKeyFilter::TriState DefaultKeyFilter::cardKey() const
674 {
675  return d->mCardKey;
676 }
677 
678 DefaultKeyFilter::TriState DefaultKeyFilter::hasSecret() const
679 {
680  return d->mHasSecret;
681 }
682 
683 DefaultKeyFilter::TriState DefaultKeyFilter::isOpenPGP() const
684 {
685  return d->mIsOpenPGP;
686 }
687 
688 DefaultKeyFilter::TriState DefaultKeyFilter::wasValidated() const
689 {
690  return d->mWasValidated;
691 }
692 
693 DefaultKeyFilter::LevelState DefaultKeyFilter::ownerTrust() const
694 {
695  return d->mOwnerTrust;
696 }
697 
698 GpgME::Key::OwnerTrust DefaultKeyFilter::ownerTrustReferenceLevel() const
699 {
700  return d->mOwnerTrustReferenceLevel;
701 }
702 
703 DefaultKeyFilter::LevelState DefaultKeyFilter::validity() const
704 {
705  return d->mValidity;
706 }
707 
708 GpgME::UserID::Validity DefaultKeyFilter::validityReferenceLevel() const
709 {
710  return d->mValidityReferenceLevel;
711 }
712 
713 DefaultKeyFilter::TriState DefaultKeyFilter::isDeVS() const
714 {
715  return d->mIsDeVs;
716 }
717 
718 DefaultKeyFilter::TriState DefaultKeyFilter::isBad() const
719 {
720  return d->mBad;
721 }
722 
723 DefaultKeyFilter::TriState DefaultKeyFilter::validIfSMIME() const
724 {
725  return d->mValidIfSMIME;
726 }
void setValidIfSMIME(TriState value)
If value is Set, then invalid S/MIME certificates do not match.
An abstract base class key filters.
Definition: keyfilter.h:36
LevelState
Used for level checks.
TriState
Used for bool checks.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:56:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.