diff --git a/autotests/keyresolvercoretest.cpp b/autotests/keyresolvercoretest.cpp
index b63f397a..67c53037 100644
--- a/autotests/keyresolvercoretest.cpp
+++ b/autotests/keyresolvercoretest.cpp
@@ -1,321 +1,348 @@
 /*
     autotests/keyresolvercoretest.cpp
 
     This file is part of libkleopatra's test suite.
     SPDX-FileCopyrightText: 2021 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include <Libkleo/KeyCache>
 #include <Libkleo/KeyResolverCore>
 
 #include <QObject>
 #include <QTest>
 
 #include <gpgme++/key.h>
 
 #include <memory>
 
 using namespace Kleo;
 using namespace GpgME;
 
 namespace QTest
 {
 template <>
 inline bool qCompare(GpgME::UserID::Validity const &t1, GpgME::UserID::Validity const &t2, const char *actual, const char *expected,
                     const char *file, int line)
 {
     return qCompare(int(t1), int(t2), actual, expected, file, line);
 }
 }
 
 class KeyResolverCoreTest: public QObject
 {
     Q_OBJECT
 private Q_SLOTS:
     void init()
     {
         mGnupgHome = QTest::qExtractTestData("/fixtures/keyresolvercoretest");
         qputenv("GNUPGHOME", mGnupgHome->path().toLocal8Bit());
 
         // hold a reference to the key cache to avoid rebuilding while the test is running
         mKeyCache = KeyCache::instance();
     }
 
     void cleanup()
     {
         // verify that nobody else holds a reference to the key cache
         QVERIFY(mKeyCache.use_count() == 1);
         mKeyCache.reset();
 
         mGnupgHome.reset();
     }
 
     void test_verify_test_keys()
     {
         {
             const Key openpgp = testKey("sender-mixed@example.net", OpenPGP);
             QVERIFY(openpgp.hasSecret() && openpgp.canEncrypt() && openpgp.canSign());
             QCOMPARE(openpgp.userID(0).validity(), UserID::Ultimate);
             const Key smime = testKey("sender-mixed@example.net", CMS);
             QVERIFY(smime.hasSecret() && smime.canEncrypt() && smime.canSign());
             QCOMPARE(smime.userID(0).validity(), UserID::Full);
         }
         {
             const Key openpgp = testKey("sender-openpgp@example.net", OpenPGP);
             QVERIFY(openpgp.hasSecret() && openpgp.canEncrypt() && openpgp.canSign());
             QCOMPARE(openpgp.userID(0).validity(), UserID::Ultimate);
         }
         {
             const Key smime = testKey("sender-smime@example.net", CMS);
             QVERIFY(smime.hasSecret() && smime.canEncrypt() && smime.canSign());
             QCOMPARE(smime.userID(0).validity(), UserID::Full);
         }
         {
             const Key openpgp = testKey("prefer-openpgp@example.net", OpenPGP);
             QVERIFY(openpgp.canEncrypt());
             QCOMPARE(openpgp.userID(0).validity(), UserID::Ultimate);
             const Key smime = testKey("prefer-openpgp@example.net", CMS);
             QVERIFY(smime.canEncrypt());
             QCOMPARE(smime.userID(0).validity(), UserID::Full);
         }
         {
             const Key openpgp = testKey("full-validity@example.net", OpenPGP);
             QVERIFY(openpgp.canEncrypt());
             QCOMPARE(openpgp.userID(0).validity(), UserID::Full);
             const Key smime = testKey("full-validity@example.net", CMS);
             QVERIFY(smime.canEncrypt());
             QCOMPARE(smime.userID(0).validity(), UserID::Full);
         }
         {
             const Key openpgp = testKey("prefer-smime@example.net", OpenPGP);
             QVERIFY(openpgp.canEncrypt());
             QCOMPARE(openpgp.userID(0).validity(), UserID::Marginal);
             const Key smime = testKey("prefer-smime@example.net", CMS);
             QVERIFY(smime.canEncrypt());
             QCOMPARE(smime.userID(0).validity(), UserID::Full);
         }
     }
 
     void test_openpgp_is_used_if_openpgp_only_and_smime_only_are_both_possible()
     {
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.signingKeys().value(OpenPGP).size(), 1);
         QCOMPARE(resolver.signingKeys().value(OpenPGP)[0].primaryFingerprint(),
                  testKey("sender-mixed@example.net", OpenPGP).primaryFingerprint());
         QCOMPARE(resolver.signingKeys().value(CMS).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("sender-mixed@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("sender-mixed@example.net")[0].primaryFingerprint(),
                  testKey("sender-mixed@example.net", OpenPGP).primaryFingerprint());
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 0);
     }
 
     void test_openpgp_is_used_if_openpgp_only_and_smime_only_are_both_possible_with_preference_for_openpgp()
     {
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true);
         resolver.setPreferredProtocol(OpenPGP);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.signingKeys().value(OpenPGP).size(), 1);
         QCOMPARE(resolver.signingKeys().value(OpenPGP)[0].primaryFingerprint(),
                  testKey("sender-mixed@example.net", OpenPGP).primaryFingerprint());
         QCOMPARE(resolver.signingKeys().value(CMS).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("sender-mixed@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("sender-mixed@example.net")[0].primaryFingerprint(),
                  testKey("sender-mixed@example.net", OpenPGP).primaryFingerprint());
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 0);
     }
 
     void test_smime_is_used_if_openpgp_only_and_smime_only_are_both_possible_with_preference_for_smime()
     {
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true);
         resolver.setPreferredProtocol(CMS);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.signingKeys().value(OpenPGP).size(), 0);
         QCOMPARE(resolver.signingKeys().value(CMS).size(), 1);
         QCOMPARE(resolver.signingKeys().value(CMS)[0].primaryFingerprint(),
                  testKey("sender-mixed@example.net", CMS).primaryFingerprint());
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("sender-mixed@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("sender-mixed@example.net")[0].primaryFingerprint(),
                  testKey("sender-mixed@example.net", CMS).primaryFingerprint());
     }
 
     void test_in_mixed_mode_keys_with_higher_validity_are_preferred()
     {
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ false);
         resolver.setRecipients({"sender-openpgp@example.net", "sender-smime@example.net", "prefer-openpgp@example.net", "prefer-smime@example.net"});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).size(), 4);
         QVERIFY(resolver.encryptionKeys().value(UnknownProtocol).contains("sender-openpgp@example.net"));
         QVERIFY(resolver.encryptionKeys().value(UnknownProtocol).contains("sender-smime@example.net"));
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("prefer-openpgp@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("prefer-openpgp@example.net")[0].primaryFingerprint(),
                  testKey("prefer-openpgp@example.net", OpenPGP).primaryFingerprint());
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("prefer-smime@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("prefer-smime@example.net")[0].primaryFingerprint(),
                  testKey("prefer-smime@example.net", CMS).primaryFingerprint());
     }
 
     void test_encryption_keys_result_has_no_entry_for_unresolved_recipients()
     {
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ false);
         resolver.setRecipients({"prefer-smime@example.net", "unknown@example.net"});
 
         const bool success = resolver.resolve();
 
         QVERIFY(!success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 1);
         QVERIFY(resolver.encryptionKeys().value(OpenPGP).contains("prefer-smime@example.net"));
         QVERIFY(!resolver.encryptionKeys().value(OpenPGP).contains("unknown@example.net"));
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 1);
         QVERIFY(resolver.encryptionKeys().value(CMS).contains("prefer-smime@example.net"));
         QVERIFY(!resolver.encryptionKeys().value(CMS).contains("unknown@example.net"));
     }
 
     void test_openpgp_overrides_are_used_if_both_protocols_are_allowed()
     {
         const QString override = testKey("prefer-openpgp@example.net", OpenPGP).primaryFingerprint();
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
         resolver.setRecipients({"full-validity@example.net"});
         resolver.setOverrideKeys({{OpenPGP, {{QStringLiteral("Needs to be normalized <full-validity@example.net>"), {override}}}}});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("full-validity@example.net")[0].primaryFingerprint(), override);
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("full-validity@example.net")[0].primaryFingerprint(), override);
     }
 
     void test_openpgp_overrides_are_used_if_openpgp_only_is_requested()
     {
         const QString override = testKey("prefer-openpgp@example.net", OpenPGP).primaryFingerprint();
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true, OpenPGP);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
         resolver.setRecipients({"full-validity@example.net"});
         resolver.setOverrideKeys({{OpenPGP, {{QStringLiteral("Needs to be normalized <full-validity@example.net>"), {override}}}}});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("full-validity@example.net")[0].primaryFingerprint(), override);
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).size(), 0);
     }
 
     void test_openpgp_overrides_are_ignored_if_smime_only_is_requested()
     {
         const QString override = testKey("prefer-openpgp@example.net", OpenPGP).primaryFingerprint();
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true, CMS);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
         resolver.setRecipients({"full-validity@example.net"});
         resolver.setOverrideKeys({{OpenPGP, {{QStringLiteral("Needs to be normalized <full-validity@example.net>"), {override}}}}});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("full-validity@example.net")[0].primaryFingerprint(),
                  testKey("full-validity@example.net", CMS).primaryFingerprint());
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).size(), 0);
     }
 
     void test_smime_overrides_are_used_if_both_protocols_are_allowed()
     {
         const QString override = testKey("prefer-smime@example.net", CMS).primaryFingerprint();
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true);
         resolver.setPreferredProtocol(CMS);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
         resolver.setRecipients({"full-validity@example.net"});
         resolver.setOverrideKeys({{CMS, {{QStringLiteral("Needs to be normalized <full-validity@example.net>"), {override}}}}});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("full-validity@example.net")[0].primaryFingerprint(), override);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("full-validity@example.net")[0].primaryFingerprint(), override);
     }
 
     void test_smime_overrides_are_used_if_smime_only_is_requested()
     {
         const QString override = testKey("prefer-smime@example.net", CMS).primaryFingerprint();
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true, CMS);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
         resolver.setRecipients({"full-validity@example.net"});
         resolver.setOverrideKeys({{CMS, {{QStringLiteral("Needs to be normalized <full-validity@example.net>"), {override}}}}});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(CMS).value("full-validity@example.net")[0].primaryFingerprint(), override);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).size(), 0);
     }
 
     void test_smime_overrides_are_ignored_if_openpgp_only_is_requested()
     {
         const QString override = testKey("prefer-smime@example.net", CMS).primaryFingerprint();
         KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true, OpenPGP);
         resolver.setSender(QStringLiteral("sender-mixed@example.net"));
         resolver.setRecipients({"full-validity@example.net"});
         resolver.setOverrideKeys({{CMS, {{QStringLiteral("Needs to be normalized <full-validity@example.net>"), {override}}}}});
 
         const bool success = resolver.resolve();
 
         QVERIFY(success);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("full-validity@example.net").size(), 1);
         QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("full-validity@example.net")[0].primaryFingerprint(),
                  testKey("full-validity@example.net", OpenPGP).primaryFingerprint());
         QCOMPARE(resolver.encryptionKeys().value(CMS).size(), 0);
         QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).size(), 0);
     }
 
+    void test_overrides_for_wrong_protocol_are_ignored()
+    {
+        const QString override1 = testKey("full-validity@example.net", CMS).primaryFingerprint();
+        const QString override2 = testKey("full-validity@example.net", OpenPGP).primaryFingerprint();
+        KeyResolverCore resolver(/*encrypt=*/ true, /*sign=*/ true);
+        resolver.setSender(QStringLiteral("sender-mixed@example.net"));
+        resolver.setRecipients({"sender-openpgp@example.net", "sender-smime@example.net"});
+        resolver.setOverrideKeys({{OpenPGP, {{QStringLiteral("Needs to be normalized <sender-openpgp@example.net>"), {override1}}}}});
+        resolver.setOverrideKeys({{CMS, {{QStringLiteral("Needs to be normalized <sender-smime@example.net>"), {override2}}}}});
+
+        const bool success = resolver.resolve();
+
+        QVERIFY(success);
+        QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("sender-openpgp@example.net").size(), 1);
+        QCOMPARE(resolver.encryptionKeys().value(OpenPGP).value("sender-openpgp@example.net")[0].primaryFingerprint(),
+                 testKey("sender-openpgp@example.net", OpenPGP).primaryFingerprint());
+        QCOMPARE(resolver.encryptionKeys().value(CMS).value("sender-smime@example.net").size(), 1);
+        QCOMPARE(resolver.encryptionKeys().value(CMS).value("sender-smime@example.net")[0].primaryFingerprint(),
+                 testKey("sender-smime@example.net", CMS).primaryFingerprint());
+        QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("sender-openpgp@example.net").size(), 1);
+        QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("sender-openpgp@example.net")[0].primaryFingerprint(),
+                 testKey("sender-openpgp@example.net", OpenPGP).primaryFingerprint());
+        QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("sender-smime@example.net").size(), 1);
+        QCOMPARE(resolver.encryptionKeys().value(UnknownProtocol).value("sender-smime@example.net")[0].primaryFingerprint(),
+                 testKey("sender-smime@example.net", CMS).primaryFingerprint());
+    }
+
 private:
     Key testKey(const char *email, Protocol protocol = UnknownProtocol)
     {
         const std::vector<Key> keys = KeyCache::instance()->findByEMailAddress(email);
         for (const auto &key: keys) {
             if (protocol == UnknownProtocol || key.protocol() == protocol) {
                 return key;
             }
         }
         return Key();
     }
 
 private:
     QSharedPointer<QTemporaryDir> mGnupgHome;
     std::shared_ptr<const KeyCache> mKeyCache;
 };
 
 QTEST_MAIN(KeyResolverCoreTest)
 #include "keyresolvercoretest.moc"
diff --git a/src/kleo/keyresolvercore.cpp b/src/kleo/keyresolvercore.cpp
index 2a452f30..10f36bcf 100644
--- a/src/kleo/keyresolvercore.cpp
+++ b/src/kleo/keyresolvercore.cpp
@@ -1,568 +1,573 @@
 /*  -*- c++ -*-
     kleo/keyresolvercore.cpp
 
     This file is part of libkleopatra, the KDE keymanagement library
     SPDX-FileCopyrightText: 2004 Klarälvdalens Datakonsult AB
     SPDX-FileCopyrightText: 2018 Intevation GmbH
     SPDX-FileCopyrightText: 2021 g10 Code GmbH
     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
 
     Based on kpgp.cpp
     SPDX-FileCopyrightText: 2001, 2002 the KPGP authors
     See file libkdenetwork/AUTHORS.kpgp for details
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include "keyresolvercore.h"
 
 #include "models/keycache.h"
 #include "utils/formatting.h"
 
 #include <gpgme++/key.h>
 
 #include "libkleo_debug.h"
 
 using namespace Kleo;
 using namespace GpgME;
 
 namespace {
 
 static inline bool ValidEncryptionKey(const Key &key)
 {
     if (key.isNull() || key.isRevoked() || key.isExpired() ||
         key.isDisabled() || !key.canEncrypt()) {
         return false;
     }
     return true;
 }
 
 static inline bool ValidSigningKey(const Key &key)
 {
     if (key.isNull() || key.isRevoked() || key.isExpired() ||
         key.isDisabled() || !key.canSign() || !key.hasSecret()) {
         return false;
     }
     return true;
 }
 
 static int keyValidity(const Key &key, const QString &address)
 {
     // returns the validity of the UID matching the address or, if no UID matches, the maximal validity of all UIDs
     int overallValidity = UserID::Validity::Unknown;
     for (const auto &uid: key.userIDs()) {
         if (QString::fromStdString(uid.addrSpec()).toLower() == address.toLower()) {
             return uid.validity();
         }
         overallValidity = std::max(overallValidity, static_cast<int>(uid.validity()));
     }
     return overallValidity;
 }
 
 static int minimumValidity(const std::vector<Key> &keys, const QString &address)
 {
     const int minValidity = std::accumulate(keys.cbegin(), keys.cend(), UserID::Ultimate + 1,
                                             [address] (int validity, const Key &key) {
                                                 return std::min<int>(validity, keyValidity(key, address));
                                             });
     return minValidity <= UserID::Ultimate ? static_cast<UserID::Validity>(minValidity) : UserID::Unknown;
 }
 
 } // namespace
 
 class KeyResolverCore::Private
 {
 public:
     Private(KeyResolverCore* qq, bool enc, bool sig, Protocol fmt)
         : q(qq)
         , mFormat(fmt)
         , mEncrypt(enc)
         , mSign(sig)
         , mCache(KeyCache::instance())
         , mPreferredProtocol(UnknownProtocol)
         , mMinimumValidity(UserID::Marginal)
         , mCompliance(Formatting::complianceMode())
     {
     }
 
     ~Private() = default;
 
     bool isAcceptableSigningKey(const Key &key);
     bool isAcceptableEncryptionKey(const Key &key, const QString &address = QString());
     void setSender(const QString &address);
     void addRecipients(const QStringList &addresses);
     void setOverrideKeys(const QMap<Protocol, QMap<QString, QStringList>> &overrides);
     void resolveOverrides();
     void resolveSign(Protocol proto);
     void setSigningKeys(const QStringList &fingerprints);
     std::vector<Key> resolveRecipient(const QString &address, Protocol protocol);
     void resolveEnc(Protocol proto);
     void mergeEncryptionKeys();
     QStringList unresolvedRecipients(GpgME::Protocol protocol) const;
     bool resolve();
 
     KeyResolverCore *const q;
     QString mSender;
     QStringList mRecipients;
     QMap<Protocol, std::vector<Key>> mSigKeys;
     QMap<QString, QMap<Protocol, std::vector<Key>>> mEncKeys;
     QMap<QString, QMap<Protocol, QStringList>> mOverrides;
 
     Protocol mFormat;
     QStringList mFatalErrors;
     bool mEncrypt;
     bool mSign;
     // The cache is needed as a member variable to avoid rebuilding
     // it between calls if we are the only user.
     std::shared_ptr<const KeyCache> mCache;
     bool mAllowMixed = true;
     Protocol mPreferredProtocol;
     int mMinimumValidity;
     QString mCompliance;
 };
 
 bool KeyResolverCore::Private::isAcceptableSigningKey(const Key &key)
 {
     if (!ValidSigningKey(key)) {
         return false;
     }
     if (mCompliance == QLatin1String("de-vs")) {
         if (!Formatting::isKeyDeVs(key)) {
             qCDebug(LIBKLEO_LOG) << "Rejected sig key" << key.primaryFingerprint()
                                     << "because it is not de-vs compliant.";
             return false;
         }
     }
     return true;
 }
 
 bool KeyResolverCore::Private::isAcceptableEncryptionKey(const Key &key, const QString &address)
 {
     if (!ValidEncryptionKey(key)) {
         return false;
     }
 
     if (mCompliance == QLatin1String("de-vs")) {
         if (!Formatting::isKeyDeVs(key)) {
             qCDebug(LIBKLEO_LOG) << "Rejected enc key" << key.primaryFingerprint()
                                     << "because it is not de-vs compliant.";
             return false;
         }
     }
 
     if (address.isEmpty()) {
         return true;
     }
     for (const auto &uid: key.userIDs()) {
         if (uid.addrSpec() == address.toStdString()) {
             if (uid.validity() >= mMinimumValidity) {
                 return true;
             }
         }
     }
     return false;
 }
 
 void KeyResolverCore::Private::setSender(const QString &address)
 {
     const auto normalized = UserID::addrSpecFromString (address.toUtf8().constData());
     if (normalized.empty()) {
         // should not happen bug in the caller, non localized
         // error for bug reporting.
         mFatalErrors << QStringLiteral("The sender address '%1' could not be extracted").arg(address);
         return;
     }
     const auto normStr = QString::fromUtf8(normalized.c_str());
     if (mSign) {
         mSender = normStr;
     }
     addRecipients({address});
 }
 
 void KeyResolverCore::Private::addRecipients(const QStringList &addresses)
 {
     if (!mEncrypt) {
         return;
     }
 
     // Internally we work with normalized addresses. Normalization
     // matches the gnupg one.
     for (const auto &addr: addresses) {
         // PGP Uids are defined to be UTF-8 (RFC 4880 §5.11)
         const auto normalized = UserID::addrSpecFromString (addr.toUtf8().constData());
         if (normalized.empty()) {
             // should not happen bug in the caller, non localized
             // error for bug reporting.
             mFatalErrors << QStringLiteral("The mail address for '%1' could not be extracted").arg(addr);
             continue;
         }
         const QString normStr = QString::fromUtf8(normalized.c_str());
 
         mRecipients << normStr;
 
         // Initially add empty lists of keys for both protocols
         mEncKeys[normStr] = {{CMS, {}}, {OpenPGP, {}}};
     }
 }
 
 void KeyResolverCore::Private::setOverrideKeys(const QMap<Protocol, QMap<QString, QStringList>> &overrides)
 {
     for (auto protocolIt = overrides.cbegin(); protocolIt != overrides.cend(); ++protocolIt) {
         const Protocol &protocol = protocolIt.key();
         const auto &addressFingerprintMap = protocolIt.value();
         for (auto addressIt = addressFingerprintMap.cbegin(); addressIt != addressFingerprintMap.cend(); ++addressIt) {
             const QString &address = addressIt.key();
             const QStringList &fingerprints = addressIt.value();
             const QString normalizedAddress = QString::fromUtf8(UserID::addrSpecFromString(address.toUtf8().constData()).c_str());
             mOverrides[normalizedAddress][protocol] = fingerprints;
         }
     }
 }
 
 // Apply the overrides this is also where specific formats come in
 void KeyResolverCore::Private::resolveOverrides()
 {
     if (!mEncrypt) {
         // No encryption we are done.
         return;
     }
     for (auto addressIt = mOverrides.cbegin(); addressIt != mOverrides.cend(); ++addressIt) {
         const QString &address = addressIt.key();
         const auto &protocolFingerprintsMap = addressIt.value();
 
         if (!mRecipients.contains(address)) {
             qCDebug(LIBKLEO_LOG) << "Overrides provided for an address that is "
                 "neither sender nor recipient. Address:" << address;
             continue;
         }
 
         for (auto protocolIt = protocolFingerprintsMap.cbegin(); protocolIt != protocolFingerprintsMap.cend(); ++protocolIt) {
             const Protocol protocol = protocolIt.key();
             const QStringList &fingerprints = protocolIt.value();
             if ((mFormat == OpenPGP && protocol == CMS) ||
                 (mFormat == CMS && protocol == OpenPGP)) {
                 // Skip overrides for the wrong format
                 continue;
             }
             for (const auto &fprOrId: fingerprints) {
                 const Key key = mCache->findByKeyIDOrFingerprint(fprOrId.toUtf8().constData());
                 if (key.isNull()) {
                     qCDebug (LIBKLEO_LOG) << "Failed to find override key for:" << address
                         << "fpr:" << fprOrId;
                     continue;
                 }
+                if (protocol != UnknownProtocol && key.protocol() != protocol) {
+                    qCDebug(LIBKLEO_LOG) << "Ignoring key" << Formatting::summaryLine(key) << "given as" << Formatting::displayName(protocol) << "override for"
+                                         << address;
+                    continue;
+                }
 
                 Protocol resolvedFmt = protocol;
                 if (protocol == UnknownProtocol) {
                     // Take the format from the key.
                     resolvedFmt = key.protocol();
                 }
                 mEncKeys[address][resolvedFmt].push_back(key);
 
                 qCDebug(LIBKLEO_LOG) << "Override" << address << Formatting::displayName(resolvedFmt) << fprOrId;
             }
         }
     }
 }
 
 void KeyResolverCore::Private::resolveSign(Protocol proto)
 {
     if (mSigKeys.contains(proto)) {
         // Explicitly set
         return;
     }
     const auto keys = mCache->findBestByMailBox(mSender.toUtf8().constData(),
                                                 proto, true, false);
     for (const auto &key: keys) {
         if (key.isNull()) {
             continue;
         }
         if (!isAcceptableSigningKey(key)) {
             qCDebug(LIBKLEO_LOG) << "Unacceptable signing key" << key.primaryFingerprint()
                                     << "for" << mSender;
             return;
         }
     }
 
     if (!keys.empty() && !keys[0].isNull()) {
         mSigKeys.insert(proto, keys);
     }
 }
 
 void KeyResolverCore::Private::setSigningKeys(const QStringList &fingerprints)
 {
     if (mSign) {
         for (const auto &fpr: fingerprints) {
             const auto key = mCache->findByKeyIDOrFingerprint(fpr.toUtf8().constData());
             if (key.isNull()) {
                 qCDebug(LIBKLEO_LOG) << "Failed to find signing key with fingerprint" << fpr;
                 continue;
             }
             auto list = mSigKeys.value(key.protocol());
             list.push_back(key);
             mSigKeys.insert(key.protocol(), list);
         }
     }
 }
 
 std::vector<Key> KeyResolverCore::Private::resolveRecipient(const QString &address, Protocol protocol)
 {
     const auto keys = mCache->findBestByMailBox(address.toUtf8().constData(), protocol, false, true);
     if (keys.empty() || keys[0].isNull()) {
         qCDebug(LIBKLEO_LOG) << "Failed to find any" << Formatting::displayName(protocol) << "key for: " << address;
         return {};
     }
     if (keys.size() == 1) {
         if (!isAcceptableEncryptionKey(keys[0], address)) {
             qCDebug(LIBKLEO_LOG) << "key for:" << address << keys[0].primaryFingerprint()
                                     << "has not enough validity";
             return {};
         }
     } else {
         // If we have one unacceptable group key we reject the
         // whole group to avoid the situation where one key is
         // skipped or the operation fails.
         //
         // We are in Autoresolve land here. In the GUI we
         // will also show unacceptable group keys so that the
         // user can see which key is not acceptable.
         bool unacceptable = false;
         for (const auto &key: keys) {
             if (!isAcceptableEncryptionKey(key)) {
                 qCDebug(LIBKLEO_LOG) << "group key for:" << address << keys[0].primaryFingerprint()
                                         << "has not enough validity";
                 unacceptable = true;
                 break;
             }
         }
         if (unacceptable) {
             return {};
         }
     }
     for (const auto &k: keys) {
         qCDebug(LIBKLEO_LOG) << "Resolved encrypt to" << address << "with key" << k.primaryFingerprint();
     }
     return keys;
 }
 
 // Try to find matching keys in the provided protocol for the unresolved addresses
 void KeyResolverCore::Private::resolveEnc(Protocol proto)
 {
     for (auto it = mEncKeys.begin(); it != mEncKeys.end(); ++it) {
         const QString &address = it.key();
         auto &protocolKeysMap = it.value();
         if (!protocolKeysMap[proto].empty()) {
             continue;
         }
         protocolKeysMap[proto] = resolveRecipient(address, proto);
     }
 }
 
 void KeyResolverCore::Private::mergeEncryptionKeys()
 {
     for (auto it = mEncKeys.begin(); it != mEncKeys.end(); ++it) {
         const QString &address = it.key();
         auto &protocolKeysMap = it.value();
         if (!protocolKeysMap[UnknownProtocol].empty()) {
             // override keys are set for address
             continue;
         }
         const std::vector<Key> &keysOpenPGP = protocolKeysMap.value(OpenPGP);
         const std::vector<Key> &keysCMS = protocolKeysMap.value(CMS);
         if (keysOpenPGP.empty() && keysCMS.empty()) {
             continue;
         } else if (!keysOpenPGP.empty() && keysCMS.empty()) {
             protocolKeysMap[UnknownProtocol] = keysOpenPGP;
         } else if (keysOpenPGP.empty() && !keysCMS.empty()) {
             protocolKeysMap[UnknownProtocol] = keysCMS;
         } else {
             // check whether OpenPGP keys or S/MIME keys have higher validity
             const int validityPGP = minimumValidity(keysOpenPGP, address);
             const int validityCMS = minimumValidity(keysCMS, address);
             if ((validityPGP > validityCMS)
                 || (validityPGP == validityCMS && mPreferredProtocol == OpenPGP)) {
                 protocolKeysMap[UnknownProtocol] = keysOpenPGP;
             } else if ((validityCMS > validityPGP)
                 || (validityCMS == validityPGP && mPreferredProtocol == CMS)) {
                 protocolKeysMap[UnknownProtocol] = keysCMS;
             } else {
                 protocolKeysMap[UnknownProtocol] = keysOpenPGP;
             }
         }
     }
 }
 
 QStringList KeyResolverCore::Private::unresolvedRecipients(GpgME::Protocol protocol) const
 {
     QStringList result;
     result.reserve(mEncKeys.size());
     for (auto it = mEncKeys.begin(); it != mEncKeys.end(); ++it) {
         const auto &protocolKeysMap = it.value();
         if (protocolKeysMap.value(protocol).empty()) {
             result.push_back(it.key());
         }
     }
     return result;
 }
 
 bool KeyResolverCore::Private::resolve()
 {
     qCDebug(LIBKLEO_LOG) << "Starting ";
     if (!mSign && !mEncrypt) {
         // nothing to do
         return true;
     }
 
     // First resolve through overrides
     resolveOverrides();
 
     // Then look for signing / encryption keys
     if (mFormat != CMS) {
         resolveSign(OpenPGP);
         resolveEnc(OpenPGP);
     }
     const QStringList unresolvedPGP = unresolvedRecipients(OpenPGP);
     bool pgpOnly = unresolvedPGP.empty() && (!mSign || mSigKeys.contains(OpenPGP));
 
     if (mFormat != OpenPGP) {
         resolveSign(CMS);
         resolveEnc(CMS);
     }
     const QStringList unresolvedCMS = unresolvedRecipients(CMS);
     bool cmsOnly = unresolvedCMS.empty() && (!mSign || mSigKeys.contains(CMS));
 
     if (mAllowMixed && mFormat == UnknownProtocol) {
         mergeEncryptionKeys();
     }
 
     // Check if we need the user to select different keys.
     bool needsUser = false;
     if (!pgpOnly && !cmsOnly) {
         for (const auto &unresolved: unresolvedPGP) {
             if (unresolvedCMS.contains(unresolved)) {
                 // We have at least one unresolvable key.
                 needsUser = true;
                 break;
             }
         }
         if (mSign) {
             // So every recipient could be resolved through
             // a combination of PGP and S/MIME do we also
             // have signing keys for both?
             needsUser |= !(mSigKeys.contains(OpenPGP) &&
                            mSigKeys.contains(CMS));
         }
     }
 
     if (!needsUser) {
         if (pgpOnly && cmsOnly) {
             if (mPreferredProtocol == CMS) {
                 mSigKeys.remove(OpenPGP);
                 for (auto &protocolKeysMap: mEncKeys) {
                     protocolKeysMap.remove(OpenPGP);
                 }
             } else {
                 mSigKeys.remove(CMS);
                 for (auto &protocolKeysMap: mEncKeys) {
                     protocolKeysMap.remove(CMS);
                 }
             }
         } else if (pgpOnly) {
             mSigKeys.remove(CMS);
             for (auto &protocolKeysMap: mEncKeys) {
                 protocolKeysMap.remove(CMS);
             }
         } else if (cmsOnly) {
             mSigKeys.remove(OpenPGP);
             for (auto &protocolKeysMap: mEncKeys) {
                 protocolKeysMap.remove(OpenPGP);
             }
         }
 
         qCDebug(LIBKLEO_LOG) << "Automatic key resolution done.";
         return true;
     }
 
     return false;
 }
 
 KeyResolverCore::KeyResolverCore(bool encrypt, bool sign, Protocol fmt)
     : d(new Private(this, encrypt, sign, fmt))
 {
 }
 
 KeyResolverCore::~KeyResolverCore() = default;
 
 void KeyResolverCore::setSender(const QString &address)
 {
     d->setSender(address);
 }
 
 QString KeyResolverCore::normalizedSender() const
 {
     return d->mSender;
 }
 
 void KeyResolverCore::setRecipients(const QStringList &addresses)
 {
     d->addRecipients(addresses);
 }
 
 void KeyResolverCore::setSigningKeys(const QStringList &fingerprints)
 {
     d->setSigningKeys(fingerprints);
 }
 
 void KeyResolverCore::setOverrideKeys(const QMap<Protocol, QMap<QString, QStringList>> &overrides)
 {
     d->setOverrideKeys(overrides);
 }
 
 void KeyResolverCore::setAllowMixedProtocols(bool allowMixed)
 {
     d->mAllowMixed = allowMixed;
 }
 
 void KeyResolverCore::setPreferredProtocol(Protocol proto)
 {
     d->mPreferredProtocol = proto;
 }
 
 void KeyResolverCore::setMinimumValidity(int validity)
 {
     d->mMinimumValidity = validity;
 }
 
 bool KeyResolverCore::resolve()
 {
     return d->resolve();
 }
 
 QMap <Protocol, std::vector<Key> > KeyResolverCore::signingKeys() const
 {
     return d->mSigKeys;
 }
 
 QMap<Protocol, QMap<QString, std::vector<Key>>> KeyResolverCore::encryptionKeys() const
 {
     QMap<Protocol, QMap<QString, std::vector<Key>>> result;
 
     for (auto addressIt = d->mEncKeys.cbegin(); addressIt != d->mEncKeys.cend(); ++addressIt) {
         const QString &address = addressIt.key();
         const auto &protocolKeysMap = addressIt.value();
         for (auto protocolIt = protocolKeysMap.cbegin(); protocolIt != protocolKeysMap.cend(); ++protocolIt) {
             const Protocol protocol = protocolIt.key();
             const auto &keys = protocolIt.value();
             if (!keys.empty()) {
                 result[protocol][address] = keys;
             }
         }
     }
 
     return result;
 }
 
 QStringList KeyResolverCore::unresolvedRecipients(GpgME::Protocol protocol) const
 {
     return d->unresolvedRecipients(protocol);
 }