1 /* -*- mode: c++; c-basic-offset:4 -*-
2 crypto/gui/signingcertificateselectionwidget.cpp
3
4 This file is part of Kleopatra, the KDE keymanager
5 SPDX-FileCopyrightText: 2007, 2009 Klarälvdalens Datakonsult AB
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include <config-kleopatra.h>
11
12 #include "signingcertificateselectionwidget.h"
13
14 #include "ui_signingcertificateselectionwidget.h"
15
16 #include <Libkleo/KeyCache>
17 #include <Libkleo/Formatting>
18 #include <Libkleo/Stl_Util>
19
20 #include <QByteArray>
21 #include <QMap>
22
23
24 using namespace Kleo;
25 using namespace Kleo::Crypto::Gui;
26
27 class SigningCertificateSelectionWidget::Private
28 {
29 friend class ::SigningCertificateSelectionWidget;
30 SigningCertificateSelectionWidget *const q;
31 public:
32 explicit Private(SigningCertificateSelectionWidget *qq);
33 ~Private();
34 static std::vector<GpgME::Key> candidates(GpgME::Protocol prot);
35 static void addCandidates(GpgME::Protocol prot, QComboBox *combo);
36
37 private:
38 Ui::SigningCertificateSelectionWidget ui;
39 };
40
current_cert(const QComboBox & cb)41 static GpgME::Key current_cert(const QComboBox &cb)
42 {
43 const QByteArray fpr = cb.itemData(cb.currentIndex()).toByteArray();
44 return KeyCache::instance()->findByFingerprint(fpr.constData());
45 }
46
select_cert(QComboBox & cb,const GpgME::Key & key)47 static void select_cert(QComboBox &cb, const GpgME::Key &key)
48 {
49 const QByteArray fpr = key.primaryFingerprint();
50 if (!fpr.isEmpty()) {
51 cb.setCurrentIndex(cb.findData(fpr));
52 }
53 }
54
add_cert(QComboBox & cb,const GpgME::Key & key)55 static void add_cert(QComboBox &cb, const GpgME::Key &key)
56 {
57 cb.addItem(Formatting::formatForComboBox(key),
58 QVariant(QByteArray(key.primaryFingerprint())));
59
60 }
61
Private(SigningCertificateSelectionWidget * qq)62 SigningCertificateSelectionWidget::Private::Private(SigningCertificateSelectionWidget *qq)
63 : q(qq), ui()
64 {
65 ui.setupUi(q);
66 addCandidates(GpgME::CMS, ui.cmsCombo);
67 addCandidates(GpgME::OpenPGP, ui.pgpCombo);
68 ui.rememberCO->setChecked(true);
69 }
70
~Private()71 SigningCertificateSelectionWidget::Private::~Private() {}
72
SigningCertificateSelectionWidget(QWidget * parent,Qt::WindowFlags f)73 SigningCertificateSelectionWidget::SigningCertificateSelectionWidget(QWidget *parent, Qt::WindowFlags f)
74 : QWidget(parent, f), d(new Private(this))
75 {
76
77 }
78
~SigningCertificateSelectionWidget()79 SigningCertificateSelectionWidget::~SigningCertificateSelectionWidget() {}
80
setSelectedCertificates(const QMap<GpgME::Protocol,GpgME::Key> & certificates)81 void SigningCertificateSelectionWidget::setSelectedCertificates(const QMap<GpgME::Protocol, GpgME::Key> &certificates)
82 {
83 setSelectedCertificates(certificates[GpgME::OpenPGP], certificates[GpgME::CMS]);
84 }
85
setSelectedCertificates(const GpgME::Key & pgp,const GpgME::Key & cms)86 void SigningCertificateSelectionWidget::setSelectedCertificates(const GpgME::Key &pgp, const GpgME::Key &cms)
87 {
88 select_cert(*d->ui.pgpCombo, pgp);
89 select_cert(*d->ui.cmsCombo, cms);
90 }
91
candidates(GpgME::Protocol prot)92 std::vector<GpgME::Key> SigningCertificateSelectionWidget::Private::candidates(GpgME::Protocol prot)
93 {
94 Q_ASSERT(prot != GpgME::UnknownProtocol);
95 std::vector<GpgME::Key> keys = KeyCache::instance()->keys();
96 auto end = keys.end();
97
98 end = std::remove_if(keys.begin(), end, [prot](const GpgME::Key &key) { return key.protocol() != prot; });
99 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { return !key.hasSecret(); });
100 Q_ASSERT(std::all_of(keys.begin(), end, [](const GpgME::Key &key) { return key.hasSecret(); }));
101 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { return !key.canReallySign(); });
102 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { return key.isExpired(); });
103 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { return key.isRevoked(); });
104 keys.erase(end, keys.end());
105 return keys;
106 }
107
addCandidates(GpgME::Protocol prot,QComboBox * combo)108 void SigningCertificateSelectionWidget::Private::addCandidates(GpgME::Protocol prot, QComboBox *combo)
109 {
110 const std::vector<GpgME::Key> keys = candidates(prot);
111 for (const GpgME::Key &i : keys) {
112 add_cert(*combo, i);
113 }
114 }
115
selectedCertificates() const116 QMap<GpgME::Protocol, GpgME::Key> SigningCertificateSelectionWidget::selectedCertificates() const
117 {
118 QMap<GpgME::Protocol, GpgME::Key> res;
119
120 res.insert(GpgME::OpenPGP, current_cert(*d->ui.pgpCombo));
121 res.insert(GpgME::CMS, current_cert(*d->ui.cmsCombo));
122
123 return res;
124 }
125
rememberAsDefault() const126 bool SigningCertificateSelectionWidget::rememberAsDefault() const
127 {
128 return d->ui.rememberCO->isChecked();
129 }
130
setAllowedProtocols(const std::set<GpgME::Protocol> & allowedProtocols)131 void SigningCertificateSelectionWidget::setAllowedProtocols(const std::set<GpgME::Protocol> &allowedProtocols)
132 {
133 setAllowedProtocols(allowedProtocols.find(GpgME::OpenPGP) != allowedProtocols.end(),
134 allowedProtocols.find(GpgME::CMS) != allowedProtocols.end());
135 }
136
setAllowedProtocols(bool pgp,bool cms)137 void SigningCertificateSelectionWidget::setAllowedProtocols(bool pgp, bool cms)
138 {
139 d->ui.pgpLabel->setVisible(pgp);
140 d->ui.pgpCombo->setVisible(pgp);
141
142 d->ui.cmsLabel->setVisible(cms);
143 d->ui.cmsCombo->setVisible(cms);
144 }
145
146