1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
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"
59
#include "private/qsslsocket_openssl_p.h"
60
#include "private/qsslsocket_openssl_symbols_p.h"
61
#include "private/qsslconfiguration_p.h"
64
#include "../../../network-settings.h"
67
Q_DECLARE_METATYPE(QSslSocket::SslMode)
68
typedef QList<QSslError::SslError> SslErrorList;
69
Q_DECLARE_METATYPE(SslErrorList)
70
Q_DECLARE_METATYPE(QSslError)
71
Q_DECLARE_METATYPE(QSsl::SslProtocol)
74
#if defined Q_OS_HPUX && defined Q_CC_GNU
75
// This error is delivered every time we try to use the fluke CA
76
// certificate. For now we work around this bug. Task 202317.
77
#define QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
81
typedef QSharedPointer<QSslSocket> QSslSocketPtr;
84
class tst_QSslSocket : public QObject
92
virtual ~tst_QSslSocket();
94
static void enterLoop(int secs)
97
QTestEventLoop::instance().enterLoop(secs);
100
static bool timeout()
102
return QTestEventLoop::instance().timeout();
106
QSslSocketPtr newSocket();
110
void initTestCase_data();
114
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
119
void simpleConnect();
120
void simpleConnectWithIgnore();
123
void sslErrors_data();
125
void addCaCertificate();
126
void addCaCertificates();
127
void addCaCertificates2();
129
void connectToHostEncrypted();
130
void connectToHostEncryptedWithVerificationPeerName();
131
void sessionCipher();
134
void localCertificate();
136
void peerCertificate();
137
void peerCertificateChain();
139
void privateKeyOpaque();
141
void protocolServerSide_data();
142
void protocolServerSide();
143
void setCaCertificates();
144
void setLocalCertificate();
145
void setPrivateKey();
146
void setSocketDescriptor();
147
void setSslConfiguration_data();
148
void setSslConfiguration();
149
void waitForEncrypted();
150
void waitForEncryptedMinusOne();
151
void waitForConnectedEncryptedReadyRead();
152
void startClientEncryption();
153
void startServerEncryption();
154
void addDefaultCaCertificate();
155
void addDefaultCaCertificates();
156
void addDefaultCaCertificates2();
157
void defaultCaCertificates();
158
void defaultCiphers();
159
void resetDefaultCiphers();
160
void setDefaultCaCertificates();
161
void setDefaultCiphers();
162
void supportedCiphers();
163
void systemCaCertificates();
164
void wildcardCertificateNames();
167
void spontaneousWrite();
168
void setReadBufferSize();
169
void setReadBufferSize_task_250027();
170
void waitForMinusOne();
173
void peerVerifyError();
174
void disconnectFromHostWhenConnecting();
175
void disconnectFromHostWhenConnected();
177
void ignoreSslErrorsList_data();
178
void ignoreSslErrorsList();
179
void ignoreSslErrorsListWithSlot_data();
180
void ignoreSslErrorsListWithSlot();
181
void readFromClosedSocket();
182
void writeBigChunk();
183
void blacklistedCertificates();
184
void versionAccessors();
186
void encryptWithoutConnecting();
189
void qtbug18498_peek();
190
void qtbug18498_peek2();
191
void setEmptyDefaultConfiguration(); // this test should be last
193
static void exitLoop()
195
// Safe exit - if we aren't in an event loop, don't
199
QTestEventLoop::instance().exitLoop();
204
void ignoreErrorSlot()
206
socket->ignoreSslErrors();
208
void untrustedWorkaroundSlot(const QList<QSslError> &errors)
210
if (errors.size() == 1 &&
211
(errors.first().error() == QSslError::CertificateUntrusted ||
212
errors.first().error() == QSslError::SelfSignedCertificate))
213
socket->ignoreSslErrors();
215
void ignoreErrorListSlot(const QList<QSslError> &errors);
219
QList<QSslError> storedExpectedSslErrors;
222
static int loopLevel;
225
int tst_QSslSocket::loopLevel = 0;
227
tst_QSslSocket::tst_QSslSocket()
230
qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
231
qRegisterMetaType<QSslError>("QSslError");
232
qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
233
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
237
tst_QSslSocket::~tst_QSslSocket()
253
void tst_QSslSocket::initTestCase_data()
255
QTest::addColumn<bool>("setProxy");
256
QTest::addColumn<int>("proxyType");
258
QTest::newRow("WithoutProxy") << false << 0;
259
QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy);
260
QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic);
262
QTest::newRow("WithHttpProxy") << true << int(HttpProxy);
263
QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic);
264
// uncomment the line below when NTLM works
265
// QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm);
268
void tst_QSslSocket::initTestCase()
270
QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());
273
void tst_QSslSocket::init()
275
QFETCH_GLOBAL(bool, setProxy);
277
QFETCH_GLOBAL(int, proxyType);
278
QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
283
proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080);
286
case Socks5Proxy | AuthBasic:
287
proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081);
290
case HttpProxy | NoAuth:
291
proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128);
294
case HttpProxy | AuthBasic:
295
proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129);
298
case HttpProxy | AuthNtlm:
299
proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130);
302
QNetworkProxy::setApplicationProxy(proxy);
305
qt_qhostinfo_clear_cache();
308
void tst_QSslSocket::cleanup()
310
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
314
QSslSocketPtr tst_QSslSocket::newSocket()
316
QSslSocket *socket = new QSslSocket;
319
connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
320
SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
321
Qt::DirectConnection);
323
return QSslSocketPtr(socket);
327
void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
330
auth->setUser("qsockstest");
331
auth->setPassword("password");
336
void tst_QSslSocket::constructing()
338
if (!QSslSocket::supportsSsl())
343
QCOMPARE(socket.state(), QSslSocket::UnconnectedState);
344
QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
345
QVERIFY(!socket.isEncrypted());
346
QCOMPARE(socket.bytesAvailable(), qint64(0));
347
QCOMPARE(socket.bytesToWrite(), qint64(0));
348
QVERIFY(!socket.canReadLine());
349
QVERIFY(socket.atEnd());
350
QCOMPARE(socket.localCertificate(), QSslCertificate());
351
QCOMPARE(socket.sslConfiguration(), QSslConfiguration::defaultConfiguration());
352
QCOMPARE(socket.errorString(), QString("Unknown error"));
354
QVERIFY(!socket.getChar(&c));
356
QVERIFY(!socket.isOpen());
357
QVERIFY(!socket.isReadable());
358
QVERIFY(socket.isSequential());
359
QVERIFY(!socket.isTextModeEnabled());
360
QVERIFY(!socket.isWritable());
361
QCOMPARE(socket.openMode(), QIODevice::NotOpen);
362
QVERIFY(socket.peek(2).isEmpty());
363
QCOMPARE(socket.pos(), qint64(0));
364
QVERIFY(!socket.putChar('c'));
365
QVERIFY(socket.read(2).isEmpty());
366
QCOMPARE(socket.read(0, 0), qint64(-1));
367
QVERIFY(socket.readAll().isEmpty());
368
QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2");
369
QCOMPARE(socket.readLine(0, 0), qint64(-1));
371
QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1));
372
QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device");
373
QVERIFY(!socket.reset());
374
QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device");
375
QVERIFY(!socket.seek(2));
376
QCOMPARE(socket.size(), qint64(0));
377
QVERIFY(!socket.waitForBytesWritten(10));
378
QVERIFY(!socket.waitForReadyRead(10));
379
QCOMPARE(socket.write(0, 0), qint64(-1));
380
QCOMPARE(socket.write(QByteArray()), qint64(-1));
381
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
382
QVERIFY(!socket.flush());
383
QVERIFY(!socket.isValid());
384
QCOMPARE(socket.localAddress(), QHostAddress());
385
QCOMPARE(socket.localPort(), quint16(0));
386
QCOMPARE(socket.peerAddress(), QHostAddress());
387
QVERIFY(socket.peerName().isEmpty());
388
QCOMPARE(socket.peerPort(), quint16(0));
389
QCOMPARE(socket.proxy().type(), QNetworkProxy::DefaultProxy);
390
QCOMPARE(socket.readBufferSize(), qint64(0));
391
QCOMPARE(socket.socketDescriptor(), (qintptr)-1);
392
QCOMPARE(socket.socketType(), QAbstractSocket::TcpSocket);
393
QVERIFY(!socket.waitForConnected(10));
394
QTest::ignoreMessage(QtWarningMsg, "QSslSocket::waitForDisconnected() is not allowed in UnconnectedState");
395
QVERIFY(!socket.waitForDisconnected(10));
396
QCOMPARE(socket.protocol(), QSsl::SecureProtocols);
398
QSslConfiguration savedDefault = QSslConfiguration::defaultConfiguration();
400
// verify that changing the default config doesn't affect this socket
401
// (on Unix, the ca certs might be empty, depending on whether we load
402
// them on demand or not, so set them explicitly)
403
socket.setCaCertificates(QSslSocket::systemCaCertificates());
404
QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
405
QSslSocket::setDefaultCiphers(QList<QSslCipher>());
406
QVERIFY(!socket.caCertificates().isEmpty());
407
QVERIFY(!socket.ciphers().isEmpty());
409
// verify the default as well:
410
QVERIFY(QSslConfiguration::defaultConfiguration().caCertificates().isEmpty());
411
QVERIFY(QSslConfiguration::defaultConfiguration().ciphers().isEmpty());
413
QSslConfiguration::setDefaultConfiguration(savedDefault);
416
void tst_QSslSocket::simpleConnect()
418
if (!QSslSocket::supportsSsl())
421
QFETCH_GLOBAL(bool, setProxy);
426
QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
427
QSignalSpy hostFoundSpy(&socket, SIGNAL(hostFound()));
428
QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected()));
429
QSignalSpy connectionEncryptedSpy(&socket, SIGNAL(encrypted()));
430
QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(QList<QSslError>)));
432
connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
433
connect(&socket, SIGNAL(disconnected()), this, SLOT(exitLoop()));
434
connect(&socket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(exitLoop()));
435
connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
436
connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(exitLoop()));
437
connect(&socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(exitLoop()));
440
socket.connectToHost(QtNetworkSettings::serverName(), 993);
441
QCOMPARE(socket.state(), QAbstractSocket::HostLookupState);
444
// Entered connecting state
445
QCOMPARE(socket.state(), QAbstractSocket::ConnectingState);
446
QCOMPARE(connectedSpy.count(), 0);
447
QCOMPARE(hostFoundSpy.count(), 1);
448
QCOMPARE(disconnectedSpy.count(), 0);
451
// Entered connected state
452
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
453
QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
454
QVERIFY(!socket.isEncrypted());
455
QCOMPARE(connectedSpy.count(), 1);
456
QCOMPARE(hostFoundSpy.count(), 1);
457
QCOMPARE(disconnectedSpy.count(), 0);
459
// Enter encrypted mode
460
socket.startClientEncryption();
461
QCOMPARE(socket.mode(), QSslSocket::SslClientMode);
462
QVERIFY(!socket.isEncrypted());
463
QCOMPARE(connectionEncryptedSpy.count(), 0);
464
QCOMPARE(sslErrorsSpy.count(), 0);
466
// Starting handshake
468
QCOMPARE(sslErrorsSpy.count(), 1);
469
QCOMPARE(connectionEncryptedSpy.count(), 0);
470
QVERIFY(!socket.isEncrypted());
471
QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
474
void tst_QSslSocket::simpleConnectWithIgnore()
476
if (!QSslSocket::supportsSsl())
479
QFETCH_GLOBAL(bool, setProxy);
484
this->socket = &socket;
485
QSignalSpy encryptedSpy(&socket, SIGNAL(encrypted()));
486
QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(QList<QSslError>)));
488
connect(&socket, SIGNAL(readyRead()), this, SLOT(exitLoop()));
489
connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
490
connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
491
connect(&socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
492
connect(&socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(exitLoop()));
495
socket.connectToHost(QtNetworkSettings::serverName(), 993);
496
QVERIFY(socket.state() != QAbstractSocket::UnconnectedState); // something must be in progress
500
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
501
socket.startClientEncryption();
504
// Done; encryption should be enabled.
505
QCOMPARE(sslErrorsSpy.count(), 1);
506
QVERIFY(socket.isEncrypted());
507
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
508
QCOMPARE(encryptedSpy.count(), 1);
510
// Wait for incoming data
511
if (!socket.canReadLine())
514
QByteArray data = socket.readAll();
515
socket.disconnectFromHost();
516
QVERIFY2(QtNetworkSettings::compareReplyIMAPSSL(data), data.constData());
519
void tst_QSslSocket::sslErrors_data()
521
QTest::addColumn<QString>("host");
522
QTest::addColumn<int>("port");
523
QTest::addColumn<SslErrorList>("expected");
525
QTest::newRow(qPrintable(QtNetworkSettings::serverLocalName()))
526
<< QtNetworkSettings::serverLocalName()
528
<< (SslErrorList() << QSslError::HostNameMismatch
529
<< QSslError::SelfSignedCertificate);
532
void tst_QSslSocket::sslErrors()
534
QFETCH(QString, host);
536
QFETCH(SslErrorList, expected);
538
QSslSocketPtr socket = newSocket();
539
socket->connectToHostEncrypted(host, port);
540
if (!socket->waitForConnected())
541
QEXPECT_FAIL("imap.trolltech.com", "server not open to internet", Continue);
542
socket->waitForEncrypted(5000);
545
foreach (QSslError error, socket->sslErrors()) {
546
output << error.error();
549
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
550
if (output.count() && output.last() == QSslError::CertificateUntrusted)
553
QCOMPARE(output, expected);
556
void tst_QSslSocket::addCaCertificate()
558
if (!QSslSocket::supportsSsl())
562
void tst_QSslSocket::addCaCertificates()
564
if (!QSslSocket::supportsSsl())
568
void tst_QSslSocket::addCaCertificates2()
570
if (!QSslSocket::supportsSsl())
574
void tst_QSslSocket::ciphers()
576
if (!QSslSocket::supportsSsl())
580
QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
581
socket.setCiphers(QList<QSslCipher>());
582
QVERIFY(socket.ciphers().isEmpty());
583
socket.setCiphers(socket.defaultCiphers());
584
QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
585
socket.setCiphers(socket.defaultCiphers());
586
QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
589
socket.setCiphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
592
void tst_QSslSocket::connectToHostEncrypted()
594
if (!QSslSocket::supportsSsl())
597
QSslSocketPtr socket = newSocket();
598
this->socket = socket.data();
599
QVERIFY(socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")));
600
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
601
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)),
602
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
605
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
607
// This should pass unconditionally when using fluke's CA certificate.
608
// or use untrusted certificate workaround
609
QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
611
socket->disconnectFromHost();
612
QVERIFY(socket->waitForDisconnected());
614
QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
616
socket->connectToHost(QtNetworkSettings::serverName(), 13);
618
QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
620
QVERIFY(socket->waitForDisconnected());
623
void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName()
625
if (!QSslSocket::supportsSsl())
628
QSslSocketPtr socket = newSocket();
629
this->socket = socket.data();
631
socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
632
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
633
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)),
634
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
637
// connect to the server with its local name, but use the full name for verification.
638
socket->connectToHostEncrypted(QtNetworkSettings::serverLocalName(), 443, QtNetworkSettings::serverName());
640
// This should pass unconditionally when using fluke's CA certificate.
641
QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
643
socket->disconnectFromHost();
644
QVERIFY(socket->waitForDisconnected());
646
QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
649
void tst_QSslSocket::sessionCipher()
651
if (!QSslSocket::supportsSsl())
654
QSslSocketPtr socket = newSocket();
655
this->socket = socket.data();
656
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
657
QVERIFY(socket->sessionCipher().isNull());
658
socket->connectToHost(QtNetworkSettings::serverName(), 443 /* https */);
659
QVERIFY(socket->waitForConnected(10000));
660
QVERIFY(socket->sessionCipher().isNull());
661
socket->startClientEncryption();
662
QVERIFY(socket->waitForEncrypted(5000));
663
QVERIFY(!socket->sessionCipher().isNull());
664
QVERIFY(QSslSocket::supportedCiphers().contains(socket->sessionCipher()));
665
socket->disconnectFromHost();
666
QVERIFY(socket->waitForDisconnected());
669
void tst_QSslSocket::flush()
673
void tst_QSslSocket::isEncrypted()
677
void tst_QSslSocket::localCertificate()
679
if (!QSslSocket::supportsSsl())
682
// This test does not make 100% sense yet. We just set some local CA/cert/key and use it
683
// to authenticate ourselves against the server. The server does not actually check this
684
// values. This test should just run the codepath inside qsslsocket_openssl.cpp
686
QSslSocketPtr socket = newSocket();
687
QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
688
socket->setCaCertificates(localCert);
689
socket->setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
690
socket->setPrivateKey(QLatin1String(SRCDIR "certs/fluke.key"));
692
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
693
QVERIFY(socket->waitForEncrypted(10000));
696
void tst_QSslSocket::mode()
700
void tst_QSslSocket::peerCertificate()
704
void tst_QSslSocket::peerCertificateChain()
706
if (!QSslSocket::supportsSsl())
709
QSslSocketPtr socket = newSocket();
710
this->socket = socket.data();
712
QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
713
QVERIFY(caCertificates.count() == 1);
714
socket->addCaCertificates(caCertificates);
715
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
716
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)),
717
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
720
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
721
QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
722
QVERIFY(socket->peerCertificateChain().isEmpty());
723
QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
725
QList<QSslCertificate> certChain = socket->peerCertificateChain();
726
QVERIFY(certChain.count() > 0);
727
QCOMPARE(certChain.first(), socket->peerCertificate());
729
socket->disconnectFromHost();
730
QVERIFY(socket->waitForDisconnected());
732
// connect again to a different server
733
socket->connectToHostEncrypted("qt-project.org", 443);
734
socket->ignoreSslErrors();
735
QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
736
QVERIFY(socket->peerCertificateChain().isEmpty());
737
QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
739
QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate());
740
QVERIFY(socket->peerCertificateChain() != certChain);
742
socket->disconnectFromHost();
743
QVERIFY(socket->waitForDisconnected());
745
// now do it again back to the original server
746
socket->connectToHost(QtNetworkSettings::serverName(), 443);
747
QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
748
QVERIFY(socket->peerCertificateChain().isEmpty());
749
QVERIFY2(socket->waitForConnected(10000), "Network timeout");
751
socket->startClientEncryption();
752
QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
754
QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate());
755
QVERIFY(socket->peerCertificateChain() == certChain);
757
socket->disconnectFromHost();
758
QVERIFY(socket->waitForDisconnected());
761
void tst_QSslSocket::privateKey()
765
void tst_QSslSocket::privateKeyOpaque()
767
if (!QSslSocket::supportsSsl())
770
QFile file(SRCDIR "certs/fluke.key");
771
QVERIFY(file.open(QIODevice::ReadOnly));
772
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
773
QVERIFY(!key.isNull());
775
EVP_PKEY *pkey = q_EVP_PKEY_new();
776
q_EVP_PKEY_set1_RSA(pkey, reinterpret_cast<RSA *>(key.handle()));
778
// This test does not make 100% sense yet. We just set some local CA/cert/key and use it
779
// to authenticate ourselves against the server. The server does not actually check this
780
// values. This test should just run the codepath inside qsslsocket_openssl.cpp
782
QSslSocketPtr socket = newSocket();
783
QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
784
socket->setCaCertificates(localCert);
785
socket->setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
786
socket->setPrivateKey(QSslKey(reinterpret_cast<Qt::HANDLE>(pkey)));
788
socket->setPeerVerifyMode(QSslSocket::QueryPeer);
789
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
790
QVERIFY(socket->waitForEncrypted(10000));
793
void tst_QSslSocket::protocol()
795
if (!QSslSocket::supportsSsl())
798
QSslSocketPtr socket = newSocket();
799
this->socket = socket.data();
800
QList<QSslCertificate> certs = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
802
socket->setCaCertificates(certs);
803
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
804
connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
805
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
808
QCOMPARE(socket->protocol(), QSsl::SecureProtocols);
810
// qt-test-server allows SSLv3.
811
socket->setProtocol(QSsl::SslV3);
812
QCOMPARE(socket->protocol(), QSsl::SslV3);
813
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
814
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
815
QCOMPARE(socket->protocol(), QSsl::SslV3);
817
QCOMPARE(socket->protocol(), QSsl::SslV3);
818
socket->connectToHost(QtNetworkSettings::serverName(), 443);
819
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
820
socket->startClientEncryption();
821
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
822
QCOMPARE(socket->protocol(), QSsl::SslV3);
826
// qt-test-server allows TLSV1.
827
socket->setProtocol(QSsl::TlsV1_0);
828
QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
829
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
830
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
831
QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
833
QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
834
socket->connectToHost(QtNetworkSettings::serverName(), 443);
835
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
836
socket->startClientEncryption();
837
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
838
QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
841
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
843
// qt-test-server probably doesn't allow TLSV1.1
844
socket->setProtocol(QSsl::TlsV1_1);
845
QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
846
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
847
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
848
QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
850
QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
851
socket->connectToHost(QtNetworkSettings::serverName(), 443);
852
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
853
socket->startClientEncryption();
854
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
855
QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
859
// qt-test-server probably doesn't allows TLSV1.2
860
socket->setProtocol(QSsl::TlsV1_2);
861
QCOMPARE(socket->protocol(), QSsl::TlsV1_2);
862
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
863
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
864
QCOMPARE(socket->protocol(), QSsl::TlsV1_2);
866
QCOMPARE(socket->protocol(), QSsl::TlsV1_2);
867
socket->connectToHost(QtNetworkSettings::serverName(), 443);
868
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
869
socket->startClientEncryption();
870
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
871
QCOMPARE(socket->protocol(), QSsl::TlsV1_2);
875
#ifndef OPENSSL_NO_SSL2
877
// qt-test-server allows SSLV2.
878
socket->setProtocol(QSsl::SslV2);
879
QCOMPARE(socket->protocol(), QSsl::SslV2);
880
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
881
QVERIFY(socket->waitForEncrypted());
882
QCOMPARE(socket->protocol(), QSsl::SslV2);
884
QCOMPARE(socket->protocol(), QSsl::SslV2);
885
socket->connectToHost(QtNetworkSettings::serverName(), 443);
886
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
887
socket->startClientEncryption();
888
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
893
// qt-test-server allows SSLV3, so it allows AnyProtocol.
894
socket->setProtocol(QSsl::AnyProtocol);
895
QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
896
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
897
QVERIFY(socket->waitForEncrypted());
898
QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
900
QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
901
socket->connectToHost(QtNetworkSettings::serverName(), 443);
902
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
903
socket->startClientEncryption();
904
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
905
QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
909
// qt-test-server allows SSLV3, so it allows NoSslV2
910
socket->setProtocol(QSsl::TlsV1SslV3);
911
QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
912
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
913
QVERIFY(socket->waitForEncrypted());
914
QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
916
QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
917
socket->connectToHost(QtNetworkSettings::serverName(), 443);
918
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
919
socket->startClientEncryption();
920
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
921
QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
926
class SslServer : public QTcpServer
930
SslServer(const QString &keyFile = SRCDIR "certs/fluke.key", const QString &certFile = SRCDIR "certs/fluke.cert")
932
protocol(QSsl::TlsV1_0),
934
m_certFile(certFile) { }
936
QSsl::SslProtocol protocol;
941
void incomingConnection(qintptr socketDescriptor)
943
socket = new QSslSocket(this);
944
socket->setProtocol(protocol);
945
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
947
QFile file(m_keyFile);
948
QVERIFY(file.open(QIODevice::ReadOnly));
949
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
950
QVERIFY(!key.isNull());
951
socket->setPrivateKey(key);
953
QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile);
954
QVERIFY(!localCert.isEmpty());
955
QVERIFY(localCert.first().handle());
956
socket->setLocalCertificate(localCert.first());
958
QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
959
QVERIFY(!socket->peerAddress().isNull());
960
QVERIFY(socket->peerPort() != 0);
961
QVERIFY(!socket->localAddress().isNull());
962
QVERIFY(socket->localPort() != 0);
964
socket->startServerEncryption();
968
void ignoreErrorSlot()
970
socket->ignoreSslErrors();
974
void tst_QSslSocket::protocolServerSide_data()
976
QTest::addColumn<QSsl::SslProtocol>("serverProtocol");
977
QTest::addColumn<QSsl::SslProtocol>("clientProtocol");
978
QTest::addColumn<bool>("works");
980
#ifndef OPENSSL_NO_SSL2
981
QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2
983
QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true;
984
QTest::newRow("tls1.0-tls1.0") << QSsl::TlsV1_0 << QSsl::TlsV1_0 << true;
985
QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true;
986
QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true;
987
QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true;
989
#ifndef OPENSSL_NO_SSL2
990
QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false;
991
QTest::newRow("ssl2-tls1.0") << QSsl::SslV2 << QSsl::TlsV1_0 << false;
992
QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false;
993
QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false;
994
QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2
997
#ifndef OPENSSL_NO_SSL2
998
QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false;
1000
QTest::newRow("ssl3-tls1.0") << QSsl::SslV3 << QSsl::TlsV1_0 << false;
1001
QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true;
1002
QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << true;
1003
#ifndef OPENSSL_NO_SSL2
1004
QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a
1005
// numerical IP, so OpenSSL will send a SSL 2 handshake
1007
QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << true;
1010
#ifndef OPENSSL_NO_SSL2
1011
QTest::newRow("tls1.0-ssl2") << QSsl::TlsV1_0 << QSsl::SslV2 << false;
1013
QTest::newRow("tls1.0-ssl3") << QSsl::TlsV1_0 << QSsl::SslV3 << false;
1014
QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1_0 << QSsl::TlsV1SslV3 << true;
1015
QTest::newRow("tls1.0-secure") << QSsl::TlsV1_0 << QSsl::SecureProtocols << true;
1016
#ifndef OPENSSL_NO_SSL2
1017
QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a
1018
// numerical IP, so OpenSSL will send a SSL 2 handshake
1020
QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << true;
1023
#ifndef OPENSSL_NO_SSL2
1024
QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false;
1026
QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true;
1027
QTest::newRow("tls1ssl3-tls1.0") << QSsl::TlsV1SslV3 << QSsl::TlsV1_0 << true;
1028
QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true;
1029
QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true;
1031
#ifndef OPENSSL_NO_SSL2
1032
QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false;
1034
QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << true;
1035
QTest::newRow("secure-tls1.0") << QSsl::SecureProtocols << QSsl::TlsV1_0 << true;
1036
QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true;
1037
QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true;
1039
#ifndef OPENSSL_NO_SSL2
1040
QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2
1042
QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true;
1043
QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true;
1044
QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true;
1045
QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true;
1048
void tst_QSslSocket::protocolServerSide()
1050
if (!QSslSocket::supportsSsl()) {
1051
qWarning("SSL not supported, skipping test");
1055
QFETCH_GLOBAL(bool, setProxy);
1059
QFETCH(QSsl::SslProtocol, serverProtocol);
1061
server.protocol = serverProtocol;
1062
QVERIFY(server.listen());
1065
QTimer::singleShot(5000, &loop, SLOT(quit()));
1067
QSslSocketPtr client(new QSslSocket);
1068
socket = client.data();
1069
QFETCH(QSsl::SslProtocol, clientProtocol);
1070
socket->setProtocol(clientProtocol);
1071
// upon SSL wrong version error, error will be triggered, not sslErrors
1072
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit()));
1073
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
1074
connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit()));
1076
client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
1080
QFETCH(bool, works);
1081
QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState;
1082
QCOMPARE(int(client->state()), int(expectedState));
1083
QCOMPARE(client->isEncrypted(), works);
1086
void tst_QSslSocket::setCaCertificates()
1088
if (!QSslSocket::supportsSsl())
1092
QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
1093
socket.setCaCertificates(QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"));
1094
QCOMPARE(socket.caCertificates().size(), 1);
1095
socket.setCaCertificates(socket.defaultCaCertificates());
1096
QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
1099
void tst_QSslSocket::setLocalCertificate()
1103
void tst_QSslSocket::setPrivateKey()
1107
void tst_QSslSocket::setSocketDescriptor()
1109
if (!QSslSocket::supportsSsl())
1112
QFETCH_GLOBAL(bool, setProxy);
1117
QVERIFY(server.listen());
1120
QTimer::singleShot(5000, &loop, SLOT(quit()));
1122
QSslSocketPtr client(new QSslSocket);
1123
socket = client.data();;
1124
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
1125
connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit()));
1127
client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
1131
QCOMPARE(client->state(), QAbstractSocket::ConnectedState);
1132
QVERIFY(client->isEncrypted());
1133
QVERIFY(!client->peerAddress().isNull());
1134
QVERIFY(client->peerPort() != 0);
1135
QVERIFY(!client->localAddress().isNull());
1136
QVERIFY(client->localPort() != 0);
1139
void tst_QSslSocket::setSslConfiguration_data()
1141
QTest::addColumn<QSslConfiguration>("configuration");
1142
QTest::addColumn<bool>("works");
1144
QTest::newRow("empty") << QSslConfiguration() << false;
1145
QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
1146
QTest::newRow("default") << conf << false; // does not contain test server cert
1147
QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
1148
conf.setCaCertificates(testServerCert);
1149
QTest::newRow("set-root-cert") << conf << true;
1150
conf.setProtocol(QSsl::SecureProtocols);
1151
QTest::newRow("secure") << conf << true;
1154
void tst_QSslSocket::setSslConfiguration()
1156
if (!QSslSocket::supportsSsl())
1159
QSslSocketPtr socket = newSocket();
1160
QFETCH(QSslConfiguration, configuration);
1161
socket->setSslConfiguration(configuration);
1162
this->socket = socket.data();
1163
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1164
QFETCH(bool, works);
1165
QCOMPARE(socket->waitForEncrypted(10000), works);
1167
socket->disconnectFromHost();
1168
QVERIFY2(socket->waitForDisconnected(), qPrintable(socket->errorString()));
1172
void tst_QSslSocket::waitForEncrypted()
1174
if (!QSslSocket::supportsSsl())
1177
QSslSocketPtr socket = newSocket();
1178
this->socket = socket.data();
1180
connect(this->socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
1181
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1183
QVERIFY(socket->waitForEncrypted(10000));
1186
void tst_QSslSocket::waitForEncryptedMinusOne()
1189
QSKIP("QTBUG-24451 - indefinite wait may hang");
1191
if (!QSslSocket::supportsSsl())
1194
QSslSocketPtr socket = newSocket();
1195
this->socket = socket.data();
1197
connect(this->socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
1198
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1200
QVERIFY(socket->waitForEncrypted(-1));
1203
void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
1205
if (!QSslSocket::supportsSsl())
1208
QSslSocketPtr socket = newSocket();
1209
this->socket = socket.data();
1211
connect(this->socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
1212
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
1214
QVERIFY(socket->waitForConnected(10000));
1215
QVERIFY(socket->waitForEncrypted(10000));
1216
QVERIFY(socket->waitForReadyRead(10000));
1217
QVERIFY(!socket->peerCertificate().isNull());
1218
QVERIFY(!socket->peerCertificateChain().isEmpty());
1221
void tst_QSslSocket::startClientEncryption()
1225
void tst_QSslSocket::startServerEncryption()
1229
void tst_QSslSocket::addDefaultCaCertificate()
1231
if (!QSslSocket::supportsSsl())
1234
// Reset the global CA chain
1235
QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
1237
QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
1238
QCOMPARE(flukeCerts.size(), 1);
1239
QList<QSslCertificate> globalCerts = QSslSocket::defaultCaCertificates();
1240
QVERIFY(!globalCerts.contains(flukeCerts.first()));
1241
QSslSocket::addDefaultCaCertificate(flukeCerts.first());
1242
QCOMPARE(QSslSocket::defaultCaCertificates().size(), globalCerts.size() + 1);
1243
QVERIFY(QSslSocket::defaultCaCertificates().contains(flukeCerts.first()));
1245
// Restore the global CA chain
1246
QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
1249
void tst_QSslSocket::addDefaultCaCertificates()
1253
void tst_QSslSocket::addDefaultCaCertificates2()
1257
void tst_QSslSocket::defaultCaCertificates()
1259
if (!QSslSocket::supportsSsl())
1262
QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
1263
QVERIFY(certs.size() > 1);
1264
QCOMPARE(certs, QSslSocket::systemCaCertificates());
1267
void tst_QSslSocket::defaultCiphers()
1271
void tst_QSslSocket::resetDefaultCiphers()
1275
void tst_QSslSocket::setDefaultCaCertificates()
1279
void tst_QSslSocket::setDefaultCiphers()
1283
void tst_QSslSocket::supportedCiphers()
1285
if (!QSslSocket::supportsSsl())
1288
QList<QSslCipher> ciphers = QSslSocket::supportedCiphers();
1289
QVERIFY(ciphers.size() > 1);
1292
QCOMPARE(socket.supportedCiphers(), ciphers);
1293
QCOMPARE(socket.defaultCiphers(), ciphers);
1294
QCOMPARE(socket.ciphers(), ciphers);
1297
void tst_QSslSocket::systemCaCertificates()
1299
if (!QSslSocket::supportsSsl())
1302
QList<QSslCertificate> certs = QSslSocket::systemCaCertificates();
1303
QVERIFY(certs.size() > 1);
1304
QCOMPARE(certs, QSslSocket::defaultCaCertificates());
1307
void tst_QSslSocket::wildcardCertificateNames()
1309
// Passing CN matches
1310
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("www.example.com"), QString("www.example.com")), true );
1311
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("www.example.com")), true );
1312
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx*.example.com"), QString("xxxwww.example.com")), true );
1313
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("foo.example.com")), true );
1314
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("192.168.0.0"), QString("192.168.0.0")), true );
1316
// Failing CN matches
1317
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx.example.com"), QString("www.example.com")), false );
1318
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www.example.com")), false );
1319
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.*.com"), QString("www.example.com")), false );
1320
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("baa.foo.example.com")), false );
1321
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("baa.example.com")), false );
1322
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.com"), QString("example.com")), false );
1323
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*fail.com"), QString("example.com")), false );
1324
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example.")), false );
1325
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example")), false );
1326
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString(""), QString("www")), false );
1327
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www")), false );
1328
QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.168.0.0"), QString("192.168.0.0")), false );
1331
void tst_QSslSocket::wildcard()
1333
QSKIP("TODO: solve wildcard problem");
1335
if (!QSslSocket::supportsSsl())
1338
// Fluke runs an apache server listening on port 4443, serving the
1339
// wildcard fluke.*.troll.no. The DNS entry for
1340
// fluke.wildcard.dev.troll.no, served by ares (root for dev.troll.no),
1341
// returns the CNAME fluke.troll.no for this domain. The web server
1342
// responds with the wildcard, and QSslSocket should accept that as a
1343
// valid connection. This was broken in 4.3.0.
1344
QSslSocketPtr socket = newSocket();
1345
socket->addCaCertificates(QLatin1String("certs/aspiriniks.ca.crt"));
1346
this->socket = socket.data();
1347
#ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
1348
connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
1349
this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
1351
socket->connectToHostEncrypted(QtNetworkSettings::wildcardServerName(), 4443);
1353
QVERIFY2(socket->waitForEncrypted(3000), qPrintable(socket->errorString()));
1355
QSslCertificate certificate = socket->peerCertificate();
1356
QVERIFY(certificate.subjectInfo(QSslCertificate::CommonName).contains(QString(QtNetworkSettings::serverLocalName() + ".*." + QtNetworkSettings::serverDomainName())));
1357
QVERIFY(certificate.issuerInfo(QSslCertificate::CommonName).contains(QtNetworkSettings::serverName()));
1362
class SslServer2 : public QTcpServer
1365
void incomingConnection(qintptr socketDescriptor)
1367
QSslSocket *socket = new QSslSocket(this);
1368
socket->ignoreSslErrors();
1370
// Only set the certificate
1371
QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
1372
QVERIFY(!localCert.isEmpty());
1373
QVERIFY(localCert.first().handle());
1374
socket->setLocalCertificate(localCert.first());
1376
QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
1378
socket->startServerEncryption();
1382
void tst_QSslSocket::setEmptyKey()
1384
if (!QSslSocket::supportsSsl())
1387
QFETCH_GLOBAL(bool, setProxy);
1395
socket.connectToHostEncrypted("127.0.0.1", server.serverPort());
1397
QTestEventLoop::instance().enterLoop(2);
1399
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
1400
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
1403
void tst_QSslSocket::spontaneousWrite()
1405
QFETCH_GLOBAL(bool, setProxy);
1410
QSslSocket *receiver = new QSslSocket(this);
1411
connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
1413
// connect two sockets to each other:
1414
QVERIFY(server.listen(QHostAddress::LocalHost));
1415
receiver->connectToHost("127.0.0.1", server.serverPort());
1416
QVERIFY(receiver->waitForConnected(5000));
1417
QVERIFY(server.waitForNewConnection(0));
1419
QSslSocket *sender = server.socket;
1421
QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
1422
receiver->setObjectName("receiver");
1423
sender->setObjectName("sender");
1424
receiver->ignoreSslErrors();
1425
receiver->startClientEncryption();
1428
connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
1430
QVERIFY(!timeout());
1431
QVERIFY(sender->isEncrypted());
1432
QVERIFY(receiver->isEncrypted());
1434
// make sure there's nothing to be received on the sender:
1435
while (sender->waitForReadyRead(10) || receiver->waitForBytesWritten(10)) {}
1437
// spontaneously write something:
1438
QByteArray data("Hello World");
1439
sender->write(data);
1441
// check if the other side receives it:
1443
QVERIFY(!timeout());
1444
QCOMPARE(receiver->bytesAvailable(), qint64(data.size()));
1445
QCOMPARE(receiver->readAll(), data);
1448
void tst_QSslSocket::setReadBufferSize()
1450
QFETCH_GLOBAL(bool, setProxy);
1455
QSslSocket *receiver = new QSslSocket(this);
1456
connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
1458
// connect two sockets to each other:
1459
QVERIFY(server.listen(QHostAddress::LocalHost));
1460
receiver->connectToHost("127.0.0.1", server.serverPort());
1461
QVERIFY(receiver->waitForConnected(5000));
1462
QVERIFY(server.waitForNewConnection(0));
1464
QSslSocket *sender = server.socket;
1466
QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
1467
receiver->setObjectName("receiver");
1468
sender->setObjectName("sender");
1469
receiver->ignoreSslErrors();
1470
receiver->startClientEncryption();
1473
connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
1475
QVERIFY(!timeout());
1476
QVERIFY(sender->isEncrypted());
1477
QVERIFY(receiver->isEncrypted());
1479
QByteArray data(2048, 'b');
1480
receiver->setReadBufferSize(39 * 1024); // make it a non-multiple of the data.size()
1482
// saturate the incoming buffer
1483
while (sender->state() == QAbstractSocket::ConnectedState &&
1484
receiver->state() == QAbstractSocket::ConnectedState &&
1485
receiver->bytesAvailable() < receiver->readBufferSize()) {
1486
sender->write(data);
1487
//qDebug() << receiver->bytesAvailable() << "<" << receiver->readBufferSize() << (receiver->bytesAvailable() < receiver->readBufferSize());
1489
while (sender->bytesToWrite())
1490
QVERIFY(sender->waitForBytesWritten(10));
1493
while (receiver->bytesAvailable() < receiver->readBufferSize() &&
1494
receiver->waitForReadyRead(10)) {}
1497
//qDebug() << sender->bytesToWrite() << "bytes to write";
1498
//qDebug() << receiver->bytesAvailable() << "bytes available";
1501
sender->write(data);
1502
sender->write(data);
1503
sender->write(data);
1504
sender->write(data);
1505
QVERIFY(sender->waitForBytesWritten(10));
1507
qint64 oldBytesAvailable = receiver->bytesAvailable();
1509
// now unset the read buffer limit and iterate
1510
receiver->setReadBufferSize(0);
1512
QVERIFY(!timeout());
1514
QVERIFY(receiver->bytesAvailable() > oldBytesAvailable);
1517
class SetReadBufferSize_task_250027_handler : public QObject {
1520
void readyReadSlot() {
1521
QTestEventLoop::instance().exitLoop();
1523
void waitSomeMore(QSslSocket *socket) {
1526
while (!socket->encryptedBytesAvailable()) {
1527
QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents, 250);
1528
if (t.elapsed() > 1000 || socket->state() != QAbstractSocket::ConnectedState)
1534
void tst_QSslSocket::setReadBufferSize_task_250027()
1536
// do not execute this when a proxy is set.
1537
QFETCH_GLOBAL(bool, setProxy);
1541
QSslSocketPtr socket = newSocket();
1542
socket->setReadBufferSize(1000); // limit to 1 kb/sec
1543
socket->ignoreSslErrors();
1544
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1545
socket->ignoreSslErrors();
1546
QVERIFY(socket->waitForConnected(10*1000));
1547
QVERIFY(socket->waitForEncrypted(10*1000));
1549
// exit the event loop as soon as we receive a readyRead()
1550
SetReadBufferSize_task_250027_handler setReadBufferSize_task_250027_handler;
1551
connect(socket.data(), SIGNAL(readyRead()), &setReadBufferSize_task_250027_handler, SLOT(readyReadSlot()));
1553
// provoke a response by sending a request
1554
socket->write("GET /qtest/fluke.gif HTTP/1.0\n"); // this file is 27 KB
1555
socket->write("Host: ");
1556
socket->write(QtNetworkSettings::serverName().toLocal8Bit().constData());
1557
socket->write("\n");
1558
socket->write("Connection: close\n");
1559
socket->write("\n");
1562
QTestEventLoop::instance().enterLoop(10);
1563
setReadBufferSize_task_250027_handler.waitSomeMore(socket.data());
1564
QByteArray firstRead = socket->readAll();
1565
// First read should be some data, but not the whole file
1566
QVERIFY(firstRead.size() > 0 && firstRead.size() < 20*1024);
1568
QTestEventLoop::instance().enterLoop(10);
1569
setReadBufferSize_task_250027_handler.waitSomeMore(socket.data());
1570
QByteArray secondRead = socket->readAll();
1571
// second read should be some more data
1572
QVERIFY(secondRead.size() > 0);
1577
class SslServer3 : public QTcpServer
1581
SslServer3() : socket(0) { }
1585
void incomingConnection(qintptr socketDescriptor)
1587
socket = new QSslSocket(this);
1588
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
1590
QFile file(SRCDIR "certs/fluke.key");
1591
QVERIFY(file.open(QIODevice::ReadOnly));
1592
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
1593
QVERIFY(!key.isNull());
1594
socket->setPrivateKey(key);
1596
QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
1597
QVERIFY(!localCert.isEmpty());
1598
QVERIFY(localCert.first().handle());
1599
socket->setLocalCertificate(localCert.first());
1601
QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
1602
QVERIFY(!socket->peerAddress().isNull());
1603
QVERIFY(socket->peerPort() != 0);
1604
QVERIFY(!socket->localAddress().isNull());
1605
QVERIFY(socket->localPort() != 0);
1609
void ignoreErrorSlot()
1611
socket->ignoreSslErrors();
1615
class ThreadedSslServer: public QThread
1619
QSemaphore dataReadSemaphore;
1623
ThreadedSslServer() : serverPort(-1), ok(false)
1626
~ThreadedSslServer()
1628
if (isRunning()) wait(2000);
1638
// if all goes well (no timeouts), this thread will sleep for a total of 500 ms
1639
// (i.e., 5 times 100 ms, one sleep for each operation)
1642
server.listen(QHostAddress::LocalHost);
1643
serverPort = server.serverPort();
1646
// delayed acceptance:
1648
bool ret = server.waitForNewConnection(2000);
1651
// delayed start of encryption
1653
QSslSocket *socket = server.socket;
1654
if (!socket || !socket->isValid())
1656
socket->ignoreSslErrors();
1657
socket->startServerEncryption();
1658
if (!socket->waitForEncrypted(2000))
1661
// delayed reading data
1663
if (!socket->waitForReadyRead(2000))
1666
dataReadSemaphore.release();
1668
// delayed sending data
1670
socket->write("Hello, World");
1671
while (socket->bytesToWrite())
1672
if (!socket->waitForBytesWritten(2000))
1675
// delayed replying (reading then sending)
1677
if (!socket->waitForReadyRead(2000))
1679
socket->write("Hello, World");
1680
while (socket->bytesToWrite())
1681
if (!socket->waitForBytesWritten(2000))
1684
// delayed disconnection:
1686
socket->disconnectFromHost();
1687
if (!socket->waitForDisconnected(2000))
1695
void tst_QSslSocket::waitForMinusOne()
1698
QSKIP("QTBUG-24451 - indefinite wait may hang");
1700
QFETCH_GLOBAL(bool, setProxy);
1704
ThreadedSslServer server;
1705
connect(&server, SIGNAL(listening()), SLOT(exitLoop()));
1707
// start the thread and wait for it to be ready
1710
QVERIFY(!timeout());
1712
// connect to the server
1715
socket.connectToHost("127.0.0.1", server.serverPort);
1716
QVERIFY(socket.waitForConnected(-1));
1717
socket.ignoreSslErrors();
1718
socket.startClientEncryption();
1720
// first verification: this waiting should take 200 ms
1721
QVERIFY2(socket.waitForEncrypted(-1), qPrintable(socket.errorString()));
1722
QVERIFY(socket.isEncrypted());
1723
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
1724
QCOMPARE(socket.bytesAvailable(), Q_INT64_C(0));
1726
// second verification: write and make sure the other side got it (100 ms)
1727
socket.write("How are you doing?");
1728
QVERIFY(socket.bytesToWrite() != 0);
1729
QVERIFY(socket.waitForBytesWritten(-1));
1730
QVERIFY(server.dataReadSemaphore.tryAcquire(1, 2000));
1732
// third verification: it should wait for 100 ms:
1733
QVERIFY(socket.waitForReadyRead(-1));
1734
QVERIFY(socket.isEncrypted());
1735
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
1736
QVERIFY(socket.bytesAvailable() != 0);
1738
// fourth verification: deadlock prevention:
1739
// we write and then wait for reading; the other side needs to receive before
1740
// replying (100 ms delay)
1741
socket.write("I'm doing just fine!");
1742
QVERIFY(socket.bytesToWrite() != 0);
1743
QVERIFY(socket.waitForReadyRead(-1));
1745
// fifth verification: it should wait for 200 ms more
1746
QVERIFY(socket.waitForDisconnected(-1));
1749
class VerifyServer : public QTcpServer
1753
VerifyServer() : socket(0) { }
1757
void incomingConnection(qintptr socketDescriptor)
1759
socket = new QSslSocket(this);
1761
socket->setPrivateKey(SRCDIR "certs/fluke.key");
1762
socket->setLocalCertificate(SRCDIR "certs/fluke.cert");
1763
socket->setSocketDescriptor(socketDescriptor);
1764
socket->startServerEncryption();
1768
void tst_QSslSocket::verifyMode()
1770
QFETCH_GLOBAL(bool, setProxy);
1775
QCOMPARE(socket.peerVerifyMode(), QSslSocket::AutoVerifyPeer);
1776
socket.setPeerVerifyMode(QSslSocket::VerifyNone);
1777
QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyNone);
1778
socket.setPeerVerifyMode(QSslSocket::VerifyNone);
1779
socket.setPeerVerifyMode(QSslSocket::VerifyPeer);
1780
QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyPeer);
1782
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1783
QVERIFY(!socket.waitForEncrypted());
1785
QList<QSslError> expectedErrors = QList<QSslError>()
1786
<< QSslError(QSslError::SelfSignedCertificate, socket.peerCertificate());
1787
QCOMPARE(socket.sslErrors(), expectedErrors);
1790
VerifyServer server;
1793
QSslSocket clientSocket;
1794
clientSocket.connectToHostEncrypted("127.0.0.1", server.serverPort());
1795
clientSocket.ignoreSslErrors();
1798
QTimer::singleShot(5000, &loop, SLOT(quit()));
1799
connect(&clientSocket, SIGNAL(encrypted()), &loop, SLOT(quit()));
1802
QVERIFY(clientSocket.isEncrypted());
1803
#if (defined(UBUNTU_ONEIRIC) && defined(__x86_64__)) || defined(Q_OS_WIN) || defined(Q_OS_MAC)
1804
QEXPECT_FAIL("", "QTBUG-24234", Abort);
1806
QVERIFY(server.socket->sslErrors().isEmpty());
1809
void tst_QSslSocket::verifyDepth()
1812
QCOMPARE(socket.peerVerifyDepth(), 0);
1813
socket.setPeerVerifyDepth(1);
1814
QCOMPARE(socket.peerVerifyDepth(), 1);
1815
QTest::ignoreMessage(QtWarningMsg, "QSslSocket::setPeerVerifyDepth: cannot set negative depth of -1");
1816
socket.setPeerVerifyDepth(-1);
1817
QCOMPARE(socket.peerVerifyDepth(), 1);
1820
void tst_QSslSocket::peerVerifyError()
1822
QSslSocketPtr socket = newSocket();
1823
QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList<QSslError>)));
1824
QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError)));
1826
socket->connectToHostEncrypted(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 443);
1827
QVERIFY(!socket->waitForEncrypted(10000));
1828
QVERIFY(!peerVerifyErrorSpy.isEmpty());
1829
QVERIFY(!sslErrorsSpy.isEmpty());
1830
QCOMPARE(qvariant_cast<QSslError>(peerVerifyErrorSpy.last().at(0)).error(), QSslError::HostNameMismatch);
1831
QCOMPARE(qvariant_cast<QList<QSslError> >(sslErrorsSpy.at(0).at(0)).size(), peerVerifyErrorSpy.size());
1834
void tst_QSslSocket::disconnectFromHostWhenConnecting()
1836
QSslSocketPtr socket = newSocket();
1837
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
1838
socket->ignoreSslErrors();
1839
socket->write("XXXX LOGOUT\r\n");
1840
QAbstractSocket::SocketState state = socket->state();
1841
// without proxy, the state will be HostLookupState;
1842
// with proxy, the state will be ConnectingState.
1843
QVERIFY(socket->state() == QAbstractSocket::HostLookupState ||
1844
socket->state() == QAbstractSocket::ConnectingState);
1845
socket->disconnectFromHost();
1846
// the state of the socket must be the same before and after calling
1847
// disconnectFromHost()
1848
QCOMPARE(state, socket->state());
1849
QVERIFY(socket->state() == QAbstractSocket::HostLookupState ||
1850
socket->state() == QAbstractSocket::ConnectingState);
1851
QVERIFY(socket->waitForDisconnected(10000));
1852
QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
1853
// we did not call close, so the socket must be still open
1854
QVERIFY(socket->isOpen());
1855
QCOMPARE(socket->bytesToWrite(), qint64(0));
1857
// don't forget to login
1858
QCOMPARE((int) socket->write("USER ftptest\r\n"), 14);
1862
void tst_QSslSocket::disconnectFromHostWhenConnected()
1864
QSslSocketPtr socket = newSocket();
1865
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
1866
socket->ignoreSslErrors();
1867
QVERIFY(socket->waitForEncrypted(5000));
1868
socket->write("XXXX LOGOUT\r\n");
1869
QCOMPARE(socket->state(), QAbstractSocket::ConnectedState);
1870
socket->disconnectFromHost();
1871
QCOMPARE(socket->state(), QAbstractSocket::ClosingState);
1872
QVERIFY(socket->waitForDisconnected(5000));
1873
QCOMPARE(socket->bytesToWrite(), qint64(0));
1876
void tst_QSslSocket::resetProxy()
1878
QFETCH_GLOBAL(bool, setProxy);
1882
// check fix for bug 199941
1884
QNetworkProxy goodProxy(QNetworkProxy::NoProxy);
1885
QNetworkProxy badProxy(QNetworkProxy::HttpProxy, "thisCannotWorkAbsolutelyNotForSure", 333);
1887
// make sure the connection works, and then set a nonsense proxy, and then
1888
// make sure it does not work anymore
1890
socket.addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
1891
socket.setProxy(goodProxy);
1892
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1893
QVERIFY2(socket.waitForConnected(10000), qPrintable(socket.errorString()));
1895
socket.setProxy(badProxy);
1896
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1897
QVERIFY(! socket.waitForConnected(10000));
1899
// don't forget to login
1900
QCOMPARE((int) socket.write("USER ftptest\r\n"), 14);
1901
QCOMPARE((int) socket.write("PASS password\r\n"), 15);
1905
// now the other way round:
1906
// set the nonsense proxy and make sure the connection does not work,
1907
// and then set the right proxy and make sure it works
1909
socket2.addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
1910
socket2.setProxy(badProxy);
1911
socket2.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1912
QVERIFY(! socket2.waitForConnected(10000));
1914
socket2.setProxy(goodProxy);
1915
socket2.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1916
QVERIFY2(socket2.waitForConnected(10000), qPrintable(socket.errorString()));
1919
void tst_QSslSocket::ignoreSslErrorsList_data()
1921
QTest::addColumn<QList<QSslError> >("expectedSslErrors");
1922
QTest::addColumn<int>("expectedSslErrorSignalCount");
1924
// construct the list of errors that we will get with the SSL handshake and that we will ignore
1925
QList<QSslError> expectedSslErrors;
1926
// fromPath gives us a list of certs, but it actually only contains one
1927
QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
1928
QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0));
1929
QSslError wrongError(QSslError::SelfSignedCertificate);
1932
QTest::newRow("SSL-failure-empty-list") << expectedSslErrors << 1;
1933
expectedSslErrors.append(wrongError);
1934
QTest::newRow("SSL-failure-wrong-error") << expectedSslErrors << 1;
1935
expectedSslErrors.append(rightError);
1936
QTest::newRow("allErrorsInExpectedList1") << expectedSslErrors << 0;
1937
expectedSslErrors.removeAll(wrongError);
1938
QTest::newRow("allErrorsInExpectedList2") << expectedSslErrors << 0;
1939
expectedSslErrors.removeAll(rightError);
1940
QTest::newRow("SSL-failure-empty-list-again") << expectedSslErrors << 1;
1943
void tst_QSslSocket::ignoreSslErrorsList()
1946
connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1947
this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
1949
// this->socket = &socket;
1950
QSslCertificate cert;
1952
QFETCH(QList<QSslError>, expectedSslErrors);
1953
socket.ignoreSslErrors(expectedSslErrors);
1955
QFETCH(int, expectedSslErrorSignalCount);
1956
QSignalSpy sslErrorsSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
1958
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1960
bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0);
1961
QCOMPARE(socket.waitForEncrypted(10000), expectEncryptionSuccess);
1962
QCOMPARE(sslErrorsSpy.count(), expectedSslErrorSignalCount);
1965
void tst_QSslSocket::ignoreSslErrorsListWithSlot_data()
1967
ignoreSslErrorsList_data();
1970
// this is not a test, just a slot called in the test below
1971
void tst_QSslSocket::ignoreErrorListSlot(const QList<QSslError> &)
1973
socket->ignoreSslErrors(storedExpectedSslErrors);
1976
void tst_QSslSocket::ignoreSslErrorsListWithSlot()
1979
this->socket = &socket;
1981
QFETCH(QList<QSslError>, expectedSslErrors);
1982
// store the errors to ignore them later in the slot connected below
1983
storedExpectedSslErrors = expectedSslErrors;
1984
connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1985
this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
1986
connect(&socket, SIGNAL(sslErrors(QList<QSslError>)),
1987
this, SLOT(ignoreErrorListSlot(QList<QSslError>)));
1988
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
1990
QFETCH(int, expectedSslErrorSignalCount);
1991
bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0);
1992
QCOMPARE(socket.waitForEncrypted(10000), expectEncryptionSuccess);
1995
// make sure a closed socket has no bytesAvailable()
1996
// related to https://bugs.webkit.org/show_bug.cgi?id=28016
1997
void tst_QSslSocket::readFromClosedSocket()
1999
QSslSocketPtr socket = newSocket();
2000
socket->ignoreSslErrors();
2001
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
2002
socket->ignoreSslErrors();
2003
socket->waitForConnected();
2004
socket->waitForEncrypted();
2005
// provoke a response by sending a request
2006
socket->write("GET /qtest/fluke.gif HTTP/1.1\n");
2007
socket->write("Host: ");
2008
socket->write(QtNetworkSettings::serverName().toLocal8Bit().constData());
2009
socket->write("\n");
2010
socket->write("\n");
2011
socket->waitForBytesWritten();
2012
socket->waitForReadyRead();
2013
QVERIFY(socket->state() == QAbstractSocket::ConnectedState);
2014
QVERIFY(socket->bytesAvailable());
2016
QVERIFY(!socket->bytesAvailable());
2017
QVERIFY(!socket->bytesToWrite());
2018
QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
2021
void tst_QSslSocket::writeBigChunk()
2023
if (!QSslSocket::supportsSsl())
2026
QSslSocketPtr socket = newSocket();
2027
this->socket = socket.data();
2029
connect(this->socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
2030
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
2033
data.resize(1024*1024*10); // 10 MB
2034
// init with garbage. needed so ssl cannot compress it in an efficient way.
2035
for (size_t i = 0; i < data.size() / sizeof(int); i++) {
2037
data.data()[i*sizeof(int)] = r;
2040
QVERIFY(socket->waitForEncrypted(10000));
2041
QString errorBefore = socket->errorString();
2043
int ret = socket->write(data.constData(), data.size());
2044
QVERIFY(data.size() == ret);
2046
// spin the event loop once so QSslSocket::transmit() gets called
2047
QCoreApplication::processEvents();
2048
QString errorAfter = socket->errorString();
2050
// no better way to do this right now since the error is the same as the default error.
2051
if (socket->errorString().startsWith(QLatin1String("Unable to write data")))
2053
qWarning() << socket->error() << socket->errorString();
2054
QFAIL("Error while writing! Check if the OpenSSL BIO size is limited?!");
2056
// also check the error string. If another error (than UnknownError) occurred, it should be different than before
2057
QVERIFY(errorBefore == errorAfter);
2059
// check that everything has been written to OpenSSL
2060
QVERIFY(socket->bytesToWrite() == 0);
2065
void tst_QSslSocket::blacklistedCertificates()
2067
QFETCH_GLOBAL(bool, setProxy);
2071
SslServer server(SRCDIR "certs/fake-login.live.com.key", SRCDIR "certs/fake-login.live.com.pem");
2072
QSslSocket *receiver = new QSslSocket(this);
2073
connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
2075
// connect two sockets to each other:
2076
QVERIFY(server.listen(QHostAddress::LocalHost));
2077
receiver->connectToHost("127.0.0.1", server.serverPort());
2078
QVERIFY(receiver->waitForConnected(5000));
2079
QVERIFY(server.waitForNewConnection(0));
2081
QSslSocket *sender = server.socket;
2083
QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
2084
receiver->setObjectName("receiver");
2085
sender->setObjectName("sender");
2086
receiver->startClientEncryption();
2088
connect(receiver, SIGNAL(sslErrors(QList<QSslError>)), SLOT(exitLoop()));
2089
connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
2091
QList<QSslError> sslErrors = receiver->sslErrors();
2092
QVERIFY(sslErrors.count() > 0);
2093
// there are more errors (self signed cert and hostname mismatch), but we only care about the blacklist error
2094
QCOMPARE(sslErrors.at(0).error(), QSslError::CertificateBlacklisted);
2097
void tst_QSslSocket::versionAccessors()
2099
if (!QSslSocket::supportsSsl())
2102
qDebug() << QSslSocket::sslLibraryVersionString();
2103
qDebug() << QString::number(QSslSocket::sslLibraryVersionNumber(), 16);
2106
void tst_QSslSocket::sslOptions()
2108
if (!QSslSocket::supportsSsl())
2111
#ifdef SSL_OP_NO_COMPRESSION
2112
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2113
QSslConfigurationPrivate::defaultSslOptions),
2114
long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_COMPRESSION));
2116
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2117
QSslConfigurationPrivate::defaultSslOptions),
2118
long(SSL_OP_ALL|SSL_OP_NO_SSLv2));
2121
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2122
QSsl::SslOptionDisableEmptyFragments
2123
|QSsl::SslOptionDisableLegacyRenegotiation),
2124
long(SSL_OP_ALL|SSL_OP_NO_SSLv2));
2126
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
2127
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2128
QSsl::SslOptionDisableEmptyFragments),
2129
long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)));
2132
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
2133
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2134
QSsl::SslOptionDisableLegacyRenegotiation),
2135
long((SSL_OP_ALL|SSL_OP_NO_SSLv2) & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
2138
#ifdef SSL_OP_NO_TICKET
2139
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2140
QSsl::SslOptionDisableEmptyFragments
2141
|QSsl::SslOptionDisableLegacyRenegotiation
2142
|QSsl::SslOptionDisableSessionTickets),
2143
long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET)));
2146
#ifdef SSL_OP_NO_TICKET
2147
#ifdef SSL_OP_NO_COMPRESSION
2148
QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
2149
QSsl::SslOptionDisableEmptyFragments
2150
|QSsl::SslOptionDisableLegacyRenegotiation
2151
|QSsl::SslOptionDisableSessionTickets
2152
|QSsl::SslOptionDisableCompression),
2153
long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET|SSL_OP_NO_COMPRESSION)));
2158
void tst_QSslSocket::encryptWithoutConnecting()
2160
if (!QSslSocket::supportsSsl())
2163
QTest::ignoreMessage(QtWarningMsg,
2164
"QSslSocket::startClientEncryption: cannot start handshake when not connected");
2167
sock.startClientEncryption();
2170
void tst_QSslSocket::resume_data()
2172
QTest::addColumn<bool>("ignoreErrorsAfterPause");
2173
QTest::addColumn<QList<QSslError> >("errorsToIgnore");
2174
QTest::addColumn<bool>("expectSuccess");
2176
QList<QSslError> errorsList;
2177
QTest::newRow("DoNotIgnoreErrors") << false << QList<QSslError>() << false;
2178
QTest::newRow("ignoreAllErrors") << true << QList<QSslError>() << true;
2180
QList<QSslCertificate> certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
2181
QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0));
2182
QSslError wrongError(QSslError::SelfSignedCertificate);
2183
errorsList.append(wrongError);
2184
QTest::newRow("ignoreSpecificErrors-Wrong") << true << errorsList << false;
2186
errorsList.append(rightError);
2187
QTest::newRow("ignoreSpecificErrors-Right") << true << errorsList << true;
2190
void tst_QSslSocket::resume()
2192
// make sure the server certificate is not in the list of accepted certificates,
2193
// we want to trigger the sslErrors signal
2194
QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
2196
QFETCH(bool, ignoreErrorsAfterPause);
2197
QFETCH(QList<QSslError>, errorsToIgnore);
2198
QFETCH(bool, expectSuccess);
2201
socket.setPauseMode(QAbstractSocket::PauseOnSslErrors);
2203
QSignalSpy sslErrorSpy(&socket, SIGNAL(sslErrors(QList<QSslError>)));
2204
QSignalSpy encryptedSpy(&socket, SIGNAL(encrypted()));
2205
QSignalSpy errorSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError)));
2207
connect(&socket, SIGNAL(sslErrors(QList<QSslError>)), &QTestEventLoop::instance(), SLOT(exitLoop()));
2208
connect(&socket, SIGNAL(encrypted()), &QTestEventLoop::instance(), SLOT(exitLoop()));
2209
connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
2210
this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
2211
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop()));
2213
socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
2214
QTestEventLoop::instance().enterLoop(10);
2215
QVERIFY(!QTestEventLoop::instance().timeout());
2216
QCOMPARE(sslErrorSpy.count(), 1);
2217
QCOMPARE(errorSpy.count(), 0);
2218
QCOMPARE(encryptedSpy.count(), 0);
2219
QVERIFY(!socket.isEncrypted());
2220
if (ignoreErrorsAfterPause) {
2221
if (errorsToIgnore.empty())
2222
socket.ignoreSslErrors();
2224
socket.ignoreSslErrors(errorsToIgnore);
2227
QTestEventLoop::instance().enterLoop(10);
2228
QVERIFY(!QTestEventLoop::instance().timeout()); // quit by encrypted() or error() signal
2229
if (expectSuccess) {
2230
QCOMPARE(encryptedSpy.count(), 1);
2231
QVERIFY(socket.isEncrypted());
2232
QCOMPARE(errorSpy.count(), 0);
2233
socket.disconnectFromHost();
2234
QVERIFY(socket.waitForDisconnected(10000));
2236
QCOMPARE(encryptedSpy.count(), 0);
2237
QVERIFY(!socket.isEncrypted());
2238
QCOMPARE(errorSpy.count(), 1);
2239
QCOMPARE(socket.error(), QAbstractSocket::SslHandshakeFailedError);
2243
class WebSocket : public QSslSocket
2247
explicit WebSocket(qintptr socketDescriptor,
2248
const QString &keyFile = SRCDIR "certs/fluke.key",
2249
const QString &certFile = SRCDIR "certs/fluke.cert");
2252
void onReadyReadFirstBytes(void);
2255
void _startServerEncryption(void);
2261
Q_DISABLE_COPY(WebSocket)
2264
WebSocket::WebSocket (qintptr socketDescriptor, const QString &keyFile, const QString &certFile)
2265
: m_keyFile(keyFile),
2266
m_certFile(certFile)
2268
QVERIFY(setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState, QIODevice::ReadWrite | QIODevice::Unbuffered));
2269
connect (this, SIGNAL(readyRead()), this, SLOT(onReadyReadFirstBytes()));
2272
void WebSocket::_startServerEncryption (void)
2274
QFile file(m_keyFile);
2275
QVERIFY(file.open(QIODevice::ReadOnly));
2276
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
2277
QVERIFY(!key.isNull());
2280
QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile);
2281
QVERIFY(!localCert.isEmpty());
2282
QVERIFY(localCert.first().handle());
2283
setLocalCertificate(localCert.first());
2285
QVERIFY(!peerAddress().isNull());
2286
QVERIFY(peerPort() != 0);
2287
QVERIFY(!localAddress().isNull());
2288
QVERIFY(localPort() != 0);
2290
setProtocol(QSsl::AnyProtocol);
2291
setPeerVerifyMode(QSslSocket::VerifyNone);
2293
startServerEncryption();
2296
void WebSocket::onReadyReadFirstBytes (void)
2299
disconnect(this,SIGNAL(readyRead()), this, SLOT(onReadyReadFirstBytes()));
2300
_startServerEncryption();
2303
class SslServer4 : public QTcpServer
2307
SslServer4() : socket(0) {}
2311
void incomingConnection(qintptr socketDescriptor)
2313
socket = new WebSocket(socketDescriptor);
2317
void tst_QSslSocket::qtbug18498_peek()
2319
QFETCH_GLOBAL(bool, setProxy);
2324
QSslSocket *client = new QSslSocket(this);
2326
QVERIFY(server.listen(QHostAddress::LocalHost));
2327
client->connectToHost("127.0.0.1", server.serverPort());
2328
QVERIFY(client->waitForConnected(5000));
2329
QVERIFY(server.waitForNewConnection(1000));
2330
client->setObjectName("client");
2331
client->ignoreSslErrors();
2333
connect(client, SIGNAL(encrypted()), this, SLOT(exitLoop()));
2334
connect(client, SIGNAL(disconnected()), this, SLOT(exitLoop()));
2336
client->startClientEncryption();
2337
WebSocket *serversocket = server.socket;
2338
QVERIFY(serversocket);
2339
serversocket->setObjectName("server");
2342
QVERIFY(!timeout());
2343
QVERIFY(serversocket->isEncrypted());
2344
QVERIFY(client->isEncrypted());
2346
QByteArray data("abc123");
2347
client->write(data.data());
2349
connect(serversocket, SIGNAL(readyRead()), this, SLOT(exitLoop()));
2351
QVERIFY(!timeout());
2353
QByteArray peek1_data;
2354
peek1_data.reserve(data.size());
2355
QByteArray peek2_data;
2356
QByteArray read_data;
2358
int lngth = serversocket->peek(peek1_data.data(), 10);
2359
peek1_data.resize(lngth);
2361
peek2_data = serversocket->peek(10);
2362
read_data = serversocket->readAll();
2364
QCOMPARE(peek1_data, data);
2365
QCOMPARE(peek2_data, data);
2366
QCOMPARE(read_data, data);
2369
class SslServer5 : public QTcpServer
2373
SslServer5() : socket(0) {}
2377
void incomingConnection(qintptr socketDescriptor)
2379
socket = new QSslSocket;
2380
socket->setSocketDescriptor(socketDescriptor);
2384
void tst_QSslSocket::qtbug18498_peek2()
2386
QFETCH_GLOBAL(bool, setProxy);
2390
SslServer5 listener;
2391
QVERIFY(listener.listen(QHostAddress::Any));
2392
QScopedPointer<QSslSocket> client(new QSslSocket);
2393
client->connectToHost(QHostAddress::LocalHost, listener.serverPort());
2394
QVERIFY(client->waitForConnected(5000));
2395
QVERIFY(listener.waitForNewConnection(1000));
2397
QScopedPointer<QSslSocket> server(listener.socket);
2399
QVERIFY(server->write("HELLO\r\n", 7));
2400
QElapsedTimer stopwatch;
2402
while (client->bytesAvailable() < 7 && stopwatch.elapsed() < 5000)
2405
QVERIFY(client->peek(&c,1) == 1);
2407
QVERIFY(client->read(&c,1) == 1);
2409
QByteArray b = client->peek(2);
2410
QCOMPARE(b, QByteArray("EL"));
2412
QVERIFY(client->peek(a, 2) == 2);
2413
QCOMPARE(a[0], 'E');
2414
QCOMPARE(a[1], 'L');
2415
QCOMPARE(client->readAll(), QByteArray("ELLO\r\n"));
2417
//check data split between QIODevice and plain socket buffers.
2418
QByteArray bigblock;
2419
bigblock.fill('#', QIODEVICE_BUFFERSIZE + 1024);
2420
QVERIFY(client->write(QByteArray("head")));
2421
QVERIFY(client->write(bigblock));
2422
while (server->bytesAvailable() < bigblock.length() + 4 && stopwatch.elapsed() < 5000)
2424
QCOMPARE(server->read(4), QByteArray("head"));
2425
QCOMPARE(server->peek(bigblock.length()), bigblock);
2426
b.reserve(bigblock.length());
2427
b.resize(server->peek(b.data(), bigblock.length()));
2428
QCOMPARE(b, bigblock);
2430
//check oversized peek
2431
QCOMPARE(server->peek(bigblock.length() * 3), bigblock);
2432
b.reserve(bigblock.length() * 3);
2433
b.resize(server->peek(b.data(), bigblock.length() * 3));
2434
QCOMPARE(b, bigblock);
2436
QCOMPARE(server->readAll(), bigblock);
2438
QVERIFY(client->write("STARTTLS\r\n"));
2440
// ### Qt5 use QTRY_VERIFY
2441
while (server->bytesAvailable() < 10 && stopwatch.elapsed() < 5000)
2443
QVERIFY(server->peek(&c,1) == 1);
2445
b = server->peek(3);
2446
QCOMPARE(b, QByteArray("STA"));
2447
QCOMPARE(server->read(5), QByteArray("START"));
2448
QVERIFY(server->peek(a, 3) == 3);
2449
QCOMPARE(a[0], 'T');
2450
QCOMPARE(a[1], 'L');
2451
QCOMPARE(a[2], 'S');
2452
QCOMPARE(server->readAll(), QByteArray("TLS\r\n"));
2454
QFile file(SRCDIR "certs/fluke.key");
2455
QVERIFY(file.open(QIODevice::ReadOnly));
2456
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
2457
QVERIFY(!key.isNull());
2458
server->setPrivateKey(key);
2460
QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
2461
QVERIFY(!localCert.isEmpty());
2462
QVERIFY(localCert.first().handle());
2463
server->setLocalCertificate(localCert.first());
2465
server->setProtocol(QSsl::AnyProtocol);
2466
server->setPeerVerifyMode(QSslSocket::VerifyNone);
2468
server->ignoreSslErrors();
2469
client->ignoreSslErrors();
2471
server->startServerEncryption();
2472
client->startClientEncryption();
2474
QVERIFY(server->write("hello\r\n", 7));
2476
while (client->bytesAvailable() < 7 && stopwatch.elapsed() < 5000)
2478
QVERIFY(server->mode() == QSslSocket::SslServerMode && client->mode() == QSslSocket::SslClientMode);
2479
QVERIFY(client->peek(&c,1) == 1);
2481
QVERIFY(client->read(&c,1) == 1);
2483
b = client->peek(2);
2484
QCOMPARE(b, QByteArray("el"));
2485
QCOMPARE(client->readAll(), QByteArray("ello\r\n"));
2487
QVERIFY(client->write("goodbye\r\n"));
2489
while (server->bytesAvailable() < 9 && stopwatch.elapsed() < 5000)
2491
QVERIFY(server->peek(&c,1) == 1);
2493
QCOMPARE(server->readAll(), QByteArray("goodbye\r\n"));
2494
client->disconnectFromHost();
2495
QVERIFY(client->waitForDisconnected(5000));
2498
void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, as it has some side effects
2500
// used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265
2502
if (!QSslSocket::supportsSsl())
2505
QSslConfiguration emptyConf;
2506
QSslConfiguration::setDefaultConfiguration(emptyConf);
2508
QSslSocketPtr socket = newSocket();
2509
connect(socket.data(), SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
2510
socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
2511
QVERIFY2(!socket->waitForEncrypted(4000), qPrintable(socket->errorString()));
2516
QTEST_MAIN(tst_QSslSocket)
2518
#include "tst_qsslsocket.moc"