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 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
85DefaultKeyFilter::DefaultKeyFilter()
86 : KeyFilter{}
87 , d{new Private}
88{
89}
90
91DefaultKeyFilter::~DefaultKeyFilter() = default;
92
93bool 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
213bool 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
349KeyFilter::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
358void DefaultKeyFilter::setFgColor(const QColor &value)
359{
360 d->mFgColor = value;
361}
362
363void DefaultKeyFilter::setBgColor(const QColor &value)
364{
365 d->mBgColor = value;
366}
367
368void DefaultKeyFilter::setName(const QString &value)
369{
370 d->mName = value;
371}
372
373void DefaultKeyFilter::setIcon(const QString &value)
374{
375 d->mIcon = value;
376}
377
378void DefaultKeyFilter::setId(const QString &value)
379{
380 d->mId = value;
381}
382
383void DefaultKeyFilter::setMatchContexts(MatchContexts value)
384{
385 d->mMatchContexts = value;
386}
387
388void DefaultKeyFilter::setSpecificity(unsigned int value)
389{
390 d->mSpecificity = value;
391}
392
393void DefaultKeyFilter::setItalic(bool value)
394{
395 d->mItalic = value;
396}
397
398void DefaultKeyFilter::setBold(bool value)
399{
400 d->mBold = value;
401}
402
403void DefaultKeyFilter::setStrikeOut(bool value)
404{
405 d->mStrikeOut = value;
406}
407
408void DefaultKeyFilter::setUseFullFont(bool value)
409{
410 d->mUseFullFont = value;
411}
412
413void DefaultKeyFilter::setFont(const QFont &value)
414{
415 d->mFont = value;
416}
417
418void DefaultKeyFilter::setRevoked(DefaultKeyFilter::TriState value)
419{
420 d->mRevoked = value;
421}
422
423void DefaultKeyFilter::setExpired(DefaultKeyFilter::TriState value)
424{
425 d->mExpired = value;
426}
427
428void DefaultKeyFilter::setInvalid(DefaultKeyFilter::TriState value)
429{
430 d->mInvalid = value;
431}
432
433void DefaultKeyFilter::setDisabled(DefaultKeyFilter::TriState value)
434{
435 d->mDisabled = value;
436}
437
438void DefaultKeyFilter::setRoot(DefaultKeyFilter::TriState value)
439{
440 d->mRoot = value;
441}
442
443void DefaultKeyFilter::setCanEncrypt(DefaultKeyFilter::TriState value)
444{
445 d->mCanEncrypt = value;
446}
447
448void DefaultKeyFilter::setCanSign(DefaultKeyFilter::TriState value)
449{
450 d->mCanSign = value;
451}
452
453void DefaultKeyFilter::setCanCertify(DefaultKeyFilter::TriState value)
454{
455 d->mCanCertify = value;
456}
457
458void DefaultKeyFilter::setCanAuthenticate(DefaultKeyFilter::TriState value)
459{
460 d->mCanAuthenticate = value;
461}
462
463void DefaultKeyFilter::setHasEncrypt(DefaultKeyFilter::TriState value)
464{
465 d->mHasEncrypt = value;
466}
467
468void DefaultKeyFilter::setHasSign(DefaultKeyFilter::TriState value)
469{
470 d->mHasSign = value;
471}
472
473void DefaultKeyFilter::setHasCertify(DefaultKeyFilter::TriState value)
474{
475 d->mHasCertify = value;
476}
477
478void DefaultKeyFilter::setHasAuthenticate(DefaultKeyFilter::TriState value)
479{
480 d->mHasAuthenticate = value;
481}
482
483void DefaultKeyFilter::setQualified(DefaultKeyFilter::TriState value)
484{
485 d->mQualified = value;
486}
487
488void DefaultKeyFilter::setCardKey(DefaultKeyFilter::TriState value)
489{
490 d->mCardKey = value;
491}
492
493void DefaultKeyFilter::setHasSecret(DefaultKeyFilter::TriState value)
494{
495 d->mHasSecret = value;
496}
497
498void DefaultKeyFilter::setIsOpenPGP(DefaultKeyFilter::TriState value)
499{
500 d->mIsOpenPGP = value;
501}
502
503void DefaultKeyFilter::setWasValidated(DefaultKeyFilter::TriState value)
504{
505 d->mWasValidated = value;
506}
507
508void DefaultKeyFilter::setOwnerTrust(DefaultKeyFilter::LevelState value)
509{
510 d->mOwnerTrust = value;
511}
512
513void DefaultKeyFilter::setOwnerTrustReferenceLevel(GpgME::Key::OwnerTrust value)
514{
515 d->mOwnerTrustReferenceLevel = value;
516}
517
518void DefaultKeyFilter::setValidity(DefaultKeyFilter::LevelState value)
519{
520 d->mValidity = value;
521}
522
523void DefaultKeyFilter::setValidityReferenceLevel(GpgME::UserID::Validity value)
524{
525 d->mValidityReferenceLevel = value;
526}
527
528void DefaultKeyFilter::setIsDeVs(DefaultKeyFilter::TriState value)
529{
530 d->mIsDeVs = value;
531}
532
533void DefaultKeyFilter::setIsBad(DefaultKeyFilter::TriState value)
534{
535 d->mBad = value;
536}
537
539{
540 d->mValidIfSMIME = value;
541}
542
543QColor DefaultKeyFilter::fgColor() const
544{
545 return d->mFgColor;
546}
547
548QColor DefaultKeyFilter::bgColor() const
549{
550 return d->mBgColor;
551}
552
553QString DefaultKeyFilter::name() const
554{
555 return d->mName;
556}
557
558QString DefaultKeyFilter::icon() const
559{
560 return d->mIcon;
561}
562
563QString DefaultKeyFilter::id() const
564{
565 return d->mId;
566}
567
568QFont DefaultKeyFilter::font() const
569{
570 return d->mFont;
571}
572
573KeyFilter::MatchContexts DefaultKeyFilter::availableMatchContexts() const
574{
575 return d->mMatchContexts;
576}
577
578unsigned int DefaultKeyFilter::specificity() const
579{
580 return d->mSpecificity;
581}
582
583bool DefaultKeyFilter::italic() const
584{
585 return d->mItalic;
586}
587
588bool DefaultKeyFilter::bold() const
589{
590 return d->mBold;
591}
592
593bool DefaultKeyFilter::strikeOut() const
594{
595 return d->mStrikeOut;
596}
597
598bool DefaultKeyFilter::useFullFont() const
599{
600 return d->mUseFullFont;
601}
602
603DefaultKeyFilter::TriState DefaultKeyFilter::revoked() const
604{
605 return d->mRevoked;
606}
607
608DefaultKeyFilter::TriState DefaultKeyFilter::expired() const
609{
610 return d->mExpired;
611}
612
613DefaultKeyFilter::TriState DefaultKeyFilter::invalid() const
614{
615 return d->mInvalid;
616}
617
618DefaultKeyFilter::TriState DefaultKeyFilter::disabled() const
619{
620 return d->mDisabled;
621}
622
623DefaultKeyFilter::TriState DefaultKeyFilter::root() const
624{
625 return d->mRoot;
626}
627
628DefaultKeyFilter::TriState DefaultKeyFilter::canEncrypt() const
629{
630 return d->mCanEncrypt;
631}
632
633DefaultKeyFilter::TriState DefaultKeyFilter::canSign() const
634{
635 return d->mCanSign;
636}
637
638DefaultKeyFilter::TriState DefaultKeyFilter::canCertify() const
639{
640 return d->mCanCertify;
641}
642
643DefaultKeyFilter::TriState DefaultKeyFilter::canAuthenticate() const
644{
645 return d->mCanAuthenticate;
646}
647
648DefaultKeyFilter::TriState DefaultKeyFilter::hasEncrypt() const
649{
650 return d->mHasEncrypt;
651}
652
653DefaultKeyFilter::TriState DefaultKeyFilter::hasSign() const
654{
655 return d->mHasSign;
656}
657
658DefaultKeyFilter::TriState DefaultKeyFilter::hasCertify() const
659{
660 return d->mHasCertify;
661}
662
663DefaultKeyFilter::TriState DefaultKeyFilter::hasAuthenticate() const
664{
665 return d->mHasAuthenticate;
666}
667
668DefaultKeyFilter::TriState DefaultKeyFilter::qualified() const
669{
670 return d->mQualified;
671}
672
673DefaultKeyFilter::TriState DefaultKeyFilter::cardKey() const
674{
675 return d->mCardKey;
676}
677
678DefaultKeyFilter::TriState DefaultKeyFilter::hasSecret() const
679{
680 return d->mHasSecret;
681}
682
683DefaultKeyFilter::TriState DefaultKeyFilter::isOpenPGP() const
684{
685 return d->mIsOpenPGP;
686}
687
688DefaultKeyFilter::TriState DefaultKeyFilter::wasValidated() const
689{
690 return d->mWasValidated;
691}
692
693DefaultKeyFilter::LevelState DefaultKeyFilter::ownerTrust() const
694{
695 return d->mOwnerTrust;
696}
697
698GpgME::Key::OwnerTrust DefaultKeyFilter::ownerTrustReferenceLevel() const
699{
700 return d->mOwnerTrustReferenceLevel;
701}
702
703DefaultKeyFilter::LevelState DefaultKeyFilter::validity() const
704{
705 return d->mValidity;
706}
707
708GpgME::UserID::Validity DefaultKeyFilter::validityReferenceLevel() const
709{
710 return d->mValidityReferenceLevel;
711}
712
713DefaultKeyFilter::TriState DefaultKeyFilter::isDeVS() const
714{
715 return d->mIsDeVs;
716}
717
718DefaultKeyFilter::TriState DefaultKeyFilter::isBad() const
719{
720 return d->mBad;
721}
722
723DefaultKeyFilter::TriState DefaultKeyFilter::validIfSMIME() const
724{
725 return d->mValidIfSMIME;
726}
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 Tue Mar 26 2024 11:14:11 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.