Support for RFC-compliant TOTP hashes #873 #1566

This implements support for SHA-256 and SHA-512 hash algorithms when
generating TOTP codes. These algorithms are specified by RFC6238. The
implementation is compatible with Google's OTP URL format, as well as
with the KeeOTP plugin for KeePass.

The implementation is not wired into the GUI, as the main project
developer expressed strong negative sentiment about adding more
options there. It is possible to configure codes by putting the
appropriate string into the entry's otp property, or using another
program with a less opinionated UI and a compatible on-disk format.
This commit is contained in:
Bryan Jacobs 2019-04-10 20:58:27 +10:00 committed by Jonathan White
parent 61b1f8c966
commit 04983ce4cd
4 changed files with 86 additions and 9 deletions

View file

@ -41,15 +41,29 @@ void TestTotp::testParseSecret()
QCOMPARE(settings->custom, false);
QCOMPARE(settings->digits, 6u);
QCOMPARE(settings->step, 30u);
QCOMPARE(settings->hashType, Totp::HashType::Sha1);
// OTP URL with non-default hash type
secret = "otpauth://totp/"
"ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm="
"SHA512&digits=6&period=30";
settings = Totp::parseSettings(secret);
QVERIFY(!settings.isNull());
QCOMPARE(settings->key, QString("HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"));
QCOMPARE(settings->custom, false);
QCOMPARE(settings->digits, 6u);
QCOMPARE(settings->step, 30u);
QCOMPARE(settings->hashType, Totp::HashType::Sha512);
// KeeOTP Parsing
secret = "key=HXDMVJECJJWSRBY%3d&step=25&size=8";
secret = "key=HXDMVJECJJWSRBY%3d&step=25&size=8&otpHashMode=Sha256";
settings = Totp::parseSettings(secret);
QVERIFY(!settings.isNull());
QCOMPARE(settings->key, QString("HXDMVJECJJWSRBY="));
QCOMPARE(settings->custom, true);
QCOMPARE(settings->digits, 8u);
QCOMPARE(settings->step, 25u);
QCOMPARE(settings->hashType, Totp::HashType::Sha256);
// Semi-colon delineated "TOTP Settings"
secret = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq";
@ -59,6 +73,7 @@ void TestTotp::testParseSecret()
QCOMPARE(settings->custom, true);
QCOMPARE(settings->digits, 8u);
QCOMPARE(settings->step, 30u);
QCOMPARE(settings->hashType, Totp::HashType::Sha1);
// Bare secret (no "TOTP Settings" attribute)
secret = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq";
@ -68,6 +83,7 @@ void TestTotp::testParseSecret()
QCOMPARE(settings->custom, false);
QCOMPARE(settings->digits, 6u);
QCOMPARE(settings->step, 30u);
QCOMPARE(settings->hashType, Totp::HashType::Sha1);
}
void TestTotp::testTotpCode()