Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F26766121
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
57 KB
Subscribers
None
View Options
diff --git a/src/commands/changeexpirycommand.cpp b/src/commands/changeexpirycommand.cpp
index fb0b8a2f9..0fa0c742b 100644
--- a/src/commands/changeexpirycommand.cpp
+++ b/src/commands/changeexpirycommand.cpp
@@ -1,287 +1,287 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/changeexpirycommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "changeexpirycommand.h"
#include "command_p.h"
#include "dialogs/expirydialog.h"
#include <Libkleo/Formatting>
#include <KLocalizedString>
#include <QGpgME/Protocol>
#include <QGpgME/ChangeExpiryJob>
#include <QDateTime>
#include <gpgme++/key.h>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace GpgME;
using namespace QGpgME;
namespace
{
#ifdef QGPGME_SUPPORTS_CHANGING_EXPIRATION_OF_COMPLETE_KEY
bool allNotRevokedSubkeysHaveSameExpirationAsPrimaryKey(const Key &key)
{
Q_ASSERT(!key.isNull() && key.numSubkeys() > 0);
const auto subkeys = key.subkeys();
const auto primaryKey = subkeys[0];
if (primaryKey.neverExpires()) {
return std::all_of(std::begin(subkeys), std::end(subkeys), [] (const auto &subkey) {
// revoked subkeys are ignored by gpg --quick-set-expire when updating the expiration of all subkeys
return subkey.isRevoked() || subkey.neverExpires();
});
}
const auto primaryExpiration = primaryKey.expirationTime();
return std::all_of(std::begin(subkeys), std::end(subkeys), [primaryExpiration] (const auto &subkey) {
// revoked subkeys are ignored by gpg --quick-set-expire when updating the expiration of all subkeys;
// check if expiration of subkey is (more or less) the same as the expiration of the primary key
return subkey.isRevoked() ||
(primaryExpiration - 10 <= subkey.expirationTime() && subkey.expirationTime() <= primaryExpiration + 10);
});
}
#endif
}
class ChangeExpiryCommand::Private : public Command::Private
{
friend class ::Kleo::Commands::ChangeExpiryCommand;
ChangeExpiryCommand *q_func() const
{
return static_cast<ChangeExpiryCommand *>(q);
}
public:
explicit Private(ChangeExpiryCommand *qq, KeyListController *c);
~Private() override;
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const Error &err);
private:
void ensureDialogCreated(ExpiryDialog::Mode mode);
void createJob();
void showErrorDialog(const Error &error);
void showSuccessDialog();
private:
GpgME::Key key;
GpgME::Subkey subkey;
QPointer<ExpiryDialog> dialog;
QPointer<ChangeExpiryJob> job;
};
ChangeExpiryCommand::Private *ChangeExpiryCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const ChangeExpiryCommand::Private *ChangeExpiryCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
ChangeExpiryCommand::Private::Private(ChangeExpiryCommand *qq, KeyListController *c)
: Command::Private{qq, c}
{
}
ChangeExpiryCommand::Private::~Private() = default;
void ChangeExpiryCommand::Private::slotDialogAccepted()
{
Q_ASSERT(dialog);
static const QTime END_OF_DAY{23, 59, 59};
const QDateTime expiry{dialog->dateOfExpiry(), END_OF_DAY};
qCDebug(KLEOPATRA_LOG) << "expiry" << expiry;
createJob();
Q_ASSERT(job);
#ifdef QGPGME_SUPPORTS_CHANGING_EXPIRATION_OF_COMPLETE_KEY
if (subkey.isNull() && dialog->updateExpirationOfAllSubkeys()) {
job->setOptions(ChangeExpiryJob::UpdateAllSubkeys);
}
#endif
std::vector<Subkey> subkeys;
if (!subkey.isNull() && subkey.keyID() != key.keyID()) { // ignore the primary subkey
subkeys.push_back(subkey);
}
if (const Error err = job->start(key, expiry, subkeys)) {
showErrorDialog(err);
finished();
}
}
void ChangeExpiryCommand::Private::slotDialogRejected()
{
Q_EMIT q->canceled();
finished();
}
void ChangeExpiryCommand::Private::slotResult(const Error &err)
{
if (err.isCanceled())
;
else if (err) {
showErrorDialog(err);
} else {
showSuccessDialog();
}
finished();
}
void ChangeExpiryCommand::Private::ensureDialogCreated(ExpiryDialog::Mode mode)
{
if (dialog) {
return;
}
dialog = new ExpiryDialog{mode};
applyWindowID(dialog);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
void ChangeExpiryCommand::Private::createJob()
{
Q_ASSERT(!job);
const auto backend = (key.protocol() == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
if (!backend) {
return;
}
ChangeExpiryJob *const j = backend->changeExpiryJob();
if (!j) {
return;
}
connect(j, &Job::progress,
q, &Command::progress);
connect(j, &ChangeExpiryJob::result,
q, [this] (const auto &err) { slotResult(err); });
job = j;
}
void ChangeExpiryCommand::Private::showErrorDialog(const Error &err)
{
error(i18n("<p>An error occurred while trying to change "
"the expiry date for <b>%1</b>:</p><p>%2</p>",
Formatting::formatForComboBox(key),
QString::fromLocal8Bit(err.asString())),
i18n("Expiry Date Change Error"));
}
void ChangeExpiryCommand::Private::showSuccessDialog()
{
information(i18n("Expiry date changed successfully."),
i18n("Expiry Date Change Succeeded"));
}
ChangeExpiryCommand::ChangeExpiryCommand(KeyListController *c)
: Command{new Private{this, c}}
{
}
ChangeExpiryCommand::ChangeExpiryCommand(QAbstractItemView *v, KeyListController *c)
: Command{v, new Private{this, c}}
{
}
ChangeExpiryCommand::ChangeExpiryCommand(const GpgME::Key &key)
: Command{key, new Private{this, nullptr}}
{
}
ChangeExpiryCommand::~ChangeExpiryCommand() = default;
void ChangeExpiryCommand::setSubkey(const GpgME::Subkey &subkey)
{
d->subkey = subkey;
}
void ChangeExpiryCommand::doStart()
{
const std::vector<Key> keys = d->keys();
if (keys.size() != 1 ||
keys.front().protocol() != GpgME::OpenPGP ||
!keys.front().hasSecret() ||
keys.front().subkey(0).isNull()) {
d->finished();
return;
}
d->key = keys.front();
if (!d->subkey.isNull() &&
d->subkey.parent().primaryFingerprint() != d->key.primaryFingerprint()) {
qDebug() << "Invalid subkey" << d->subkey.fingerprint()
<< ": Not a subkey of key" << d->key.primaryFingerprint();
d->finished();
return;
}
ExpiryDialog::Mode mode;
if (!d->subkey.isNull()) {
mode = ExpiryDialog::Mode::UpdateIndividualSubkey;
} else if (d->key.numSubkeys() == 1) {
mode = ExpiryDialog::Mode::UpdateCertificateWithoutSubkeys;
} else {
mode = ExpiryDialog::Mode::UpdateCertificateWithSubkeys;
}
d->ensureDialogCreated(mode);
Q_ASSERT(d->dialog);
const Subkey subkey = !d->subkey.isNull() ? d->subkey : d->key.subkey(0);
d->dialog->setDateOfExpiry(subkey.neverExpires() ? QDate() :
QDateTime::fromSecsSinceEpoch(subkey.expirationTime()).date());
#ifdef QGPGME_SUPPORTS_CHANGING_EXPIRATION_OF_COMPLETE_KEY
if (mode == ExpiryDialog::Mode::UpdateCertificateWithSubkeys) {
d->dialog->setUpdateExpirationOfAllSubkeys(allNotRevokedSubkeysHaveSameExpirationAsPrimaryKey(d->key));
}
#endif
d->dialog->show();
}
void ChangeExpiryCommand::doCancel()
{
if (d->job) {
d->job->slotCancel();
}
}
#undef d
#undef q
#include "moc_changeexpirycommand.cpp"
diff --git a/src/commands/changeownertrustcommand.cpp b/src/commands/changeownertrustcommand.cpp
index 3ab189725..b84b39085 100644
--- a/src/commands/changeownertrustcommand.cpp
+++ b/src/commands/changeownertrustcommand.cpp
@@ -1,238 +1,238 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/changeownertrustcommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "changeownertrustcommand.h"
#include "command_p.h"
#include <dialogs/ownertrustdialog.h>
#include <Libkleo/Formatting>
#include <QGpgME/Protocol>
#include <QGpgME/ChangeOwnerTrustJob>
#include <gpgme++/key.h>
#include <KLocalizedString>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace GpgME;
using namespace QGpgME;
class ChangeOwnerTrustCommand::Private : public Command::Private
{
friend class ::Kleo::Commands::ChangeOwnerTrustCommand;
ChangeOwnerTrustCommand *q_func() const
{
return static_cast<ChangeOwnerTrustCommand *>(q);
}
public:
explicit Private(ChangeOwnerTrustCommand *qq, KeyListController *c);
~Private() override;
void init();
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const Error &err);
private:
void ensureDialogCreated();
void createJob();
void showErrorDialog(const Error &error);
void showSuccessDialog();
private:
QPointer<OwnerTrustDialog> dialog;
QPointer<ChangeOwnerTrustJob> job;
};
ChangeOwnerTrustCommand::Private *ChangeOwnerTrustCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const ChangeOwnerTrustCommand::Private *ChangeOwnerTrustCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
ChangeOwnerTrustCommand::Private::Private(ChangeOwnerTrustCommand *qq, KeyListController *c)
: Command::Private(qq, c),
dialog(),
job()
{
}
ChangeOwnerTrustCommand::Private::~Private()
{
qCDebug(KLEOPATRA_LOG);
}
ChangeOwnerTrustCommand::ChangeOwnerTrustCommand(KeyListController *c)
: Command(new Private(this, c))
{
d->init();
}
ChangeOwnerTrustCommand::ChangeOwnerTrustCommand(QAbstractItemView *v, KeyListController *c)
: Command(v, new Private(this, c))
{
d->init();
}
ChangeOwnerTrustCommand::ChangeOwnerTrustCommand(const Key &key)
: Command(key, new Private(this, nullptr))
{
d->init();
}
void ChangeOwnerTrustCommand::Private::init()
{
}
ChangeOwnerTrustCommand::~ChangeOwnerTrustCommand()
{
qCDebug(KLEOPATRA_LOG);
}
void ChangeOwnerTrustCommand::doStart()
{
if (d->keys().size() != 1) {
d->finished();
return;
}
const Key key = d->key();
if (key.protocol() != GpgME::OpenPGP || (key.hasSecret() && key.ownerTrust() == Key::Ultimate)) {
d->finished();
return;
}
d->ensureDialogCreated();
Q_ASSERT(d->dialog);
d->dialog->setHasSecretKey(key.hasSecret());
d->dialog->setFormattedCertificateName(Formatting::formatForComboBox(key));
d->dialog->setOwnerTrust(key.ownerTrust());
d->dialog->show();
}
void ChangeOwnerTrustCommand::Private::slotDialogAccepted()
{
Q_ASSERT(dialog);
const Key::OwnerTrust trust = dialog->ownerTrust();
qCDebug(KLEOPATRA_LOG) << "trust " << trust;
createJob();
Q_ASSERT(job);
if (const Error err = job->start(key(), trust)) {
showErrorDialog(err);
finished();
}
}
void ChangeOwnerTrustCommand::Private::slotDialogRejected()
{
Q_EMIT q->canceled();
finished();
}
void ChangeOwnerTrustCommand::Private::slotResult(const Error &err)
{
if (err.isCanceled())
;
else if (err) {
showErrorDialog(err);
} else {
showSuccessDialog();
}
finished();
}
void ChangeOwnerTrustCommand::doCancel()
{
qCDebug(KLEOPATRA_LOG);
if (d->job) {
d->job->slotCancel();
}
}
void ChangeOwnerTrustCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new OwnerTrustDialog;
applyWindowID(dialog);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
void ChangeOwnerTrustCommand::Private::createJob()
{
Q_ASSERT(!job);
const auto backend = (key().protocol() == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
if (!backend) {
return;
}
ChangeOwnerTrustJob *const j = backend->changeOwnerTrustJob();
if (!j) {
return;
}
connect(j, &Job::progress,
q, &Command::progress);
connect(j, &ChangeOwnerTrustJob::result, q, [this](const GpgME::Error &result) { slotResult(result); });
job = j;
}
void ChangeOwnerTrustCommand::Private::showErrorDialog(const Error &err)
{
error(i18n("<p>An error occurred while trying to change "
"the certification trust for <b>%1</b>:</p><p>%2</p>",
Formatting::formatForComboBox(key()),
QString::fromLocal8Bit(err.asString())),
i18n("Certification Trust Change Error"));
}
void ChangeOwnerTrustCommand::Private::showSuccessDialog()
{
information(i18n("Certification trust changed successfully."),
i18n("Certification Trust Change Succeeded"));
}
#undef d
#undef q
#include "moc_changeownertrustcommand.cpp"
diff --git a/src/commands/createcsrforcardkeycommand.cpp b/src/commands/createcsrforcardkeycommand.cpp
index fe38b4718..2d85ec66a 100644
--- a/src/commands/createcsrforcardkeycommand.cpp
+++ b/src/commands/createcsrforcardkeycommand.cpp
@@ -1,297 +1,297 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/createcsrforcardkeycommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "createcsrforcardkeycommand.h"
#include "cardcommand_p.h"
#include "dialogs/createcsrforcardkeydialog.h"
#include "smartcard/netkeycard.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/pivcard.h"
#include "smartcard/readerstatus.h"
#include "utils/filedialog.h"
#include "utils/keyparameters.h"
#include <Libkleo/Formatting>
#include <KLocalizedString>
#include <QDateTime>
#include <QFile>
#include <KLocalizedString>
#include <QUrl>
#include <QGpgME/Protocol>
#include <QGpgME/KeyGenerationJob>
#include <gpgme++/context.h>
#include <gpgme++/engineinfo.h>
#include <gpgme++/keygenerationresult.h>
#include <gpgme.h>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace Kleo::SmartCard;
using namespace GpgME;
using namespace QGpgME;
class CreateCSRForCardKeyCommand::Private : public CardCommand::Private
{
friend class ::Kleo::Commands::CreateCSRForCardKeyCommand;
CreateCSRForCardKeyCommand *q_func() const
{
return static_cast<CreateCSRForCardKeyCommand *>(q);
}
public:
explicit Private(CreateCSRForCardKeyCommand *qq,
const std::string &keyRef, const std::string &serialNumber, const std::string &appName, QWidget *parent);
~Private() override;
private:
void start();
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const KeyGenerationResult &result, const QByteArray &request);
QUrl saveRequest(const QByteArray &request);
void ensureDialogCreated();
private:
std::string appName;
std::string keyRef;
QStringList keyUsages;
QPointer<CreateCSRForCardKeyDialog> dialog;
};
CreateCSRForCardKeyCommand::Private *CreateCSRForCardKeyCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const CreateCSRForCardKeyCommand::Private *CreateCSRForCardKeyCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
CreateCSRForCardKeyCommand::Private::Private(CreateCSRForCardKeyCommand *qq,
const std::string &keyRef_, const std::string &serialNumber, const std::string &appName_, QWidget *parent)
: CardCommand::Private(qq, serialNumber, parent)
, appName(appName_)
, keyRef(keyRef_)
{
}
CreateCSRForCardKeyCommand::Private::~Private()
{
}
namespace
{
QStringList getKeyUsages(const KeyPairInfo &keyInfo)
{
// note: gpgsm does not support creating CSRs for authentication certificates
QStringList usages;
if (keyInfo.canCertify()) {
usages.push_back(QStringLiteral("cert"));
}
if (keyInfo.canSign()) {
usages.push_back(QStringLiteral("sign"));
}
if (keyInfo.canEncrypt()) {
usages.push_back(QStringLiteral("encrypt"));
}
return usages;
}
}
void CreateCSRForCardKeyCommand::Private::start()
{
if (appName != NetKeyCard::AppName && appName != OpenPGPCard::AppName && appName != PIVCard::AppName) {
qCWarning(KLEOPATRA_LOG) << "CreateCSRForCardKeyCommand does not support card application" << QString::fromStdString(appName);
finished();
return;
}
const auto card = ReaderStatus::instance()->getCard(serialNumber(), appName);
if (!card) {
error(i18n("Failed to find the smartcard with the serial number: %1", QString::fromStdString(serialNumber())));
finished();
return;
}
const KeyPairInfo &keyInfo = card->keyInfo(keyRef);
keyUsages = getKeyUsages(keyInfo);
ensureDialogCreated();
dialog->setWindowTitle(i18n("Certificate Details"));
if (!card->cardHolder().isEmpty()) {
dialog->setName(card->cardHolder());
}
dialog->show();
}
void CreateCSRForCardKeyCommand::Private::slotDialogAccepted()
{
const Error err = ReaderStatus::switchCardAndApp(serialNumber(), appName);
if (err) {
finished();
return;
}
const auto backend = smime();
if (!backend) {
finished();
return;
}
KeyGenerationJob *const job = backend->keyGenerationJob();
if (!job) {
finished();
return;
}
Job::context(job)->setArmor(true);
connect(job, &KeyGenerationJob::result, q, [this](const GpgME::KeyGenerationResult &result, const QByteArray &pubKeyData) {
slotResult(result, pubKeyData);
});
KeyParameters keyParameters(KeyParameters::CMS);
keyParameters.setKeyType(QString::fromStdString(keyRef));
keyParameters.setKeyUsages(keyUsages);
keyParameters.setDN(dialog->dn());
keyParameters.setEmail(dialog->email());
if (const Error err = job->start(keyParameters.toString())) {
error(i18nc("@info", "Creating a CSR for the card key failed:\n%1", QString::fromUtf8(err.asString())),
i18nc("@title", "Error"));
finished();
}
}
void CreateCSRForCardKeyCommand::Private::slotDialogRejected()
{
canceled();
}
void CreateCSRForCardKeyCommand::Private::slotResult(const KeyGenerationResult &result, const QByteArray &request)
{
if (result.error().isCanceled()) {
// do nothing
} else if (result.error()) {
error(i18nc("@info", "Creating a CSR for the card key failed:\n%1", QString::fromUtf8(result.error().asString())),
i18nc("@title", "Error"));
} else {
const QUrl url = saveRequest(request);
if (!url.isEmpty()) {
information(xi18nc("@info", "<para>Successfully wrote request to <filename>%1</filename>.</para>"
"<para>You should now send the request to the Certification Authority (CA).</para>",
url.toLocalFile()),
i18nc("@title", "Request Saved"));
}
}
finished();
}
namespace
{
struct SaveToFileResult {
QUrl url;
QString errorMessage;
};
SaveToFileResult saveRequestToFile(const QString &filename, const QByteArray &request, QIODevice::OpenMode mode)
{
QFile file(filename);
if (file.open(mode)) {
const auto bytesWritten = file.write(request);
if (bytesWritten < request.size()) {
return { QUrl(), file.errorString() };
}
return { QUrl::fromLocalFile(file.fileName()), QString() };
}
return { QUrl(), file.errorString() };
}
}
QUrl CreateCSRForCardKeyCommand::Private::saveRequest(const QByteArray &request)
{
const QString proposedFilename = QLatin1String("request_%1.p10").arg(QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd_HHmmss")));
while (true) {
const QString filePath = FileDialog::getSaveFileNameEx(
parentWidgetOrView(), i18nc("@title", "Save Request"), QStringLiteral("save_csr"), proposedFilename, i18n("PKCS#10 Requests (*.p10)"));
if (filePath.isEmpty()) {
// user canceled the dialog
return QUrl();
}
const auto result = saveRequestToFile(filePath, request, QIODevice::NewOnly);
if (result.url.isEmpty()) {
qCDebug(KLEOPATRA_LOG) << "Writing request to file" << filePath << "failed:" << result.errorMessage;
error(xi18nc("@info", "<para>Saving the request failed.</para><para><message>%1</message></para>", result.errorMessage),
i18nc("@title", "Error Saving Request"));
} else {
return result.url;
}
}
}
void CreateCSRForCardKeyCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new CreateCSRForCardKeyDialog;
applyWindowID(dialog);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
CreateCSRForCardKeyCommand::CreateCSRForCardKeyCommand(const std::string &keyRef, const std::string &serialNumber, const std::string &appName, QWidget *parent)
: CardCommand(new Private(this, keyRef, serialNumber, appName, parent))
{
}
CreateCSRForCardKeyCommand::~CreateCSRForCardKeyCommand()
{
}
void CreateCSRForCardKeyCommand::doStart()
{
d->start();
}
void CreateCSRForCardKeyCommand::doCancel()
{
}
#undef d
#undef q
#include "moc_createcsrforcardkeycommand.cpp"
diff --git a/src/commands/createopenpgpkeyfromcardkeyscommand.cpp b/src/commands/createopenpgpkeyfromcardkeyscommand.cpp
index aaf3b24c6..f2d258280 100644
--- a/src/commands/createopenpgpkeyfromcardkeyscommand.cpp
+++ b/src/commands/createopenpgpkeyfromcardkeyscommand.cpp
@@ -1,220 +1,220 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/createopenpgpkeyfromcardkeyscommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "createopenpgpkeyfromcardkeyscommand.h"
#include "cardcommand_p.h"
#include "dialogs/adduseriddialog.h"
#include "smartcard/netkeycard.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/pivcard.h"
#include "smartcard/readerstatus.h"
#include <Libkleo/Formatting>
#include <Libkleo/KeyCache>
#include <KLocalizedString>
#include <QGpgME/Protocol>
#include <QGpgME/QuickJob>
#include <gpgme++/context.h>
#include <gpgme++/engineinfo.h>
#include <gpgme.h>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::SmartCard;
using namespace GpgME;
using namespace QGpgME;
class CreateOpenPGPKeyFromCardKeysCommand::Private : public CardCommand::Private
{
friend class ::Kleo::Commands::CreateOpenPGPKeyFromCardKeysCommand;
CreateOpenPGPKeyFromCardKeysCommand *q_func() const
{
return static_cast<CreateOpenPGPKeyFromCardKeysCommand *>(q);
}
public:
explicit Private(CreateOpenPGPKeyFromCardKeysCommand *qq, const std::string &serialNumber, const std::string &appName, QWidget *parent);
~Private() override;
private:
void start();
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const Error &err);
void ensureDialogCreated();
private:
std::string appName;
QPointer<AddUserIDDialog> dialog;
};
CreateOpenPGPKeyFromCardKeysCommand::Private *CreateOpenPGPKeyFromCardKeysCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const CreateOpenPGPKeyFromCardKeysCommand::Private *CreateOpenPGPKeyFromCardKeysCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
CreateOpenPGPKeyFromCardKeysCommand::Private::Private(CreateOpenPGPKeyFromCardKeysCommand *qq, const std::string &serialNumber, const std::string &appName_, QWidget *parent)
: CardCommand::Private(qq, serialNumber, parent)
, appName(appName_)
{
}
CreateOpenPGPKeyFromCardKeysCommand::Private::~Private()
{
}
void CreateOpenPGPKeyFromCardKeysCommand::Private::start()
{
if (appName != NetKeyCard::AppName && appName != OpenPGPCard::AppName && appName != PIVCard::AppName) {
qCWarning(KLEOPATRA_LOG) << "CreateOpenPGPKeyFromCardKeysCommand does not support card application" << QString::fromStdString(appName);
finished();
return;
}
const auto card = ReaderStatus::instance()->getCard(serialNumber(), appName);
if (!card) {
error(i18n("Failed to find the smartcard with the serial number: %1", QString::fromStdString(serialNumber())));
finished();
return;
}
const auto signingKeyGrip = card->keyInfo(card->signingKeyRef()).grip;
const Key signingKey = KeyCache::instance()->findSubkeyByKeyGrip(signingKeyGrip, OpenPGP).parent();
if (!signingKey.isNull()) {
const QString message = i18nc("@info",
"<p>There is already an OpenPGP key corresponding to the signing key on this card:</p><p>%1</p>"
"<p>Do you still want to create an OpenPGP key for the card keys?</p>",
Formatting::summaryLine(signingKey));
const auto choice = KMessageBox::warningContinueCancel(parentWidgetOrView(), message,
i18nc("@title:window", "Create OpenPGP Key"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QString(), KMessageBox::Notify);
if (choice != KMessageBox::Continue) {
finished();
return;
}
}
ensureDialogCreated();
dialog->setWindowTitle(i18n("Enter User ID"));
dialog->setName(card->cardHolder());
dialog->show();
}
void CreateOpenPGPKeyFromCardKeysCommand::Private::slotDialogAccepted()
{
const Error err = ReaderStatus::switchCardAndApp(serialNumber(), appName);
if (err) {
finished();
return;
}
const auto backend = openpgp();
if (!backend) {
finished();
return;
}
QuickJob *const job = backend->quickJob();
if (!job) {
finished();
return;
}
connect(job, &QGpgME::QuickJob::result, q, [this](const GpgME::Error &error) { slotResult(error); });
const QString userID = Formatting::prettyNameAndEMail(OpenPGP, QString(), dialog->name(), dialog->email());
const QDateTime expires = QDateTime();
const unsigned int flags = GPGME_CREATE_FORCE;
job->startCreate(userID, "card", expires, Key(), flags);
}
void CreateOpenPGPKeyFromCardKeysCommand::Private::slotDialogRejected()
{
canceled();
}
void CreateOpenPGPKeyFromCardKeysCommand::Private::slotResult(const Error &err)
{
if (err.isCanceled()) {
// do nothing
} else if (err) {
error(i18nc("@info", "Creating an OpenPGP key from the card keys failed: %1", QString::fromUtf8(err.asString())),
i18nc("@title", "Error"));
} else {
information(i18nc("@info", "Successfully generated an OpenPGP key from the card keys."),
i18nc("@title", "Success"));
}
finished();
}
void CreateOpenPGPKeyFromCardKeysCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new AddUserIDDialog;
applyWindowID(dialog);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
CreateOpenPGPKeyFromCardKeysCommand::CreateOpenPGPKeyFromCardKeysCommand(const std::string &serialNumber, const std::string &appName, QWidget *parent)
: CardCommand(new Private(this, serialNumber, appName, parent))
{
}
CreateOpenPGPKeyFromCardKeysCommand::~CreateOpenPGPKeyFromCardKeysCommand()
{
}
// static
bool CreateOpenPGPKeyFromCardKeysCommand::isSupported()
{
return !(engineInfo(GpgEngine).engineVersion() < "2.3.0");
}
void CreateOpenPGPKeyFromCardKeysCommand::doStart()
{
d->start();
}
void CreateOpenPGPKeyFromCardKeysCommand::doCancel()
{
}
#undef d
#undef q
#include "moc_createopenpgpkeyfromcardkeyscommand.cpp"
diff --git a/src/commands/newcertificatecommand.cpp b/src/commands/newcertificatecommand.cpp
index 44d5571a4..6a5e15ca1 100644
--- a/src/commands/newcertificatecommand.cpp
+++ b/src/commands/newcertificatecommand.cpp
@@ -1,166 +1,166 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/newcertificatecommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "newcertificatecommand.h"
#include "command_p.h"
#include <settings.h>
#include <newcertificatewizard/newcertificatewizard.h>
using namespace Kleo;
using namespace Kleo::Commands;
using namespace GpgME;
class NewCertificateCommand::Private : public Command::Private
{
friend class ::Kleo::Commands::NewCertificateCommand;
NewCertificateCommand *q_func() const
{
return static_cast<NewCertificateCommand *>(q);
}
public:
explicit Private(NewCertificateCommand *qq, KeyListController *c);
~Private() override;
void init();
private:
void slotDialogRejected();
void slotDialogAccepted();
private:
void ensureDialogCreated();
private:
Protocol protocol;
QPointer<NewCertificateWizard> dialog;
};
NewCertificateCommand::Private *NewCertificateCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const NewCertificateCommand::Private *NewCertificateCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
NewCertificateCommand::Private::Private(NewCertificateCommand *qq, KeyListController *c)
: Command::Private(qq, c),
protocol(UnknownProtocol),
dialog()
{
}
NewCertificateCommand::Private::~Private() {}
NewCertificateCommand::NewCertificateCommand()
: Command(new Private(this, nullptr))
{
d->init();
}
NewCertificateCommand::NewCertificateCommand(KeyListController *c)
: Command(new Private(this, c))
{
d->init();
}
NewCertificateCommand::NewCertificateCommand(QAbstractItemView *v, KeyListController *c)
: Command(v, new Private(this, c))
{
d->init();
}
void NewCertificateCommand::Private::init()
{
}
NewCertificateCommand::~NewCertificateCommand() {}
void NewCertificateCommand::setProtocol(Protocol proto)
{
d->protocol = proto;
if (d->dialog) {
d->dialog->setProtocol(proto);
}
}
Protocol NewCertificateCommand::protocol() const
{
if (d->dialog) {
return d->dialog->protocol();
} else {
return d->protocol;
}
}
void NewCertificateCommand::doStart()
{
d->ensureDialogCreated();
Q_ASSERT(d->dialog);
const Kleo::Settings settings{};
const auto cmsAllowed = settings.cmsEnabled() && settings.cmsCertificateCreationAllowed();
if (d->protocol == UnknownProtocol && !cmsAllowed) {
d->protocol = GpgME::OpenPGP;
}
if (d->protocol != UnknownProtocol) {
d->dialog->setProtocol(d->protocol);
}
d->dialog->show();
}
void NewCertificateCommand::Private::slotDialogRejected()
{
Q_EMIT q->canceled();
finished();
}
void NewCertificateCommand::Private::slotDialogAccepted()
{
finished();
}
void NewCertificateCommand::doCancel()
{
if (d->dialog) {
d->dialog->close();
}
}
void NewCertificateCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new NewCertificateWizard;
applyWindowID(dialog);
dialog->setAttribute(Qt::WA_DeleteOnClose);
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
}
#undef d
#undef q
#include "moc_newcertificatecommand.cpp"
diff --git a/src/commands/pivgeneratecardkeycommand.cpp b/src/commands/pivgeneratecardkeycommand.cpp
index c061ff6ce..8f92d9611 100644
--- a/src/commands/pivgeneratecardkeycommand.cpp
+++ b/src/commands/pivgeneratecardkeycommand.cpp
@@ -1,254 +1,254 @@
/* commands/pivgeneratecardkeycommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "pivgeneratecardkeycommand.h"
#include "cardcommand_p.h"
#include "smartcard/pivcard.h"
#include "smartcard/readerstatus.h"
#include "commands/authenticatepivcardapplicationcommand.h"
#include "dialogs/gencardkeydialog.h"
#include <KLocalizedString>
#include <gpgme++/error.h>
#include <gpg-error.h>
#if GPG_ERROR_VERSION_NUMBER >= 0x12400 // 1.36
# define GPG_ERROR_HAS_NO_AUTH
#endif
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::SmartCard;
using namespace GpgME;
class PIVGenerateCardKeyCommand::Private : public CardCommand::Private
{
friend class ::Kleo::Commands::PIVGenerateCardKeyCommand;
PIVGenerateCardKeyCommand *q_func() const
{
return static_cast<PIVGenerateCardKeyCommand *>(q);
}
public:
explicit Private(PIVGenerateCardKeyCommand *qq, const std::string &serialNumber, QWidget *p);
~Private() override;
void init();
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const Error &err);
private:
void authenticate();
void authenticationFinished();
void authenticationCanceled();
void generateKey();
void ensureDialogCreated();
private:
std::string keyRef;
bool overwriteExistingKey = false;
std::string algorithm;
QPointer<GenCardKeyDialog> dialog;
bool hasBeenCanceled = false;
};
PIVGenerateCardKeyCommand::Private *PIVGenerateCardKeyCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const PIVGenerateCardKeyCommand::Private *PIVGenerateCardKeyCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
PIVGenerateCardKeyCommand::Private::Private(PIVGenerateCardKeyCommand *qq, const std::string &serialNumber, QWidget *p)
: CardCommand::Private(qq, serialNumber, p)
, dialog()
{
}
PIVGenerateCardKeyCommand::Private::~Private()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::Private::~Private()";
}
PIVGenerateCardKeyCommand::PIVGenerateCardKeyCommand(const std::string &serialNumber, QWidget *p)
: CardCommand(new Private(this, serialNumber, p))
{
d->init();
}
void PIVGenerateCardKeyCommand::Private::init()
{
}
PIVGenerateCardKeyCommand::~PIVGenerateCardKeyCommand()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::~PIVGenerateCardKeyCommand()";
}
void PIVGenerateCardKeyCommand::setKeyRef(const std::string &keyRef)
{
d->keyRef = keyRef;
}
void PIVGenerateCardKeyCommand::doStart()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::doStart()";
// check if key exists
auto pivCard = ReaderStatus::instance()->getCard<PIVCard>(d->serialNumber());
if (!pivCard) {
d->error(i18n("Failed to find the PIV card with the serial number: %1", QString::fromStdString(d->serialNumber())));
d->finished();
return;
}
auto existingKey = pivCard->keyInfo(d->keyRef).grip;
if (!existingKey.empty()) {
const QString warningText = i18nc("@info",
"<p>This card already contains a key in this slot. Continuing will <b>overwrite</b> that key.</p>"
"<p>If there is no backup the existing key will be irrecoverably lost.</p>") +
i18n("The existing key has the ID:") + QStringLiteral("<pre>%1</pre>").arg(QString::fromStdString(existingKey)) +
(d->keyRef == PIVCard::keyManagementKeyRef() ?
i18n("It will no longer be possible to decrypt past communication encrypted for the existing key.") :
QString());
const auto choice = KMessageBox::warningContinueCancel(d->parentWidgetOrView(), warningText,
i18nc("@title:window", "Overwrite existing key"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous);
if (choice != KMessageBox::Continue) {
d->finished();
return;
}
d->overwriteExistingKey = true;
}
d->ensureDialogCreated();
Q_ASSERT(d->dialog);
d->dialog->show();
}
void PIVGenerateCardKeyCommand::doCancel()
{
}
void PIVGenerateCardKeyCommand::Private::authenticate()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::authenticate()";
auto cmd = new AuthenticatePIVCardApplicationCommand(serialNumber(), parentWidgetOrView());
connect(cmd, &AuthenticatePIVCardApplicationCommand::finished,
q, [this]() { authenticationFinished(); });
connect(cmd, &AuthenticatePIVCardApplicationCommand::canceled,
q, [this]() { authenticationCanceled(); });
cmd->start();
}
void PIVGenerateCardKeyCommand::Private::authenticationFinished()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::authenticationFinished()";
if (!hasBeenCanceled) {
generateKey();
}
}
void PIVGenerateCardKeyCommand::Private::authenticationCanceled()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::authenticationCanceled()";
hasBeenCanceled = true;
canceled();
}
void PIVGenerateCardKeyCommand::Private::generateKey()
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::generateKey()";
auto pivCard = ReaderStatus::instance()->getCard<PIVCard>(serialNumber());
if (!pivCard) {
error(i18n("Failed to find the PIV card with the serial number: %1", QString::fromStdString(serialNumber())));
finished();
return;
}
QByteArrayList command;
command << "SCD GENKEY";
if (overwriteExistingKey) {
command << "--force";
}
if (!algorithm.empty()) {
command << "--algo=" + QByteArray::fromStdString(algorithm);
}
command << "--" << QByteArray::fromStdString(keyRef);
ReaderStatus::mutableInstance()->startSimpleTransaction(pivCard, command.join(' '), q, "slotResult");
}
void PIVGenerateCardKeyCommand::Private::slotResult(const GpgME::Error& err)
{
qCDebug(KLEOPATRA_LOG) << "PIVGenerateCardKeyCommand::slotResult():"
<< err.asString() << "(" << err.code() << ")";
if (err) {
#ifdef GPG_ERROR_HAS_NO_AUTH
if (err.code() == GPG_ERR_NO_AUTH) {
authenticate();
return;
}
#endif
error(i18nc("@info", "Generating key failed: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
} else if (!err.isCanceled()) {
information(i18nc("@info", "Key successfully generated."), i18nc("@title", "Success"));
ReaderStatus::mutableInstance()->updateStatus();
}
finished();
}
void PIVGenerateCardKeyCommand::Private::slotDialogAccepted()
{
algorithm = dialog->getKeyParams().algorithm;
// assume that we are already authenticated to the card
generateKey();
}
void PIVGenerateCardKeyCommand::Private::slotDialogRejected()
{
finished();
}
void PIVGenerateCardKeyCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new GenCardKeyDialog(GenCardKeyDialog::KeyAlgorithm, parentWidgetOrView());
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setSupportedAlgorithms(PIVCard::supportedAlgorithms(keyRef), "rsa2048");
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
#undef d
#undef q
#include "moc_pivgeneratecardkeycommand.cpp"
diff --git a/src/commands/revokecertificationcommand.cpp b/src/commands/revokecertificationcommand.cpp
index 48b0c9b91..08dd0fd9f 100644
--- a/src/commands/revokecertificationcommand.cpp
+++ b/src/commands/revokecertificationcommand.cpp
@@ -1,252 +1,252 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/revokecertificationcommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "revokecertificationcommand.h"
#include "command_p.h"
#include "exportopenpgpcertstoservercommand.h"
#include "dialogs/revokecertificationdialog.h"
#include <Libkleo/Formatting>
#include <Libkleo/KeyCache>
#include <QGpgME/Protocol>
#include <QGpgME/QuickJob>
#include <gpgme++/engineinfo.h>
#include <KLocalizedString>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace GpgME;
using namespace QGpgME;
class RevokeCertificationCommand::Private : public Command::Private
{
friend class ::Kleo::Commands::RevokeCertificationCommand;
RevokeCertificationCommand *q_func() const
{
return static_cast<RevokeCertificationCommand *>(q);
}
public:
explicit Private(RevokeCertificationCommand *qq, KeyListController *c);
~Private() override;
void init();
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const Error &err);
private:
void ensureDialogCreated();
QGpgME::QuickJob *createJob();
private:
Key certificationKey;
Key certificationTarget;
std::vector<UserID> uids;
QPointer<RevokeCertificationDialog> dialog;
QPointer<QGpgME::QuickJob> job;
};
RevokeCertificationCommand::Private *RevokeCertificationCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const RevokeCertificationCommand::Private *RevokeCertificationCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
RevokeCertificationCommand::Private::Private(RevokeCertificationCommand *qq, KeyListController *c)
: Command::Private(qq, c)
{
}
RevokeCertificationCommand::Private::~Private()
{
}
void RevokeCertificationCommand::Private::init()
{
const std::vector<Key> keys_ = keys();
if (keys_.size() != 1) {
qCWarning(KLEOPATRA_LOG) << "RevokeCertificationCommand::Private::init: Expected exactly one key, but got" << keys_.size();
return;
}
if (keys_.front().protocol() != GpgME::OpenPGP) {
qCWarning(KLEOPATRA_LOG) << "RevokeCertificationCommand::Private::init: Expected OpenPGP key, but got" << keys_.front().protocolAsString();
return;
}
certificationTarget = keys_.front();
}
void RevokeCertificationCommand::Private::slotDialogAccepted()
{
const auto certificationKey = dialog->selectedCertificationKey();
const auto selectedUserIDs = dialog->selectedUserIDs();
if (certificationKey.isNull() || selectedUserIDs.empty()) {
qCDebug(KLEOPATRA_LOG) << "No certification key or no user IDs selected -> skipping revocation";
finished();
return;
}
job = createJob();
if (!job) {
qCDebug(KLEOPATRA_LOG) << "Failed to create QuickJob";
finished();
return;
}
job->startRevokeSignature(certificationTarget, dialog->selectedCertificationKey(), dialog->selectedUserIDs());
}
void RevokeCertificationCommand::Private::slotDialogRejected()
{
canceled();
}
void RevokeCertificationCommand::Private::slotResult(const Error &err)
{
if (err.isCanceled()) {
// do nothing
} else if (err) {
error(i18n("<p>An error occurred while trying to revoke the certification of<br/><br/>"
"<b>%1</b>:</p><p>\t%2</p>",
Formatting::formatForComboBox(certificationTarget),
QString::fromUtf8(err.asString())),
i18n("Revocation Error"));
} else {
information(i18n("Revocation successful."),
i18n("Revocation Succeeded"));
if (dialog && dialog->sendToServer()) {
auto const cmd = new ExportOpenPGPCertsToServerCommand(certificationTarget);
cmd->start();
}
}
finished();
}
void RevokeCertificationCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new RevokeCertificationDialog;
applyWindowID(dialog);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
QGpgME::QuickJob *RevokeCertificationCommand::Private::createJob()
{
Q_ASSERT(!job);
Q_ASSERT(certificationTarget.protocol() == OpenPGP);
const auto backend = QGpgME::openpgp();
if (!backend) {
return nullptr;
}
QuickJob *const j = backend->quickJob();
if (j) {
connect(j, &Job::progress,
q, &Command::progress);
connect(j, &QGpgME::QuickJob::result, q, [this](const GpgME::Error &error) { slotResult(error); });
}
return j;
}
RevokeCertificationCommand::RevokeCertificationCommand(QAbstractItemView *v, KeyListController *c)
: Command(v, new Private(this, c))
{
d->init();
}
RevokeCertificationCommand::RevokeCertificationCommand(const GpgME::UserID &uid)
: Command(uid.parent(), new Private(this, nullptr))
{
std::vector<UserID>(1, uid).swap(d->uids);
d->init();
}
RevokeCertificationCommand::RevokeCertificationCommand(const GpgME::UserID::Signature &signature)
: Command(signature.parent().parent(), new Private(this, nullptr))
{
std::vector<UserID>(1, signature.parent()).swap(d->uids);
d->certificationKey = KeyCache::instance()->findByKeyIDOrFingerprint(signature.signerKeyID());
d->init();
}
RevokeCertificationCommand::~RevokeCertificationCommand()
{
qCDebug(KLEOPATRA_LOG) << "~RevokeCertificationCommand()";
}
// static
bool RevokeCertificationCommand::isSupported()
{
return engineInfo(GpgEngine).engineVersion() >= "2.2.24";
}
void RevokeCertificationCommand::doStart()
{
if (d->certificationTarget.isNull()) {
d->finished();
return;
}
for (const UserID &uid : std::as_const(d->uids))
if (qstricmp(uid.parent().primaryFingerprint(), d->certificationTarget.primaryFingerprint()) != 0) {
qCWarning(KLEOPATRA_LOG) << "User ID <-> Key mismatch!";
d->finished();
return;
}
d->ensureDialogCreated();
Q_ASSERT(d->dialog);
d->dialog->setCertificateToRevoke(d->certificationTarget);
if (!d->uids.empty()) {
d->dialog->setSelectedUserIDs(d->uids);
}
if (!d->certificationKey.isNull()) {
d->dialog->setSelectedCertificationKey(d->certificationKey);
}
d->dialog->show();
}
void RevokeCertificationCommand::doCancel()
{
qCDebug(KLEOPATRA_LOG) << "RevokeCertificationCommand::doCancel()";
if (d->job) {
d->job->slotCancel();
}
}
#undef d
#undef q
#include "moc_revokecertificationcommand.cpp"
diff --git a/src/commands/setpivcardapplicationadministrationkeycommand.cpp b/src/commands/setpivcardapplicationadministrationkeycommand.cpp
index f3cbb8cb4..1f6bd955f 100644
--- a/src/commands/setpivcardapplicationadministrationkeycommand.cpp
+++ b/src/commands/setpivcardapplicationadministrationkeycommand.cpp
@@ -1,220 +1,220 @@
/* commands/setpivcardapplicationadministrationkeycommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "setpivcardapplicationadministrationkeycommand.h"
#include "cardcommand_p.h"
#include "smartcard/pivcard.h"
#include "smartcard/readerstatus.h"
#include "commands/authenticatepivcardapplicationcommand.h"
#include "dialogs/pivcardapplicationadministrationkeyinputdialog.h"
#include <KLocalizedString>
#include <gpgme++/error.h>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Commands;
using namespace Kleo::Dialogs;
using namespace Kleo::SmartCard;
using namespace GpgME;
class SetPIVCardApplicationAdministrationKeyCommand::Private : public CardCommand::Private
{
friend class ::Kleo::Commands::SetPIVCardApplicationAdministrationKeyCommand;
SetPIVCardApplicationAdministrationKeyCommand *q_func() const
{
return static_cast<SetPIVCardApplicationAdministrationKeyCommand *>(q);
}
public:
explicit Private(SetPIVCardApplicationAdministrationKeyCommand *qq, const std::string &serialNumber, QWidget *p);
~Private() override;
void init();
private:
void slotDialogAccepted();
void slotDialogRejected();
void slotResult(const Error &err);
private:
void authenticate();
void authenticationFinished();
void authenticationCanceled();
void setAdminKey();
void ensureDialogCreated();
private:
QByteArray newAdminKey;
QPointer<PIVCardApplicationAdministrationKeyInputDialog> dialog;
bool hasBeenCanceled = false;
};
SetPIVCardApplicationAdministrationKeyCommand::Private *SetPIVCardApplicationAdministrationKeyCommand::d_func()
{
return static_cast<Private *>(d.get());
}
const SetPIVCardApplicationAdministrationKeyCommand::Private *SetPIVCardApplicationAdministrationKeyCommand::d_func() const
{
return static_cast<const Private *>(d.get());
}
#define d d_func()
#define q q_func()
SetPIVCardApplicationAdministrationKeyCommand::Private::Private(SetPIVCardApplicationAdministrationKeyCommand *qq, const std::string &serialNumber, QWidget *p)
: CardCommand::Private(qq, serialNumber, p)
, dialog()
{
}
SetPIVCardApplicationAdministrationKeyCommand::Private::~Private()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::Private::~Private()";
}
SetPIVCardApplicationAdministrationKeyCommand::SetPIVCardApplicationAdministrationKeyCommand(const std::string &serialNumber, QWidget *p)
: CardCommand(new Private(this, serialNumber, p))
{
d->init();
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::init()
{
}
SetPIVCardApplicationAdministrationKeyCommand::~SetPIVCardApplicationAdministrationKeyCommand()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::~SetPIVCardApplicationAdministrationKeyCommand()";
}
void SetPIVCardApplicationAdministrationKeyCommand::doStart()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::doStart()";
d->authenticate();
}
void SetPIVCardApplicationAdministrationKeyCommand::doCancel()
{
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::authenticate()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::authenticate()";
auto cmd = new AuthenticatePIVCardApplicationCommand(serialNumber(), parentWidgetOrView());
cmd->setPrompt(i18n("Please enter the old PIV Card Application Administration Key in hex-encoded form."));
connect(cmd, &AuthenticatePIVCardApplicationCommand::finished,
q, [this]() { authenticationFinished(); });
connect(cmd, &AuthenticatePIVCardApplicationCommand::canceled,
q, [this]() { authenticationCanceled(); });
cmd->start();
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::authenticationFinished()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::authenticationFinished()";
if (!hasBeenCanceled) {
setAdminKey();
}
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::authenticationCanceled()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::authenticationCanceled()";
hasBeenCanceled = true;
canceled();
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::setAdminKey()
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::setAdminKey()";
ensureDialogCreated();
Q_ASSERT(dialog);
dialog->show();
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::ensureDialogCreated()
{
if (dialog) {
return;
}
dialog = new PIVCardApplicationAdministrationKeyInputDialog(parentWidgetOrView());
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setLabelText(newAdminKey.isEmpty() ?
i18n("Please enter the new PIV Card Application Administration Key in hex-encoded form. "
"The key needs to consist of 24 bytes, i.e. 48 hex-characters.") :
i18n("Please enter the new PIV Card Application Administration Key again."));
connect(dialog, &QDialog::accepted, q, [this]() { slotDialogAccepted(); });
- connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
+ connect(dialog, &QDialog::rejected, q, [this]() { slotDialogRejected(); });
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::slotDialogAccepted()
{
if (newAdminKey.isEmpty()) {
newAdminKey = dialog->adminKey();
dialog = nullptr;
setAdminKey();
return;
}
const QByteArray newAdminKey2 = dialog->adminKey();
if (newAdminKey != newAdminKey2) {
error(i18nc("@info", "The two keys you have entered do not match. Please retry."),
i18nc("@title", "Error"));
newAdminKey.clear();
dialog = nullptr;
setAdminKey();
return;
}
auto pivCard = ReaderStatus::instance()->getCard<PIVCard>(serialNumber());
if (!pivCard) {
error(i18n("Failed to find the PIV card with the serial number: %1", QString::fromStdString(serialNumber())));
finished();
return;
}
const QByteArray plusPercentEncodedAdminKey = newAdminKey.toPercentEncoding().replace(' ', '+');
const QByteArray command = QByteArray("SCD SETATTR SET-ADM-KEY ") + plusPercentEncodedAdminKey;
ReaderStatus::mutableInstance()->startSimpleTransaction(pivCard, command, q, "slotResult");
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::slotDialogRejected()
{
finished();
}
void SetPIVCardApplicationAdministrationKeyCommand::Private::slotResult(const GpgME::Error& err)
{
qCDebug(KLEOPATRA_LOG) << "SetPIVCardApplicationAdministrationKeyCommand::slotResult():"
<< err.asString() << "(" << err.code() << ")";
if (err) {
error(i18nc("@info", "Setting the PIV Card Application Administration Key failed: %1", QString::fromLatin1(err.asString())),
i18nc("@title", "Error"));
} else if (!err.isCanceled()) {
information(i18nc("@info", "PIV Card Application Administration Key set successfully."), i18nc("@title", "Success"));
ReaderStatus::mutableInstance()->updateStatus();
}
finished();
}
#undef d
#undef q
#include "moc_setpivcardapplicationadministrationkeycommand.cpp"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Aug 6, 10:12 PM (15 h, 19 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
50/4c/1cd7179f4670a9841ba5c40a4ef9
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment