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

KDE's Doxygen guidelines are available online.