keepassxc

Форк
0
/
TestTotp.cpp 
179 строк · 6.6 Кб
1
/*
2
 *  Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
3
 *  Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation, either version 2 or (at your option)
8
 *  version 3 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
#include "TestTotp.h"
20

21
#include "core/Entry.h"
22
#include "core/Totp.h"
23
#include "crypto/Crypto.h"
24

25
#include <QTest>
26

27
QTEST_GUILESS_MAIN(TestTotp)
28

29
void TestTotp::initTestCase()
30
{
31
    QVERIFY(Crypto::init());
32
}
33

34
void TestTotp::testParseSecret()
35
{
36
    // OTP URL Parsing
37
    QString secret = "otpauth://totp/"
38
                     "ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm="
39
                     "SHA1&digits=6&period=30";
40
    auto settings = Totp::parseSettings(secret);
41
    QVERIFY(!settings.isNull());
42
    QCOMPARE(settings->key, QString("HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"));
43
    QCOMPARE(settings->custom, false);
44
    QCOMPARE(settings->format, Totp::StorageFormat::OTPURL);
45
    QCOMPARE(settings->digits, 6u);
46
    QCOMPARE(settings->step, 30u);
47
    QCOMPARE(settings->algorithm, Totp::Algorithm::Sha1);
48

49
    // OTP URL with non-default hash type
50
    secret = "otpauth://totp/"
51
             "ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm="
52
             "SHA512&digits=6&period=30";
53
    settings = Totp::parseSettings(secret);
54
    QVERIFY(!settings.isNull());
55
    QCOMPARE(settings->key, QString("HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"));
56
    QCOMPARE(settings->custom, true);
57
    QCOMPARE(settings->format, Totp::StorageFormat::OTPURL);
58
    QCOMPARE(settings->digits, 6u);
59
    QCOMPARE(settings->step, 30u);
60
    QCOMPARE(settings->algorithm, Totp::Algorithm::Sha512);
61

62
    // Max TOTP step of 24-hours
63
    secret.replace("period=30", "period=90000");
64
    settings = Totp::parseSettings(secret);
65
    QVERIFY(!settings.isNull());
66
    QCOMPARE(settings->step, 86400u);
67

68
    // KeeOTP Parsing
69
    secret = "key=HXDMVJECJJWSRBY%3d&step=25&size=8&otpHashMode=Sha256";
70
    settings = Totp::parseSettings(secret);
71
    QVERIFY(!settings.isNull());
72
    QCOMPARE(settings->key, QString("HXDMVJECJJWSRBY="));
73
    QCOMPARE(settings->custom, true);
74
    QCOMPARE(settings->format, Totp::StorageFormat::KEEOTP);
75
    QCOMPARE(settings->digits, 8u);
76
    QCOMPARE(settings->step, 25u);
77
    QCOMPARE(settings->algorithm, Totp::Algorithm::Sha256);
78

79
    // Semi-colon delineated "TOTP Settings"
80
    secret = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq";
81
    settings = Totp::parseSettings("30;8", secret);
82
    QVERIFY(!settings.isNull());
83
    QCOMPARE(settings->key, QString("gezdgnbvgy3tqojqgezdgnbvgy3tqojq"));
84
    QCOMPARE(settings->custom, true);
85
    QCOMPARE(settings->format, Totp::StorageFormat::LEGACY);
86
    QCOMPARE(settings->digits, 8u);
87
    QCOMPARE(settings->step, 30u);
88
    QCOMPARE(settings->algorithm, Totp::Algorithm::Sha1);
89

90
    // Bare secret (no "TOTP Settings" attribute)
91
    secret = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq";
92
    settings = Totp::parseSettings("", secret);
93
    QVERIFY(!settings.isNull());
94
    QCOMPARE(settings->key, QString("gezdgnbvgy3tqojqgezdgnbvgy3tqojq"));
95
    QCOMPARE(settings->custom, false);
96
    QCOMPARE(settings->format, Totp::StorageFormat::LEGACY);
97
    QCOMPARE(settings->digits, 6u);
98
    QCOMPARE(settings->step, 30u);
99
    QCOMPARE(settings->algorithm, Totp::Algorithm::Sha1);
100

101
    // Blank settings (expected failure)
102
    settings = Totp::parseSettings("", "");
103
    QVERIFY(settings.isNull());
104

105
    // TOTP Settings with blank secret (expected failure)
106
    settings = Totp::parseSettings("30;8", "");
107
    QVERIFY(settings.isNull());
108
}
109

110
void TestTotp::testTotpCode()
111
{
112
    // Test vectors from RFC 6238
113
    // https://tools.ietf.org/html/rfc6238#appendix-B
114
    auto settings = Totp::createSettings("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", Totp::DEFAULT_DIGITS, Totp::DEFAULT_STEP);
115

116
    // Test 6 digit TOTP (default)
117
    quint64 time = 1234567890;
118
    QCOMPARE(Totp::generateTotp(settings, time), QString("005924"));
119

120
    time = 1111111109;
121
    QCOMPARE(Totp::generateTotp(settings, time), QString("081804"));
122

123
    // Test 8 digit TOTP (custom)
124
    settings->digits = 8;
125
    settings->custom = true;
126
    time = 1111111111;
127
    QCOMPARE(Totp::generateTotp(settings, time), QString("14050471"));
128

129
    time = 2000000000;
130
    QCOMPARE(Totp::generateTotp(settings, time), QString("69279037"));
131
}
132

133
void TestTotp::testSteamTotp()
134
{
135
    // OTP URL Parsing
136
    QString secret = "otpauth://totp/"
137
                     "test:test@example.com?secret=63BEDWCQZKTQWPESARIERL5DTTQFCJTK&issuer=Valve&algorithm="
138
                     "SHA1&digits=5&period=30&encoder=steam";
139
    auto settings = Totp::parseSettings(secret);
140

141
    QCOMPARE(settings->key, QString("63BEDWCQZKTQWPESARIERL5DTTQFCJTK"));
142
    QCOMPARE(settings->encoder.shortName, Totp::STEAM_SHORTNAME);
143
    QCOMPARE(settings->format, Totp::StorageFormat::OTPURL);
144
    QCOMPARE(settings->digits, Totp::STEAM_DIGITS);
145
    QCOMPARE(settings->step, 30u);
146

147
    // These time/value pairs were created by running the Steam Guard function of the
148
    // Steam mobile app with a throw-away steam account. The above secret was extracted
149
    // from the Steam app's data for use in testing here.
150
    quint64 time = 1511200518;
151
    QCOMPARE(Totp::generateTotp(settings, time), QString("FR8RV"));
152
    time = 1511200714;
153
    QCOMPARE(Totp::generateTotp(settings, time), QString("9P3VP"));
154
}
155

156
void TestTotp::testEntryHistory()
157
{
158
    Entry entry;
159
    uint step = 16;
160
    uint digits = 6;
161
    auto settings = Totp::createSettings("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", digits, step);
162
    // Test that entry starts without TOTP
163
    QCOMPARE(entry.historyItems().size(), 0);
164
    QVERIFY(!entry.hasTotp());
165
    // Add TOTP to entry
166
    entry.setTotp(settings);
167
    QCOMPARE(entry.historyItems().size(), 1);
168
    QVERIFY(entry.hasTotp());
169
    QCOMPARE(entry.totpSettings()->key, QString("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"));
170
    // Change key and verify settings changed
171
    settings->key = "foo";
172
    entry.setTotp(settings);
173
    QCOMPARE(entry.historyItems().size(), 2);
174
    QCOMPARE(entry.totpSettings()->key, QString("foo"));
175
    // Nullptr Settings (expected reset of TOTP)
176
    entry.setTotp(nullptr);
177
    QVERIFY(!entry.hasTotp());
178
    QCOMPARE(entry.historyItems().size(), 3);
179
}
180

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.