Page MenuHome GnuPG

No OneTemporary

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

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

Event Timeline