File indexing completed on 2024-06-23 05:13:53
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 crypto/gui/signingcertificateselectionwidget.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2007, 2009 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "signingcertificateselectionwidget.h" 0013 0014 #include "ui_signingcertificateselectionwidget.h" 0015 0016 #include "utils/certificatepair.h" 0017 0018 #include <Libkleo/Compat> 0019 #include <Libkleo/Formatting> 0020 #include <Libkleo/KeyCache> 0021 #include <Libkleo/Stl_Util> 0022 0023 #include <QByteArray> 0024 0025 using namespace Kleo; 0026 using namespace Kleo::Crypto::Gui; 0027 0028 class SigningCertificateSelectionWidget::Private 0029 { 0030 friend class ::SigningCertificateSelectionWidget; 0031 SigningCertificateSelectionWidget *const q; 0032 0033 public: 0034 explicit Private(SigningCertificateSelectionWidget *qq); 0035 ~Private(); 0036 static std::vector<GpgME::Key> candidates(GpgME::Protocol prot); 0037 static void addCandidates(GpgME::Protocol prot, QComboBox *combo); 0038 0039 private: 0040 Ui::SigningCertificateSelectionWidget ui; 0041 }; 0042 0043 static GpgME::Key current_cert(const QComboBox &cb) 0044 { 0045 const QByteArray fpr = cb.itemData(cb.currentIndex()).toByteArray(); 0046 return KeyCache::instance()->findByFingerprint(fpr.constData()); 0047 } 0048 0049 static void select_cert(QComboBox &cb, const GpgME::Key &key) 0050 { 0051 const QByteArray fpr = key.primaryFingerprint(); 0052 if (!fpr.isEmpty()) { 0053 cb.setCurrentIndex(cb.findData(fpr)); 0054 } 0055 } 0056 0057 static void add_cert(QComboBox &cb, const GpgME::Key &key) 0058 { 0059 cb.addItem(Formatting::formatForComboBox(key), QVariant(QByteArray(key.primaryFingerprint()))); 0060 } 0061 0062 SigningCertificateSelectionWidget::Private::Private(SigningCertificateSelectionWidget *qq) 0063 : q(qq) 0064 , ui() 0065 { 0066 ui.setupUi(q); 0067 addCandidates(GpgME::CMS, ui.cmsCombo); 0068 addCandidates(GpgME::OpenPGP, ui.pgpCombo); 0069 ui.rememberCO->setChecked(true); 0070 } 0071 0072 SigningCertificateSelectionWidget::Private::~Private() 0073 { 0074 } 0075 0076 SigningCertificateSelectionWidget::SigningCertificateSelectionWidget(QWidget *parent, Qt::WindowFlags f) 0077 : QWidget(parent, f) 0078 , d(new Private(this)) 0079 { 0080 } 0081 0082 SigningCertificateSelectionWidget::~SigningCertificateSelectionWidget() 0083 { 0084 } 0085 0086 void SigningCertificateSelectionWidget::setSelectedCertificates(const CertificatePair &certificates) 0087 { 0088 setSelectedCertificates(certificates.openpgp, certificates.cms); 0089 } 0090 0091 void SigningCertificateSelectionWidget::setSelectedCertificates(const GpgME::Key &pgp, const GpgME::Key &cms) 0092 { 0093 select_cert(*d->ui.pgpCombo, pgp); 0094 select_cert(*d->ui.cmsCombo, cms); 0095 } 0096 0097 std::vector<GpgME::Key> SigningCertificateSelectionWidget::Private::candidates(GpgME::Protocol prot) 0098 { 0099 Q_ASSERT(prot != GpgME::UnknownProtocol); 0100 std::vector<GpgME::Key> keys = KeyCache::instance()->keys(); 0101 auto end = keys.end(); 0102 0103 end = std::remove_if(keys.begin(), end, [prot](const GpgME::Key &key) { 0104 return key.protocol() != prot; 0105 }); 0106 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { 0107 return !key.hasSecret(); 0108 }); 0109 Q_ASSERT(std::all_of(keys.begin(), end, [](const GpgME::Key &key) { 0110 return key.hasSecret(); 0111 })); 0112 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { 0113 return !Kleo::keyHasSign(key); 0114 }); 0115 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { 0116 return key.isExpired(); 0117 }); 0118 end = std::remove_if(keys.begin(), end, [](const GpgME::Key &key) { 0119 return key.isRevoked(); 0120 }); 0121 keys.erase(end, keys.end()); 0122 return keys; 0123 } 0124 0125 void SigningCertificateSelectionWidget::Private::addCandidates(GpgME::Protocol prot, QComboBox *combo) 0126 { 0127 const std::vector<GpgME::Key> keys = candidates(prot); 0128 for (const GpgME::Key &i : keys) { 0129 add_cert(*combo, i); 0130 } 0131 } 0132 0133 CertificatePair SigningCertificateSelectionWidget::selectedCertificates() const 0134 { 0135 return { 0136 current_cert(*d->ui.pgpCombo), 0137 current_cert(*d->ui.cmsCombo), 0138 }; 0139 } 0140 0141 bool SigningCertificateSelectionWidget::rememberAsDefault() const 0142 { 0143 return d->ui.rememberCO->isChecked(); 0144 } 0145 0146 void SigningCertificateSelectionWidget::setAllowedProtocols(const std::set<GpgME::Protocol> &allowedProtocols) 0147 { 0148 setAllowedProtocols(allowedProtocols.find(GpgME::OpenPGP) != allowedProtocols.end(), allowedProtocols.find(GpgME::CMS) != allowedProtocols.end()); 0149 } 0150 0151 void SigningCertificateSelectionWidget::setAllowedProtocols(bool pgp, bool cms) 0152 { 0153 d->ui.pgpLabel->setVisible(pgp); 0154 d->ui.pgpCombo->setVisible(pgp); 0155 0156 d->ui.cmsLabel->setVisible(cms); 0157 d->ui.cmsCombo->setVisible(cms); 0158 } 0159 0160 #include "moc_signingcertificateselectionwidget.cpp"