1/****************************************************************************
2**
3** Copyright (C) 2014 Jeremy Lainé <jeremy.laine@m4x.org>
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31#include "private/qasn1element_p.h"
32
33class tst_QAsn1Element : public QObject
34{
35 Q_OBJECT
36
37private slots:
38 void emptyConstructor();
39 void equals_data();
40 void equals();
41 void toBool_data();
42 void toBool();
43 void dateTime_data();
44 void dateTime();
45 void integer_data();
46 void integer();
47 void invalid_data();
48 void invalid();
49 void octetString_data();
50 void octetString();
51 void objectIdentifier_data();
52 void objectIdentifier();
53 void string_data();
54 void string();
55};
56
57void tst_QAsn1Element::emptyConstructor()
58{
59 QAsn1Element elem;
60 QCOMPARE(elem.type(), quint8(0));
61 QCOMPARE(elem.value(), QByteArray());
62}
63
64Q_DECLARE_METATYPE(QAsn1Element)
65
66void tst_QAsn1Element::equals_data()
67{
68 QTest::addColumn<QAsn1Element>(name: "a");
69 QTest::addColumn<QAsn1Element>(name: "b");
70 QTest::addColumn<bool>(name: "equals");
71
72 QTest::newRow(dataTag: "equal")
73 << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
74 << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
75 << true;
76 QTest::newRow(dataTag: "different type")
77 << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
78 << QAsn1Element(QAsn1Element::IntegerType, QByteArray("\0", 1))
79 << false;
80 QTest::newRow(dataTag: "different value")
81 << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
82 << QAsn1Element(QAsn1Element::BooleanType, QByteArray("\xff", 1))
83 << false;
84}
85
86void tst_QAsn1Element::equals()
87{
88 QFETCH(QAsn1Element, a);
89 QFETCH(QAsn1Element, b);
90 QFETCH(bool, equals);
91 QCOMPARE(a == b, equals);
92 QCOMPARE(a != b, !equals);
93}
94
95void tst_QAsn1Element::toBool_data()
96{
97 QTest::addColumn<QByteArray>(name: "encoded");
98 QTest::addColumn<bool>(name: "value");
99 QTest::addColumn<bool>(name: "valid");
100
101 QTest::newRow(dataTag: "bad type") << QByteArray::fromHex(hexEncoded: "0201ff") << false << false;
102 QTest::newRow(dataTag: "bad value") << QByteArray::fromHex(hexEncoded: "010102") << false << false;
103 QTest::newRow(dataTag: "false") << QByteArray::fromHex(hexEncoded: "010100") << false << true;
104 QTest::newRow(dataTag: "true") << QByteArray::fromHex(hexEncoded: "0101ff") << true << true;
105}
106
107void tst_QAsn1Element::toBool()
108{
109 QFETCH(QByteArray, encoded);
110 QFETCH(bool, value);
111 QFETCH(bool, valid);
112
113 bool ok;
114 QAsn1Element elem;
115 QVERIFY(elem.read(encoded));
116 QCOMPARE(elem.toBool(&ok), value);
117 QCOMPARE(ok, valid);
118}
119
120void tst_QAsn1Element::dateTime_data()
121{
122 QTest::addColumn<QByteArray>(name: "encoded");
123 QTest::addColumn<QDateTime>(name: "value");
124
125 QTest::newRow(dataTag: "bad type")
126 << QByteArray::fromHex(hexEncoded: "020100")
127 << QDateTime();
128 QTest::newRow(dataTag: "UTCTime - 070417074026Z")
129 << QByteArray::fromHex(hexEncoded: "170d3037303431373037343032365a")
130 << QDateTime(QDate(2007, 4, 17), QTime(7, 40, 26), Qt::UTC);
131 QTest::newRow(dataTag: "UTCTime - bad length")
132 << QByteArray::fromHex(hexEncoded: "170c30373034313730373430325a")
133 << QDateTime();
134 QTest::newRow(dataTag: "UTCTime - no trailing Z")
135 << QByteArray::fromHex(hexEncoded: "170d30373034313730373430323659")
136 << QDateTime();
137 QTest::newRow(dataTag: "UTCTime - year 1950")
138 << QByteArray::fromHex(hexEncoded: "170d3530313232343035353530305a")
139 << QDateTime(QDate(1950, 12, 24), QTime(5, 55), Qt::UTC);
140 QTest::newRow(dataTag: "UTCTime - year 1999")
141 << QByteArray::fromHex(hexEncoded: "170d3939313232343035353530305a")
142 << QDateTime(QDate(1999, 12, 24), QTime(5, 55), Qt::UTC);
143 QTest::newRow(dataTag: "UTCTime - year 2000")
144 << QByteArray::fromHex(hexEncoded: "170d3030313232343035353530305a")
145 << QDateTime(QDate(2000, 12, 24), QTime(5, 55), Qt::UTC);
146 QTest::newRow(dataTag: "UTCTime - year 2049")
147 << QByteArray::fromHex(hexEncoded: "170d3439313232343035353530305a")
148 << QDateTime(QDate(2049, 12, 24), QTime(5, 55), Qt::UTC);
149 QTest::newRow(dataTag: "UTCTime - invalid year ('-9')")
150 << QByteArray::fromHex(hexEncoded: "170d2d39313232343035353530305a")
151 << QDateTime();
152 QTest::newRow(dataTag: "UTCTime - invalid year ('*9')")
153 << QByteArray::fromHex(hexEncoded: "170d2a39313232343035353530305a")
154 << QDateTime();
155 QTest::newRow(dataTag: "UTCTime - invalid year ('5*')")
156 << QByteArray::fromHex(hexEncoded: "170d352a313232343035353530305a")
157 << QDateTime();
158 QTest::newRow(dataTag: "UTCTime - invalid year ('AB')")
159 << QByteArray::fromHex(hexEncoded: "170d4142313232343035353530305a")
160 << QDateTime();
161 QTest::newRow(dataTag: "UTCTime - invalid year ('+1')")
162 << QByteArray::fromHex(hexEncoded: "170d2b31313232343035353530305a")
163 << QDateTime();
164 QTest::newRow(dataTag: "GeneralizedTime - 20510829095341Z")
165 << QByteArray::fromHex(hexEncoded: "180f32303531303832393039353334315a")
166 << QDateTime(QDate(2051, 8, 29), QTime(9, 53, 41), Qt::UTC);
167 QTest::newRow(dataTag: "GeneralizedTime - bad length")
168 << QByteArray::fromHex(hexEncoded: "180e323035313038323930393533345a")
169 << QDateTime();
170 QTest::newRow(dataTag: "GeneralizedTime - no trailing Z")
171 << QByteArray::fromHex(hexEncoded: "180f323035313038323930393533343159")
172 << QDateTime();
173}
174
175void tst_QAsn1Element::dateTime()
176{
177 QFETCH(QByteArray, encoded);
178 QFETCH(QDateTime, value);
179
180 QAsn1Element elem;
181 QVERIFY(elem.read(encoded));
182 QCOMPARE(elem.toDateTime(), value);
183}
184
185void tst_QAsn1Element::integer_data()
186{
187 QTest::addColumn<QByteArray>(name: "encoded");
188 QTest::addColumn<int>(name: "value");
189
190 QTest::newRow(dataTag: "0") << QByteArray::fromHex(hexEncoded: "020100") << 0;
191 QTest::newRow(dataTag: "127") << QByteArray::fromHex(hexEncoded: "02017F") << 127;
192 QTest::newRow(dataTag: "128") << QByteArray::fromHex(hexEncoded: "02020080") << 128;
193 QTest::newRow(dataTag: "256") << QByteArray::fromHex(hexEncoded: "02020100") << 256;
194}
195
196void tst_QAsn1Element::integer()
197{
198 QFETCH(QByteArray, encoded);
199 QFETCH(int, value);
200
201 // read
202 bool ok;
203 QAsn1Element elem;
204 QVERIFY(elem.read(encoded));
205 QCOMPARE(elem.type(), quint8(QAsn1Element::IntegerType));
206 QCOMPARE(elem.toInteger(&ok), value);
207 QVERIFY(ok);
208
209 // write
210 QByteArray buffer;
211 QDataStream stream(&buffer, QIODevice::WriteOnly);
212 QAsn1Element::fromInteger(val: value).write(data&: stream);
213 QCOMPARE(buffer, encoded);
214}
215
216void tst_QAsn1Element::invalid_data()
217{
218 QTest::addColumn<QByteArray>(name: "encoded");
219
220 QTest::newRow(dataTag: "empty") << QByteArray();
221 QTest::newRow(dataTag: "bad type") << QByteArray::fromHex(hexEncoded: "000100");
222 QTest::newRow(dataTag: "truncated value") << QByteArray::fromHex(hexEncoded: "0401");
223}
224
225void tst_QAsn1Element::invalid()
226{
227 QFETCH(QByteArray, encoded);
228
229 QAsn1Element elem;
230 QVERIFY(!elem.read(encoded));
231}
232
233void tst_QAsn1Element::octetString_data()
234{
235 QTest::addColumn<QByteArray>(name: "encoded");
236 QTest::addColumn<QByteArray>(name: "value");
237
238 QTest::newRow(dataTag: "0 byte") << QByteArray::fromHex(hexEncoded: "0400") << QByteArray();
239 QTest::newRow(dataTag: "1 byte") << QByteArray::fromHex(hexEncoded: "040100") << QByteArray(1, '\0');
240 QTest::newRow(dataTag: "127 bytes") << QByteArray::fromHex(hexEncoded: "047f") + QByteArray(127, '\0') << QByteArray(127, '\0');
241 QTest::newRow(dataTag: "128 bytes") << QByteArray::fromHex(hexEncoded: "048180") + QByteArray(128, '\0') << QByteArray(128, '\0');
242}
243
244void tst_QAsn1Element::octetString()
245{
246 QFETCH(QByteArray, encoded);
247 QFETCH(QByteArray, value);
248
249 // read
250 QAsn1Element elem;
251 QVERIFY(elem.read(encoded));
252 QCOMPARE(elem.type(), quint8(QAsn1Element::OctetStringType));
253 QCOMPARE(elem.value(), value);
254
255 // write
256 QByteArray buffer;
257 QDataStream stream(&buffer, QIODevice::WriteOnly);
258 elem.write(data&: stream);
259 QCOMPARE(buffer, encoded);
260}
261
262void tst_QAsn1Element::objectIdentifier_data()
263{
264 QTest::addColumn<QByteArray>(name: "encoded");
265 QTest::addColumn<QByteArray>(name: "oid");
266 QTest::addColumn<QByteArray>(name: "name");
267
268 QTest::newRow(dataTag: "1.2.3.4")
269 << QByteArray::fromHex(hexEncoded: "06032a0304")
270 << QByteArray("1.2.3.4")
271 << QByteArray("1.2.3.4");
272 QTest::newRow(dataTag: "favouriteDrink")
273 << QByteArray::fromHex(hexEncoded: "060a0992268993f22c640105")
274 << QByteArray("0.9.2342.19200300.100.1.5")
275 << QByteArray("favouriteDrink");
276}
277
278void tst_QAsn1Element::objectIdentifier()
279{
280 QFETCH(QByteArray, encoded);
281 QFETCH(QByteArray, oid);
282 QFETCH(QByteArray, name);
283
284 QAsn1Element elem;
285 QVERIFY(elem.read(encoded));
286 QCOMPARE(elem.type(), quint8(QAsn1Element::ObjectIdentifierType));
287 QCOMPARE(elem.toObjectId(), oid);
288 QCOMPARE(QAsn1Element::fromObjectId(oid).toObjectId(), oid);
289 QCOMPARE(elem.toObjectName(), name);
290}
291
292void tst_QAsn1Element::string_data()
293{
294 QTest::addColumn<QAsn1Element>(name: "element");
295 QTest::addColumn<QString>(name: "value");
296
297 QTest::newRow(dataTag: "printablestring")
298 << QAsn1Element(QAsn1Element::PrintableStringType, QByteArray("Hello World"))
299 << QStringLiteral("Hello World");
300 QTest::newRow(dataTag: "teletextstring")
301 << QAsn1Element(QAsn1Element::TeletexStringType, QByteArray("Hello World"))
302 << QStringLiteral("Hello World");
303 QTest::newRow(dataTag: "utf8string")
304 << QAsn1Element(QAsn1Element::Utf8StringType, QByteArray("Hello World"))
305 << QStringLiteral("Hello World");
306 QTest::newRow(dataTag: "rfc822name")
307 << QAsn1Element(QAsn1Element::Rfc822NameType, QByteArray("Hello World"))
308 << QStringLiteral("Hello World");
309 QTest::newRow(dataTag: "dnsname")
310 << QAsn1Element(QAsn1Element::DnsNameType, QByteArray("Hello World"))
311 << QStringLiteral("Hello World");
312 QTest::newRow(dataTag: "uri")
313 << QAsn1Element(QAsn1Element::UniformResourceIdentifierType, QByteArray("Hello World"))
314 << QStringLiteral("Hello World");
315
316 // Embedded NULs are not allowed and should be rejected
317 QTest::newRow(dataTag: "evil_printablestring")
318 << QAsn1Element(QAsn1Element::PrintableStringType, QByteArray("Hello\0World", 11))
319 << QString();
320 QTest::newRow(dataTag: "evil_teletextstring")
321 << QAsn1Element(QAsn1Element::TeletexStringType, QByteArray("Hello\0World", 11))
322 << QString();
323 QTest::newRow(dataTag: "evil_utf8string")
324 << QAsn1Element(QAsn1Element::Utf8StringType, QByteArray("Hello\0World", 11))
325 << QString();
326 QTest::newRow(dataTag: "evil_rfc822name")
327 << QAsn1Element(QAsn1Element::Rfc822NameType, QByteArray("Hello\0World", 11))
328 << QString();
329 QTest::newRow(dataTag: "evil_dnsname")
330 << QAsn1Element(QAsn1Element::DnsNameType, QByteArray("Hello\0World", 11))
331 << QString();
332 QTest::newRow(dataTag: "evil_uri")
333 << QAsn1Element(QAsn1Element::UniformResourceIdentifierType, QByteArray("Hello\0World", 11))
334 << QString();
335}
336
337void tst_QAsn1Element::string()
338{
339 QFETCH(QAsn1Element, element);
340 QFETCH(QString, value);
341
342 QCOMPARE(element.toString(), value);
343}
344
345QTEST_MAIN(tst_QAsn1Element)
346#include "tst_qasn1element.moc"
347

source code of qtbase/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp