/tests/auto/qsslsocket/tst_qsslsocket.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 2054 lines · 1559 code · 335 blank · 160 comment · 106 complexity · c7758dc669c58dc269f3cf3300619672 MD5 · raw file

Large files are truncated click here to view the full file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the test suite of the Qt Toolkit.
  8. **
  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.
  17. **
  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.
  21. **
  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.
  29. **
  30. ** Other Usage
  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.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include <QtCore/qthread.h>
  42. #include <QtNetwork/qhostaddress.h>
  43. #include <QtNetwork/qhostinfo.h>
  44. #include <QtNetwork/qnetworkproxy.h>
  45. #include <QtNetwork/qsslcipher.h>
  46. #include <QtNetwork/qsslconfiguration.h>
  47. #include <QtNetwork/qsslkey.h>
  48. #include <QtNetwork/qsslsocket.h>
  49. #include <QtNetwork/qtcpserver.h>
  50. #include <QtTest/QtTest>
  51. #include <QNetworkProxy>
  52. #include <QAuthenticator>
  53. #include "private/qhostinfo_p.h"
  54. #include "private/qsslsocket_openssl_p.h"
  55. #include "../network-settings.h"
  56. Q_DECLARE_METATYPE(QAbstractSocket::SocketState)
  57. Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
  58. #ifndef QT_NO_OPENSSL
  59. Q_DECLARE_METATYPE(QSslSocket::SslMode)
  60. typedef QList<QSslError::SslError> SslErrorList;
  61. Q_DECLARE_METATYPE(SslErrorList)
  62. Q_DECLARE_METATYPE(QSslError)
  63. Q_DECLARE_METATYPE(QSsl::SslProtocol)
  64. Q_DECLARE_METATYPE(QSslConfiguration)
  65. #endif
  66. #if defined Q_OS_HPUX && defined Q_CC_GNU
  67. // This error is delivered every time we try to use the fluke CA
  68. // certificate. For now we work around this bug. Task 202317.
  69. #define QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  70. #endif
  71. #ifdef Q_OS_SYMBIAN
  72. #define SRCDIR ""
  73. #endif
  74. #ifndef QT_NO_OPENSSL
  75. class QSslSocketPtr: public QSharedPointer<QSslSocket>
  76. {
  77. public:
  78. inline QSslSocketPtr(QSslSocket *ptr = 0)
  79. : QSharedPointer<QSslSocket>(ptr)
  80. { }
  81. inline operator QSslSocket *() const { return data(); }
  82. };
  83. #endif
  84. class tst_QSslSocket : public QObject
  85. {
  86. Q_OBJECT
  87. int proxyAuthCalled;
  88. public:
  89. tst_QSslSocket();
  90. virtual ~tst_QSslSocket();
  91. static void enterLoop(int secs)
  92. {
  93. ++loopLevel;
  94. QTestEventLoop::instance().enterLoop(secs);
  95. }
  96. static bool timeout()
  97. {
  98. return QTestEventLoop::instance().timeout();
  99. }
  100. #ifndef QT_NO_OPENSSL
  101. QSslSocketPtr newSocket();
  102. #endif
  103. public slots:
  104. void initTestCase_data();
  105. void init();
  106. void cleanup();
  107. void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
  108. #ifndef QT_NO_OPENSSL
  109. private slots:
  110. void constructing();
  111. void simpleConnect();
  112. void simpleConnectWithIgnore();
  113. // API tests
  114. void sslErrors_data();
  115. void sslErrors();
  116. void addCaCertificate();
  117. void addCaCertificates();
  118. void addCaCertificates2();
  119. void ciphers();
  120. void connectToHostEncrypted();
  121. void connectToHostEncryptedWithVerificationPeerName();
  122. void sessionCipher();
  123. void flush();
  124. void isEncrypted();
  125. void localCertificate();
  126. void mode();
  127. void peerCertificate();
  128. void peerCertificateChain();
  129. void privateKey();
  130. void protocol();
  131. void protocolServerSide_data();
  132. void protocolServerSide();
  133. void setCaCertificates();
  134. void setLocalCertificate();
  135. void setPrivateKey();
  136. void setSocketDescriptor();
  137. void setSslConfiguration_data();
  138. void setSslConfiguration();
  139. void waitForEncrypted();
  140. void waitForEncryptedMinusOne();
  141. void waitForConnectedEncryptedReadyRead();
  142. void startClientEncryption();
  143. void startServerEncryption();
  144. void addDefaultCaCertificate();
  145. void addDefaultCaCertificates();
  146. void addDefaultCaCertificates2();
  147. void defaultCaCertificates();
  148. void defaultCiphers();
  149. void resetDefaultCiphers();
  150. void setDefaultCaCertificates();
  151. void setDefaultCiphers();
  152. void supportedCiphers();
  153. void systemCaCertificates();
  154. void wildcardCertificateNames();
  155. void wildcard();
  156. void setEmptyKey();
  157. void spontaneousWrite();
  158. void setReadBufferSize();
  159. void setReadBufferSize_task_250027();
  160. void waitForMinusOne();
  161. void verifyMode();
  162. void verifyDepth();
  163. void peerVerifyError();
  164. void disconnectFromHostWhenConnecting();
  165. void disconnectFromHostWhenConnected();
  166. void resetProxy();
  167. void ignoreSslErrorsList_data();
  168. void ignoreSslErrorsList();
  169. void ignoreSslErrorsListWithSlot_data();
  170. void ignoreSslErrorsListWithSlot();
  171. void readFromClosedSocket();
  172. void writeBigChunk();
  173. void blacklistedCertificates();
  174. void setEmptyDefaultConfiguration();
  175. static void exitLoop()
  176. {
  177. // Safe exit - if we aren't in an event loop, don't
  178. // exit one.
  179. if (loopLevel > 0) {
  180. --loopLevel;
  181. QTestEventLoop::instance().exitLoop();
  182. }
  183. }
  184. protected slots:
  185. void ignoreErrorSlot()
  186. {
  187. socket->ignoreSslErrors();
  188. }
  189. void untrustedWorkaroundSlot(const QList<QSslError> &errors)
  190. {
  191. if (errors.size() == 1 &&
  192. (errors.first().error() == QSslError::CertificateUntrusted ||
  193. errors.first().error() == QSslError::SelfSignedCertificate))
  194. socket->ignoreSslErrors();
  195. }
  196. void ignoreErrorListSlot(const QList<QSslError> &errors);
  197. private:
  198. QSslSocket *socket;
  199. QList<QSslError> storedExpectedSslErrors;
  200. #endif // QT_NO_OPENSSL
  201. private:
  202. static int loopLevel;
  203. };
  204. int tst_QSslSocket::loopLevel = 0;
  205. tst_QSslSocket::tst_QSslSocket()
  206. {
  207. #ifndef QT_NO_OPENSSL
  208. qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
  209. qRegisterMetaType<QSslError>("QSslError");
  210. qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
  211. qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
  212. qRegisterMetaType<QAbstractSocket::SocketState>("QSslSocket::SslMode");
  213. #endif
  214. Q_SET_DEFAULT_IAP
  215. }
  216. tst_QSslSocket::~tst_QSslSocket()
  217. {
  218. }
  219. enum ProxyTests {
  220. NoProxy = 0x00,
  221. Socks5Proxy = 0x01,
  222. HttpProxy = 0x02,
  223. TypeMask = 0x0f,
  224. NoAuth = 0x00,
  225. AuthBasic = 0x10,
  226. AuthNtlm = 0x20,
  227. AuthMask = 0xf0
  228. };
  229. void tst_QSslSocket::initTestCase_data()
  230. {
  231. QTest::addColumn<bool>("setProxy");
  232. QTest::addColumn<int>("proxyType");
  233. QTest::newRow("WithoutProxy") << false << 0;
  234. QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy);
  235. QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic);
  236. QTest::newRow("WithHttpProxy") << true << int(HttpProxy);
  237. QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic);
  238. // uncomment the line below when NTLM works
  239. // QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm);
  240. }
  241. void tst_QSslSocket::init()
  242. {
  243. QFETCH_GLOBAL(bool, setProxy);
  244. if (setProxy) {
  245. QFETCH_GLOBAL(int, proxyType);
  246. QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
  247. QNetworkProxy proxy;
  248. switch (proxyType) {
  249. case Socks5Proxy:
  250. proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080);
  251. break;
  252. case Socks5Proxy | AuthBasic:
  253. proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081);
  254. break;
  255. case HttpProxy | NoAuth:
  256. proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128);
  257. break;
  258. case HttpProxy | AuthBasic:
  259. proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129);
  260. break;
  261. case HttpProxy | AuthNtlm:
  262. proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130);
  263. break;
  264. }
  265. QNetworkProxy::setApplicationProxy(proxy);
  266. }
  267. qt_qhostinfo_clear_cache();
  268. }
  269. void tst_QSslSocket::cleanup()
  270. {
  271. QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
  272. }
  273. #ifndef QT_NO_OPENSSL
  274. QSslSocketPtr tst_QSslSocket::newSocket()
  275. {
  276. QSslSocket *socket = new QSslSocket;
  277. proxyAuthCalled = 0;
  278. connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
  279. SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
  280. Qt::DirectConnection);
  281. return QSslSocketPtr(socket);
  282. }
  283. #endif
  284. void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
  285. {
  286. ++proxyAuthCalled;
  287. auth->setUser("qsockstest");
  288. auth->setPassword("password");
  289. }
  290. #ifndef QT_NO_OPENSSL
  291. void tst_QSslSocket::constructing()
  292. {
  293. if (!QSslSocket::supportsSsl())
  294. return;
  295. QSslSocket socket;
  296. QCOMPARE(socket.state(), QSslSocket::UnconnectedState);
  297. QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
  298. QVERIFY(!socket.isEncrypted());
  299. QCOMPARE(socket.bytesAvailable(), qint64(0));
  300. QCOMPARE(socket.bytesToWrite(), qint64(0));
  301. QVERIFY(!socket.canReadLine());
  302. QVERIFY(socket.atEnd());
  303. QCOMPARE(socket.localCertificate(), QSslCertificate());
  304. QCOMPARE(socket.sslConfiguration(), QSslConfiguration::defaultConfiguration());
  305. QCOMPARE(socket.errorString(), QString("Unknown error"));
  306. char c = '\0';
  307. QVERIFY(!socket.getChar(&c));
  308. QCOMPARE(c, '\0');
  309. QVERIFY(!socket.isOpen());
  310. QVERIFY(!socket.isReadable());
  311. QVERIFY(socket.isSequential());
  312. QVERIFY(!socket.isTextModeEnabled());
  313. QVERIFY(!socket.isWritable());
  314. QCOMPARE(socket.openMode(), QIODevice::NotOpen);
  315. QVERIFY(socket.peek(2).isEmpty());
  316. QCOMPARE(socket.pos(), qint64(0));
  317. QVERIFY(!socket.putChar('c'));
  318. QVERIFY(socket.read(2).isEmpty());
  319. QCOMPARE(socket.read(0, 0), qint64(-1));
  320. QVERIFY(socket.readAll().isEmpty());
  321. QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2");
  322. QCOMPARE(socket.readLine(0, 0), qint64(-1));
  323. char buf[10];
  324. QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1));
  325. QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: The device is not open");
  326. QVERIFY(!socket.reset());
  327. QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: The device is not open");
  328. QVERIFY(!socket.seek(2));
  329. QCOMPARE(socket.size(), qint64(0));
  330. QVERIFY(!socket.waitForBytesWritten(10));
  331. QVERIFY(!socket.waitForReadyRead(10));
  332. QCOMPARE(socket.write(0, 0), qint64(-1));
  333. QCOMPARE(socket.write(QByteArray()), qint64(-1));
  334. QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
  335. QVERIFY(!socket.flush());
  336. QVERIFY(!socket.isValid());
  337. QCOMPARE(socket.localAddress(), QHostAddress());
  338. QCOMPARE(socket.localPort(), quint16(0));
  339. QCOMPARE(socket.peerAddress(), QHostAddress());
  340. QVERIFY(socket.peerName().isEmpty());
  341. QCOMPARE(socket.peerPort(), quint16(0));
  342. QCOMPARE(socket.proxy().type(), QNetworkProxy::DefaultProxy);
  343. QCOMPARE(socket.readBufferSize(), qint64(0));
  344. QCOMPARE(socket.socketDescriptor(), -1);
  345. QCOMPARE(socket.socketType(), QAbstractSocket::TcpSocket);
  346. QVERIFY(!socket.waitForConnected(10));
  347. QTest::ignoreMessage(QtWarningMsg, "QSslSocket::waitForDisconnected() is not allowed in UnconnectedState");
  348. QVERIFY(!socket.waitForDisconnected(10));
  349. QCOMPARE(socket.protocol(), QSsl::SecureProtocols);
  350. QSslConfiguration savedDefault = QSslConfiguration::defaultConfiguration();
  351. // verify that changing the default config doesn't affect this socket
  352. // (on Unix, the ca certs might be empty, depending on whether we load
  353. // them on demand or not, so set them explicitly)
  354. socket.setCaCertificates(QSslSocket::systemCaCertificates());
  355. QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
  356. QSslSocket::setDefaultCiphers(QList<QSslCipher>());
  357. QVERIFY(!socket.caCertificates().isEmpty());
  358. QVERIFY(!socket.ciphers().isEmpty());
  359. // verify the default as well:
  360. QVERIFY(QSslConfiguration::defaultConfiguration().caCertificates().isEmpty());
  361. QVERIFY(QSslConfiguration::defaultConfiguration().ciphers().isEmpty());
  362. QSslConfiguration::setDefaultConfiguration(savedDefault);
  363. }
  364. void tst_QSslSocket::simpleConnect()
  365. {
  366. if (!QSslSocket::supportsSsl())
  367. return;
  368. QFETCH_GLOBAL(bool, setProxy);
  369. if (setProxy)
  370. return;
  371. QSslSocket socket;
  372. QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
  373. QSignalSpy hostFoundSpy(&socket, SIGNAL(hostFound()));
  374. QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected()));
  375. QSignalSpy connectionEncryptedSpy(&socket, SIGNAL(encrypted()));
  376. QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(const QList<QSslError> &)));
  377. connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
  378. connect(&socket, SIGNAL(disconnected()), this, SLOT(exitLoop()));
  379. connect(&socket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(exitLoop()));
  380. connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
  381. connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(exitLoop()));
  382. connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(exitLoop()));
  383. // Start connecting
  384. socket.connectToHost(QtNetworkSettings::serverName(), 993);
  385. QCOMPARE(socket.state(), QAbstractSocket::HostLookupState);
  386. enterLoop(10);
  387. // Entered connecting state
  388. #ifndef Q_OS_SYMBIAN
  389. QCOMPARE(socket.state(), QAbstractSocket::ConnectingState);
  390. QCOMPARE(connectedSpy.count(), 0);
  391. #endif
  392. QCOMPARE(hostFoundSpy.count(), 1);
  393. QCOMPARE(disconnectedSpy.count(), 0);
  394. enterLoop(10);
  395. // Entered connected state
  396. QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
  397. QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
  398. QVERIFY(!socket.isEncrypted());
  399. QCOMPARE(connectedSpy.count(), 1);
  400. QCOMPARE(hostFoundSpy.count(), 1);
  401. QCOMPARE(disconnectedSpy.count(), 0);
  402. // Enter encrypted mode
  403. socket.startClientEncryption();
  404. QCOMPARE(socket.mode(), QSslSocket::SslClientMode);
  405. QVERIFY(!socket.isEncrypted());
  406. QCOMPARE(connectionEncryptedSpy.count(), 0);
  407. QCOMPARE(sslErrorsSpy.count(), 0);
  408. // Starting handshake
  409. enterLoop(10);
  410. QCOMPARE(sslErrorsSpy.count(), 1);
  411. QCOMPARE(connectionEncryptedSpy.count(), 0);
  412. QVERIFY(!socket.isEncrypted());
  413. QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
  414. }
  415. void tst_QSslSocket::simpleConnectWithIgnore()
  416. {
  417. if (!QSslSocket::supportsSsl())
  418. return;
  419. QFETCH_GLOBAL(bool, setProxy);
  420. if (setProxy)
  421. return;
  422. QSslSocket socket;
  423. this->socket = &socket;
  424. QSignalSpy encryptedSpy(&socket, SIGNAL(encrypted()));
  425. QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(const QList<QSslError> &)));
  426. connect(&socket, SIGNAL(readyRead()), this, SLOT(exitLoop()));
  427. connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
  428. connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
  429. connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  430. connect(&socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(exitLoop()));
  431. // Start connecting
  432. socket.connectToHost(QtNetworkSettings::serverName(), 993);
  433. QVERIFY(socket.state() != QAbstractSocket::UnconnectedState); // something must be in progress
  434. enterLoop(10);
  435. // Start handshake
  436. QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
  437. socket.startClientEncryption();
  438. enterLoop(10);
  439. // Done; encryption should be enabled.
  440. QCOMPARE(sslErrorsSpy.count(), 1);
  441. QVERIFY(socket.isEncrypted());
  442. QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
  443. QCOMPARE(encryptedSpy.count(), 1);
  444. // Wait for incoming data
  445. if (!socket.canReadLine())
  446. enterLoop(10);
  447. QByteArray data = socket.readAll();
  448. socket.disconnectFromHost();
  449. QVERIFY2(QtNetworkSettings::compareReplyIMAPSSL(data), data.constData());
  450. }
  451. void tst_QSslSocket::sslErrors_data()
  452. {
  453. QTest::addColumn<QString>("host");
  454. QTest::addColumn<int>("port");
  455. QTest::addColumn<SslErrorList>("expected");
  456. QTest::newRow(qPrintable(QtNetworkSettings::serverLocalName()))
  457. << QtNetworkSettings::serverLocalName()
  458. << 993
  459. << (SslErrorList() << QSslError::HostNameMismatch
  460. << QSslError::SelfSignedCertificate);
  461. }
  462. void tst_QSslSocket::sslErrors()
  463. {
  464. QFETCH(QString, host);
  465. QFETCH(int, port);
  466. QFETCH(SslErrorList, expected);
  467. QSslSocketPtr socket = newSocket();
  468. socket->connectToHostEncrypted(host, port);
  469. if (!socket->waitForConnected())
  470. QEXPECT_FAIL("imap.trolltech.com", "server not open to internet", Continue);
  471. socket->waitForEncrypted(5000);
  472. SslErrorList output;
  473. foreach (QSslError error, socket->sslErrors()) {
  474. output << error.error();
  475. }
  476. #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  477. if (output.count() && output.last() == QSslError::CertificateUntrusted)
  478. output.takeLast();
  479. #endif
  480. QCOMPARE(output, expected);
  481. }
  482. void tst_QSslSocket::addCaCertificate()
  483. {
  484. if (!QSslSocket::supportsSsl())
  485. return;
  486. }
  487. void tst_QSslSocket::addCaCertificates()
  488. {
  489. if (!QSslSocket::supportsSsl())
  490. return;
  491. }
  492. void tst_QSslSocket::addCaCertificates2()
  493. {
  494. if (!QSslSocket::supportsSsl())
  495. return;
  496. }
  497. void tst_QSslSocket::ciphers()
  498. {
  499. if (!QSslSocket::supportsSsl())
  500. return;
  501. QSslSocket socket;
  502. QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
  503. socket.setCiphers(QList<QSslCipher>());
  504. QVERIFY(socket.ciphers().isEmpty());
  505. socket.setCiphers(socket.defaultCiphers());
  506. QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
  507. socket.setCiphers(socket.defaultCiphers());
  508. QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
  509. // Task 164356
  510. socket.setCiphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
  511. }
  512. void tst_QSslSocket::connectToHostEncrypted()
  513. {
  514. if (!QSslSocket::supportsSsl())
  515. return;
  516. QSslSocketPtr socket = newSocket();
  517. this->socket = socket;
  518. QVERIFY(socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")));
  519. #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  520. connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
  521. this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
  522. #endif
  523. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  524. // This should pass unconditionally when using fluke's CA certificate.
  525. // or use untrusted certificate workaround
  526. QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
  527. socket->disconnectFromHost();
  528. QVERIFY(socket->waitForDisconnected());
  529. QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
  530. socket->connectToHost(QtNetworkSettings::serverName(), 13);
  531. QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
  532. QVERIFY(socket->waitForDisconnected());
  533. }
  534. void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName()
  535. {
  536. if (!QSslSocket::supportsSsl())
  537. return;
  538. QSslSocketPtr socket = newSocket();
  539. this->socket = socket;
  540. socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
  541. #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  542. connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
  543. this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
  544. #endif
  545. // connect to the server with its local name, but use the full name for verification.
  546. socket->connectToHostEncrypted(QtNetworkSettings::serverLocalName(), 443, QtNetworkSettings::serverName());
  547. // This should pass unconditionally when using fluke's CA certificate.
  548. QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
  549. socket->disconnectFromHost();
  550. QVERIFY(socket->waitForDisconnected());
  551. QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
  552. }
  553. void tst_QSslSocket::sessionCipher()
  554. {
  555. if (!QSslSocket::supportsSsl())
  556. return;
  557. QSslSocketPtr socket = newSocket();
  558. this->socket = socket;
  559. connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
  560. QVERIFY(socket->sessionCipher().isNull());
  561. socket->connectToHost(QtNetworkSettings::serverName(), 443 /* https */);
  562. QVERIFY(socket->waitForConnected(10000));
  563. QVERIFY(socket->sessionCipher().isNull());
  564. socket->startClientEncryption();
  565. QVERIFY(socket->waitForEncrypted(5000));
  566. QVERIFY(!socket->sessionCipher().isNull());
  567. QVERIFY(QSslSocket::supportedCiphers().contains(socket->sessionCipher()));
  568. socket->disconnectFromHost();
  569. QVERIFY(socket->waitForDisconnected());
  570. }
  571. void tst_QSslSocket::flush()
  572. {
  573. }
  574. void tst_QSslSocket::isEncrypted()
  575. {
  576. }
  577. void tst_QSslSocket::localCertificate()
  578. {
  579. if (!QSslSocket::supportsSsl())
  580. return;
  581. // This test does not make 100% sense yet. We just set some local CA/cert/key and use it
  582. // to authenticate ourselves against the server. The server does not actually check this
  583. // values. This test should just run the codepath inside qsslsocket_openssl.cpp
  584. QSslSocketPtr socket = newSocket();
  585. QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
  586. socket->setCaCertificates(localCert);
  587. socket->setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
  588. socket->setPrivateKey(QLatin1String(SRCDIR "certs/fluke.key"));
  589. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  590. QVERIFY(socket->waitForEncrypted(10000));
  591. }
  592. void tst_QSslSocket::mode()
  593. {
  594. }
  595. void tst_QSslSocket::peerCertificate()
  596. {
  597. }
  598. void tst_QSslSocket::peerCertificateChain()
  599. {
  600. if (!QSslSocket::supportsSsl())
  601. return;
  602. QSslSocketPtr socket = newSocket();
  603. this->socket = socket;
  604. QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem"));
  605. QVERIFY(caCertificates.count() == 1);
  606. socket->addCaCertificates(caCertificates);
  607. #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  608. connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
  609. this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
  610. #endif
  611. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  612. QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
  613. QVERIFY(socket->peerCertificateChain().isEmpty());
  614. QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
  615. QList<QSslCertificate> certChain = socket->peerCertificateChain();
  616. QVERIFY(certChain.count() > 0);
  617. QCOMPARE(certChain.first(), socket->peerCertificate());
  618. socket->disconnectFromHost();
  619. QVERIFY(socket->waitForDisconnected());
  620. // connect again to a different server
  621. socket->connectToHostEncrypted("trolltech.com", 443);
  622. socket->ignoreSslErrors();
  623. QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
  624. QVERIFY(socket->peerCertificateChain().isEmpty());
  625. QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
  626. QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate());
  627. QVERIFY(socket->peerCertificateChain() != certChain);
  628. socket->disconnectFromHost();
  629. QVERIFY(socket->waitForDisconnected());
  630. // now do it again back to the original server
  631. socket->connectToHost(QtNetworkSettings::serverName(), 443);
  632. QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
  633. QVERIFY(socket->peerCertificateChain().isEmpty());
  634. QVERIFY2(socket->waitForConnected(10000), "Network timeout");
  635. socket->startClientEncryption();
  636. QVERIFY2(socket->waitForEncrypted(10000), qPrintable(socket->errorString()));
  637. QCOMPARE(socket->peerCertificateChain().first(), socket->peerCertificate());
  638. QVERIFY(socket->peerCertificateChain() == certChain);
  639. socket->disconnectFromHost();
  640. QVERIFY(socket->waitForDisconnected());
  641. }
  642. void tst_QSslSocket::privateKey()
  643. {
  644. }
  645. void tst_QSslSocket::protocol()
  646. {
  647. if (!QSslSocket::supportsSsl())
  648. return;
  649. QSslSocketPtr socket = newSocket();
  650. this->socket = socket;
  651. QList<QSslCertificate> certs = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
  652. socket->setCaCertificates(certs);
  653. #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  654. connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
  655. this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
  656. #endif
  657. QCOMPARE(socket->protocol(), QSsl::SecureProtocols);
  658. {
  659. // Fluke allows SSLv3.
  660. socket->setProtocol(QSsl::SslV3);
  661. QCOMPARE(socket->protocol(), QSsl::SslV3);
  662. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  663. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  664. QCOMPARE(socket->protocol(), QSsl::SslV3);
  665. socket->abort();
  666. QCOMPARE(socket->protocol(), QSsl::SslV3);
  667. socket->connectToHost(QtNetworkSettings::serverName(), 443);
  668. QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
  669. socket->startClientEncryption();
  670. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  671. QCOMPARE(socket->protocol(), QSsl::SslV3);
  672. socket->abort();
  673. }
  674. {
  675. // Fluke allows TLSV1.
  676. socket->setProtocol(QSsl::TlsV1);
  677. QCOMPARE(socket->protocol(), QSsl::TlsV1);
  678. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  679. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  680. QCOMPARE(socket->protocol(), QSsl::TlsV1);
  681. socket->abort();
  682. QCOMPARE(socket->protocol(), QSsl::TlsV1);
  683. socket->connectToHost(QtNetworkSettings::serverName(), 443);
  684. QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
  685. socket->startClientEncryption();
  686. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  687. QCOMPARE(socket->protocol(), QSsl::TlsV1);
  688. socket->abort();
  689. }
  690. {
  691. // Fluke allows SSLV2.
  692. socket->setProtocol(QSsl::SslV2);
  693. QCOMPARE(socket->protocol(), QSsl::SslV2);
  694. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  695. QVERIFY(socket->waitForEncrypted());
  696. QCOMPARE(socket->protocol(), QSsl::SslV2);
  697. socket->abort();
  698. QCOMPARE(socket->protocol(), QSsl::SslV2);
  699. socket->connectToHost(QtNetworkSettings::serverName(), 443);
  700. QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
  701. socket->startClientEncryption();
  702. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  703. socket->abort();
  704. }
  705. {
  706. // Fluke allows SSLV3, so it allows AnyProtocol.
  707. socket->setProtocol(QSsl::AnyProtocol);
  708. QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
  709. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  710. QVERIFY(socket->waitForEncrypted());
  711. QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
  712. socket->abort();
  713. QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
  714. socket->connectToHost(QtNetworkSettings::serverName(), 443);
  715. QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
  716. socket->startClientEncryption();
  717. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  718. QCOMPARE(socket->protocol(), QSsl::AnyProtocol);
  719. socket->abort();
  720. }
  721. {
  722. // Fluke allows SSLV3, so it allows NoSslV2
  723. socket->setProtocol(QSsl::TlsV1SslV3);
  724. QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
  725. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  726. QVERIFY(socket->waitForEncrypted());
  727. QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
  728. socket->abort();
  729. QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
  730. socket->connectToHost(QtNetworkSettings::serverName(), 443);
  731. QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
  732. socket->startClientEncryption();
  733. QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
  734. QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3);
  735. socket->abort();
  736. }
  737. }
  738. class SslServer : public QTcpServer
  739. {
  740. Q_OBJECT
  741. public:
  742. SslServer(const QString &keyFile = SRCDIR "certs/fluke.key", const QString &certFile = SRCDIR "certs/fluke.cert")
  743. : socket(0),
  744. protocol(QSsl::TlsV1),
  745. m_keyFile(keyFile),
  746. m_certFile(certFile) { }
  747. QSslSocket *socket;
  748. QSsl::SslProtocol protocol;
  749. QString m_keyFile;
  750. QString m_certFile;
  751. protected:
  752. void incomingConnection(int socketDescriptor)
  753. {
  754. socket = new QSslSocket(this);
  755. socket->setProtocol(protocol);
  756. connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  757. QFile file(m_keyFile);
  758. QVERIFY(file.open(QIODevice::ReadOnly));
  759. QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
  760. QVERIFY(!key.isNull());
  761. socket->setPrivateKey(key);
  762. QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile);
  763. QVERIFY(!localCert.isEmpty());
  764. QVERIFY(localCert.first().handle());
  765. socket->setLocalCertificate(localCert.first());
  766. QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
  767. QVERIFY(!socket->peerAddress().isNull());
  768. QVERIFY(socket->peerPort() != 0);
  769. QVERIFY(!socket->localAddress().isNull());
  770. QVERIFY(socket->localPort() != 0);
  771. socket->startServerEncryption();
  772. }
  773. protected slots:
  774. void ignoreErrorSlot()
  775. {
  776. socket->ignoreSslErrors();
  777. }
  778. };
  779. void tst_QSslSocket::protocolServerSide_data()
  780. {
  781. QTest::addColumn<QSsl::SslProtocol>("serverProtocol");
  782. QTest::addColumn<QSsl::SslProtocol>("clientProtocol");
  783. QTest::addColumn<bool>("works");
  784. QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2
  785. QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true;
  786. QTest::newRow("tls1-tls1") << QSsl::TlsV1 << QSsl::TlsV1 << true;
  787. QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true;
  788. QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true;
  789. QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true;
  790. QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false;
  791. QTest::newRow("ssl2-tls1") << QSsl::SslV2 << QSsl::TlsV1 << false;
  792. QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false;
  793. QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false;
  794. QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2
  795. QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false;
  796. QTest::newRow("ssl3-tls1") << QSsl::SslV3 << QSsl::TlsV1 << false;
  797. QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true;
  798. QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << true;
  799. QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a
  800. // numerical IP, so OpenSSL will send a SSL 2 handshake
  801. QTest::newRow("tls1-ssl2") << QSsl::TlsV1 << QSsl::SslV2 << false;
  802. QTest::newRow("tls1-ssl3") << QSsl::TlsV1 << QSsl::SslV3 << false;
  803. QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1 << QSsl::TlsV1SslV3 << true;
  804. QTest::newRow("tls1-secure") << QSsl::TlsV1 << QSsl::SecureProtocols << true;
  805. QTest::newRow("tls1-any") << QSsl::TlsV1 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a
  806. // numerical IP, so OpenSSL will send a SSL 2 handshake
  807. QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false;
  808. QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true;
  809. QTest::newRow("tls1ssl3-tls1") << QSsl::TlsV1SslV3 << QSsl::TlsV1 << true;
  810. QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true;
  811. QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true;
  812. QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false;
  813. QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << true;
  814. QTest::newRow("secure-tls1") << QSsl::SecureProtocols << QSsl::TlsV1 << true;
  815. QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true;
  816. QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true;
  817. QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2
  818. QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true;
  819. QTest::newRow("any-tls1") << QSsl::AnyProtocol << QSsl::TlsV1 << true;
  820. QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true;
  821. QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true;
  822. }
  823. void tst_QSslSocket::protocolServerSide()
  824. {
  825. if (!QSslSocket::supportsSsl()) {
  826. qWarning("SSL not supported, skipping test");
  827. return;
  828. }
  829. QFETCH_GLOBAL(bool, setProxy);
  830. if (setProxy)
  831. return;
  832. QFETCH(QSsl::SslProtocol, serverProtocol);
  833. SslServer server;
  834. server.protocol = serverProtocol;
  835. QVERIFY(server.listen());
  836. QEventLoop loop;
  837. QTimer::singleShot(5000, &loop, SLOT(quit()));
  838. QSslSocketPtr client = new QSslSocket;
  839. socket = client;
  840. QFETCH(QSsl::SslProtocol, clientProtocol);
  841. socket->setProtocol(clientProtocol);
  842. // upon SSL wrong version error, error will be triggered, not sslErrors
  843. connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit()));
  844. connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  845. connect(client, SIGNAL(encrypted()), &loop, SLOT(quit()));
  846. client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
  847. loop.exec();
  848. QFETCH(bool, works);
  849. QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState;
  850. QCOMPARE(client->state(), expectedState);
  851. QCOMPARE(client->isEncrypted(), works);
  852. }
  853. void tst_QSslSocket::setCaCertificates()
  854. {
  855. if (!QSslSocket::supportsSsl())
  856. return;
  857. QSslSocket socket;
  858. QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
  859. socket.setCaCertificates(QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"));
  860. QCOMPARE(socket.caCertificates().size(), 1);
  861. socket.setCaCertificates(socket.defaultCaCertificates());
  862. QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates());
  863. }
  864. void tst_QSslSocket::setLocalCertificate()
  865. {
  866. }
  867. void tst_QSslSocket::setPrivateKey()
  868. {
  869. }
  870. void tst_QSslSocket::setSocketDescriptor()
  871. {
  872. if (!QSslSocket::supportsSsl())
  873. return;
  874. QFETCH_GLOBAL(bool, setProxy);
  875. if (setProxy)
  876. return;
  877. SslServer server;
  878. QVERIFY(server.listen());
  879. QEventLoop loop;
  880. QTimer::singleShot(5000, &loop, SLOT(quit()));
  881. QSslSocketPtr client = new QSslSocket;
  882. socket = client;
  883. connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  884. connect(client, SIGNAL(encrypted()), &loop, SLOT(quit()));
  885. client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
  886. loop.exec();
  887. QCOMPARE(client->state(), QAbstractSocket::ConnectedState);
  888. QVERIFY(client->isEncrypted());
  889. QVERIFY(!client->peerAddress().isNull());
  890. QVERIFY(client->peerPort() != 0);
  891. QVERIFY(!client->localAddress().isNull());
  892. QVERIFY(client->localPort() != 0);
  893. }
  894. void tst_QSslSocket::setSslConfiguration_data()
  895. {
  896. QTest::addColumn<QSslConfiguration>("configuration");
  897. QTest::addColumn<bool>("works");
  898. QTest::newRow("empty") << QSslConfiguration() << false;
  899. QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
  900. QTest::newRow("default") << conf << false; // does not contain test server cert
  901. QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
  902. conf.setCaCertificates(testServerCert);
  903. QTest::newRow("set-root-cert") << conf << true;
  904. conf.setProtocol(QSsl::SecureProtocols);
  905. QTest::newRow("secure") << conf << true;
  906. }
  907. void tst_QSslSocket::setSslConfiguration()
  908. {
  909. if (!QSslSocket::supportsSsl())
  910. return;
  911. QSslSocketPtr socket = newSocket();
  912. QFETCH(QSslConfiguration, configuration);
  913. socket->setSslConfiguration(configuration);
  914. this->socket = socket;
  915. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  916. QFETCH(bool, works);
  917. QCOMPARE(socket->waitForEncrypted(10000), works);
  918. if (works) {
  919. socket->disconnectFromHost();
  920. QVERIFY2(socket->waitForDisconnected(), qPrintable(socket->errorString()));
  921. }
  922. }
  923. void tst_QSslSocket::waitForEncrypted()
  924. {
  925. if (!QSslSocket::supportsSsl())
  926. return;
  927. QSslSocketPtr socket = newSocket();
  928. this->socket = socket;
  929. connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  930. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  931. QVERIFY(socket->waitForEncrypted(10000));
  932. }
  933. void tst_QSslSocket::waitForEncryptedMinusOne()
  934. {
  935. if (!QSslSocket::supportsSsl())
  936. return;
  937. QSslSocketPtr socket = newSocket();
  938. this->socket = socket;
  939. connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  940. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443);
  941. QVERIFY(socket->waitForEncrypted(-1));
  942. }
  943. void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
  944. {
  945. if (!QSslSocket::supportsSsl())
  946. return;
  947. QSslSocketPtr socket = newSocket();
  948. this->socket = socket;
  949. connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot()));
  950. socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 993);
  951. #ifdef Q_OS_SYMBIAN
  952. QVERIFY(socket->waitForConnected(10000));
  953. QVERIFY(socket->waitForEncrypted(10000));
  954. // dont forget to login
  955. QCOMPARE((int) socket->write("USER ftptest\r\n"), 14);
  956. QCOMPARE((int) socket->write("PASS ftP2Ptf\r\n"), 14);
  957. QVERIFY(socket->waitForReadyRead(10000));
  958. QVERIFY(!socket->peerCertificate().isNull());
  959. QVERIFY(!socket->peerCertificateChain().isEmpty());
  960. #else
  961. QVERIFY(socket->waitForConnected(10000));
  962. QVERIFY(socket->waitForEncrypted(10000));
  963. QVERIFY(socket->waitForReadyRead(10000));
  964. QVERIFY(!socket->peerCertificate().isNull());
  965. QVERIFY(!socket->peerCertificateChain().isEmpty());
  966. #endif
  967. }
  968. void tst_QSslSocket::startClientEncryption()
  969. {
  970. }
  971. void tst_QSslSocket::startServerEncryption()
  972. {
  973. }
  974. void tst_QSslSocket::addDefaultCaCertificate()
  975. {
  976. if (!QSslSocket::supportsSsl())
  977. return;
  978. // Reset the global CA chain
  979. QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
  980. QList<QSslCertificate> flukeCerts = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem");
  981. QCOMPARE(flukeCerts.size(), 1);
  982. QList<QSslCertificate> globalCerts = QSslSocket::defaultCaCertificates();
  983. QVERIFY(!globalCerts.contains(flukeCerts.first()));
  984. QSslSocket::addDefaultCaCertificate(flukeCerts.first());
  985. QCOMPARE(QSslSocket::defaultCaCertificates().size(), globalCerts.size() + 1);
  986. QVERIFY(QSslSocket::defaultCaCertificates().contains(flukeCerts.first()));
  987. // Restore the global CA chain
  988. QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());
  989. }
  990. void tst_QSslSocket::addDefaultCaCertificates()
  991. {
  992. }
  993. void tst_QSslSocket::addDefaultCaCertificates2()
  994. {
  995. }
  996. void tst_QSslSocket::defaultCaCertificates()
  997. {
  998. if (!QSslSocket::supportsSsl())
  999. return;
  1000. QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
  1001. QVERIFY(certs.size() > 1);
  1002. QCOMPARE(certs, QSslSocket::systemCaCertificates());
  1003. }
  1004. void tst_QSslSocket::defaultCiphers()
  1005. {
  1006. }
  1007. void tst_QSslSocket::resetDefaultCiphers()
  1008. {
  1009. }
  1010. void tst_QSslSocket::setDefaultCaCertificates()
  1011. {
  1012. }
  1013. void tst_QSslSocket::setDefaultCiphers()
  1014. {
  1015. }
  1016. void tst_QSslSocket::supportedCiphers()
  1017. {
  1018. if (!QSslSocket::supportsSsl())
  1019. return;
  1020. QList<QSslCipher> ciphers = QSslSocket::supportedCiphers();
  1021. QVERIFY(ciphers.size() > 1);
  1022. QSslSocket socket;
  1023. QCOMPARE(socket.supportedCiphers(), ciphers);
  1024. QCOMPARE(socket.defaultCiphers(), ciphers);
  1025. QCOMPARE(socket.ciphers(), ciphers);
  1026. }
  1027. void tst_QSslSocket::systemCaCertificates()
  1028. {
  1029. if (!QSslSocket::supportsSsl())
  1030. return;
  1031. QList<QSslCertificate> certs = QSslSocket::systemCaCertificates();
  1032. QVERIFY(certs.size() > 1);
  1033. QCOMPARE(certs, QSslSocket::defaultCaCertificates());
  1034. }
  1035. void tst_QSslSocket::wildcardCertificateNames()
  1036. {
  1037. // Passing CN matches
  1038. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("www.example.com"), QString("www.example.com")), true );
  1039. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("www.example.com")), true );
  1040. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx*.example.com"), QString("xxxwww.example.com")), true );
  1041. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("foo.example.com")), true );
  1042. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("192.168.0.0"), QString("192.168.0.0")), true );
  1043. // Failing CN matches
  1044. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("xxx.example.com"), QString("www.example.com")), false );
  1045. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www.example.com")), false );
  1046. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.*.com"), QString("www.example.com")), false );
  1047. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example.com"), QString("baa.foo.example.com")), false );
  1048. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("f*.example.com"), QString("baa.example.com")), false );
  1049. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.com"), QString("example.com")), false );
  1050. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*fail.com"), QString("example.com")), false );
  1051. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example.")), false );
  1052. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.example."), QString("www.example")), false );
  1053. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString(""), QString("www")), false );
  1054. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*"), QString("www")), false );
  1055. QCOMPARE( QSslSocketBackendPrivate::isMatchingHostname(QString("*.168.0.0"), QString("192.168.0.0")), false );
  1056. }
  1057. void tst_QSslSocket::wildcard()
  1058. {
  1059. QSKIP("TODO: solve wildcard problem", SkipAll);
  1060. if (!QSslSocket::supportsSsl())
  1061. return;
  1062. // Fluke runs an apache server listening on port 4443, serving the
  1063. // wildcard fluke.*.troll.no. The DNS entry for
  1064. // fluke.wildcard.dev.troll.no, served by ares (root for dev.troll.no),
  1065. // returns the CNAME fluke.troll.no for this domain. The web server
  1066. // responds with the wildcard, and QSslSocket should accept that as a
  1067. // valid connection. This was broken in 4.3.0.
  1068. QSslSocketPtr socket = newSocket();
  1069. socket->addCaCertificates(QLatin1String("certs/aspiriniks.ca.crt"));
  1070. this->socket = socket;
  1071. #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND
  1072. connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
  1073. this, SLOT(untrustedWorkaroundSlot(QList<QSslError>)));
  1074. #endif
  1075. socket->connectToHostEncrypted(QtNetworkSettings::wildcardServerName(), 4443);
  1076. QVERIFY2(socket->waitForEncrypted(3000), qPrintable(socket->errorString()));
  1077. QSslCertificate certificate = socket->peerCertificate();
  1078. QCOMPARE(certificate.subjectInfo(QSslCertificate::CommonName), QString(QtNetworkSettings::serverLocalName() + ".*." + QtNetworkSettings::serverDomainName()));
  1079. QCOMPARE(certificate.issuerInfo(QSslCertificate::CommonName), QtNetworkSettings::serverName());
  1080. socket->close();
  1081. }
  1082. class SslServer2 : public QTcpServer
  1083. {
  1084. protected:
  1085. void incomingConnection(int socketDescriptor)
  1086. {
  1087. QSslSocket *socket = new QSslSocket(this);
  1088. socket->ignoreSslErrors();
  1089. // Only set the certificate
  1090. QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert");
  1091. QVERIFY(!localCert.isEmpty());
  1092. QVERIFY(localCert.first().handle());
  1093. socket->setLocalCertificate(localCert.first());
  1094. QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState));
  1095. socket->startServerEncryption();
  1096. }
  1097. };
  1098. void tst_QSslSocket::setEmptyKey()
  1099. {
  1100. if (!QSslSocket::supportsSsl())
  1101. return;
  1102. QFETCH_GLOBAL(bool, setProxy);
  1103. if (setProxy)
  1104. return;
  1105. SslServer2 server;
  1106. server.listen();
  1107. QSslSocket socket;
  1108. socket.connectToHostEncrypted("127.0.0.1", server.serverPort());
  1109. QTestEventLoop::instance().enterLoop(2);
  1110. QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
  1111. QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
  1112. }
  1113. void tst_QSslSocket::spontaneousWrite()
  1114. {
  1115. QFETCH_GLOBAL(bool, setProxy);
  1116. if (setProxy)
  1117. return;
  1118. SslServer server;
  1119. QSslSocket *receiver = new QSslSocket(this);
  1120. connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
  1121. // connect two sockets to each other:
  1122. QVERIFY(server.listen(QHostAddress::LocalHost));
  1123. receiver->connectToHost("127.0.0.1", server.serverPort());
  1124. QVERIFY(receiver->waitForConnected(5000));
  1125. QVERIFY(server.waitForNewConnection(0));
  1126. QSslSocket *sender = server.socket;
  1127. QVERIFY(sender);
  1128. QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
  1129. receiver->setObjectName("receiver");
  1130. sender->setObjectName("sender");
  1131. receiver->ignoreSslErrors();
  1132. receiver->startClientEncryption();
  1133. // SSL handshake:
  1134. connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
  1135. enterLoop(1);
  1136. QVERIFY(!timeout());
  1137. QVERIFY(sender->isEncrypted());
  1138. QVERIFY(receiver->isEncrypted());
  1139. // make sure there's nothing to be received on the sender:
  1140. while (sender->waitForReadyRead(10) || receiver->waitForBytesWritten(10)) {}
  1141. // spontaneously write something:
  1142. QByteArray data("Hello World");
  1143. sender->write(data);
  1144. // check if the other side receives it:
  1145. enterLoop(1);
  1146. QVERIFY(!timeout());
  1147. QCOMPARE(receiver->bytesAvailable(), qint64(data.size()));
  1148. QCOMPARE(receiver->readAll(), data);
  1149. }
  1150. void tst_QSslSocket::setReadBufferSize()
  1151. {
  1152. QFETCH_GLOBAL(bool, setProxy);
  1153. if (setProxy)
  1154. return;
  1155. SslServer server;
  1156. QSslSocket *receiver = new QSslSocket(this);
  1157. connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop()));
  1158. // connect two sockets to each other:
  1159. QVERIFY(server.listen(QHostAddress::LocalHost));
  1160. receiver->connectToHost("127.0.0.1", server.serverPort());
  1161. QVERIFY(receiver->waitForConnected(5000));
  1162. QVERIFY(server.waitForNewConnection(0));
  1163. QSslSocket *sender = server.socket;
  1164. QVERIFY(sender);
  1165. QVERIFY(sender->state() == QAbstractSocket::ConnectedState);
  1166. receiver->setObjectName("receiver");
  1167. sender->setObjectName("sender");
  1168. receiver->ignoreSslErrors();
  1169. receiver->startClientEncryption();
  1170. // SSL handshake:
  1171. connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
  1172. enterLoop(1);
  1173. QVERIFY(!timeout());
  1174. QVERIFY(sender->isEncrypted());
  1175. QVERIFY(receiver->isEncrypted());
  1176. QByteArray data(2048, 'b');
  1177. receiver->setReadBufferSize(39 * 1024); // make it a non-multiple of the data.size()
  1178. // saturate the incoming buffer
  1179. while (sender->state() == QAbstractSocket::ConnectedState &&
  1180. receiver->state() == QAbstractSocket::ConnectedState &&
  1181. receiver->bytesAvailable() < receiver->readBufferSize()) {
  1182. sender->write(data);
  1183. //qDebug() << receiver->bytesAvailable() << "<" << receiver->readBufferSize() << (receiver->bytesAvailable() < receiver->readBufferSize());
  1184. while (sender->bytesToWrite())
  1185. QVERIFY(sender->waitForBytesWritten(10));
  1186. // drain it:
  1187. while (receiver->bytesAvailable() < receiver->readBufferSize() &&