diff --git a/src/commands/certificatetopivcardcommand.cpp b/src/commands/certificatetopivcardcommand.cpp
index 66465263c..c9fb49455 100644
--- a/src/commands/certificatetopivcardcommand.cpp
+++ b/src/commands/certificatetopivcardcommand.cpp
@@ -1,250 +1,257 @@
 /* commands/certificatetopivcardcommand.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 "certificatetopivcardcommand.h"
 
 #include "cardcommand_p.h"
 
 #include "commands/authenticatepivcardapplicationcommand.h"
 
 #include "smartcard/pivcard.h"
 #include "smartcard/readerstatus.h"
 
 #include "utils/writecertassuantransaction.h"
 
 #include <Libkleo/Dn>
 #include <Libkleo/Formatting>
 #include <Libkleo/KeyCache>
 
 #include <KLocalizedString>
 
 #include <qgpgme/dataprovider.h>
 
 #include <gpgme++/context.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 CertificateToPIVCardCommand::Private : public CardCommand::Private
 {
     friend class ::Kleo::Commands::CertificateToPIVCardCommand;
     CertificateToPIVCardCommand *q_func() const
     {
         return static_cast<CertificateToPIVCardCommand *>(q);
     }
 public:
     explicit Private(CertificateToPIVCardCommand *qq, const std::string &slot, const std::string &serialno);
     ~Private();
 
 private:
     void start();
     void startCertificateToPIVCard();
 
     void authenticate();
     void authenticationFinished();
     void authenticationCanceled();
 
 private:
     std::string cardSlot;
     Key certificate;
     bool hasBeenCanceled = false;
 };
 
 CertificateToPIVCardCommand::Private *CertificateToPIVCardCommand::d_func()
 {
     return static_cast<Private *>(d.get());
 }
 const CertificateToPIVCardCommand::Private *CertificateToPIVCardCommand::d_func() const
 {
     return static_cast<const Private *>(d.get());
 }
 
 #define q q_func()
 #define d d_func()
 
 
 CertificateToPIVCardCommand::Private::Private(CertificateToPIVCardCommand *qq, const std::string &slot, const std::string &serialno)
     : CardCommand::Private(qq, serialno, nullptr)
     , cardSlot(slot)
 {
 }
 
 CertificateToPIVCardCommand::Private::~Private()
 {
 }
 
 namespace {
 static Key getCertificateToWriteToPIVCard(const std::string &cardSlot, const std::shared_ptr<PIVCard> &card)
 {
     if (!cardSlot.empty()) {
         const std::string cardKeygrip = card->keyGrip(cardSlot);
         const auto certificate = KeyCache::instance()->findSubkeyByKeyGrip(cardKeygrip).parent();
         if (certificate.isNull() || certificate.protocol() != GpgME::CMS) {
             return Key();
         }
         if ((cardSlot == PIVCard::pivAuthenticationKeyRef() && certificate.canSign()) ||
             (cardSlot == PIVCard::cardAuthenticationKeyRef() && certificate.canSign()) ||
             (cardSlot == PIVCard::digitalSignatureKeyRef() && certificate.canSign()) ||
             (cardSlot == PIVCard::keyManagementKeyRef() && certificate.canEncrypt())) {
             return certificate;
         }
     }
 
     return Key();
 }
 }
 
 void CertificateToPIVCardCommand::Private::start()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::Private::start()";
 
     const auto pivCard = SmartCard::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;
     }
 
     certificate = getCertificateToWriteToPIVCard(cardSlot, pivCard);
     if (certificate.isNull()) {
         error(i18n("Sorry! No suitable certificate to write to this card slot was found."));
         finished();
         return;
     }
 
     const QString certificateInfo = i18nc("X.509 certificate DN (validity, created: date)", "%1 (%2, created: %3)",
                                           DN(certificate.userID(0).id()).prettyDN(),
                                           Formatting::complianceStringShort(certificate),
                                           Formatting::creationDateString(certificate));
     const QString message = i18nc(
         "@info %1 name of card slot, %2 serial number of card",
         "<p>Please confirm that you want to write the following certificate to the %1 slot of card %2:</p>"
         "<center>%3</center>",
         PIVCard::keyDisplayName(cardSlot), QString::fromStdString(serialNumber()), certificateInfo);
     auto confirmButton = KStandardGuiItem::yes();
     confirmButton.setText(i18nc("@action:button", "Write certificate"));
     confirmButton.setToolTip(QString());
     const auto choice = KMessageBox::questionYesNo(
         parentWidgetOrView(), message, i18nc("@title:window", "Write certificate to card"),
         confirmButton, KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::WindowModal);
     if (choice != KMessageBox::Yes) {
         finished();
         return;
     }
 
     startCertificateToPIVCard();
 }
 
 void CertificateToPIVCardCommand::Private::startCertificateToPIVCard()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::Private::startCertificateToPIVCard()";
 
     auto ctx = Context::createForProtocol(GpgME::CMS);
     QGpgME::QByteArrayDataProvider dp;
     Data data(&dp);
     const Error err = ctx->exportPublicKeys(certificate.primaryFingerprint(), data);
     if (err) {
         error(i18nc("@info", "Exporting the certificate failed: %1", QString::fromUtf8(err.asString())),
               i18nc("@title", "Error"));
         finished();
         return;
     }
     const QByteArray certificateData = dp.data();
 
     const auto pivCard = SmartCard::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 command = QByteArrayLiteral("SCD WRITECERT ") + QByteArray::fromStdString(cardSlot);
     auto transaction = std::unique_ptr<AssuanTransaction>(new WriteCertAssuanTransaction(certificateData));
     ReaderStatus::mutableInstance()->startTransaction(pivCard, command, q_func(), "certificateToPIVCardDone", std::move(transaction));
 }
 
 void CertificateToPIVCardCommand::Private::authenticate()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::authenticate()";
 
     auto cmd = new AuthenticatePIVCardApplicationCommand(serialNumber(), parentWidgetOrView());
     connect(cmd, &AuthenticatePIVCardApplicationCommand::finished,
             q, [this]() { authenticationFinished(); });
     connect(cmd, &AuthenticatePIVCardApplicationCommand::canceled,
             q, [this]() { authenticationCanceled(); });
     cmd->start();
 }
 
 void CertificateToPIVCardCommand::Private::authenticationFinished()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::authenticationFinished()";
     if (!hasBeenCanceled) {
         startCertificateToPIVCard();
     }
 }
 
 void CertificateToPIVCardCommand::Private::authenticationCanceled()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::authenticationCanceled()";
     hasBeenCanceled = true;
     canceled();
 }
 
 CertificateToPIVCardCommand::CertificateToPIVCardCommand(const std::string& cardSlot, const std::string &serialno)
     : CardCommand(new Private(this, cardSlot, serialno))
 {
 }
 
 CertificateToPIVCardCommand::~CertificateToPIVCardCommand()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::~CertificateToPIVCardCommand()";
 }
 
 void CertificateToPIVCardCommand::certificateToPIVCardDone(const Error &err)
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::certificateToPIVCardDone():"
                            << err.asString() << "(" << err.code() << ")";
     if (err) {
+#ifdef GPG_ERROR_HAS_NO_AUTH
         // gpgme 1.13 reports "BAD PIN" instead of "NO AUTH"
         if (err.code() == GPG_ERR_NO_AUTH || err.code() == GPG_ERR_BAD_PIN) {
             d->authenticate();
             return;
         }
+#endif
 
         d->error(i18nc("@info", "Writing the certificate to the card failed: %1", QString::fromUtf8(err.asString())),
                  i18nc("@title", "Error"));
     } else if (!err.isCanceled()) {
         KMessageBox::information(d->parentWidgetOrView(),
                                  i18nc("@info", "Writing the certificate to the card succeeded."),
                                  i18nc("@title", "Success"));
         ReaderStatus::mutableInstance()->updateStatus();
     }
 
     d->finished();
 }
 
 void CertificateToPIVCardCommand::doStart()
 {
     qCDebug(KLEOPATRA_LOG) << "CertificateToPIVCardCommand::doStart()";
 
     d->start();
 }
 
 void CertificateToPIVCardCommand::doCancel()
 {
 }
 
 #undef q_func
 #undef d_func
diff --git a/src/commands/keytocardcommand.cpp b/src/commands/keytocardcommand.cpp
index 0ba849ff6..d0cf33da1 100644
--- a/src/commands/keytocardcommand.cpp
+++ b/src/commands/keytocardcommand.cpp
@@ -1,517 +1,524 @@
 /* commands/keytocardcommand.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
     SPDX-FileContributor: Intevation GmbH
     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 "keytocardcommand.h"
 
 #include "cardcommand_p.h"
 
 #include "commands/authenticatepivcardapplicationcommand.h"
 
 #include "dialogs/certificateselectiondialog.h"
 
 #include "smartcard/openpgpcard.h"
 #include "smartcard/pivcard.h"
 #include "smartcard/readerstatus.h"
 #include "smartcard/utils.h"
 
 #include <Libkleo/Dn>
 #include <Libkleo/Formatting>
 #include <Libkleo/KeyCache>
 #include <Libkleo/KeySelectionDialog>
 
 #include <KLocalizedString>
 
 #include <QDateTime>
 #include <QInputDialog>
 #include <QStringList>
 
+#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::Dialogs;
 using namespace Kleo::SmartCard;
 using namespace GpgME;
 
 class KeyToCardCommand::Private : public CardCommand::Private
 {
     friend class ::Kleo::Commands::KeyToCardCommand;
     KeyToCardCommand *q_func() const
     {
         return static_cast<KeyToCardCommand *>(q);
     }
 public:
     explicit Private(KeyToCardCommand *qq, const GpgME::Subkey &subkey);
     explicit Private(KeyToCardCommand *qq, const std::string &slot, const std::string &serialNumber, const std::string &appName);
     ~Private();
 
 private:
     void start();
 
     void startKeyToOpenPGPCard();
 
     Subkey getSubkeyToTransferToPIVCard(const std::string &cardSlot, const std::shared_ptr<PIVCard> &card);
     void startKeyToPIVCard();
 
     void authenticate();
     void authenticationFinished();
     void authenticationCanceled();
 
 private:
     std::string appName;
     GpgME::Subkey subkey;
     std::string cardSlot;
     bool overwriteExistingAlreadyApproved = false;
     bool hasBeenCanceled = false;
 };
 
 KeyToCardCommand::Private *KeyToCardCommand::d_func()
 {
     return static_cast<Private *>(d.get());
 }
 const KeyToCardCommand::Private *KeyToCardCommand::d_func() const
 {
     return static_cast<const Private *>(d.get());
 }
 
 #define q q_func()
 #define d d_func()
 
 
 KeyToCardCommand::Private::Private(KeyToCardCommand *qq, const GpgME::Subkey &subkey_)
     : CardCommand::Private(qq, "", nullptr)
     , subkey(subkey_)
 {
 }
 
 KeyToCardCommand::Private::Private(KeyToCardCommand *qq, const std::string &slot, const std::string &serialNumber, const std::string &appName_)
     : CardCommand::Private(qq, serialNumber, nullptr)
     , appName(appName_)
     , cardSlot(slot)
 {
 }
 
 KeyToCardCommand::Private::~Private()
 {
 }
 
 namespace {
 static std::shared_ptr<Card> getCardToTransferSubkeyTo(const Subkey &subkey, QWidget *parent)
 {
     const std::vector<std::shared_ptr<Card> > suitableCards = KeyToCardCommand::getSuitableCards(subkey);
     if (suitableCards.empty()) {
         return std::shared_ptr<Card>();
     } else if (suitableCards.size() == 1) {
         return suitableCards[0];
     }
 
     QStringList options;
     for (const auto &card: suitableCards) {
         options.push_back(i18nc("smartcard application - serial number of smartcard", "%1 - %2",
             displayAppName(card->appName()), card->displaySerialNumber()));
     }
 
     bool ok;
     const QString choice = QInputDialog::getItem(parent, i18n("Select Card"),
         i18n("Please select the card the key should be written to:"), options, /* current= */ 0, /* editable= */ false, &ok);
     if (!ok) {
         return std::shared_ptr<Card>();
     }
     const int index = options.indexOf(choice);
     return suitableCards[index];
 }
 }
 
 void KeyToCardCommand::Private::start()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::Private::start()";
 
     if (!subkey.isNull() && serialNumber().empty()) {
         const auto card = getCardToTransferSubkeyTo(subkey, parentWidgetOrView());
         if (!card) {
             finished();
             return;
         }
         setSerialNumber(card->serialNumber());
         appName = card->appName();
     }
 
     const auto card = SmartCard::ReaderStatus::instance()->getCard(serialNumber(), appName);
     if (!card) {
         error(i18n("Failed to find the card with the serial number: %1", QString::fromStdString(serialNumber())));
         finished();
         return;
     }
 
     if (card->appName() == SmartCard::OpenPGPCard::AppName) {
         startKeyToOpenPGPCard();
     } else if (card->appName() == SmartCard::PIVCard::AppName) {
         startKeyToPIVCard();
     } else {
         error(i18n("Sorry! Transferring keys to this card is not supported."));
         finished();
         return;
     }
 }
 
 namespace {
 static int getOpenPGPCardSlotForKey(const GpgME::Subkey &subKey, QWidget *parent)
 {
     // Check if we need to ask the user for the slot
     if ((subKey.canSign() || subKey.canCertify()) && !subKey.canEncrypt() && !subKey.canAuthenticate()) {
         // Signing only
         return 1;
     }
     if (subKey.canEncrypt() && !(subKey.canSign() || subKey.canCertify()) && !subKey.canAuthenticate()) {
         // Encrypt only
         return 2;
     }
     if (subKey.canAuthenticate() && !(subKey.canSign() || subKey.canCertify()) && !subKey.canEncrypt()) {
         // Auth only
         return 3;
     }
     // Multiple uses, ask user.
     QStringList options;
 
     if (subKey.canSign() || subKey.canCertify()) {
         options << i18nc("Placeholder is the number of a slot on a smart card", "Signature (%1)", 1);
     }
     if (subKey.canEncrypt()) {
         options << i18nc("Placeholder is the number of a slot on a smart card", "Encryption (%1)", 2);
     }
     if (subKey.canAuthenticate()) {
         options << i18nc("Placeholder is the number of a slot on a smart card", "Authentication (%1)", 3);
     }
 
     bool ok;
     const QString choice = QInputDialog::getItem(parent, i18n("Select Card Slot"),
         i18n("Please select the card slot the key should be written to:"), options, /* current= */ 0, /* editable= */ false, &ok);
     const int slot = options.indexOf(choice) + 1;
     return ok ? slot : -1;
 }
 }
 
 void KeyToCardCommand::Private::startKeyToOpenPGPCard() {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::Private::startKeyToOpenPGPCard()";
 
     const auto pgpCard = SmartCard::ReaderStatus::instance()->getCard<OpenPGPCard>(serialNumber());
     if (!pgpCard) {
         error(i18n("Failed to find the OpenPGP card with the serial number: %1", QString::fromStdString(serialNumber())));
         finished();
         return;
     }
 
     if (subkey.isNull()) {
         finished();
         return;
     }
     if (subkey.parent().protocol() != GpgME::OpenPGP) {
         error(i18n("Sorry! This key cannot be transferred to an OpenPGP card."));
         finished();
         return;
     }
 
     const auto slot = getOpenPGPCardSlotForKey(subkey, parentWidgetOrView());
     if (slot < 1) {
         finished();
         return;
     }
 
     // Check if we need to do the overwrite warning.
     std::string existingKey;
     QString encKeyWarning;
     if (slot == 1) {
         existingKey = pgpCard->sigFpr();
     } else if (slot == 2) {
         existingKey = pgpCard->encFpr();
         encKeyWarning = i18n("It will no longer be possible to decrypt past communication "
                                 "encrypted for the existing key.");
     } else if (slot == 3) {
         existingKey = pgpCard->authFpr();
     }
     if (!existingKey.empty()) {
         const QString message = 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 fingerprint:") +
             QStringLiteral("<pre>%1</pre>").arg(QString::fromStdString(existingKey)) +
             encKeyWarning;
         const auto choice = KMessageBox::warningContinueCancel(parentWidgetOrView(), message,
             i18nc("@title:window", "Overwrite existing key"),
             KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous);
         if (choice != KMessageBox::Continue) {
             finished();
             return;
         }
     }
 
     // Now do the deed
     const auto time = QDateTime::fromSecsSinceEpoch(subkey.creationTime(), Qt::UTC);
     const auto timestamp = time.toString(QStringLiteral("yyyyMMdd'T'HHmmss"));
     const QString cmd = QStringLiteral("KEYTOCARD --force %1 %2 OPENPGP.%3 %4")
         .arg(QString::fromLatin1(subkey.keyGrip()), QString::fromStdString(serialNumber()))
         .arg(slot)
         .arg(timestamp);
     ReaderStatus::mutableInstance()->startSimpleTransaction(pgpCard, cmd.toUtf8(), q_func(), "keyToOpenPGPCardDone");
 }
 
 namespace {
 static std::vector<Key> getSigningCertificates()
 {
     std::vector<Key> signingCertificates = KeyCache::instance()->secretKeys();
     const auto it = std::remove_if(signingCertificates.begin(), signingCertificates.end(),
                                    [](const Key &key) {
                                        return ! (key.protocol() == GpgME::CMS &&
                                                  !key.subkey(0).isNull() &&
                                                  key.subkey(0).canSign() &&
                                                  !key.subkey(0).canEncrypt() &&
                                                  key.subkey(0).isSecret() &&
                                                  !key.subkey(0).isCardKey());
                                    });
     signingCertificates.erase(it, signingCertificates.end());
     return signingCertificates;
 }
 
 static std::vector<Key> getEncryptionCertificates()
 {
     std::vector<Key> encryptionCertificates = KeyCache::instance()->secretKeys();
     const auto it = std::remove_if(encryptionCertificates.begin(), encryptionCertificates.end(),
                                    [](const Key &key) {
                                        return ! (key.protocol() == GpgME::CMS &&
                                                  !key.subkey(0).isNull() &&
                                                  key.subkey(0).canEncrypt() &&
                                                  key.subkey(0).isSecret() &&
                                                  !key.subkey(0).isCardKey());
                                    });
     encryptionCertificates.erase(it, encryptionCertificates.end());
     return encryptionCertificates;
 }
 }
 
 Subkey KeyToCardCommand::Private::getSubkeyToTransferToPIVCard(const std::string &cardSlot, const std::shared_ptr<PIVCard> &/*card*/)
 {
     if (cardSlot != PIVCard::cardAuthenticationKeyRef() && cardSlot != PIVCard::keyManagementKeyRef()) {
         return Subkey();
     }
 
     const std::vector<Key> certificates = cardSlot == PIVCard::cardAuthenticationKeyRef() ? getSigningCertificates() : getEncryptionCertificates();
     if (certificates.empty()) {
         error(i18n("Sorry! No suitable certificate to write to this card slot was found."));
         return Subkey();
     }
 
     auto dialog = new KeySelectionDialog(parentWidgetOrView());
     dialog->setWindowTitle(i18nc("@title:window", "Select Certificate"));
     dialog->setText(i18n("Please select the certificate whose key pair you want to write to the card:"));
     dialog->setKeys(certificates);
 
     if (dialog->exec() == QDialog::Rejected) {
         return Subkey();
     }
 
     return dialog->selectedKey().subkey(0);
 }
 
 void KeyToCardCommand::Private::startKeyToPIVCard()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::Private::startKeyToPIVCard()";
 
     const auto pivCard = SmartCard::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;
     }
 
     if (cardSlot != PIVCard::cardAuthenticationKeyRef() && cardSlot != PIVCard::keyManagementKeyRef()) {
         // key to card is only supported for the Card Authentication key and the Key Management key
         finished();
         return;
     }
 
     if (subkey.isNull()) {
         subkey = getSubkeyToTransferToPIVCard(cardSlot, pivCard);
     }
     if (subkey.isNull()) {
         finished();
         return;
     }
     if (subkey.parent().protocol() != GpgME::CMS) {
         error(i18n("Sorry! This key cannot be transferred to a PIV card."));
         finished();
         return;
     }
     if (!subkey.canEncrypt() && !subkey.canSign()) {
         error(i18n("Sorry! Only encryption keys and signing keys can be transferred to a PIV card."));
         finished();
         return;
     }
 
     // Check if we need to do the overwrite warning.
     if (!overwriteExistingAlreadyApproved) {
         const std::string existingKey = pivCard->keyGrip(cardSlot);
         if (!existingKey.empty() && (existingKey != subkey.keyGrip())) {
             const QString decryptionWarning = (cardSlot == PIVCard::keyManagementKeyRef()) ?
                 i18n("It will no longer be possible to decrypt past communication encrypted for the existing key.") :
                 QString();
             const QString message = 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 key grip:") +
                 QStringLiteral("<pre>%1</pre>").arg(QString::fromStdString(existingKey)) +
                 decryptionWarning;
             const auto choice = KMessageBox::warningContinueCancel(parentWidgetOrView(), message,
                 i18nc("@title:window", "Overwrite existing key"),
                 KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous);
             if (choice != KMessageBox::Continue) {
                 finished();
                 return;
             }
             overwriteExistingAlreadyApproved = true;
         }
     }
 
     const QString cmd = QStringLiteral("KEYTOCARD --force %1 %2 %3")
         .arg(QString::fromLatin1(subkey.keyGrip()), QString::fromStdString(serialNumber()))
         .arg(QString::fromStdString(cardSlot));
     ReaderStatus::mutableInstance()->startSimpleTransaction(pivCard, cmd.toUtf8(), q_func(), "keyToPIVCardDone");
 }
 
 void KeyToCardCommand::Private::authenticate()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::authenticate()";
 
     auto cmd = new AuthenticatePIVCardApplicationCommand(serialNumber(), parentWidgetOrView());
     connect(cmd, &AuthenticatePIVCardApplicationCommand::finished,
             q, [this]() { authenticationFinished(); });
     connect(cmd, &AuthenticatePIVCardApplicationCommand::canceled,
             q, [this]() { authenticationCanceled(); });
     cmd->start();
 }
 
 void KeyToCardCommand::Private::authenticationFinished()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::authenticationFinished()";
     if (!hasBeenCanceled) {
         startKeyToPIVCard();
     }
 }
 
 void KeyToCardCommand::Private::authenticationCanceled()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::authenticationCanceled()";
     hasBeenCanceled = true;
     canceled();
 }
 
 KeyToCardCommand::KeyToCardCommand(const GpgME::Subkey &subkey)
     : CardCommand(new Private(this, subkey))
 {
 }
 
 KeyToCardCommand::KeyToCardCommand(const std::string& cardSlot, const std::string &serialNumber, const std::string &appName)
     : CardCommand(new Private(this, cardSlot, serialNumber, appName))
 {
 }
 
 KeyToCardCommand::~KeyToCardCommand()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::~KeyToCardCommand()";
 }
 
 // static
 std::vector<std::shared_ptr<Card> > KeyToCardCommand::getSuitableCards(const GpgME::Subkey &subkey)
 {
     std::vector<std::shared_ptr<Card> > suitableCards;
     if (subkey.isNull() || subkey.parent().protocol() != GpgME::OpenPGP) {
         return suitableCards;
     }
     for (const auto &card: ReaderStatus::instance()->getCards()) {
         if (card->appName() == OpenPGPCard::AppName) {
             suitableCards.push_back(card);
         }
     }
     return suitableCards;
 }
 
 void KeyToCardCommand::keyToOpenPGPCardDone(const GpgME::Error &err)
 {
     if (err) {
         d->error(i18nc("@info",
                        "Moving the key to the card failed: %1", QString::fromUtf8(err.asString())),
                         i18nc("@title", "Error"));
     } else if (!err.isCanceled()) {
         /* TODO DELETE_KEY is too strong, because it also deletes the stub
          * of the secret key. I could not find out how GnuPG does this. Question
          * to GnuPG Developers is pending an answer
         if (KMessageBox::questionYesNo(d->parentWidgetOrView(),
                                        i18n("Do you want to delete the key on this computer?"),
                                        i18nc("@title:window",
                                        "Key transferred to card")) == KMessageBox::Yes) {
             const QString cmd = QStringLiteral("DELETE_KEY --force %1").arg(d->subkey.keyGrip());
             // Using readerstatus is a bit overkill but it's an easy way to talk to the agent.
             ReaderStatus::mutableInstance()->startSimpleTransaction(card, cmd.toUtf8(), this, "deleteDone");
         }
         */
         d->information(i18nc("@info", "Successfully copied the key to the card."),
                        i18nc("@title", "Success"));
         ReaderStatus::mutableInstance()->updateStatus();
     }
     d->finished();
 }
 
 void KeyToCardCommand::keyToPIVCardDone(const GpgME::Error &err)
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::keyToPIVCardDone():"
                            << err.asString() << "(" << err.code() << ")";
     if (err) {
+#ifdef GPG_ERROR_HAS_NO_AUTH
         // gpgme 1.13 reports "BAD PIN" instead of "NO AUTH"
         if (err.code() == GPG_ERR_NO_AUTH || err.code() == GPG_ERR_BAD_PIN) {
             d->authenticate();
             return;
         }
+#endif
 
         d->error(i18nc("@info",
                        "Copying the key pair to the card failed: %1", QString::fromUtf8(err.asString())),
                         i18nc("@title", "Error"));
     } else if (!err.isCanceled()) {
         d->information(i18nc("@info", "Successfully copied the key pair to the card."),
                        i18nc("@title", "Success"));
         ReaderStatus::mutableInstance()->updateStatus();
     }
 
     d->finished();
 }
 
 void KeyToCardCommand::deleteDone(const GpgME::Error &err)
 {
     if (err) {
         d->error(i18nc("@info", "Failed to delete the key: %1", QString::fromUtf8(err.asString())),
                         i18nc("@title", "Error"));
     }
     d->finished();
 }
 
 void KeyToCardCommand::doStart()
 {
     qCDebug(KLEOPATRA_LOG) << "KeyToCardCommand::doStart()";
 
     d->start();
 }
 
 void KeyToCardCommand::doCancel()
 {
 }
 
 #undef q_func
 #undef d_func
diff --git a/src/commands/pivgeneratecardkeycommand.cpp b/src/commands/pivgeneratecardkeycommand.cpp
index edbbce55d..56f68f4c1 100644
--- a/src/commands/pivgeneratecardkeycommand.cpp
+++ b/src/commands/pivgeneratecardkeycommand.cpp
@@ -1,247 +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();
 
     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->keyGrip(d->keyRef);
     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, SIGNAL(accepted()), q, SLOT(slotDialogAccepted()));
     connect(dialog, SIGNAL(rejected()), q, SLOT(slotDialogRejected()));
 }
 
 #undef d
 #undef q
 
 #include "moc_pivgeneratecardkeycommand.cpp"