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"