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

KDE's Doxygen guidelines are available online.