1/**
2 * Copyright (C) 2006 Brad Hards <bradh@frogmouth.net>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <QTcpSocket>
27#include <QtCrypto>
28#include <QtTest/QtTest>
29
30#ifdef QT_STATICPLUGIN
31#include "import_plugins.h"
32#endif
33
34class TlsTest : public QObject
35{
36 Q_OBJECT
37public:
38 TlsTest()
39 {
40 sock = new QTcpSocket(this);
41 connect(sender: sock, signal: &QTcpSocket::connected, context: this, slot: &TlsTest::sock_connected);
42 connect(sender: sock, signal: &QTcpSocket::readyRead, context: this, slot: &TlsTest::sock_readyRead);
43
44 ssl = new QCA::TLS(this);
45 connect(sender: ssl, signal: &QCA::TLS::handshaken, context: this, slot: &TlsTest::ssl_handshaken);
46 connect(sender: ssl, signal: &QCA::TLS::readyReadOutgoing, context: this, slot: &TlsTest::ssl_readyReadOutgoing);
47
48 sync = new QCA::Synchronizer(this);
49 }
50
51 ~TlsTest() override
52 {
53 delete ssl;
54 delete sock;
55 }
56
57 void start(const QString &_host, int port)
58 {
59 host = _host;
60 sock->connectToHost(hostName: host, port);
61 }
62
63 void waitForHandshake(int timeout = 20000)
64 {
65 sync->waitForCondition(msecs: timeout);
66 }
67
68 bool isHandshaken()
69 {
70 return ssl->isHandshaken();
71 }
72
73private Q_SLOTS:
74 void sock_connected()
75 {
76 QCA::CertificateCollection rootCerts;
77 QCA::ConvertResult resultRootCert;
78 QCA::Certificate rootCert = QCA::Certificate::fromPEMFile(QStringLiteral("root.crt"), result: &resultRootCert);
79 QCOMPARE(resultRootCert, QCA::ConvertGood);
80 rootCerts.addCertificate(cert: rootCert);
81
82 ssl->setTrustedCertificates(rootCerts);
83
84 ssl->startClient(host);
85 }
86
87 void sock_readyRead()
88 {
89 ssl->writeIncoming(a: sock->readAll());
90 }
91
92 void ssl_handshaken()
93 {
94 QCA::TLS::IdentityResult r = ssl->peerIdentityResult();
95
96 QCOMPARE(r, QCA::TLS::Valid);
97
98 sync->conditionMet();
99 }
100
101 void ssl_readyReadOutgoing()
102 {
103 sock->write(data: ssl->readOutgoing());
104 }
105
106private:
107 QString host;
108 QTcpSocket *sock;
109 QCA::TLS *ssl;
110 QCA::Certificate cert;
111 QCA::Synchronizer *sync;
112};
113
114class VeloxUnitTest : public QObject
115{
116 Q_OBJECT
117
118private Q_SLOTS:
119 void initTestCase();
120 void cleanupTestCase();
121 void sniAlice();
122 void sniBob();
123 void sniCarol();
124 void sniDave();
125 void sniMallory();
126 void sniIvan();
127
128private:
129 QCA::Initializer *m_init;
130 QCA::CertificateCollection rootCerts;
131};
132
133void VeloxUnitTest::initTestCase()
134{
135 m_init = new QCA::Initializer;
136}
137
138void VeloxUnitTest::cleanupTestCase()
139{
140 delete m_init;
141}
142
143void VeloxUnitTest::sniAlice()
144{
145 if (!QCA::isSupported(features: "tls", QStringLiteral("qca-ossl")))
146 QWARN("TLS not supported for qca-ossl");
147 else {
148 TlsTest *s = new TlsTest;
149 s->start(QStringLiteral("alice.sni.velox.ch"), port: 443);
150 s->waitForHandshake();
151 QVERIFY(s->isHandshaken());
152 }
153}
154
155void VeloxUnitTest::sniBob()
156{
157 if (!QCA::isSupported(features: "tls", QStringLiteral("qca-ossl")))
158 QWARN("TLS not supported for qca-ossl");
159 else {
160 TlsTest *s = new TlsTest;
161 s->start(QStringLiteral("bob.sni.velox.ch"), port: 443);
162 s->waitForHandshake();
163 QVERIFY(s->isHandshaken());
164 }
165}
166
167void VeloxUnitTest::sniCarol()
168{
169 if (!QCA::isSupported(features: "tls", QStringLiteral("qca-ossl")))
170 QWARN("TLS not supported for qca-ossl");
171 else {
172 TlsTest *s = new TlsTest;
173 s->start(QStringLiteral("carol.sni.velox.ch"), port: 443);
174 s->waitForHandshake();
175 QVERIFY(s->isHandshaken());
176 }
177}
178
179void VeloxUnitTest::sniDave()
180{
181 if (!QCA::isSupported(features: "tls", QStringLiteral("qca-ossl")))
182 QWARN("TLS not supported for qca-ossl");
183 else {
184 TlsTest *s = new TlsTest;
185 s->start(QStringLiteral("dave.sni.velox.ch"), port: 443);
186 s->waitForHandshake();
187 QVERIFY(s->isHandshaken());
188 }
189}
190
191void VeloxUnitTest::sniMallory()
192{
193 if (!QCA::isSupported(features: "tls", QStringLiteral("qca-ossl")))
194 QWARN("TLS not supported for qca-ossl");
195 else {
196 TlsTest *s = new TlsTest;
197 s->start(QStringLiteral("mallory.sni.velox.ch"), port: 443);
198 s->waitForHandshake();
199 QVERIFY(s->isHandshaken());
200 }
201}
202
203void VeloxUnitTest::sniIvan()
204{
205 if (!QCA::isSupported(features: "tls", QStringLiteral("qca-ossl")))
206 QWARN("TLS not supported for qca-ossl");
207 else {
208 TlsTest *s = new TlsTest;
209 s->start(QStringLiteral("ivan.sni.velox.ch"), port: 443);
210 s->waitForHandshake();
211 QVERIFY(s->isHandshaken());
212 }
213}
214
215QTEST_MAIN(VeloxUnitTest)
216
217#include "veloxunittest.moc"
218

source code of qca/unittest/velox/veloxunittest.cpp