qt,tests: Verify reason code and description of revocation
* lang/qt/tests/t-revokekey.cpp (RevokeKeyJobTest::testRevokeKeyAsync, RevokeKeyJobTest::testRevokeKeySync_noReasonDescription, RevokeKeyJobTest::testRevokeKeySync_oneLineReasonDescription, RevokeKeyJobTest::testRevokeKeySync_twoLinesReasonDescription): Call verifyReason. (class RevokeKeyJobTest): Add private member function verifyReason. -- gpgme doesn't parse the information, so we run gpg manually to verify the revocation reason and the description. GnuPG-bug-id: 5904
This commit is contained in:
parent
41297520da
commit
3856ae8621
@ -38,6 +38,7 @@
|
|||||||
#include <protocol.h>
|
#include <protocol.h>
|
||||||
#include <revokekeyjob.h>
|
#include <revokekeyjob.h>
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
#include <QSignalSpy>
|
#include <QSignalSpy>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
@ -131,6 +132,8 @@ private Q_SLOTS:
|
|||||||
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
||||||
key.update();
|
key.update();
|
||||||
QVERIFY(key.isRevoked());
|
QVERIFY(key.isRevoked());
|
||||||
|
verifyReason(key, RevocationReason::NoLongerUsed,
|
||||||
|
{"This key is not used anymore."});
|
||||||
}
|
}
|
||||||
|
|
||||||
void testSync_noReasonDescription()
|
void testSync_noReasonDescription()
|
||||||
@ -148,6 +151,7 @@ private Q_SLOTS:
|
|||||||
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
||||||
key.update();
|
key.update();
|
||||||
QVERIFY(key.isRevoked());
|
QVERIFY(key.isRevoked());
|
||||||
|
verifyReason(key, RevocationReason::Unspecified, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void testSync_oneLineReasonDescription()
|
void testSync_oneLineReasonDescription()
|
||||||
@ -166,6 +170,8 @@ private Q_SLOTS:
|
|||||||
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
||||||
key.update();
|
key.update();
|
||||||
QVERIFY(key.isRevoked());
|
QVERIFY(key.isRevoked());
|
||||||
|
verifyReason(key, RevocationReason::Compromised,
|
||||||
|
{"The secret key was stolen."});
|
||||||
}
|
}
|
||||||
|
|
||||||
void testSync_twoLinesReasonDescription()
|
void testSync_twoLinesReasonDescription()
|
||||||
@ -185,6 +191,9 @@ private Q_SLOTS:
|
|||||||
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
QVERIFY(result.code() == GPG_ERR_NO_ERROR);
|
||||||
key.update();
|
key.update();
|
||||||
QVERIFY(key.isRevoked());
|
QVERIFY(key.isRevoked());
|
||||||
|
verifyReason(key, RevocationReason::Superseded,
|
||||||
|
{"This key has been superseded by key",
|
||||||
|
"0000 1111 2222 3333 4444 5555 6666 7777 8888 9999."});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -200,6 +209,63 @@ private:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool verifyReason(const Key &key, RevocationReason reason, const QStringList &description)
|
||||||
|
{
|
||||||
|
static const auto startTimeout = std::chrono::milliseconds{1000};
|
||||||
|
static const auto finishTimeout = std::chrono::milliseconds{2000};
|
||||||
|
static const QStringList hexCodeForReason = {
|
||||||
|
QStringLiteral("00"), /* no particular reason */
|
||||||
|
QStringLiteral("02"), /* key has been compromised */
|
||||||
|
QStringLiteral("01"), /* key is superseded */
|
||||||
|
QStringLiteral("03") /* key is no longer used */
|
||||||
|
};
|
||||||
|
|
||||||
|
QProcess p;
|
||||||
|
p.setProgram(dirInfo("gpg-name"));
|
||||||
|
p.setArguments({QStringLiteral("-K"),
|
||||||
|
QStringLiteral("--with-colon"),
|
||||||
|
QStringLiteral("--with-sig-list"),
|
||||||
|
QLatin1String{key.primaryFingerprint()}
|
||||||
|
});
|
||||||
|
|
||||||
|
p.start();
|
||||||
|
|
||||||
|
if (!p.waitForStarted(startTimeout.count())) {
|
||||||
|
qWarning() << "Timeout while waiting for start of" << p.program() << p.arguments().join(u' ');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!p.waitForFinished(finishTimeout.count())) {
|
||||||
|
qWarning() << "Timeout while waiting for completion of" << p.program() << p.arguments().join(u' ');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (p.exitStatus() != QProcess::NormalExit) {
|
||||||
|
qWarning() << p.program() << "terminated abnormally with exit status" << p.exitStatus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto lines = QString::fromUtf8(p.readAllStandardOutput()).split(u'\n');
|
||||||
|
for (const auto &l : lines) {
|
||||||
|
const auto fields = l.split(u':');
|
||||||
|
if (fields[0] == QLatin1String{"rev"}) {
|
||||||
|
// or "rev" the signature class may be followed by a comma
|
||||||
|
// and a 2 digit hexnumber with the revocation reason
|
||||||
|
const auto sigClass = fields.value(10);
|
||||||
|
const auto revReason = sigClass.split(u',').value(1);
|
||||||
|
COMPARE_OR_FALSE(revReason, hexCodeForReason.value(static_cast<int>(reason)));
|
||||||
|
|
||||||
|
// decode the \n in the C-style quoted comment field
|
||||||
|
const auto comment = fields.value(20).replace(QStringLiteral("\\n"), QStringLiteral("\n"));
|
||||||
|
COMPARE_OR_FALSE(comment, description.join(u'\n'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (fields[0] == QLatin1String{"uid"}) {
|
||||||
|
qWarning() << "Found uid before rev in key listing:\n" << stdout;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTemporaryDir mGnupgHomeTestFixture;
|
QTemporaryDir mGnupgHomeTestFixture;
|
||||||
std::unique_ptr<QTemporaryDir> mGnupgHomeTestCopy;
|
std::unique_ptr<QTemporaryDir> mGnupgHomeTestCopy;
|
||||||
|
Loading…
Reference in New Issue
Block a user