File indexing completed on 2024-04-28 05:50:04

0001 /*
0002  * SPDX-License-Identifier: GPL-3.0-or-later
0003  * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
0004  */
0005 #include "oath/oath.h"
0006 
0007 #include <QTest>
0008 #include <QtDebug>
0009 
0010 class TotpAlgorithmTest: public QObject
0011 {
0012     Q_OBJECT
0013 private Q_SLOTS:
0014     void rfcTestVector(void);
0015     void rfcTestVector_data(void);
0016 };
0017 
0018 void define_test_case(const QString &testCase, const QString &datetime, const QByteArray &secret, QCryptographicHash::Algorithm algorithm, const char *expected)
0019 {
0020     const QDateTime dt = QDateTime::fromString(datetime, Qt::ISODate);
0021     QTest::newRow(qPrintable(testCase.arg(datetime).arg(QLatin1String(expected)))) << dt << ((int) algorithm) << secret << QString(QLatin1String(expected));
0022 }
0023 
0024 void define_sha1_test_case(const char * datetime, const char *expected)
0025 {
0026     define_test_case(QLatin1String("%1 (SHA1) ... %2"), QLatin1String(datetime), QByteArray("12345678901234567890"), QCryptographicHash::Sha1, expected);
0027 }
0028 
0029 void define_sha256_test_case(const char * datetime, const char *expected)
0030 {
0031     define_test_case(QLatin1String("%1 (SHA256) ... %2"), QLatin1String(datetime), QByteArray("12345678901234567890123456789012"), QCryptographicHash::Sha256, expected);
0032 }
0033 
0034 void define_sha512_test_case(const char * datetime, const char *expected)
0035 {
0036     define_test_case(QLatin1String("%1 (SHA512) ... %2"), QLatin1String(datetime), QByteArray("1234567890123456789012345678901234567890123456789012345678901234"), QCryptographicHash::Sha512, expected);
0037 }
0038 
0039 /*
0040  * (Static) test vector params obtained from RFC-6238
0041  * https://tools.ietf.org/html/rfc6238#page-9
0042  */
0043 static const uint tokenLength = 8U;
0044 static const QDateTime epoch = QDateTime::fromMSecsSinceEpoch(0);
0045 static const uint timeStep = 30U;
0046 
0047 void TotpAlgorithmTest::rfcTestVector(void)
0048 {
0049     QFETCH(QDateTime, now);
0050     QFETCH(int, hash);
0051     QFETCH(QByteArray, secret);
0052 
0053     std::optional<quint64> counter = oath::count(epoch, timeStep, [now](void) -> qint64
0054     {
0055         return now.toMSecsSinceEpoch();
0056     });
0057 
0058     QVERIFY2(counter, "should be able to count timesteps using the settings of the RFC test vector");
0059 
0060     std::optional<oath::Algorithm> uut = oath::Algorithm::totp((QCryptographicHash::Algorithm) hash, tokenLength);
0061     QVERIFY2(uut, "should be able to construct the algorithm using settings of the RFC test vector");
0062 
0063     QByteArray copy(secret);
0064 
0065     std::optional<QString> result = uut->compute(*counter, copy.data(), copy.size());
0066     QVERIFY2(result, "token should be computed successfully");
0067     QTEST(*result, "rfc-test-vector");
0068 }
0069 
0070 void TotpAlgorithmTest::rfcTestVector_data(void)
0071 {
0072     QTest::addColumn<QDateTime>("now");
0073     QTest::addColumn<int>("hash");
0074     QTest::addColumn<QByteArray>("secret");
0075     QTest::addColumn<QString>("rfc-test-vector");
0076 
0077     define_sha1_test_case("1970-01-01T00:00:59Z", "94287082");
0078     define_sha256_test_case("1970-01-01T00:00:59Z", "46119246");
0079     define_sha512_test_case("1970-01-01T00:00:59Z", "90693936");
0080 
0081     define_sha1_test_case("2005-03-18T01:58:29Z", "07081804");
0082     define_sha256_test_case("2005-03-18T01:58:29Z", "68084774");
0083     define_sha512_test_case("2005-03-18T01:58:29Z", "25091201");
0084 
0085     define_sha1_test_case("2005-03-18T01:58:31Z", "14050471");
0086     define_sha256_test_case("2005-03-18T01:58:31Z", "67062674");
0087     define_sha512_test_case("2005-03-18T01:58:31Z", "99943326");
0088 
0089     define_sha1_test_case("2009-02-13T23:31:30Z", "89005924");
0090     define_sha256_test_case("2009-02-13T23:31:30Z", "91819424");
0091     define_sha512_test_case("2009-02-13T23:31:30Z", "93441116");
0092 
0093     define_sha1_test_case("2033-05-18T03:33:20Z", "69279037");
0094     define_sha256_test_case("2033-05-18T03:33:20Z", "90698825");
0095     define_sha512_test_case("2033-05-18T03:33:20Z", "38618901");
0096 
0097     define_sha1_test_case("2603-10-11T11:33:20Z", "65353130");
0098     define_sha256_test_case("2603-10-11T11:33:20Z", "77737706");
0099     define_sha512_test_case("2603-10-11T11:33:20Z", "47863826");
0100 }
0101 
0102 QTEST_APPLESS_MAIN(TotpAlgorithmTest)
0103 
0104 #include "totp-algorithm.moc"