File indexing completed on 2024-05-12 05:52:46

0001 /*
0002  * SPDX-License-Identifier: GPL-3.0-or-later
0003  * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
0004  */
0005 #include "account/actions_p.h"
0006 
0007 #include "../test-utils/secret.h"
0008 #include "../../test-utils/spy.h"
0009 
0010 #include <QSignalSpy>
0011 #include <QTest>
0012 
0013 class ComputeHotpTest: public QObject
0014 {
0015     Q_OBJECT
0016 private Q_SLOTS:
0017     void initTestCase(void);
0018     void testDefaults(void);
0019     void testDefaults_data(void);
0020 private:
0021     accounts::AccountSecret m_secret;
0022 };
0023 
0024 // RFC test vector uses the key: 12345678901234567890
0025 static QByteArray rfcSecret("12345678901234567890");
0026 
0027 // the RFC test vector consists of 6-character tokens
0028 static uint tokenLength = 6;
0029 
0030 void ComputeHotpTest::initTestCase(void)
0031 {
0032     QVERIFY2(test::useDummyPassword(&m_secret), "should be able to set up the master key");
0033 }
0034 
0035 void ComputeHotpTest::testDefaults(void)
0036 {
0037     QFETCH(quint64, counter);
0038 
0039     std::optional<secrets::EncryptedSecret> tokenSecret = test::encrypt(&m_secret, rfcSecret);
0040     QVERIFY2(tokenSecret, "should be able to encrypt the token secret");
0041 
0042     accounts::ComputeHotp uut(&m_secret, *tokenSecret, tokenLength, counter, std::nullopt, false);
0043     QSignalSpy tokenGenerated(&uut, &accounts::ComputeHotp::otp);
0044     QSignalSpy jobFinished(&uut, &accounts::ComputeHotp::finished);
0045 
0046     uut.run();
0047 
0048     QVERIFY2(test::signal_eventually_emitted_once(tokenGenerated), "token should be generated by now");
0049     QVERIFY2(test::signal_eventually_emitted_once(jobFinished), "job should be finished by now");
0050 
0051     QTEST(tokenGenerated.at(0).at(0).toString(), "rfc-test-vector");
0052     QCOMPARE(tokenGenerated.at(0).at(2).toULongLong(), counter + 1ULL);
0053 }
0054 
0055 static void define_test_case(int k, const char *expected)
0056 {
0057 
0058     QByteArray output(expected, tokenLength);
0059     QTest::newRow(qPrintable(QStringLiteral("RFC 4226 test vector, counter value = %1").arg(k))) << (quint64) k << QString::fromLocal8Bit(output);
0060 }
0061 
0062 void ComputeHotpTest::testDefaults_data(void)
0063 {
0064     static const char * corpus[10] {
0065         "755224",
0066         "287082",
0067         "359152",
0068         "969429",
0069         "338314",
0070         "254676",
0071         "287922",
0072         "162583",
0073         "399871",
0074         "520489"
0075     };
0076 
0077     QTest::addColumn<quint64>("counter");
0078     QTest::addColumn<QString>("rfc-test-vector");
0079 
0080     for (int k = 0; k < 10; ++k) {
0081         define_test_case(k, corpus[k]);
0082     }
0083 }
0084 
0085 QTEST_MAIN(ComputeHotpTest)
0086 
0087 #include "compute-hotp.moc"
0088