Page MenuHome GnuPG

No OneTemporary

diff --git a/src/view/openpgpkeycardwidget.cpp b/src/view/openpgpkeycardwidget.cpp
index c9e74b2d0..bcdaaa2c5 100644
--- a/src/view/openpgpkeycardwidget.cpp
+++ b/src/view/openpgpkeycardwidget.cpp
@@ -1,266 +1,266 @@
/* view/openpgpkeycardwidget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2021, 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "openpgpkeycardwidget.h"
#include "commands/detailscommand.h"
#include "smartcard/card.h"
#include "smartcard/keypairinfo.h"
#include "smartcard/openpgpcard.h"
#include <Libkleo/Compliance>
#include <Libkleo/Formatting>
#include <Libkleo/KeyCache>
#include <KLocalizedString>
#include <KMessageBox>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <gpgme++/key.h>
using namespace Kleo;
using namespace SmartCard;
namespace
{
struct KeyWidgets {
std::string cardKeyRef;
std::string keyFingerprint;
KeyPairInfo keyInfo;
QLabel *keyTitleLabel = nullptr;
QLabel *keyInfoLabel = nullptr;
QPushButton *showCertificateDetailsButton = nullptr;
QPushButton *generateButton = nullptr;
QPushButton *createCSRButton = nullptr;
};
KeyWidgets createKeyWidgets(const KeyPairInfo &keyInfo, QWidget *parent)
{
KeyWidgets keyWidgets;
keyWidgets.keyTitleLabel = new QLabel{OpenPGPCard::keyDisplayName(keyInfo.keyRef), parent};
keyWidgets.keyInfoLabel = new QLabel{parent};
keyWidgets.keyInfoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction | Qt::TextSelectableByKeyboard);
keyWidgets.showCertificateDetailsButton = new QPushButton{i18nc("@action:button", "Show Details"), parent};
keyWidgets.showCertificateDetailsButton->setToolTip(i18nc("@action:tooltip", "Show detailed information about this key"));
keyWidgets.showCertificateDetailsButton->setEnabled(false);
keyWidgets.generateButton = new QPushButton{i18nc("@action:button", "Generate Key"), parent};
keyWidgets.generateButton->setEnabled(false);
if (keyInfo.canCertify() || keyInfo.canSign() || keyInfo.canAuthenticate()) {
keyWidgets.createCSRButton = new QPushButton{i18nc("@action:button", "Create CSR"), parent};
keyWidgets.createCSRButton->setToolTip(i18nc("@info:tooltip", "Create a certificate signing request for this key"));
keyWidgets.createCSRButton->setEnabled(false);
}
return keyWidgets;
}
}
class OpenPGPKeyCardWidget::Private
{
public:
explicit Private(OpenPGPKeyCardWidget *q);
~Private() = default;
void setAllowedActions(Actions actions);
void update(const Card *card = nullptr);
private:
void updateCachedValues(const std::string &openPGPKeyRef, const std::string &cardKeyRef, const Card *card);
void updateKeyWidgets(const std::string &openPGPKeyRef);
void showCertificateDetails(const std::string &openPGPKeyRef);
private:
OpenPGPKeyCardWidget *const q;
Actions mAllowedActions = AllActions;
std::map<std::string, KeyWidgets> mKeyWidgets;
};
OpenPGPKeyCardWidget::Private::Private(OpenPGPKeyCardWidget *q)
: q{q}
{
auto grid = new QGridLayout{q};
grid->setContentsMargins(0, 0, 0, 0);
for (const auto &keyInfo : OpenPGPCard::supportedKeys()) {
const KeyWidgets keyWidgets = createKeyWidgets(keyInfo, q);
const std::string keyRef = keyInfo.keyRef;
connect(keyWidgets.showCertificateDetailsButton, &QPushButton::clicked, q, [this, keyRef]() {
showCertificateDetails(keyRef);
});
connect(keyWidgets.generateButton, &QPushButton::clicked, q, [q, keyRef]() {
Q_EMIT q->generateKeyRequested(keyRef);
});
if (keyWidgets.createCSRButton) {
connect(keyWidgets.createCSRButton, &QPushButton::clicked, q, [q, keyRef]() {
Q_EMIT q->createCSRRequested(keyRef);
});
}
const int row = grid->rowCount();
grid->addWidget(keyWidgets.keyTitleLabel, row, 0, Qt::AlignTop);
grid->addWidget(keyWidgets.keyInfoLabel, row, 1, Qt::AlignTop);
auto buttons = new QHBoxLayout;
buttons->addWidget(keyWidgets.showCertificateDetailsButton);
buttons->addWidget(keyWidgets.generateButton);
if (keyWidgets.createCSRButton) {
buttons->addWidget(keyWidgets.createCSRButton);
}
buttons->addStretch(1);
grid->addLayout(buttons, row, 2, Qt::AlignTop);
mKeyWidgets.insert({keyInfo.keyRef, keyWidgets});
}
grid->setColumnStretch(grid->columnCount(), 1);
}
void OpenPGPKeyCardWidget::Private::setAllowedActions(Actions actions)
{
mAllowedActions = actions;
update();
}
void OpenPGPKeyCardWidget::Private::update(const Card *card)
{
if (card) {
updateCachedValues(OpenPGPCard::pgpSigKeyRef(), card->signingKeyRef(), card);
updateCachedValues(OpenPGPCard::pgpEncKeyRef(), card->encryptionKeyRef(), card);
updateCachedValues(OpenPGPCard::pgpAuthKeyRef(), card->authenticationKeyRef(), card);
}
updateKeyWidgets(OpenPGPCard::pgpSigKeyRef());
updateKeyWidgets(OpenPGPCard::pgpEncKeyRef());
updateKeyWidgets(OpenPGPCard::pgpAuthKeyRef());
}
void OpenPGPKeyCardWidget::Private::updateCachedValues(const std::string &openPGPKeyRef, const std::string &cardKeyRef, const Card *card)
{
KeyWidgets &widgets = mKeyWidgets.at(openPGPKeyRef);
widgets.cardKeyRef = cardKeyRef;
widgets.keyFingerprint = card->keyFingerprint(openPGPKeyRef);
widgets.keyInfo = card->keyInfo(cardKeyRef);
}
void OpenPGPKeyCardWidget::Private::updateKeyWidgets(const std::string &openPGPKeyRef)
{
const KeyWidgets &widgets = mKeyWidgets.at(openPGPKeyRef);
const auto cardSupportsKey = !widgets.cardKeyRef.empty();
widgets.keyTitleLabel->setVisible(cardSupportsKey);
widgets.keyInfoLabel->setVisible(cardSupportsKey);
widgets.showCertificateDetailsButton->setVisible(cardSupportsKey);
- widgets.generateButton->setVisible(cardSupportsKey && (mAllowedActions & Action::GenerateKey));
+ widgets.generateButton->setVisible(cardSupportsKey && (mAllowedActions & Action::GenerateKey) && !DeVSCompliance::isActive());
if (widgets.createCSRButton) {
widgets.createCSRButton->setVisible(cardSupportsKey && (mAllowedActions & Action::CreateCSR));
}
if (!cardSupportsKey) {
return;
}
widgets.showCertificateDetailsButton->setEnabled(false);
if (widgets.keyFingerprint.empty()) {
widgets.keyInfoLabel->setTextFormat(Qt::RichText);
widgets.keyInfoLabel->setText(i18nc("@info", "<em>No key</em>"));
widgets.generateButton->setText(i18nc("@action:button", "Generate Key"));
widgets.generateButton->setToolTip(i18nc("@info:tooltip", "Generate a key for this card slot"));
if (widgets.createCSRButton) {
widgets.createCSRButton->setEnabled(false);
}
} else {
QStringList lines;
if (widgets.keyFingerprint.size() >= 16) {
const std::string keyid = widgets.keyFingerprint.substr(widgets.keyFingerprint.size() - 16);
const auto subkeys = KeyCache::instance()->findSubkeysByKeyID({keyid});
if (subkeys.empty() || subkeys[0].isNull()) {
widgets.keyInfoLabel->setTextFormat(Qt::RichText);
lines.push_back(i18nc("@info", "<em>Public key not found locally</em>"));
widgets.keyInfoLabel->setToolTip({});
} else {
// force interpretation of text as plain text to avoid problems with HTML in user IDs
widgets.keyInfoLabel->setTextFormat(Qt::PlainText);
QStringList toolTips;
toolTips.reserve(subkeys.size());
for (const auto &sub : subkeys) {
// Yep you can have one subkey associated with multiple primary keys.
const GpgME::Key key = sub.parent();
toolTips << Formatting::toolTip(key, Formatting::Validity | Formatting::ExpiryDates | Formatting::UserIDs | Formatting::Fingerprint);
const auto uids = key.userIDs();
for (const auto &uid : uids) {
lines.push_back(Formatting::prettyUserID(uid));
}
}
widgets.keyInfoLabel->setToolTip(toolTips.join(QLatin1StringView("<br/>")));
widgets.showCertificateDetailsButton->setEnabled(true);
}
} else {
widgets.keyInfoLabel->setTextFormat(Qt::RichText);
lines.push_back(i18nc("@info", "<em>Invalid fingerprint</em>"));
}
const QString fingerprint = widgets.keyInfoLabel->textFormat() == Qt::RichText
? Formatting::prettyID(widgets.keyFingerprint.c_str()).replace(QLatin1Char(' '), QLatin1StringView("&nbsp;"))
: Formatting::prettyID(widgets.keyFingerprint.c_str());
lines.insert(0, fingerprint);
const auto lineSeparator = widgets.keyInfoLabel->textFormat() == Qt::PlainText ? QLatin1StringView("\n") : QLatin1String("<br>");
widgets.keyInfoLabel->setText(lines.join(lineSeparator));
widgets.generateButton->setText(i18nc("@action:button", "Regenerate Key"));
widgets.generateButton->setToolTip(i18nc("@info:tooltip", "Generate a new key for this card slot replacing the existing key"));
if (widgets.createCSRButton) {
widgets.createCSRButton->setEnabled(DeVSCompliance::algorithmIsCompliant(widgets.keyInfo.algorithm));
}
}
widgets.generateButton->setEnabled(!widgets.generateButton->isHidden());
}
void OpenPGPKeyCardWidget::Private::showCertificateDetails(const std::string &openPGPKeyRef)
{
const KeyWidgets &widgets = mKeyWidgets.at(openPGPKeyRef);
if (widgets.keyFingerprint.size() >= 16) {
const std::string keyid = widgets.keyFingerprint.substr(widgets.keyFingerprint.size() - 16);
const auto subkeys = KeyCache::instance()->findSubkeysByKeyID({keyid});
if (!subkeys.empty() && !subkeys[0].isNull()) {
auto cmd = new Commands::DetailsCommand(subkeys[0].parent());
cmd->setParentWidget(q);
cmd->start();
return;
}
}
KMessageBox::error(q, i18nc("@info", "Sorry, I cannot find the key with fingerprint %1.", Formatting::prettyID(widgets.keyFingerprint.c_str())));
}
OpenPGPKeyCardWidget::OpenPGPKeyCardWidget(QWidget *parent)
: QWidget{parent}
, d{std::make_unique<Private>(this)}
{
connect(KeyCache::instance().get(), &KeyCache::keysMayHaveChanged, this, [this]() {
d->update();
});
}
OpenPGPKeyCardWidget::~OpenPGPKeyCardWidget() = default;
void OpenPGPKeyCardWidget::setAllowedActions(Actions actions)
{
d->setAllowedActions(actions);
}
void OpenPGPKeyCardWidget::update(const Card *card)
{
d->update(card);
}
#include "moc_openpgpkeycardwidget.cpp"

File Metadata

Mime Type
text/x-diff
Expires
Mon, Dec 23, 4:46 PM (15 h, 13 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
4f/55/353a251a7a7fd0993ccf3f49adcd

Event Timeline