Commit 5850dc18 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Mark partial/full single-protocol solutions in mixed mode with protocol

If, in mixed mode, the resolver finds a single-protocol solution or if
all keys of a partial solution have the same protocol, then mark the
solution with this protocol.

GnuPG-bug-id: 5283
parent 2f216aae
......@@ -8,6 +8,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <Libkleo/Formatting>
#include <Libkleo/KeyCache>
#include <Libkleo/KeyResolverCore>
......@@ -36,6 +37,20 @@ inline bool qCompare(int const &t1, KeyResolverCore::SolutionFlags const &t2, co
{
return qCompare(int(t1), int(t2), actual, expected, file, line);
}
template <>
inline char *toString(const GpgME::Protocol &t)
{
return qstrdup(Formatting::displayName(t).toLocal8Bit().constData());
}
template <>
inline bool qCompare(GpgME::Protocol const &t1, GpgME::Protocol const &t2, const char *actual, const char *expected,
const char *file, int line)
{
return compare_helper(t1 == t2, "Compared values are not the same",
toString(t1), toString(t2), actual, expected, file, line);
}
}
class KeyResolverCoreTest: public QObject
......@@ -201,7 +216,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::AllResolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::OpenPGPOnly);
QCOMPARE(result.solution.protocol, UnknownProtocol);
QCOMPARE(result.solution.protocol, OpenPGP);
QCOMPARE(result.solution.signingKeys.size(), 1);
QCOMPARE(result.solution.signingKeys[0].primaryFingerprint(),
testKey("sender-mixed@example.net", OpenPGP).primaryFingerprint());
......@@ -224,7 +239,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::AllResolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::OpenPGPOnly);
QCOMPARE(result.solution.protocol, UnknownProtocol);
QCOMPARE(result.solution.protocol, OpenPGP);
QCOMPARE(result.solution.signingKeys.size(), 1);
QCOMPARE(result.solution.signingKeys[0].primaryFingerprint(),
testKey("sender-mixed@example.net", OpenPGP).primaryFingerprint());
......@@ -247,7 +262,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::AllResolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::CMSOnly);
QCOMPARE(result.solution.protocol, UnknownProtocol);
QCOMPARE(result.solution.protocol, CMS);
QCOMPARE(result.solution.signingKeys.size(), 1);
QCOMPARE(result.solution.signingKeys[0].primaryFingerprint(),
testKey("sender-mixed@example.net", CMS).primaryFingerprint());
......@@ -293,6 +308,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::SomeUnresolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::OpenPGPOnly);
QCOMPARE(result.solution.protocol, OpenPGP);
QCOMPARE(result.solution.encryptionKeys.value("unknown@example.net").size(), 0);
}
......@@ -305,6 +321,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::SomeUnresolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::OpenPGPOnly);
QCOMPARE(result.solution.protocol, OpenPGP);
QCOMPARE(result.solution.encryptionKeys.size(), 2);
QCOMPARE(result.solution.encryptionKeys.value("sender-openpgp@example.net").size(), 1);
QCOMPARE(result.solution.encryptionKeys.value("sender-smime@example.net").size(), 0);
......@@ -320,6 +337,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::SomeUnresolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::CMSOnly);
QCOMPARE(result.solution.protocol, CMS);
QCOMPARE(result.solution.encryptionKeys.size(), 2);
QCOMPARE(result.solution.encryptionKeys.value("sender-openpgp@example.net").size(), 0);
QCOMPARE(result.solution.encryptionKeys.value("sender-smime@example.net").size(), 1);
......@@ -336,6 +354,7 @@ private Q_SLOTS:
QCOMPARE(result.flags & KeyResolverCore::ResolvedMask, KeyResolverCore::SomeUnresolved);
QCOMPARE(result.flags & KeyResolverCore::ProtocolsMask, KeyResolverCore::OpenPGPOnly);
QCOMPARE(result.solution.protocol, OpenPGP);
QCOMPARE(result.solution.encryptionKeys.size(), 2);
QCOMPARE(result.solution.encryptionKeys.value("sender-openpgp@example.net").size(), 1);
QCOMPARE(result.solution.encryptionKeys.value("sender-smime@example.net").size(), 0);
......
......@@ -105,13 +105,6 @@ void KeyResolver::start(bool showApproval, QWidget *parentWidget)
const bool success = (result.flags & KeyResolverCore::AllResolved);
if (success && !showApproval) {
d->mResult = std::move(result.solution);
// update protocol hint of solution if solution is single-protocol solution
const auto protocolsHint = result.flags & KeyResolverCore::ProtocolsMask;
if (protocolsHint == KeyResolverCore::OpenPGPOnly) {
d->mResult.protocol = OpenPGP;
} else if (protocolsHint == KeyResolverCore::CMSOnly) {
d->mResult.protocol = CMS;
}
Q_EMIT keysResolved(true, false);
return;
} else if (success) {
......
......@@ -541,10 +541,9 @@ KeyResolverCore::Result KeyResolverCore::Private::resolve()
{OpenPGP, mSigKeys.value(OpenPGP), keysForProtocol(mEncKeys, OpenPGP)}
};
} else {
// keys marked as mixed (UnknownProtocol) as hint that OpenPGP keys are also allowed in key approval
return {
SolutionFlags(AllResolved | CMSOnly),
{UnknownProtocol, mSigKeys.value(CMS), keysForProtocol(mEncKeys, CMS)},
{CMS, mSigKeys.value(CMS), keysForProtocol(mEncKeys, CMS)},
{}
};
}
......@@ -557,10 +556,9 @@ KeyResolverCore::Result KeyResolverCore::Private::resolve()
{CMS, mSigKeys.value(CMS), keysForProtocol(mEncKeys, CMS)}
};
} else {
// keys marked as mixed (UnknownProtocol) as hint that S/MIME keys are also allowed in key approval
return {
SolutionFlags(AllResolved | OpenPGPOnly),
{UnknownProtocol, mSigKeys.value(OpenPGP), keysForProtocol(mEncKeys, OpenPGP)},
{OpenPGP, mSigKeys.value(OpenPGP), keysForProtocol(mEncKeys, OpenPGP)},
{}
};
}
......@@ -597,10 +595,9 @@ KeyResolverCore::Result KeyResolverCore::Private::resolve()
const bool allKeysAreOpenPGP = std::all_of(std::begin(bestEncryptionKeys), std::end(bestEncryptionKeys),
[] (const auto &keys) { return allKeysHaveProtocol(keys, OpenPGP); });
if (allKeysAreOpenPGP) {
// keys marked as mixed (UnknownProtocol) as hint that S/MIME keys are also allowed in key approval
return {
SolutionFlags(SomeUnresolved | OpenPGPOnly),
{UnknownProtocol, mSigKeys.value(OpenPGP), bestEncryptionKeys},
{OpenPGP, mSigKeys.value(OpenPGP), bestEncryptionKeys},
{}
};
}
......@@ -608,10 +605,9 @@ KeyResolverCore::Result KeyResolverCore::Private::resolve()
const bool allKeysAreCMS = std::all_of(std::begin(bestEncryptionKeys), std::end(bestEncryptionKeys),
[] (const auto &keys) { return allKeysHaveProtocol(keys, CMS); });
if (allKeysAreCMS) {
// keys marked as mixed (UnknownProtocol) as hint that S/MIME keys are also allowed in key approval
return {
SolutionFlags(SomeUnresolved | CMSOnly),
{UnknownProtocol, mSigKeys.value(CMS), bestEncryptionKeys},
{CMS, mSigKeys.value(CMS), bestEncryptionKeys},
{}
};
}
......
......@@ -849,8 +849,8 @@ NewKeyApprovalDialog::NewKeyApprovalDialog(bool encrypt,
d->setSigningKeys(std::move(preferredSolution.signingKeys), std::move(alternativeSolution.signingKeys));
}
if (encrypt) {
d->setEncryptionKeys(preferredSolution.protocol, std::move(preferredSolution.encryptionKeys),
alternativeSolution.protocol, std::move(alternativeSolution.encryptionKeys));
d->setEncryptionKeys(allowMixed ? UnknownProtocol : preferredSolution.protocol, std::move(preferredSolution.encryptionKeys),
allowMixed ? UnknownProtocol : alternativeSolution.protocol, std::move(alternativeSolution.encryptionKeys));
}
d->updateWidgetVisibility();
d->updateOkButton();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment