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 SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "changeexpirycommand.h" #include "command_p.h" #include "dialogs/expirydialog.h" #include #include #include #include #include #include #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(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 dialog; QPointer job; }; ChangeExpiryCommand::Private *ChangeExpiryCommand::d_func() { return static_cast(d.get()); } const ChangeExpiryCommand::Private *ChangeExpiryCommand::d_func() const { return static_cast(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 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("

An error occurred while trying to change " "the expiry date for %1:

%2

", 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 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 #include "changeownertrustcommand.h" #include "command_p.h" #include #include #include #include #include #include #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(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 dialog; QPointer job; }; ChangeOwnerTrustCommand::Private *ChangeOwnerTrustCommand::d_func() { return static_cast(d.get()); } const ChangeOwnerTrustCommand::Private *ChangeOwnerTrustCommand::d_func() const { return static_cast(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("

An error occurred while trying to change " "the certification trust for %1:

%2

", 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 SPDX-License-Identifier: GPL-2.0-or-later */ #include #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 #include #include #include #include #include #include #include #include #include #include #include #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(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 dialog; }; CreateCSRForCardKeyCommand::Private *CreateCSRForCardKeyCommand::d_func() { return static_cast(d.get()); } const CreateCSRForCardKeyCommand::Private *CreateCSRForCardKeyCommand::d_func() const { return static_cast(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", "Successfully wrote request to %1." "You should now send the request to the Certification Authority (CA).", 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", "Saving the request failed.%1", 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 SPDX-License-Identifier: GPL-2.0-or-later */ #include #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 #include #include #include #include #include #include #include #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(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 dialog; }; CreateOpenPGPKeyFromCardKeysCommand::Private *CreateOpenPGPKeyFromCardKeysCommand::d_func() { return static_cast(d.get()); } const CreateOpenPGPKeyFromCardKeysCommand::Private *CreateOpenPGPKeyFromCardKeysCommand::d_func() const { return static_cast(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", "

There is already an OpenPGP key corresponding to the signing key on this card:

%1

" "

Do you still want to create an OpenPGP key for the card keys?

", 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 #include "newcertificatecommand.h" #include "command_p.h" #include #include 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(q); } public: explicit Private(NewCertificateCommand *qq, KeyListController *c); ~Private() override; void init(); private: void slotDialogRejected(); void slotDialogAccepted(); private: void ensureDialogCreated(); private: Protocol protocol; QPointer dialog; }; NewCertificateCommand::Private *NewCertificateCommand::d_func() { return static_cast(d.get()); } const NewCertificateCommand::Private *NewCertificateCommand::d_func() const { return static_cast(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 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 #include #include #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(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 dialog; bool hasBeenCanceled = false; }; PIVGenerateCardKeyCommand::Private *PIVGenerateCardKeyCommand::d_func() { return static_cast(d.get()); } const PIVGenerateCardKeyCommand::Private *PIVGenerateCardKeyCommand::d_func() const { return static_cast(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(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", "

This card already contains a key in this slot. Continuing will overwrite that key.

" "

If there is no backup the existing key will be irrecoverably lost.

") + i18n("The existing key has the ID:") + QStringLiteral("
%1
").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(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 SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "revokecertificationcommand.h" #include "command_p.h" #include "exportopenpgpcertstoservercommand.h" #include "dialogs/revokecertificationdialog.h" #include #include #include #include #include #include #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(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 uids; QPointer dialog; QPointer job; }; RevokeCertificationCommand::Private *RevokeCertificationCommand::d_func() { return static_cast(d.get()); } const RevokeCertificationCommand::Private *RevokeCertificationCommand::d_func() const { return static_cast(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 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("

An error occurred while trying to revoke the certification of

" "%1:

\t%2

", 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(1, uid).swap(d->uids); d->init(); } RevokeCertificationCommand::RevokeCertificationCommand(const GpgME::UserID::Signature &signature) : Command(signature.parent().parent(), new Private(this, nullptr)) { std::vector(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 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 #include #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(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 dialog; bool hasBeenCanceled = false; }; SetPIVCardApplicationAdministrationKeyCommand::Private *SetPIVCardApplicationAdministrationKeyCommand::d_func() { return static_cast(d.get()); } const SetPIVCardApplicationAdministrationKeyCommand::Private *SetPIVCardApplicationAdministrationKeyCommand::d_func() const { return static_cast(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(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"