File indexing completed on 2024-04-28 04:44:12

0001 /**
0002  * Copyright (C)  2006  Brad Hards <bradh@frogmouth.net>
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  *
0008  * 1. Redistributions of source code must retain the above copyright
0009  *   notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *   notice, this list of conditions and the following disclaimer in the
0012  *   documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include <QTcpSocket>
0027 #include <QtCrypto>
0028 #include <QtTest/QtTest>
0029 
0030 #ifdef QT_STATICPLUGIN
0031 #include "import_plugins.h"
0032 #endif
0033 
0034 class TlsTest : public QObject
0035 {
0036     Q_OBJECT
0037 public:
0038     TlsTest()
0039     {
0040         sock = new QTcpSocket(this);
0041         connect(sock, &QTcpSocket::connected, this, &TlsTest::sock_connected);
0042         connect(sock, &QTcpSocket::readyRead, this, &TlsTest::sock_readyRead);
0043 
0044         ssl = new QCA::TLS(this);
0045         connect(ssl, &QCA::TLS::handshaken, this, &TlsTest::ssl_handshaken);
0046         connect(ssl, &QCA::TLS::readyReadOutgoing, this, &TlsTest::ssl_readyReadOutgoing);
0047 
0048         sync = new QCA::Synchronizer(this);
0049     }
0050 
0051     ~TlsTest() override
0052     {
0053         delete ssl;
0054         delete sock;
0055     }
0056 
0057     void start(const QString &_host, int port)
0058     {
0059         host = _host;
0060         sock->connectToHost(host, port);
0061     }
0062 
0063     void waitForHandshake(int timeout = 20000)
0064     {
0065         sync->waitForCondition(timeout);
0066     }
0067 
0068     bool isHandshaken()
0069     {
0070         return ssl->isHandshaken();
0071     }
0072 
0073 private Q_SLOTS:
0074     void sock_connected()
0075     {
0076         QCA::CertificateCollection rootCerts;
0077         QCA::ConvertResult         resultRootCert;
0078         QCA::Certificate rootCert = QCA::Certificate::fromPEMFile(QStringLiteral("root.crt"), &resultRootCert);
0079         QCOMPARE(resultRootCert, QCA::ConvertGood);
0080         rootCerts.addCertificate(rootCert);
0081 
0082         ssl->setTrustedCertificates(rootCerts);
0083 
0084         ssl->startClient(host);
0085     }
0086 
0087     void sock_readyRead()
0088     {
0089         ssl->writeIncoming(sock->readAll());
0090     }
0091 
0092     void ssl_handshaken()
0093     {
0094         QCA::TLS::IdentityResult r = ssl->peerIdentityResult();
0095 
0096         QCOMPARE(r, QCA::TLS::Valid);
0097 
0098         sync->conditionMet();
0099     }
0100 
0101     void ssl_readyReadOutgoing()
0102     {
0103         sock->write(ssl->readOutgoing());
0104     }
0105 
0106 private:
0107     QString            host;
0108     QTcpSocket        *sock;
0109     QCA::TLS          *ssl;
0110     QCA::Certificate   cert;
0111     QCA::Synchronizer *sync;
0112 };
0113 
0114 class VeloxUnitTest : public QObject
0115 {
0116     Q_OBJECT
0117 
0118 private Q_SLOTS:
0119     void initTestCase();
0120     void cleanupTestCase();
0121     void sniAlice();
0122     void sniBob();
0123     void sniCarol();
0124     void sniDave();
0125     void sniMallory();
0126     void sniIvan();
0127 
0128 private:
0129     QCA::Initializer          *m_init;
0130     QCA::CertificateCollection rootCerts;
0131 };
0132 
0133 void VeloxUnitTest::initTestCase()
0134 {
0135     m_init = new QCA::Initializer;
0136 }
0137 
0138 void VeloxUnitTest::cleanupTestCase()
0139 {
0140     delete m_init;
0141 }
0142 
0143 void VeloxUnitTest::sniAlice()
0144 {
0145     if (!QCA::isSupported("tls", QStringLiteral("qca-ossl")))
0146         QWARN("TLS not supported for qca-ossl");
0147     else {
0148         TlsTest *s = new TlsTest;
0149         s->start(QStringLiteral("alice.sni.velox.ch"), 443);
0150         s->waitForHandshake();
0151         QVERIFY(s->isHandshaken());
0152     }
0153 }
0154 
0155 void VeloxUnitTest::sniBob()
0156 {
0157     if (!QCA::isSupported("tls", QStringLiteral("qca-ossl")))
0158         QWARN("TLS not supported for qca-ossl");
0159     else {
0160         TlsTest *s = new TlsTest;
0161         s->start(QStringLiteral("bob.sni.velox.ch"), 443);
0162         s->waitForHandshake();
0163         QVERIFY(s->isHandshaken());
0164     }
0165 }
0166 
0167 void VeloxUnitTest::sniCarol()
0168 {
0169     if (!QCA::isSupported("tls", QStringLiteral("qca-ossl")))
0170         QWARN("TLS not supported for qca-ossl");
0171     else {
0172         TlsTest *s = new TlsTest;
0173         s->start(QStringLiteral("carol.sni.velox.ch"), 443);
0174         s->waitForHandshake();
0175         QVERIFY(s->isHandshaken());
0176     }
0177 }
0178 
0179 void VeloxUnitTest::sniDave()
0180 {
0181     if (!QCA::isSupported("tls", QStringLiteral("qca-ossl")))
0182         QWARN("TLS not supported for qca-ossl");
0183     else {
0184         TlsTest *s = new TlsTest;
0185         s->start(QStringLiteral("dave.sni.velox.ch"), 443);
0186         s->waitForHandshake();
0187         QVERIFY(s->isHandshaken());
0188     }
0189 }
0190 
0191 void VeloxUnitTest::sniMallory()
0192 {
0193     if (!QCA::isSupported("tls", QStringLiteral("qca-ossl")))
0194         QWARN("TLS not supported for qca-ossl");
0195     else {
0196         TlsTest *s = new TlsTest;
0197         s->start(QStringLiteral("mallory.sni.velox.ch"), 443);
0198         s->waitForHandshake();
0199         QVERIFY(s->isHandshaken());
0200     }
0201 }
0202 
0203 void VeloxUnitTest::sniIvan()
0204 {
0205     if (!QCA::isSupported("tls", QStringLiteral("qca-ossl")))
0206         QWARN("TLS not supported for qca-ossl");
0207     else {
0208         TlsTest *s = new TlsTest;
0209         s->start(QStringLiteral("ivan.sni.velox.ch"), 443);
0210         s->waitForHandshake();
0211         QVERIFY(s->isHandshaken());
0212     }
0213 }
0214 
0215 QTEST_MAIN(VeloxUnitTest)
0216 
0217 #include "veloxunittest.moc"