1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtCore/qthread.h>
44 #include <QtNetwork/qhostaddress.h>
45 #include <QtNetwork/qhostinfo.h>
46 #include <QtNetwork/qnetworkproxy.h>
47 #include <QtNetwork/qsslcipher.h>
48 #include <QtNetwork/qsslconfiguration.h>
49 #include <QtNetwork/qsslkey.h>
50 #include <QtNetwork/qsslsocket.h>
51 #include <QtNetwork/qtcpserver.h>
52 #include <QtTest/QtTest>
54 #include <QNetworkProxy>
55 #include <QAuthenticator>
57 #include "private/qhostinfo_p.h"
58 #include "private/qsslsocket_openssl_p.h"
60 #include "../network-settings.h"
62 Q_DECLARE_METATYPE(QAbstractSocket::SocketState)
63 Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
65 Q_DECLARE_METATYPE(QSslSocket::SslMode)
66 typedef QList<QSslError::SslError> SslErrorList;
67 Q_DECLARE_METATYPE(SslErrorList)
68 Q_DECLARE_METATYPE(QSslError)
69 Q_DECLARE_METATYPE(QSsl::SslProtocol)
70 Q_DECLARE_METATYPE(QSslConfiguration)
73 #if defined Q_OS_HPUX && defined Q_CC_GNU
74 // This error is delivered every time we try to use the fluke CA
75 // certificate. For now we work around this bug. Task 202317.
76 #define QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
84 class QSslSocketPtr: public QSharedPointer<QSslSocket>
87 inline QSslSocketPtr(QSslSocket *ptr = 0)
88 : QSharedPointer<QSslSocket>(ptr)
91 inline operator QSslSocket *() const { return data(); }
95 class tst_QSslSocket : public QObject
103 virtual ~tst_QSslSocket();
105 static void enterLoop(int secs)
108 QTestEventLoop::instance().enterLoop(secs);
111 static bool timeout()
113 return QTestEventLoop::instance().timeout();
116 #ifndef QT_NO_OPENSSL
117 QSslSocketPtr newSocket();
121 void initTestCase_data();
124 void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
126 #ifndef QT_NO_OPENSSL
129 void simpleConnect();
130 void simpleConnectWithIgnore();
133 void sslErrors_data();
135 void addCaCertificate();
136 void addCaCertificates();
137 void addCaCertificates2();
139 void connectToHostEncrypted();
140 void connectToHostEncryptedWithVerificationPeerName();
141 void sessionCipher();
144 void localCertificate();
146 void peerCertificate();
147 void peerCertificateChain();
150 void protocolServerSide_data();
151 void protocolServerSide();
152 void setCaCertificates();
153 void setLocalCertificate();
154 void setPrivateKey();
155 void setSocketDescriptor();
156 void setSslConfiguration_data();
157 void setSslConfiguration();
158 void waitForEncrypted();
159 void waitForEncryptedMinusOne();
160 void waitForConnectedEncryptedReadyRead();
161 void startClientEncryption();
162 void startServerEncryption();
163 void addDefaultCaCertificate();
164 void addDefaultCaCertificates();
165 void addDefaultCaCertificates2();
166 void defaultCaCertificates();
167 void defaultCiphers();
168 void resetDefaultCiphers();
169 void setDefaultCaCertificates();
170 void setDefaultCiphers();
171 void supportedCiphers();
172 void systemCaCertificates();
173 void wildcardCertificateNames();
176 void spontaneousWrite();
177 void setReadBufferSize();
178 void setReadBufferSize_task_250027();
179 void waitForMinusOne();
182 void peerVerifyError();
183 void disconnectFromHostWhenConnecting();
184 void disconnectFromHostWhenConnected();
186 void ignoreSslErrorsList_data();
187 void ignoreSslErrorsList();
188 void ignoreSslErrorsListWithSlot_data();
189 void ignoreSslErrorsListWithSlot();
190 void readFromClosedSocket();
191 void writeBigChunk();
192 void blacklistedCertificates();
193 void setEmptyDefaultConfiguration();
195 static void exitLoop()
197 // Safe exit - if we aren't in an event loop, don't
201 QTestEventLoop::instance().exitLoop();
206 void ignoreErrorSlot()
208 socket->ignoreSslErrors();
210 void untrustedWorkaroundSlot(const QList<QSslError> &errors)
212 if (errors.size() == 1 &&
213 (errors.first().error() == QSslError::CertificateUntrusted ||
214 errors.first().error() == QSslError::SelfSignedCertificate))
215 socket->ignoreSslErrors();
217 void ignoreErrorListSlot(const QList<QSslError> &errors);
221 QList<QSslError> storedExpectedSslErrors;
222 #endif // QT_NO_OPENSSL
224 static int loopLevel;
227 int tst_QSslSocket::loopLevel = 0;
229 tst_QSslSocket::tst_QSslSocket()
231 #ifndef QT_NO_OPENSSL
232 qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
233 qRegisterMetaType<QSslError>("QSslError");
234 qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
235 qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
236 qRegisterMetaType<QAbstractSocket::SocketState>("QSslSocket::SslMode");
241 tst_QSslSocket::~tst_QSslSocket()
257 void tst_QSslSocket::initTestCase_data()
259 QTest::addColumn<bool>("setProxy");
260 QTest::addColumn<int>("proxyType");
262 QTest::newRow("WithoutProxy") << false << 0;
263 QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy);
264 QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic);
266 QTest::newRow("WithHttpProxy") << true << int(HttpProxy);
267 QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic);
268 // uncomment the line below when NTLM works
269 // QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm);
272 void tst_QSslSocket::init()
274 QFETCH_GLOBAL(bool, setProxy);
276 QFETCH_GLOBAL(int, proxyType);
277 QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
282 proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080);
285 case Socks5Proxy | AuthBasic:
286 proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081);
289 case HttpProxy | NoAuth:
290 proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128);
293 case HttpProxy | AuthBasic:
294 proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129);
297 case HttpProxy | AuthNtlm:
298 proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130);
301 QNetworkProxy::setApplicationProxy(proxy);
304 qt_qhostinfo_clear_cache();
307 void tst_QSslSocket::cleanup()
309 QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
312 #ifndef QT_NO_OPENSSL
313 QSslSocketPtr tst_QSslSocket::newSocket()
315 QSslSocket *socket = new QSslSocket;
318 connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
319 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
320 Qt::DirectConnection);
322 return QSslSocketPtr(socket);
326 void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
329 auth->setUser("qsockstest");
330 auth->setPassword("password");
333 #ifndef QT_NO_OPENSSL
335 void tst_QSslSocket::constructing()
337 if (!QSslSocket::supportsSsl())
342 QCOMPARE(socket.state(), QSslSocket::UnconnectedState);
343 QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
344 QVERIFY(!socket.isEncrypted());
345 QCOMPARE(socket.bytesAvailable(), qint64(0));
346 QCOMPARE(socket.bytesToWrite(), qint64(0));
347 QVERIFY(!socket.canReadLine());
348 QVERIFY(socket.atEnd());
349 QCOMPARE(socket.localCertificate(), QSslCertificate());
350 QCOMPARE(socket.sslConfiguration(), QSslConfiguration::defaultConfiguration());
351 QCOMPARE(socket.errorString(), QString("Unknown error"));
353 QVERIFY(!socket.getChar(&c));
355 QVERIFY(!socket.isOpen());
356 QVERIFY(!socket.isReadable());
357 QVERIFY(socket.isSequential());
358 QVERIFY(!socket.isTextModeEnabled());
359 QVERIFY(!socket.isWritable());
360 QCOMPARE(socket.openMode(), QIODevice::NotOpen);
361 QVERIFY(socket.peek(2).isEmpty());
362 QCOMPARE(socket.pos(), qint64(0));
363 QVERIFY(!socket.putChar('c'));
364 QVERIFY(socket.read(2).isEmpty());
365 QCOMPARE(socket.read(0, 0), qint64(-1));
366 QVERIFY(socket.readAll().isEmpty());
367 QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2");
368 QCOMPARE(socket.readLine(0, 0), qint64(-1));
370 QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1));
371 QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: The device is not open");
372 QVERIFY(!socket.reset());
373 QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: The device is not open");
374 QVERIFY(!socket.seek(2));
375 QCOMPARE(socket.size(), qint64(0));
376 QVERIFY(!socket.waitForBytesWritten(10));
377 QVERIFY(!socket.waitForReadyRead(10));
378 QCOMPARE(socket.write(0, 0), qint64(-1));
379 QCOMPARE(socket.write(QByteArray()), qint64(-1));
380 QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
381 QVERIFY(!socket.flush());
382 QVERIFY(!socket.isValid());
383 QCOMPARE(socket.localAddress(), QHostAddress());
384 QCOMPARE(socket.localPort(), quint16(0));
385 QCOMPARE(socket.peerAddress(), QHostAddress());
386 QVERIFY(socket.peerName().isEmpty());
387 QCOMPARE(socket.peerPort(), quint16(0));
388 QCOMPARE(socket.proxy().type(), QNetworkProxy::DefaultProxy);
389 QCOMPARE(socket.readBufferSize(), qint64(0));
390 QCOMPARE(socket.socketDescriptor(), -1);
391 QCOMPARE(socket.socketType(), QAbstractSocket::TcpSocket);
392 QVERIFY(!socket.waitForConnected(10));
393 QTest::ignoreMessage(QtWarningMsg, "QSslSocket::waitForDisconnected() is not allowed in UnconnectedState");
394 QVERIFY(!socket.waitForDisconnected(10));
395 QCOMPARE(socket.protocol(), QSsl::SecureProtocols);
397 QSslConfiguration savedDefault = QSslConfiguration::defaultConfiguration();
399 // verify that changing the default config doesn't affect this socket
400 // (on Unix, the ca certs might be empty, depending on whether we load
401 // them on demand or not, so set them explicitly)
402 socket.setCaCertificates(QSslSocket::systemCaCertificates());
403 QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
404 QSslSocket::setDefaultCiphers(QList<QSslCipher>());
405 QVERIFY(!socket.caCertificates().isEmpty());
406 QVERIFY(!socket.ciphers().isEmpty());
408 // verify the default as well:
409 QVERIFY(QSslConfiguration::defaultConfiguration().caCertificates().isEmpty());
410 QVERIFY(QSslConfiguration::defaultConfiguration().ciphers().isEmpty());
412 QSslConfiguration::setDefaultConfiguration(savedDefault);
415 void tst_QSslSocket::simpleConnect()
417 if (!QSslSocket::supportsSsl())
420 QFETCH_GLOBAL(bool, setProxy);
425 QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
426 QSignalSpy hostFoundSpy(&socket, SIGNAL(hostFound()));
427 QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected()));
428 QSignalSpy connectionEncryptedSpy(&socket, SIGNAL(encrypted()));
429 QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(const QList<QSslError> &)));
431 connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
432 connect(&socket, SIGNAL(disconnected()), this, SLOT(exitLoop()));
433 connect(&socket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(exitLoop()));
434 connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
435 connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(exitLoop()));
436 connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(exitLoop()));
439 socket.connectToHost(QtNetworkSettings::serverName(), 993);
440 QCOMPARE(socket.state(), QAbstractSocket::HostLookupState);
443 // Entered connecting state
445 QCOMPARE(socket.state(), QAbstractSocket::ConnectingState);
446 QCOMPARE(connectedSpy.count(), 0);
448 QCOMPARE(hostFoundSpy.count(), 1);
449 QCOMPARE(disconnectedSpy.count(), 0);
452 // Entered connected state
453 QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
454 QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
455 QVERIFY(!socket.isEncrypted());
456 QCOMPARE(connectedSpy.count(), 1);
457 QCOMPARE(hostFoundSpy.count(), 1);
458 QCOMPARE(disconnectedSpy.count(), 0);
460 // Enter encrypted mode
461 socket.startClientEncryption();
462 QCOMPARE(socket.mode(), QSslSocket::SslClientMode);
463 QVERIFY(!socket.isEncrypted());
464 QCOMPARE(connectionEncryptedSpy.count(), 0);
465 QCOMPARE(sslErrorsSpy.count(), 0);
467 // Starting handshake
469 QCOMPARE(sslErrorsSpy.count(), 1);
470 QCOMPARE(connectionEncryptedSpy.count(), 0);
471 QVERIFY(!socket.isEncrypted());
472 QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
475 void tst_QSslSocket::simpleConnectWithIgnore()
477 if (!QSslSocket::supportsSsl())
480 QFETCH_GLOBAL(bool, setProxy);
485 this->socket = &socket;
486 QSignalSpy encryptedSpy(&socket, SIGNAL(encrypted()));
487 QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(const QList<QSslError> &)));
489 connect(&socket, SIGNAL(readyRead()), this, SLOT(exitLoop()));
490 connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
491 connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
492 connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
493 connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(exitLoop()));
496 socket.connectToHost(QtNetworkSettings::serverName(), 993);
497 QVERIFY(socket.state() != QAbstractSocket::UnconnectedState); // something must be in progress
501 QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
502 socket.startClientEncryption();
505 // Done; encryption should be enabled.
506 QCOMPARE(sslErrorsSpy.count(), 1);
507 QVERIFY(socket.isEncrypted());
508 QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
509 QCOMPARE(encryptedSpy.count(), 1);
511 // Wait for incoming data
512 if (!socket.canReadLine())
515 QByteArray data = socket.readAll();
516 socket.disconnectFromHost();
517 QVERIFY2(QtNetworkSettings::compareReplyIMAPSSL(data), data.constData());
520 void tst_QSslSocket::sslErrors_data()
522 QTest::addColumn<QString>("host");
523 QTest::addColumn<int>("port");
524 QTest::addColumn<SslErrorList>("expected");
526 QTest::newRow(qPrintable(QtNetworkSettings::serverLocalName()))
527 << QtNetworkSettings::serverLocalName()
529 << (SslErrorList() << QSslError::HostNameMismatch
530 << QSslError::SelfSignedCertificate);
533 void tst_QSslSocket::sslErrors()
535 QFETCH(QString, host);
537 QFETCH(SslErrorList, expected);
539 QSslSocketPtr socket = newSocket();
540 socket->connectToHostEncrypted(host, port);
541 if (!socket->waitForConnected())
542 QEXPECT_FAIL("imap.trolltech.com", "server not open to internet", Continue);
543 socket->waitForEncrypted(5000);
546 foreach (QSslError error, socket->sslErrors()) {
547 output << error.error();
550 #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
551 if (output.count() && output.last() == QSslError::CertificateUntrusted)
554 QCOMPARE(output, expected);
557 void tst_QSslSocket::addCaCertificate()
559 if (!QSslSocket::supportsSsl())
563 void tst_QSslSocket::addCaCertificates()
565 if (!QSslSocket::supportsSsl())
569 void tst_QSslSocket::addCaCertificates2()
571 if (!QSslSocket::supportsSsl())
575 void tst_QSslSocket::ciphers()
577 if (!QSslSocket::supportsSsl())
581 QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
582 socket.setCiphers(QList<QSslCipher>());
583 QVERIFY(socket.ciphers().isEmpty());
584 socket.setCiphers(socket.defaultCiphers());
585 QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
586 socket.setCiphers(socket.defaultCiphers());
587 QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
590 socket.setCiphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
593 void tst_QSslSocket::connectToHostEncrypted()
595 if (!QSslSocket::supportsSsl())
598 QSslSocketPtr socket = newSocket();
599 this->socket = socket;
600 QVERIFY(socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")));
601 #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
602 connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
603 this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
606 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
608 // This should pass unconditionally when using fluke's CA certificate.
609 // or use untrusted certificate workaround
610 QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
612 socket->disconnectFromHost();
613 QVERIFY(socket->waitForDisconnected());
615 QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
617 socket->connectToHost(QtNetworkSettings::serverName(), 13);
619 QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
621 QVERIFY(socket->waitForDisconnected());
624 void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName()
626 if (!QSslSocket::supportsSsl())
629 QSslSocketPtr socket = newSocket();
630 this->socket = socket;
632 socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
633 #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
634 connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
635 this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
638 // connect to the server with its local name, but use the full name for verification.
639 socket->connectToHostEncrypted(QtNetworkSettings::serverLocalName(), 443, QtNetworkSettings::serverName());
641 // This should pass unconditionally when using fluke's CA certificate.
642 QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
644 socket->disconnectFromHost();
645 QVERIFY(socket->waitForDisconnected());
647 QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
650 void tst_QSslSocket::sessionCipher()
652 if (!QSslSocket::supportsSsl())
655 QSslSocketPtr socket = newSocket();
656 this->socket = socket;
657 connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
658 QVERIFY(socket->sessionCipher().isNull());
659 socket->connectToHost(QtNetworkSettings::serverName(), 443 /* https */);
660 QVERIFY(socket->waitForConnected(10000));
661 QVERIFY(socket->sessionCipher().isNull());
662 socket->startClientEncryption();
663 QVERIFY(socket->waitForEncrypted(5000));
664 QVERIFY(!socket->sessionCipher().isNull());
665 QVERIFY(QSslSocket::supportedCiphers().contains(socket->sessionCipher()));
666 socket->disconnectFromHost();
667 QVERIFY(socket->waitForDisconnected());
670 void tst_QSslSocket::flush()
674 void tst_QSslSocket::isEncrypted()
678 void tst_QSslSocket::localCertificate()
680 if (!QSslSocket::supportsSsl())
683 // This test does not make 100% sense yet. We just set some local CA/cert/key and use it
684 // to authenticate ourselves against the server. The server does not actually check this
685 // values. This test should just run the codepath inside qsslsocket_openssl.cpp
687 QSslSocketPtr socket = newSocket();
688 QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
689 socket->setCaCertificates(localCert);
690 socket->setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
691 socket->setPrivateKey(QLatin1String(SRCDIR "certs/fluke.key"));
693 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
694 QVERIFY(socket->waitForEncrypted(10000));
697 void tst_QSslSocket::mode()
701 void tst_QSslSocket::peerCertificate()
705 void tst_QSslSocket::peerCertificateChain()
707 if (!QSslSocket::supportsSsl())
710 QSslSocketPtr socket = newSocket();
711 this->socket = socket;
713 QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
714 QVERIFY(caCertificates.count() == 1);
715 socket->addCaCertificates(caCertificates);
716 #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
717 connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
718 this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
721 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
722 QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
723 QVERIFY(socket->peerCertificateChain().isEmpty());
724 QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
726 QList<QSslCertificate> certChain = socket->peerCertificateChain();
727 QVERIFY(certChain.count() > 0);
728 QCOMPARE(certChain.first(), socket->peerCertificate());
730 socket->disconnectFromHost();
731 QVERIFY(socket->waitForDisconnected());
733 // connect again to a different server
734 socket->connectToHostEncrypted("trolltech.com", 443);
735 socket->ignoreSslErrors();
736 QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
737 QVERIFY(socket->peerCertificateChain().isEmpty());
738 QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
740 QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate());
741 QVERIFY(socket->peerCertificateChain() != certChain);
743 socket->disconnectFromHost();
744 QVERIFY(socket->waitForDisconnected());
746 // now do it again back to the original server
747 socket->connectToHost(QtNetworkSettings::serverName(), 443);
748 QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
749 QVERIFY(socket->peerCertificateChain().isEmpty());
750 QVERIFY2(socket->waitForConnected(10000), "Network timeout");
752 socket->startClientEncryption();
753 QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
755 QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate());
756 QVERIFY(socket->peerCertificateChain() == certChain);
758 socket->disconnectFromHost();
759 QVERIFY(socket->waitForDisconnected());
762 void tst_QSslSocket::privateKey()
766 void tst_QSslSocket::protocol()
768 if (!QSslSocket::supportsSsl())
771 QSslSocketPtr socket = newSocket();
772 this->socket = socket;
773 QList<QSslCertificate> certs = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
775 socket->setCaCertificates(certs);
776 #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
777 connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
778 this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
781 QCOMPARE(socket->protocol(), QSsl::SecureProtocols);
783 // Fluke allows SSLv3.
784 socket->setProtocol(QSsl::SslV3);
785 QCOMPARE(socket->protocol(), QSsl::SslV3);
786 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
787 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
788 QCOMPARE(socket->protocol(), QSsl::SslV3);
790 QCOMPARE(socket->protocol(), QSsl::SslV3);
791 socket->connectToHost(QtNetworkSettings::serverName(), 443);
792 QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
793 socket->startClientEncryption();
794 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
795 QCOMPARE(socket->protocol(), QSsl::SslV3);
799 // Fluke allows TLSV1.
800 socket->setProtocol(QSsl::TlsV1);
801 QCOMPARE(socket->protocol(), QSsl::TlsV1);
802 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
803 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
804 QCOMPARE(socket->protocol(), QSsl::TlsV1);
806 QCOMPARE(socket->protocol(), QSsl::TlsV1);
807 socket->connectToHost(QtNetworkSettings::serverName(), 443);
808 QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
809 socket->startClientEncryption();
810 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
811 QCOMPARE(socket->protocol(), QSsl::TlsV1);
815 // Fluke allows SSLV2.
816 socket->setProtocol(QSsl::SslV2);
817 QCOMPARE(socket->protocol(), QSsl::SslV2);
818 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
819 QVERIFY(socket->waitForEncrypted());
820 QCOMPARE(socket->protocol(), QSsl::SslV2);
822 QCOMPARE(socket->protocol(), QSsl::SslV2);
823 socket->connectToHost(QtNetworkSettings::serverName(), 443);
824 QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
825 socket->startClientEncryption();
826 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
830 // Fluke allows SSLV3, so it allows AnyProtocol.
831 socket->setProtocol(QSsl::AnyProtocol);
832 QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
833 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
834 QVERIFY(socket->waitForEncrypted());
835 QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
837 QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
838 socket->connectToHost(QtNetworkSettings::serverName(), 443);
839 QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
840 socket->startClientEncryption();
841 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
842 QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
846 // Fluke allows SSLV3, so it allows NoSslV2
847 socket->setProtocol(QSsl::TlsV1SslV3);
848 QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
849 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
850 QVERIFY(socket->waitForEncrypted());
851 QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
853 QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
854 socket->connectToHost(QtNetworkSettings::serverName(), 443);
855 QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
856 socket->startClientEncryption();
857 QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
858 QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
863 class SslServer : public QTcpServer
867 SslServer(const QString &keyFile = SRCDIR "certs/fluke.key", const QString &certFile = SRCDIR "certs/fluke.cert")
869 protocol(QSsl::TlsV1),
871 m_certFile(certFile) { }
873 QSsl::SslProtocol protocol;
878 void incomingConnection(int socketDescriptor)
880 socket = new QSslSocket(this);
881 socket->setProtocol(protocol);
882 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
884 QFile file(m_keyFile);
885 QVERIFY(file.open(QIODevice::ReadOnly));
886 QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
887 QVERIFY(!key.isNull());
888 socket->setPrivateKey(key);
890 QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile);
891 QVERIFY(!localCert.isEmpty());
892 QVERIFY(localCert.first().handle());
893 socket->setLocalCertificate(localCert.first());
895 QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
896 QVERIFY(!socket->peerAddress().isNull());
897 QVERIFY(socket->peerPort() != 0);
898 QVERIFY(!socket->localAddress().isNull());
899 QVERIFY(socket->localPort() != 0);
901 socket->startServerEncryption();
905 void ignoreErrorSlot()
907 socket->ignoreSslErrors();
911 void tst_QSslSocket::protocolServerSide_data()
914 QTest::addColumn<QSsl::SslProtocol>("serverProtocol");
915 QTest::addColumn<QSsl::SslProtocol>("clientProtocol");
916 QTest::addColumn<bool>("works");
918 QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2
919 QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true;
920 QTest::newRow("tls1-tls1") << QSsl::TlsV1 << QSsl::TlsV1 << true;
921 QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true;
922 QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true;
923 QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true;
925 QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false;
926 QTest::newRow("ssl2-tls1") << QSsl::SslV2 << QSsl::TlsV1 << false;
927 QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false;
928 QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false;
929 QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2
931 QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false;
932 QTest::newRow("ssl3-tls1") << QSsl::SslV3 << QSsl::TlsV1 << false;
933 QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true;
934 QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << true;
935 QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a
936 // numerical IP, so OpenSSL will send a SSL 2 handshake
938 QTest::newRow("tls1-ssl2") << QSsl::TlsV1 << QSsl::SslV2 << false;
939 QTest::newRow("tls1-ssl3") << QSsl::TlsV1 << QSsl::SslV3 << false;
940 QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1 << QSsl::TlsV1SslV3 << true;
941 QTest::newRow("tls1-secure") << QSsl::TlsV1 << QSsl::SecureProtocols << true;
942 QTest::newRow("tls1-any") << QSsl::TlsV1 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a
943 // numerical IP, so OpenSSL will send a SSL 2 handshake
945 QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false;
946 QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true;
947 QTest::newRow("tls1ssl3-tls1") << QSsl::TlsV1SslV3 << QSsl::TlsV1 << true;
948 QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true;
949 QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true;
951 QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false;
952 QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << true;
953 QTest::newRow("secure-tls1") << QSsl::SecureProtocols << QSsl::TlsV1 << true;
954 QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true;
955 QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true;
957 QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2
958 QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true;
959 QTest::newRow("any-tls1") << QSsl::AnyProtocol << QSsl::TlsV1 << true;
960 QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true;
961 QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true;
964 void tst_QSslSocket::protocolServerSide()
966 if (!QSslSocket::supportsSsl()) {
967 qWarning("SSL not supported, skipping test");
971 QFETCH_GLOBAL(bool, setProxy);
975 QFETCH(QSsl::SslProtocol, serverProtocol);
977 server.protocol = serverProtocol;
978 QVERIFY(server.listen());
981 QTimer::singleShot(5000, &loop, SLOT(quit()));
983 QSslSocketPtr client = new QSslSocket;
985 QFETCH(QSsl::SslProtocol, clientProtocol);
986 socket->setProtocol(clientProtocol);
987 // upon SSL wrong version error, error will be triggered, not sslErrors
988 connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit()));
989 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
990 connect(client, SIGNAL(encrypted()), &loop, SLOT(quit()));
992 client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
997 QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState;
998 QCOMPARE(client->state(), expectedState);
999 QCOMPARE(client->isEncrypted(), works);
1002 void tst_QSslSocket::setCaCertificates()
1004 if (!QSslSocket::supportsSsl())
1008 QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
1009 socket.setCaCertificates(QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"));
1010 QCOMPARE(socket.caCertificates().size(), 1);
1011 socket.setCaCertificates(socket.defaultCaCertificates());
1012 QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
1015 void tst_QSslSocket::setLocalCertificate()
1019 void tst_QSslSocket::setPrivateKey()
1023 void tst_QSslSocket::setSocketDescriptor()
1025 if (!QSslSocket::supportsSsl())
1028 QFETCH_GLOBAL(bool, setProxy);
1033 QVERIFY(server.listen());
1036 QTimer::singleShot(5000, &loop, SLOT(quit()));
1038 QSslSocketPtr client = new QSslSocket;
1040 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
1041 connect(client, SIGNAL(encrypted()), &loop, SLOT(quit()));
1043 client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
1047 QCOMPARE(client->state(), QAbstractSocket::ConnectedState);
1048 QVERIFY(client->isEncrypted());
1049 QVERIFY(!client->peerAddress().isNull());
1050 QVERIFY(client->peerPort() != 0);
1051 QVERIFY(!client->localAddress().isNull());
1052 QVERIFY(client->localPort() != 0);
1055 void tst_QSslSocket::setSslConfiguration_data()
1057 QTest::addColumn<QSslConfiguration>("configuration");
1058 QTest::addColumn<bool>("works");
1060 QTest::newRow("empty") << QSslConfiguration() << false;
1061 QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
1062 QTest::newRow("default") << conf << false; // does not contain test server cert
1063 QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
1064 conf.setCaCertificates(testServerCert);
1065 QTest::newRow("set-root-cert") << conf << true;
1066 conf.setProtocol(QSsl::SecureProtocols);
1067 QTest::newRow("secure") << conf << true;
1070 void tst_QSslSocket::setSslConfiguration()
1072 if (!QSslSocket::supportsSsl())
1075 QSslSocketPtr socket = newSocket();
1076 QFETCH(QSslConfiguration, configuration);
1077 socket->setSslConfiguration(configuration);
1078 this->socket = socket;
1079 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1080 QFETCH(bool, works);
1081 QCOMPARE(socket->waitForEncrypted(10000), works);
1083 socket->disconnectFromHost();
1084 QVERIFY2(socket->waitForDisconnected(), qPrintable(socket->errorString()));
1088 void tst_QSslSocket::waitForEncrypted()
1090 if (!QSslSocket::supportsSsl())
1093 QSslSocketPtr socket = newSocket();
1094 this->socket = socket;
1096 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
1097 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1099 QVERIFY(socket->waitForEncrypted(10000));
1102 void tst_QSslSocket::waitForEncryptedMinusOne()
1104 if (!QSslSocket::supportsSsl())
1107 QSslSocketPtr socket = newSocket();
1108 this->socket = socket;
1110 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
1111 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1113 QVERIFY(socket->waitForEncrypted(-1));
1116 void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
1118 if (!QSslSocket::supportsSsl())
1121 QSslSocketPtr socket = newSocket();
1122 this->socket = socket;
1124 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
1125 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
1128 QVERIFY(socket->waitForConnected(10000));
1129 QVERIFY(socket->waitForEncrypted(10000));
1131 // dont forget to login
1132 QCOMPARE((int) socket->write("USER ftptest\r\n"), 14);
1133 QCOMPARE((int) socket->write("PASS ftP2Ptf\r\n"), 14);
1135 QVERIFY(socket->waitForReadyRead(10000));
1136 QVERIFY(!socket->peerCertificate().isNull());
1137 QVERIFY(!socket->peerCertificateChain().isEmpty());
1139 QVERIFY(socket->waitForConnected(10000));
1140 QVERIFY(socket->waitForEncrypted(10000));
1141 QVERIFY(socket->waitForReadyRead(10000));
1142 QVERIFY(!socket->peerCertificate().isNull());
1143 QVERIFY(!socket->peerCertificateChain().isEmpty());
1147 void tst_QSslSocket::startClientEncryption()
1151 void tst_QSslSocket::startServerEncryption()
1155 void tst_QSslSocket::addDefaultCaCertificate()
1157 if (!QSslSocket::supportsSsl())
1160 // Reset the global CA chain
1161 QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
1163 QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
1164 QCOMPARE(flukeCerts.size(), 1);
1165 QList<QSslCertificate> globalCerts = QSslSocket::defaultCaCertificates();
1166 QVERIFY(!globalCerts.contains(flukeCerts.first()));
1167 QSslSocket::addDefaultCaCertificate(flukeCerts.first());
1168 QCOMPARE(QSslSocket::defaultCaCertificates().size(), globalCerts.size() + 1);
1169 QVERIFY(QSslSocket::defaultCaCertificates().contains(flukeCerts.first()));
1171 // Restore the global CA chain
1172 QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
1175 void tst_QSslSocket::addDefaultCaCertificates()
1179 void tst_QSslSocket::addDefaultCaCertificates2()
1183 void tst_QSslSocket::defaultCaCertificates()
1185 if (!QSslSocket::supportsSsl())
1188 QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
1189 QVERIFY(certs.size() > 1);
1190 QCOMPARE(certs, QSslSocket::systemCaCertificates());
1193 void tst_QSslSocket::defaultCiphers()
1197 void tst_QSslSocket::resetDefaultCiphers()
1201 void tst_QSslSocket::setDefaultCaCertificates()
1205 void tst_QSslSocket::setDefaultCiphers()
1209 void tst_QSslSocket::supportedCiphers()
1211 if (!QSslSocket::supportsSsl())
1214 QList<QSslCipher> ciphers = QSslSocket::supportedCiphers();
1215 QVERIFY(ciphers.size() > 1);
1218 QCOMPARE(socket.supportedCiphers(), ciphers);
1219 QCOMPARE(socket.defaultCiphers(), ciphers);
1220 QCOMPARE(socket.ciphers(), ciphers);
1223 void tst_QSslSocket::systemCaCertificates()
1225 if (!QSslSocket::supportsSsl())
1228 QList<QSslCertificate> certs = QSslSocket::systemCaCertificates();
1229 QVERIFY(certs.size() > 1);
1230 QCOMPARE(certs, QSslSocket::defaultCaCertificates());
1233 void tst_QSslSocket::wildcardCertificateNames()
1235 // Passing CN matches
1236 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("www.example.com"), QString("www.example.com")), true );
1237 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("www.example.com")), true );
1238 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx*.example.com"), QString("xxxwww.example.com")), true );
1239 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("foo.example.com")), true );
1240 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("192.168.0.0"), QString("192.168.0.0")), true );
1242 // Failing CN matches
1243 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx.example.com"), QString("www.example.com")), false );
1244 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www.example.com")), false );
1245 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.*.com"), QString("www.example.com")), false );
1246 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("baa.foo.example.com")), false );
1247 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("baa.example.com")), false );
1248 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.com"), QString("example.com")), false );
1249 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*fail.com"), QString("example.com")), false );
1250 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example.")), false );
1251 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example")), false );
1252 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString(""), QString("www")), false );
1253 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www")), false );
1254 QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.168.0.0"), QString("192.168.0.0")), false );
1257 void tst_QSslSocket::wildcard()
1259 QSKIP("TODO: solve wildcard problem", SkipAll);
1261 if (!QSslSocket::supportsSsl())
1264 // Fluke runs an apache server listening on port 4443, serving the
1265 // wildcard fluke.*.troll.no. The DNS entry for
1266 // fluke.wildcard.dev.troll.no, served by ares (root for dev.troll.no),
1267 // returns the CNAME fluke.troll.no for this domain. The web server
1268 // responds with the wildcard, and QSslSocket should accept that as a
1269 // valid connection. This was broken in 4.3.0.
1270 QSslSocketPtr socket = newSocket();
1271 socket->addCaCertificates(QLatin1String("certs/aspiriniks.ca.crt"));
1272 this->socket = socket;
1273 #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
1274 connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
1275 this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
1277 socket->connectToHostEncrypted(QtNetworkSettings::wildcardServerName(), 4443);
1279 QVERIFY2(socket->waitForEncrypted(3000), qPrintable(socket->errorString()));
1281 QSslCertificate certificate = socket->peerCertificate();
1282 QCOMPARE(certificate.subjectInfo(QSslCertificate::CommonName), QString(QtNetworkSettings::serverLocalName() + ".*." + QtNetworkSettings::serverDomainName()));
1283 QCOMPARE(certificate.issuerInfo(QSslCertificate::CommonName), QtNetworkSettings::serverName());
1288 class SslServer2 : public QTcpServer
1291 void incomingConnection(int socketDescriptor)
1293 QSslSocket *socket = new QSslSocket(this);
1294 socket->ignoreSslErrors();
1296 // Only set the certificate
1297 QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
1298 QVERIFY(!localCert.isEmpty());
1299 QVERIFY(localCert.first().handle());
1300 socket->setLocalCertificate(localCert.first());
1302 QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
1304 socket->startServerEncryption();
1308 void tst_QSslSocket::setEmptyKey()
1310 if (!QSslSocket::supportsSsl())
1313 QFETCH_GLOBAL(bool, setProxy);
1321 socket.connectToHostEncrypted("127.0.0.1", server.serverPort());
1323 QTestEventLoop::instance().enterLoop(2);
1325 QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
1326 QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
1329 void tst_QSslSocket::spontaneousWrite()
1331 QFETCH_GLOBAL(bool, setProxy);
1336 QSslSocket *receiver = new QSslSocket(this);
1337 connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
1339 // connect two sockets to each other:
1340 QVERIFY(server.listen(QHostAddress::LocalHost));
1341 receiver->connectToHost("127.0.0.1", server.serverPort());
1342 QVERIFY(receiver->waitForConnected(5000));
1343 QVERIFY(server.waitForNewConnection(0));
1345 QSslSocket *sender = server.socket;
1347 QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
1348 receiver->setObjectName("receiver");
1349 sender->setObjectName("sender");
1350 receiver->ignoreSslErrors();
1351 receiver->startClientEncryption();
1354 connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
1356 QVERIFY(!timeout());
1357 QVERIFY(sender->isEncrypted());
1358 QVERIFY(receiver->isEncrypted());
1360 // make sure there's nothing to be received on the sender:
1361 while (sender->waitForReadyRead(10) || receiver->waitForBytesWritten(10)) {}
1363 // spontaneously write something:
1364 QByteArray data("Hello World");
1365 sender->write(data);
1367 // check if the other side receives it:
1369 QVERIFY(!timeout());
1370 QCOMPARE(receiver->bytesAvailable(), qint64(data.size()));
1371 QCOMPARE(receiver->readAll(), data);
1374 void tst_QSslSocket::setReadBufferSize()
1376 QFETCH_GLOBAL(bool, setProxy);
1381 QSslSocket *receiver = new QSslSocket(this);
1382 connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
1384 // connect two sockets to each other:
1385 QVERIFY(server.listen(QHostAddress::LocalHost));
1386 receiver->connectToHost("127.0.0.1", server.serverPort());
1387 QVERIFY(receiver->waitForConnected(5000));
1388 QVERIFY(server.waitForNewConnection(0));
1390 QSslSocket *sender = server.socket;
1392 QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
1393 receiver->setObjectName("receiver");
1394 sender->setObjectName("sender");
1395 receiver->ignoreSslErrors();
1396 receiver->startClientEncryption();
1399 connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
1401 QVERIFY(!timeout());
1402 QVERIFY(sender->isEncrypted());
1403 QVERIFY(receiver->isEncrypted());
1405 QByteArray data(2048, 'b');
1406 receiver->setReadBufferSize(39 * 1024); // make it a non-multiple of the data.size()
1408 // saturate the incoming buffer
1409 while (sender->state() == QAbstractSocket::ConnectedState &&
1410 receiver->state() == QAbstractSocket::ConnectedState &&
1411 receiver->bytesAvailable() < receiver->readBufferSize()) {
1412 sender->write(data);
1413 //qDebug() << receiver->bytesAvailable() << "<" << receiver->readBufferSize() << (receiver->bytesAvailable() < receiver->readBufferSize());
1415 while (sender->bytesToWrite())
1416 QVERIFY(sender->waitForBytesWritten(10));
1419 while (receiver->bytesAvailable() < receiver->readBufferSize() &&
1420 receiver->waitForReadyRead(10)) {}
1423 //qDebug() << sender->bytesToWrite() << "bytes to write";
1424 //qDebug() << receiver->bytesAvailable() << "bytes available";
1427 sender->write(data);
1428 sender->write(data);
1429 sender->write(data);
1430 sender->write(data);
1431 QVERIFY(sender->waitForBytesWritten(10));
1433 qint64 oldBytesAvailable = receiver->bytesAvailable();
1435 // now unset the read buffer limit and iterate
1436 receiver->setReadBufferSize(0);
1438 QVERIFY(!timeout());
1440 QVERIFY(receiver->bytesAvailable() > oldBytesAvailable);
1443 class SetReadBufferSize_task_250027_handler : public QObject {
1446 void readyReadSlot() {
1447 QTestEventLoop::instance().exitLoop();
1449 void waitSomeMore(QSslSocket *socket) {
1452 while (!socket->encryptedBytesAvailable()) {
1453 QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents, 250);
1454 if (t.elapsed() > 1000 || socket->state() != QAbstractSocket::ConnectedState)
1460 void tst_QSslSocket::setReadBufferSize_task_250027()
1462 // do not execute this when a proxy is set.
1463 QFETCH_GLOBAL(bool, setProxy);
1467 QSslSocketPtr socket = newSocket();
1468 socket->setReadBufferSize(1000); // limit to 1 kb/sec
1469 socket->ignoreSslErrors();
1470 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1471 socket->ignoreSslErrors();
1472 QVERIFY(socket->waitForConnected(10*1000));
1473 QVERIFY(socket->waitForEncrypted(10*1000));
1475 // exit the event loop as soon as we receive a readyRead()
1476 SetReadBufferSize_task_250027_handler setReadBufferSize_task_250027_handler;
1477 connect(socket, SIGNAL(readyRead()), &setReadBufferSize_task_250027_handler, SLOT(readyReadSlot()));
1479 // provoke a response by sending a request
1480 socket->write("GET /qtest/fluke.gif HTTP/1.0\n"); // this file is 27 KB
1481 socket->write("Host: ");
1482 socket->write(QtNetworkSettings::serverName().toLocal8Bit().constData());
1483 socket->write("\n");
1484 socket->write("Connection: close\n");
1485 socket->write("\n");
1488 QTestEventLoop::instance().enterLoop(10);
1489 setReadBufferSize_task_250027_handler.waitSomeMore(socket);
1490 QByteArray firstRead = socket->readAll();
1491 // First read should be some data, but not the whole file
1492 QVERIFY(firstRead.size() > 0 && firstRead.size() < 20*1024);
1494 QTestEventLoop::instance().enterLoop(10);
1495 setReadBufferSize_task_250027_handler.waitSomeMore(socket);
1496 QByteArray secondRead = socket->readAll();
1497 // second read should be some more data
1498 QVERIFY(secondRead.size() > 0);
1503 class SslServer3 : public QTcpServer
1507 SslServer3() : socket(0) { }
1511 void incomingConnection(int socketDescriptor)
1513 socket = new QSslSocket(this);
1514 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
1516 QFile file(SRCDIR "certs/fluke.key");
1517 QVERIFY(file.open(QIODevice::ReadOnly));
1518 QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
1519 QVERIFY(!key.isNull());
1520 socket->setPrivateKey(key);
1522 QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
1523 QVERIFY(!localCert.isEmpty());
1524 QVERIFY(localCert.first().handle());
1525 socket->setLocalCertificate(localCert.first());
1527 QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
1528 QVERIFY(!socket->peerAddress().isNull());
1529 QVERIFY(socket->peerPort() != 0);
1530 QVERIFY(!socket->localAddress().isNull());
1531 QVERIFY(socket->localPort() != 0);
1535 void ignoreErrorSlot()
1537 socket->ignoreSslErrors();
1541 class ThreadedSslServer: public QThread
1545 QSemaphore dataReadSemaphore;
1549 ThreadedSslServer() : serverPort(-1), ok(false)
1552 ~ThreadedSslServer()
1554 if (isRunning()) wait(2000);
1564 // if all goes well (no timeouts), this thread will sleep for a total of 500 ms
1565 // (i.e., 5 times 100 ms, one sleep for each operation)
1568 server.listen(QHostAddress::LocalHost);
1569 serverPort = server.serverPort();
1572 // delayed acceptance:
1574 #ifndef Q_OS_SYMBIAN
1575 bool ret = server.waitForNewConnection(2000);
1577 bool ret = server.waitForNewConnection(20000);
1581 // delayed start of encryption
1583 QSslSocket *socket = server.socket;
1584 if (!socket || !socket->isValid())
1586 socket->ignoreSslErrors();
1587 socket->startServerEncryption();
1588 if (!socket->waitForEncrypted(2000))
1591 // delayed reading data
1593 if (!socket->waitForReadyRead(2000))
1596 dataReadSemaphore.release();
1598 // delayed sending data
1600 socket->write("Hello, World");
1601 while (socket->bytesToWrite())
1602 if (!socket->waitForBytesWritten(2000))
1605 // delayed replying (reading then sending)
1607 if (!socket->waitForReadyRead(2000))
1609 socket->write("Hello, World");
1610 while (socket->bytesToWrite())
1611 if (!socket->waitForBytesWritten(2000))
1614 // delayed disconnection:
1616 socket->disconnectFromHost();
1617 if (!socket->waitForDisconnected(2000))
1625 void tst_QSslSocket::waitForMinusOne()
1627 QFETCH_GLOBAL(bool, setProxy);
1631 ThreadedSslServer server;
1632 connect(&server, SIGNAL(listening()), SLOT(exitLoop()));
1634 // start the thread and wait for it to be ready
1637 QVERIFY(!timeout());
1639 // connect to the server
1642 socket.connectToHost("127.0.0.1", server.serverPort);
1643 QVERIFY(socket.waitForConnected(-1));
1644 socket.ignoreSslErrors();
1645 socket.startClientEncryption();
1647 // first verification: this waiting should take 200 ms
1648 QVERIFY2(socket.waitForEncrypted(-1), qPrintable(socket.errorString()));
1649 QVERIFY(socket.isEncrypted());
1650 QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
1651 QCOMPARE(socket.bytesAvailable(), Q_INT64_C(0));
1653 // second verification: write and make sure the other side got it (100 ms)
1654 socket.write("How are you doing?");
1655 QVERIFY(socket.bytesToWrite() != 0);
1656 QVERIFY(socket.waitForBytesWritten(-1));
1657 QVERIFY(server.dataReadSemaphore.tryAcquire(1, 2000));
1659 // third verification: it should wait for 100 ms:
1660 QVERIFY(socket.waitForReadyRead(-1));
1661 QVERIFY(socket.isEncrypted());
1662 QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
1663 QVERIFY(socket.bytesAvailable() != 0);
1665 // fourth verification: deadlock prevention:
1666 // we write and then wait for reading; the other side needs to receive before
1667 // replying (100 ms delay)
1668 socket.write("I'm doing just fine!");
1669 QVERIFY(socket.bytesToWrite() != 0);
1670 QVERIFY(socket.waitForReadyRead(-1));
1672 // fifth verification: it should wait for 200 ms more
1673 QVERIFY(socket.waitForDisconnected(-1));
1676 class VerifyServer : public QTcpServer
1680 VerifyServer() : socket(0) { }
1684 void incomingConnection(int socketDescriptor)
1686 socket = new QSslSocket(this);
1688 socket->setPrivateKey(SRCDIR "certs/fluke.key");
1689 socket->setLocalCertificate(SRCDIR "certs/fluke.cert");
1690 socket->setSocketDescriptor(socketDescriptor);
1691 socket->startServerEncryption();
1695 void tst_QSslSocket::verifyMode()
1697 QFETCH_GLOBAL(bool, setProxy);
1702 QCOMPARE(socket.peerVerifyMode(), QSslSocket::AutoVerifyPeer);
1703 socket.setPeerVerifyMode(QSslSocket::VerifyNone);
1704 QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyNone);
1705 socket.setPeerVerifyMode(QSslSocket::VerifyNone);
1706 socket.setPeerVerifyMode(QSslSocket::VerifyPeer);
1707 QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyPeer);
1709 socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1710 QVERIFY(!socket.waitForEncrypted());
1712 QList<QSslError> expectedErrors = QList<QSslError>()
1713 << QSslError(QSslError::SelfSignedCertificate, socket.peerCertificate());
1714 QCOMPARE(socket.sslErrors(), expectedErrors);
1717 VerifyServer server;
1720 QSslSocket clientSocket;
1721 clientSocket.connectToHostEncrypted("127.0.0.1", server.serverPort());
1722 clientSocket.ignoreSslErrors();
1725 QTimer::singleShot(5000, &loop, SLOT(quit()));
1726 connect(&clientSocket, SIGNAL(encrypted()), &loop, SLOT(quit()));
1729 QVERIFY(clientSocket.isEncrypted());
1730 QVERIFY(server.socket->sslErrors().isEmpty());
1733 void tst_QSslSocket::verifyDepth()
1736 QCOMPARE(socket.peerVerifyDepth(), 0);
1737 socket.setPeerVerifyDepth(1);
1738 QCOMPARE(socket.peerVerifyDepth(), 1);
1739 QTest::ignoreMessage(QtWarningMsg, "QSslSocket::setPeerVerifyDepth: cannot set negative depth of -1");
1740 socket.setPeerVerifyDepth(-1);
1741 QCOMPARE(socket.peerVerifyDepth(), 1);
1744 void tst_QSslSocket::peerVerifyError()
1746 QSslSocketPtr socket = newSocket();
1747 QSignalSpy sslErrorsSpy(socket, SIGNAL(sslErrors(QList<QSslError>)));
1748 QSignalSpy peerVerifyErrorSpy(socket, SIGNAL(peerVerifyError(QSslError)));
1750 socket->connectToHostEncrypted(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 443);
1751 QVERIFY(!socket->waitForEncrypted(10000));
1752 QVERIFY(!peerVerifyErrorSpy.isEmpty());
1753 QVERIFY(!sslErrorsSpy.isEmpty());
1754 QCOMPARE(qVariantValue<QSslError>(peerVerifyErrorSpy.last().at(0)).error(), QSslError::HostNameMismatch);
1755 QCOMPARE(qVariantValue<QList<QSslError> >(sslErrorsSpy.at(0).at(0)).size(), peerVerifyErrorSpy.size());
1758 void tst_QSslSocket::disconnectFromHostWhenConnecting()
1760 QSslSocketPtr socket = newSocket();
1761 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
1762 socket->ignoreSslErrors();
1763 socket->write("XXXX LOGOUT\r\n");
1764 QAbstractSocket::SocketState state = socket->state();
1765 // without proxy, the state will be HostLookupState;
1766 // with proxy, the state will be ConnectingState.
1767 QVERIFY(socket->state() == QAbstractSocket::HostLookupState ||
1768 socket->state() == QAbstractSocket::ConnectingState);
1769 socket->disconnectFromHost();
1770 // the state of the socket must be the same before and after calling
1771 // disconnectFromHost()
1772 QCOMPARE(state, socket->state());
1773 QVERIFY(socket->state() == QAbstractSocket::HostLookupState ||
1774 socket->state() == QAbstractSocket::ConnectingState);
1775 QVERIFY(socket->waitForDisconnected(10000));
1776 QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
1777 // we did not call close, so the socket must be still open
1778 QVERIFY(socket->isOpen());
1779 QCOMPARE(socket->bytesToWrite(), qint64(0));
1781 // dont forget to login
1782 QCOMPARE((int) socket->write("USER ftptest\r\n"), 14);
1786 void tst_QSslSocket::disconnectFromHostWhenConnected()
1788 QSslSocketPtr socket = newSocket();
1789 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
1790 socket->ignoreSslErrors();
1791 #ifndef Q_OS_SYMBIAN
1792 QVERIFY(socket->waitForEncrypted(5000));
1794 QVERIFY(socket->waitForEncrypted(10000));
1796 socket->write("XXXX LOGOUT\r\n");
1797 QCOMPARE(socket->state(), QAbstractSocket::ConnectedState);
1798 socket->disconnectFromHost();
1799 QCOMPARE(socket->state(), QAbstractSocket::ClosingState);
1801 // I don't understand how socket->waitForDisconnected can work on other platforms
1802 // since socket->write will end to:
1803 // QMetaObject::invokeMethod(this, "_q_flushWriteBuffer", Qt::QueuedConnection);
1804 // In order that _q_flushWriteBuffer will be called the eventloop need to run
1805 // If we just call waitForDisconnected, which blocks the whole thread how that can happen?
1806 connect(socket, SIGNAL(disconnected()), this, SLOT(exitLoop()));
1808 QVERIFY(!timeout());
1810 QVERIFY(socket->waitForDisconnected(5000));
1812 QCOMPARE(socket->bytesToWrite(), qint64(0));
1815 void tst_QSslSocket::resetProxy()
1817 QFETCH_GLOBAL(bool, setProxy);
1821 // check fix for bug 199941
1823 QNetworkProxy goodProxy(QNetworkProxy::NoProxy);
1824 QNetworkProxy badProxy(QNetworkProxy::HttpProxy, "thisCannotWorkAbsolutelyNotForSure", 333);
1826 // make sure the connection works, and then set a nonsense proxy, and then
1827 // make sure it does not work anymore
1829 socket.addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
1830 socket.setProxy(goodProxy);
1831 socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1832 QVERIFY2(socket.waitForConnected(10000), qPrintable(socket.errorString()));
1834 socket.setProxy(badProxy);
1835 socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1836 QVERIFY(! socket.waitForConnected(10000));
1838 // dont forget to login
1839 QCOMPARE((int) socket.write("USER ftptest\r\n"), 14);
1840 QCOMPARE((int) socket.write("PASS password\r\n"), 15);
1844 // now the other way round:
1845 // set the nonsense proxy and make sure the connection does not work,
1846 // and then set the right proxy and make sure it works
1848 socket2.addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
1849 socket2.setProxy(badProxy);
1850 socket2.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1851 QVERIFY(! socket2.waitForConnected(10000));
1853 socket2.setProxy(goodProxy);
1854 socket2.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1855 QVERIFY2(socket2.waitForConnected(10000), qPrintable(socket.errorString()));
1858 void tst_QSslSocket::ignoreSslErrorsList_data()
1860 QTest::addColumn<QList<QSslError> >("expectedSslErrors");
1861 QTest::addColumn<int>("expectedSslErrorSignalCount");
1863 // construct the list of errors that we will get with the SSL handshake and that we will ignore
1864 QList<QSslError> expectedSslErrors;
1865 // fromPath gives us a list of certs, but it actually only contains one
1866 QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
1867 QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0));
1868 QSslError wrongError(QSslError::SelfSignedCertificate);
1871 QTest::newRow("SSL-failure-empty-list") << expectedSslErrors << 1;
1872 expectedSslErrors.append(wrongError);
1873 QTest::newRow("SSL-failure-wrong-error") << expectedSslErrors << 1;
1874 expectedSslErrors.append(rightError);
1875 QTest::newRow("allErrorsInExpectedList1") << expectedSslErrors << 0;
1876 expectedSslErrors.removeAll(wrongError);
1877 QTest::newRow("allErrorsInExpectedList2") << expectedSslErrors << 0;
1878 expectedSslErrors.removeAll(rightError);
1879 QTest::newRow("SSL-failure-empty-list-again") << expectedSslErrors << 1;
1882 void tst_QSslSocket::ignoreSslErrorsList()
1885 connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1886 this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
1888 // this->socket = &socket;
1889 QSslCertificate cert;
1891 QFETCH(QList<QSslError>, expectedSslErrors);
1892 socket.ignoreSslErrors(expectedSslErrors);
1894 QFETCH(int, expectedSslErrorSignalCount);
1895 QSignalSpy sslErrorsSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
1897 socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1899 bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0);
1900 QCOMPARE(socket.waitForEncrypted(10000), expectEncryptionSuccess);
1901 QCOMPARE(sslErrorsSpy.count(), expectedSslErrorSignalCount);
1904 void tst_QSslSocket::ignoreSslErrorsListWithSlot_data()
1906 ignoreSslErrorsList_data();
1909 // this is not a test, just a slot called in the test below
1910 void tst_QSslSocket::ignoreErrorListSlot(const QList<QSslError> &)
1912 socket->ignoreSslErrors(storedExpectedSslErrors);
1915 void tst_QSslSocket::ignoreSslErrorsListWithSlot()
1918 this->socket = &socket;
1920 QFETCH(QList<QSslError>, expectedSslErrors);
1921 // store the errors to ignore them later in the slot connected below
1922 storedExpectedSslErrors = expectedSslErrors;
1923 connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1924 this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
1925 connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)),
1926 this, SLOT(ignoreErrorListSlot(const QList<QSslError> &)));
1927 socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1929 QFETCH(int, expectedSslErrorSignalCount);
1930 bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0);
1931 QCOMPARE(socket.waitForEncrypted(10000), expectEncryptionSuccess);
1934 // make sure a closed socket has no bytesAvailable()
1935 // related to https://bugs.webkit.org/show_bug.cgi?id=28016
1936 void tst_QSslSocket::readFromClosedSocket()
1938 QSslSocketPtr socket = newSocket();
1939 socket->ignoreSslErrors();
1940 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1941 socket->ignoreSslErrors();
1942 socket->waitForConnected();
1943 socket->waitForEncrypted();
1944 // provoke a response by sending a request
1945 socket->write("GET /qtest/fluke.gif HTTP/1.1\n");
1946 socket->write("Host: ");
1947 socket->write(QtNetworkSettings::serverName().toLocal8Bit().constData());
1948 socket->write("\n");
1949 socket->write("\n");
1950 socket->waitForBytesWritten();
1951 socket->waitForReadyRead();
1952 QVERIFY(socket->state() == QAbstractSocket::ConnectedState);
1953 QVERIFY(socket->bytesAvailable());
1955 QVERIFY(!socket->bytesAvailable());
1956 QVERIFY(!socket->bytesToWrite());
1957 QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1960 void tst_QSslSocket::writeBigChunk()
1962 if (!QSslSocket::supportsSsl())
1965 QSslSocketPtr socket = newSocket();
1966 this->socket = socket;
1968 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
1969 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1972 data.resize(1024*1024*10); // 10 MB
1973 // init with garbage. needed so ssl cannot compress it in an efficient way.
1974 for (size_t i = 0; i < data.size() / sizeof(int); i++) {
1976 data.data()[i*sizeof(int)] = r;
1979 QVERIFY(socket->waitForEncrypted(10000));
1980 QString errorBefore = socket->errorString();
1982 int ret = socket->write(data.constData(), data.size());
1983 QVERIFY(data.size() == ret);
1985 // spin the event loop once so QSslSocket::transmit() gets called
1986 QCoreApplication::processEvents();
1987 QString errorAfter = socket->errorString();
1989 // no better way to do this right now since the error is the same as the default error.
1990 if (socket->errorString().startsWith(QLatin1String("Unable to write data")))
1992 qWarning() << socket->error() << socket->errorString();
1993 QFAIL("Error while writing! Check if the OpenSSL BIO size is limited?!");
1995 // also check the error string. If another error (than UnknownError) occured, it should be different than before
1996 QVERIFY(errorBefore == errorAfter);
1998 // check that everything has been written to OpenSSL
1999 QVERIFY(socket->bytesToWrite() == 0);
2004 void tst_QSslSocket::blacklistedCertificates()
2006 QFETCH_GLOBAL(bool, setProxy);
2010 SslServer server(SRCDIR "certs/fake-login.live.com.key", SRCDIR "certs/fake-login.live.com.pem");
2011 QSslSocket *receiver = new QSslSocket(this);
2012 connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
2014 // connect two sockets to each other:
2015 QVERIFY(server.listen(QHostAddress::LocalHost));
2016 receiver->connectToHost("127.0.0.1", server.serverPort());
2017 QVERIFY(receiver->waitForConnected(5000));
2018 QVERIFY(server.waitForNewConnection(0));
2020 QSslSocket *sender = server.socket;
2022 QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
2023 receiver->setObjectName("receiver");
2024 sender->setObjectName("sender");
2025 receiver->startClientEncryption();
2027 connect(receiver, SIGNAL(sslErrors(QList<QSslError>)), SLOT(exitLoop()));
2028 connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
2030 QList<QSslError> sslErrors = receiver->sslErrors();
2031 QVERIFY(sslErrors.count() > 0);
2032 // there are more errors (self signed cert and hostname mismatch), but we only care about the blacklist error
2033 QCOMPARE(sslErrors.at(0).error(), QSslError::CertificateBlacklisted);
2036 void tst_QSslSocket::setEmptyDefaultConfiguration()
2038 // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265
2040 if (!QSslSocket::supportsSsl())
2043 QSslConfiguration emptyConf;
2044 QSslConfiguration::setDefaultConfiguration(emptyConf);
2046 QSslSocketPtr socket = newSocket();
2047 connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
2048 socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
2049 QVERIFY2(!socket->waitForEncrypted(4000), qPrintable(socket->errorString()));
2052 #endif // QT_NO_OPENSSL
2054 QTEST_MAIN(tst_QSslSocket)
2055 #include "tst_qsslsocket.moc"