summaryrefslogtreecommitdiffstats
path: root/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp')
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp1077
1 files changed, 609 insertions, 468 deletions
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index f9790e8597..b45d6b5d8f 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -1,31 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2014 Governikus GmbH & Co. KG.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2014 Governikus GmbH & Co. KG.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/qglobal.h>
#include <QtCore/qthread.h>
@@ -42,6 +19,8 @@
#include <QtNetwork/qtcpserver.h>
#include <QtNetwork/qsslpresharedkeyauthenticator.h>
+#include <QtTest/private/qemulationdetector_p.h>
+
#include <QTest>
#include <QNetworkProxy>
#include <QAuthenticator>
@@ -53,19 +32,34 @@
#include "private/qiodevice_p.h" // for QIODEVICE_BUFFERSIZE
#include "../../../network-settings.h"
+#include "../shared/tlshelpers.h"
-#ifndef QT_NO_SSL
+#if QT_CONFIG(openssl)
+#include "../shared/qopenssl_symbols.h"
+#endif
#include "private/qtlsbackend_p.h"
-#ifndef QT_NO_OPENSSL
-#include "private/qsslsocket_openssl_p.h"
-#include "private/qsslsocket_openssl_symbols_p.h"
-#endif // QT_NO_OPENSSL
-
#include "private/qsslsocket_p.h"
#include "private/qsslconfiguration_p.h"
+using namespace std::chrono_literals;
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+// make these enum values available without causing deprecation warnings:
+namespace Test {
+#define COPY(tag, v) \
+ constexpr auto tag ## V ## v = QSsl:: tag ## V ## v ; \
+ constexpr auto tag ## V ## v ## OrLater = QSsl:: tag ## V ## v ## OrLater ; \
+ /* end */
+COPY(Tls, 1_0)
+COPY(Dtls, 1_0)
+COPY(Tls, 1_1)
+#undef COPY
+} // namespace Test
+QT_WARNING_POP
+
Q_DECLARE_METATYPE(QSslSocket::SslMode)
typedef QList<QSslError::SslError> SslErrorList;
Q_DECLARE_METATYPE(SslErrorList)
@@ -75,26 +69,6 @@ Q_DECLARE_METATYPE(QSsl::SslProtocol)
Q_DECLARE_METATYPE(QSslSocket::PeerVerifyMode);
typedef QSharedPointer<QSslSocket> QSslSocketPtr;
-// Non-OpenSSL backends are not able to report a specific error code
-// for self-signed certificates.
-#ifndef QT_NO_OPENSSL
-#define FLUKE_CERTIFICATE_ERROR QSslError::SelfSignedCertificate
-#else
-#define FLUKE_CERTIFICATE_ERROR QSslError::CertificateUntrusted
-#endif // QT_NO_OPENSSL
-
-#endif // QT_NO_OPENSSL
-
-// Detect ALPN (Application-Layer Protocol Negotiation) support
-#undef ALPN_SUPPORTED // Undef the variable first to be safe
-#if defined(OPENSSL_VERSION_NUMBER) && !defined(OPENSSL_NO_TLSEXT)
-#define ALPN_SUPPORTED 1
-#endif
-
-#if QT_CONFIG(schannel) && !defined(Q_CC_MINGW)
-#define ALPN_SUPPORTED 1
-#endif
-
#if defined Q_OS_HPUX && defined Q_CC_GNU
// This error is delivered every time we try to use the fluke CA
// certificate. For now we work around this bug. Task 202317.
@@ -104,19 +78,18 @@ typedef QSharedPointer<QSslSocket> QSslSocketPtr;
// Use this cipher to force PSK key sharing.
// Also, it's a cipher w/o auth, to check that we emit the signals warning
// about the identity of the peer.
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
static const QString PSK_CIPHER_WITHOUT_AUTH = QStringLiteral("PSK-AES256-CBC-SHA");
static const quint16 PSK_SERVER_PORT = 4433;
static const QByteArray PSK_CLIENT_PRESHAREDKEY = QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f");
static const QByteArray PSK_SERVER_IDENTITY_HINT = QByteArrayLiteral("QtTestServerHint");
static const QByteArray PSK_CLIENT_IDENTITY = QByteArrayLiteral("Client_identity");
+#endif // QT_CONFIG(openssl)
QT_BEGIN_NAMESPACE
void qt_ForceTlsSecurityLevel();
QT_END_NAMESPACE
-#endif // !QT_NO_OPENSSL
-
class tst_QSslSocket : public QObject
{
Q_OBJECT
@@ -137,10 +110,10 @@ public:
return QTestEventLoop::instance().timeout();
}
-#ifndef QT_NO_SSL
+#if QT_CONFIG(ssl)
QSslSocketPtr newSocket();
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
enum PskConnectTestType {
PskConnectDoNotHandlePsk,
PskConnectEmptyCredentials,
@@ -151,19 +124,19 @@ public:
PskConnectRightCredentialsVerifyPeer,
PskConnectRightCredentialsDoNotVerifyPeer,
};
-#endif
-#endif
+#endif // QT_CONFIG(openssl)
+#endif // QT_CONFIG(ssl)
public slots:
void initTestCase_data();
void initTestCase();
void init();
void cleanup();
-#ifndef QT_NO_NETWORKPROXY
+#if QT_CONFIG(networkproxy)
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
#endif
-#ifndef QT_NO_SSL
+#if QT_CONFIG(ssl)
private slots:
void activeBackend();
void backends();
@@ -176,25 +149,24 @@ private slots:
void sslErrors_data();
void sslErrors();
void ciphers();
+#if QT_CONFIG(securetransport)
+ void tls13Ciphers();
+#endif // QT_CONFIG(securetransport)
void connectToHostEncrypted();
void connectToHostEncryptedWithVerificationPeerName();
void sessionCipher();
- void flush();
- void isEncrypted();
void localCertificate();
void mode();
void peerCertificate();
void peerCertificateChain();
void privateKey();
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
void privateKeyOpaque();
#endif
void protocol();
void protocolServerSide_data();
void protocolServerSide();
-#ifndef QT_NO_OPENSSL
void serverCipherPreferences();
-#endif // QT_NO_OPENSSL
void setCaCertificates();
void setLocalCertificate();
void localCertificateChain();
@@ -226,12 +198,10 @@ private slots:
void waitForMinusOne();
void verifyMode();
void verifyDepth();
-#ifndef QT_NO_OPENSSL
void verifyAndDefaultConfiguration();
-#endif // QT_NO_OPENSSL
void disconnectFromHostWhenConnecting();
void disconnectFromHostWhenConnected();
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
void closeWhileEmittingSocketError();
#endif
void resetProxy();
@@ -244,19 +214,16 @@ private slots:
void writeBigChunk();
void blacklistedCertificates();
void versionAccessors();
-#ifndef QT_NO_OPENSSL
- void sslOptions();
-#endif
void encryptWithoutConnecting();
void resume_data();
void resume();
void qtbug18498_peek();
void qtbug18498_peek2();
void dhServer();
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
void dhServerCustomParamsNull();
void dhServerCustomParams();
-#endif
+#endif // QT_CONFIG(openssl)
void ecdhServer();
void verifyClientCertificate_data();
void verifyClientCertificate();
@@ -264,7 +231,7 @@ private slots:
void allowedProtocolNegotiation();
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
void simplePskConnect_data();
void simplePskConnect();
void ephemeralServerKey_data();
@@ -273,7 +240,7 @@ private slots:
void forwardReadChannelFinished();
void signatureAlgorithm_data();
void signatureAlgorithm();
-#endif
+#endif // QT_CONFIG(openssl)
void unsupportedProtocols_data();
void unsupportedProtocols();
@@ -323,19 +290,48 @@ protected slots:
private:
QSslSocket *socket;
QList<QSslError> storedExpectedSslErrors;
-#endif // QT_NO_SSL
+ bool isTestingOpenSsl = false;
+ bool isSecurityLevel0Required = false;
+ bool opensslResolved = false;
+ bool isTestingSecureTransport = false;
+ bool isTestingSchannel = false;
+ QSslError::SslError flukeCertificateError = QSslError::CertificateUntrusted;
+ bool hasServerAlpn = false;
+#endif // QT_CONFIG(ssl)
private:
static int loopLevel;
public:
static QString testDataDir;
+
+ bool supportsTls13() const
+ {
+ if (isTestingOpenSsl) {
+#ifdef TLS1_3_VERSION
+ return true;
+#endif
+ }
+ if (isTestingSchannel) {
+ // Copied from qtls_schannel.cpp #supportsTls13()
+ static bool supported = []() {
+ const auto current = QOperatingSystemVersion::current();
+ const auto minimum =
+ QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 20221);
+ return current >= minimum;
+ }();
+ return supported;
+ }
+
+ return false;
+ }
+
};
QString tst_QSslSocket::testDataDir;
-#ifndef QT_NO_SSL
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(ssl)
+#if QT_CONFIG(openssl)
Q_DECLARE_METATYPE(tst_QSslSocket::PskConnectTestType)
-#endif
-#endif
+#endif // QT_CONFIG(openssl)
+#endif // QT_CONFIG(ssl)
int tst_QSslSocket::loopLevel = 0;
@@ -352,39 +348,22 @@ QString httpServerCertChainPath()
#endif // QT_TEST_SERVER
}
-bool supportsTls13()
-{
-#ifdef TLS1_3_VERSION
- return true;
-#elif QT_CONFIG(schannel)
- // Copied from qsslsocket_schannel.cpp #supportsTls13()
- static bool supported = []() {
- const auto current = QOperatingSystemVersion::current();
- const auto minimum =
- QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 20221);
- return current >= minimum;
- }();
- return supported;
-#else
- return false;
-#endif
-}
-
} // unnamed namespace
tst_QSslSocket::tst_QSslSocket()
{
-#ifndef QT_NO_SSL
+#if QT_CONFIG(ssl)
qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
qRegisterMetaType<QSslError>("QSslError");
qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
qRegisterMetaType<QSslPreSharedKeyAuthenticator *>();
qRegisterMetaType<tst_QSslSocket::PskConnectTestType>();
-#endif
-#endif
+#endif // QT_CONFIG(openssl)
+
+#endif // QT_CONFIG(ssl)
}
enum ProxyTests {
@@ -421,7 +400,31 @@ void tst_QSslSocket::initTestCase()
testDataDir = QCoreApplication::applicationDirPath();
if (!testDataDir.endsWith(QLatin1String("/")))
testDataDir += QLatin1String("/");
-#ifndef QT_NO_SSL
+
+ hasServerAlpn = QSslSocket::supportedFeatures().contains(QSsl::SupportedFeature::ServerSideAlpn);
+ // Several plugins (TLS-backends) can co-exist. QSslSocket would implicitly
+ // select 'openssl' if available, and if not: 'securetransport' (Darwin) or
+ // 'schannel' (Windows). Check what we actually have:
+ const auto &tlsBackends = QSslSocket::availableBackends();
+ if (tlsBackends.contains(QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexOpenSSL])) {
+ isTestingOpenSsl = true;
+ flukeCertificateError = QSslError::SelfSignedCertificate;
+#if QT_CONFIG(openssl)
+ opensslResolved = qt_auto_test_resolve_OpenSSL_symbols();
+ // This is where OpenSSL moved several protocols under
+ // non-default (0) security level (the default is 1).
+ isSecurityLevel0Required = OPENSSL_VERSION_NUMBER >= 0x30100010;
+#else
+ opensslResolved = false; // Not 'unused variable' anymore.
+#endif
+ } else if (tlsBackends.contains(QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSchannel])) {
+ isTestingSchannel = true;
+ } else {
+ QVERIFY(tlsBackends.contains(QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSecureTransport]));
+ isTestingSecureTransport = true;
+ }
+
+#if QT_CONFIG(ssl)
qDebug("Using SSL library %s (%ld)",
qPrintable(QSslSocket::sslLibraryVersionString()),
QSslSocket::sslLibraryVersionNumber());
@@ -438,14 +441,14 @@ void tst_QSslSocket::initTestCase()
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
#endif // QT_TEST_SERVER
-#endif // QT_NO_SSL
+#endif // QT_CONFIG(ssl)
}
void tst_QSslSocket::init()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
-#ifndef QT_NO_NETWORKPROXY
+#if QT_CONFIG(networkproxy)
QFETCH_GLOBAL(int, proxyType);
const QString socksProxyAddr = QtNetworkSettings::socksProxyServerIp().toString();
const QString httpProxyAddr = QtNetworkSettings::httpProxyServerIp().toString();
@@ -473,26 +476,24 @@ void tst_QSslSocket::init()
break;
}
QNetworkProxy::setApplicationProxy(proxy);
-#else // !QT_NO_NETWORKPROXY
+#else
QSKIP("No proxy support");
-#endif // QT_NO_NETWORKPROXY
+#endif // QT_CONFIG(networkproxy)
}
-#ifndef QT_NO_OPENSSL
QT_PREPEND_NAMESPACE(qt_ForceTlsSecurityLevel)();
-#endif // QT_NO_OPENSSL
qt_qhostinfo_clear_cache();
}
void tst_QSslSocket::cleanup()
{
-#ifndef QT_NO_NETWORKPROXY
+#if QT_CONFIG(networkproxy)
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
#endif
}
-#ifndef QT_NO_SSL
+#if QT_CONFIG(ssl)
QSslSocketPtr tst_QSslSocket::newSocket()
{
const auto socket = QSslSocketPtr::create();
@@ -504,18 +505,18 @@ QSslSocketPtr tst_QSslSocket::newSocket()
return socket;
}
-#endif
+#endif // QT_CONFIG(ssl)
-#ifndef QT_NO_NETWORKPROXY
+#if QT_CONFIG(networkproxy)
void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
{
++proxyAuthCalled;
auth->setUser("qsockstest");
auth->setPassword("password");
}
-#endif // !QT_NO_NETWORKPROXY
+#endif // QT_CONFIG(networkproxy)
-#ifndef QT_NO_SSL
+#if QT_CONFIG(ssl)
void tst_QSslSocket::activeBackend()
{
@@ -523,8 +524,6 @@ void tst_QSslSocket::activeBackend()
if (setProxy) // Not interesting for backend test.
return;
- QCOMPARE(QSslSocket::activeBackend(), QTlsBackend::defaultBackendName());
-
// We cannot set non-existing as active:
const QString nonExistingBackend = QStringLiteral("TheQtTLS");
QCOMPARE(QSslSocket::setActiveBackend(nonExistingBackend), false);
@@ -607,23 +606,27 @@ void tst_QSslSocket::backends()
if (setProxy) // Not interesting for backend test.
return;
- // We are here, protected by !QT_NO_SSL. Some backend must be pre-existing.
+ // We are here, protected by QT_CONFIG(ssl). Some backend must be pre-existing.
// Let's test the 'real' backend:
auto backendNames = QTlsBackend::availableBackendNames();
const auto sizeBefore = backendNames.size();
QVERIFY(sizeBefore > 0);
- const auto builtinBackend = backendNames.first();
- const auto builtinProtocols = QSslSocket::supportedProtocols(builtinBackend);
+ const QString tlsBackend = QSslSocket::activeBackend();
+ QVERIFY(tlsBackend == QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexOpenSSL]
+ || tlsBackend == QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSchannel]
+ || tlsBackend == QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSecureTransport]);
+
+ const auto builtinProtocols = QSslSocket::supportedProtocols(tlsBackend);
QVERIFY(builtinProtocols.contains(QSsl::SecureProtocols));
// Socket and ALPN are supported by all our backends:
- const auto builtinClasses = QSslSocket::implementedClasses(builtinBackend);
+ const auto builtinClasses = QSslSocket::implementedClasses(tlsBackend);
QVERIFY(builtinClasses.contains(QSsl::ImplementedClass::Socket));
- const auto builtinFeatures = QSslSocket::supportedFeatures(builtinBackend);
+ const auto builtinFeatures = QSslSocket::supportedFeatures(tlsBackend);
QVERIFY(builtinFeatures.contains(QSsl::SupportedFeature::ClientSideAlpn));
- // Verify that non-dummy backend can be created (and delete it):
- auto *systemBackend = QTlsBackend::findBackend(builtinBackend);
+ // Verify that non-dummy backend can be found:
+ auto *systemBackend = QTlsBackend::findBackend(tlsBackend);
QVERIFY(systemBackend);
const auto protocols = QList<QSsl::SslProtocol>{QSsl::SecureProtocols};
@@ -711,7 +714,7 @@ void tst_QSslSocket::constructing()
QVERIFY(!socket.isTextModeEnabled());
QVERIFY(!socket.isWritable());
QCOMPARE(socket.openMode(), QIODevice::NotOpen);
- QTest::ignoreMessage(QtWarningMsg, readNotOpenMessage);
+ QTest::ignoreMessage(QtWarningMsg, "QIODevice::peek (QSslSocket): device not open");
QVERIFY(socket.peek(2).isEmpty());
QCOMPARE(socket.pos(), qint64(0));
QTest::ignoreMessage(QtWarningMsg, writeNotOpenMessage);
@@ -722,8 +725,7 @@ void tst_QSslSocket::constructing()
QCOMPARE(socket.read(0, 0), qint64(-1));
QTest::ignoreMessage(QtWarningMsg, readNotOpenMessage);
QVERIFY(socket.readAll().isEmpty());
- QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine (QSslSocket): Called with maxSize < 2");
- QCOMPARE(socket.readLine(0, 0), qint64(-1));
+ QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine (QSslSocket): device not open");
char buf[10];
QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1));
QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device");
@@ -745,7 +747,7 @@ void tst_QSslSocket::constructing()
QCOMPARE(socket.peerAddress(), QHostAddress());
QVERIFY(socket.peerName().isEmpty());
QCOMPARE(socket.peerPort(), quint16(0));
-#ifndef QT_NO_NETWORKPROXY
+#if QT_CONFIG(networkproxy)
QCOMPARE(socket.proxy().type(), QNetworkProxy::DefaultProxy);
#endif
QCOMPARE(socket.readBufferSize(), qint64(0));
@@ -796,16 +798,32 @@ void tst_QSslSocket::configNoOnDemandLoad()
QCOMPARE(customConfig, socket.sslConfiguration());
}
+static void downgrade_TLS_QTQAINFRA_4499(QSslSocket &socket)
+{
+ // Set TLS 1.0 or above because the server doesn't support TLS 1.2 or above
+ // QTQAINFRA-4499
+ QSslConfiguration config = socket.sslConfiguration();
+ config.setProtocol(Test::TlsV1_0OrLater);
+ socket.setSslConfiguration(config);
+}
+
void tst_QSslSocket::simpleConnect()
{
if (!QSslSocket::supportsSsl())
return;
+ // Starting from OpenSSL v 3.1.1 deprecated protocol versions (we want to use when connecting) are not available by default.
+ if (isSecurityLevel0Required)
+ QSKIP("Testing with OpenSSL backend, but security level 0 is required for TLS v1.1 or earlier");
+
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
QSslSocket socket;
+
+ downgrade_TLS_QTQAINFRA_4499(socket);
+
QSignalSpy connectedSpy(&socket, SIGNAL(connected()));
QSignalSpy hostFoundSpy(&socket, SIGNAL(hostFound()));
QSignalSpy disconnectedSpy(&socket, SIGNAL(disconnected()));
@@ -826,30 +844,30 @@ void tst_QSslSocket::simpleConnect()
// Entered connecting state
QCOMPARE(socket.state(), QAbstractSocket::ConnectingState);
- QCOMPARE(connectedSpy.count(), 0);
- QCOMPARE(hostFoundSpy.count(), 1);
- QCOMPARE(disconnectedSpy.count(), 0);
+ QCOMPARE(connectedSpy.size(), 0);
+ QCOMPARE(hostFoundSpy.size(), 1);
+ QCOMPARE(disconnectedSpy.size(), 0);
enterLoop(10);
// Entered connected state
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(connectedSpy.count(), 1);
- QCOMPARE(hostFoundSpy.count(), 1);
- QCOMPARE(disconnectedSpy.count(), 0);
+ QCOMPARE(connectedSpy.size(), 1);
+ QCOMPARE(hostFoundSpy.size(), 1);
+ QCOMPARE(disconnectedSpy.size(), 0);
// Enter encrypted mode
socket.startClientEncryption();
QCOMPARE(socket.mode(), QSslSocket::SslClientMode);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(connectionEncryptedSpy.count(), 0);
- QCOMPARE(sslErrorsSpy.count(), 0);
+ QCOMPARE(connectionEncryptedSpy.size(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 0);
// Starting handshake
enterLoop(10);
- QCOMPARE(sslErrorsSpy.count(), 1);
- QCOMPARE(connectionEncryptedSpy.count(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 1);
+ QCOMPARE(connectionEncryptedSpy.size(), 0);
QVERIFY(!socket.isEncrypted());
QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
}
@@ -859,6 +877,10 @@ void tst_QSslSocket::simpleConnectWithIgnore()
if (!QSslSocket::supportsSsl())
return;
+ // Starting from OpenSSL v 3.1.1 deprecated protocol versions (we want to use when connecting) are not available by default.
+ if (isSecurityLevel0Required)
+ QSKIP("Testing with OpenSSL backend, but security level 0 is required for TLS v1.1 or earlier");
+
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -868,6 +890,8 @@ void tst_QSslSocket::simpleConnectWithIgnore()
QSignalSpy encryptedSpy(&socket, SIGNAL(encrypted()));
QSignalSpy sslErrorsSpy(&socket, SIGNAL(sslErrors(QList<QSslError>)));
+ downgrade_TLS_QTQAINFRA_4499(socket);
+
connect(&socket, SIGNAL(readyRead()), this, SLOT(exitLoop()));
connect(&socket, SIGNAL(encrypted()), this, SLOT(exitLoop()));
connect(&socket, SIGNAL(connected()), this, SLOT(exitLoop()));
@@ -885,10 +909,10 @@ void tst_QSslSocket::simpleConnectWithIgnore()
enterLoop(10);
// Done; encryption should be enabled.
- QCOMPARE(sslErrorsSpy.count(), 1);
+ QCOMPARE(sslErrorsSpy.size(), 1);
QVERIFY(socket.isEncrypted());
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
- QCOMPARE(encryptedSpy.count(), 1);
+ QCOMPARE(encryptedSpy.size(), 1);
// Wait for incoming data
if (!socket.canReadLine())
@@ -901,6 +925,10 @@ void tst_QSslSocket::simpleConnectWithIgnore()
void tst_QSslSocket::sslErrors_data()
{
+ // Starting from OpenSSL v 3.1.1 deprecated protocol versions (we want to use in 'sslErrors' test) are not available by default.
+ if (isSecurityLevel0Required)
+ QSKIP("Testing with OpenSSL backend, but security level 0 is required for TLS v1.1 or earlier");
+
QTest::addColumn<QString>("host");
QTest::addColumn<int>("port");
@@ -917,10 +945,10 @@ void tst_QSslSocket::sslErrors()
QFETCH(int, port);
QSslSocketPtr socket = newSocket();
-#if QT_CONFIG(schannel)
- // Needs to be < 1.2 because of the old certificate and <= 1.0 because of the mail server
- socket->setProtocol(QSsl::SslProtocol::TlsV1_0);
-#endif
+
+ QVERIFY(socket);
+ downgrade_TLS_QTQAINFRA_4499(*socket);
+
QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList<QSslError>)));
QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError)));
@@ -950,12 +978,15 @@ void tst_QSslSocket::sslErrors()
sslErrors << err.error();
std::sort(sslErrors.begin(), sslErrors.end());
QVERIFY(sslErrors.contains(QSslError::HostNameMismatch));
- QVERIFY(sslErrors.contains(FLUKE_CERTIFICATE_ERROR));
+
+ // Non-OpenSSL backends are not able to report a specific error code
+ // for self-signed certificates.
+ QVERIFY(sslErrors.contains(flukeCertificateError));
// check the same errors were emitted by sslErrors
QVERIFY(!sslErrorsSpy.isEmpty());
SslErrorList emittedErrors;
- const auto sslErrorsSpyErrors = qvariant_cast<QList<QSslError> >(qAsConst(sslErrorsSpy).first().first());
+ const auto sslErrorsSpyErrors = qvariant_cast<QList<QSslError> >(std::as_const(sslErrorsSpy).first().first());
for (const QSslError &err : sslErrorsSpyErrors)
emittedErrors << err.error();
std::sort(emittedErrors.begin(), emittedErrors.end());
@@ -1004,7 +1035,7 @@ void tst_QSslSocket::ciphers()
QString ciphersAsString;
const auto &supported = sslConfig.supportedCiphers();
for (const auto &cipher : supported) {
- if (cipher.isNull() || !cipher.name().length())
+ if (cipher.isNull() || !cipher.name().size())
continue;
if (ciphers.size() > 0)
ciphersAsString += QStringLiteral(":");
@@ -1017,27 +1048,65 @@ void tst_QSslSocket::ciphers()
if (!ciphers.size())
QSKIP("No proper ciphersuite was found to test 'setCiphers'");
-#if QT_CONFIG(schannel)
- qWarning("Schannel doesn't support setting ciphers from a cipher-string.");
-#else
- sslConfig.setCiphers(ciphersAsString);
- socket.setSslConfiguration(sslConfig);
- QCOMPARE(ciphers, socket.sslConfiguration().ciphers());
-#endif
+
+ if (isTestingSchannel) {
+ qWarning("Schannel doesn't support setting ciphers from a cipher-string.");
+ } else {
+ sslConfig.setCiphers(ciphersAsString);
+ socket.setSslConfiguration(sslConfig);
+ QCOMPARE(ciphers, socket.sslConfiguration().ciphers());
+ }
+
sslConfig.setCiphers(ciphers);
socket.setSslConfiguration(sslConfig);
QCOMPARE(ciphers, socket.sslConfiguration().ciphers());
-#ifndef QT_NO_OPENSSL
- for (const auto &cipher : ciphers) {
- if (cipher.name().size() && cipher.protocol() != QSsl::UnknownProtocol) {
- const QSslCipher aCopy(cipher.name(), cipher.protocol());
- QCOMPARE(aCopy, cipher);
+ if (isTestingOpenSsl) {
+ for (const auto &cipher : ciphers) {
+ if (cipher.name().size() && cipher.protocol() != QSsl::UnknownProtocol) {
+ const QSslCipher aCopy(cipher.name(), cipher.protocol());
+ QCOMPARE(aCopy, cipher);
+ break;
+ }
+ }
+ }
+}
+
+#if QT_CONFIG(securetransport)
+void tst_QSslSocket::tls13Ciphers()
+{
+ // SecureTransport introduced several new ciphers under
+ // "TLS 1.3 ciphersuites" section. Since Qt 6 we respect
+ // the ciphers from QSslConfiguration. In case of default
+ // configuration, these are the same we report and we
+ // were failing (for historical reasons) to report those
+ // TLS 1.3 suites when creating default QSslConfiguration.
+ // Check we now have them.
+ if (!isTestingSecureTransport)
+ QSKIP("The feature 'securetransport' was enabled, but active backend is not \"securetransport\"");
+
+ QFETCH_GLOBAL(const bool, setProxy);
+ if (setProxy)
+ return;
+
+ const auto suites = QSslConfiguration::defaultConfiguration().ciphers();
+ QSslCipher ciph;
+ // Check the one of reported and previously missed:
+ for (const auto &suite : suites) {
+ if (suite.encryptionMethod() == QStringLiteral("CHACHA20")) {
+ // There are several ciphesuites using CHACHA20, the first one
+ // is sufficient for the purpose of this test:
+ ciph = suite;
break;
}
}
-#endif // QT_NO_OPENSSL
+
+ QVERIFY(!ciph.isNull());
+ QCOMPARE(ciph.encryptionMethod(), QStringLiteral("CHACHA20"));
+ QCOMPARE(ciph.supportedBits(), 256);
+ QCOMPARE(ciph.usedBits(), 256);
}
+#endif // QT_CONFIG(securetransport)
void tst_QSslSocket::connectToHostEncrypted()
{
@@ -1045,9 +1114,7 @@ void tst_QSslSocket::connectToHostEncrypted()
return;
QSslSocketPtr socket = newSocket();
-#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
- socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
-#endif
+
this->socket = socket.data();
auto config = socket->sslConfiguration();
QVERIFY(config.addCaCertificates(httpServerCertChainPath()));
@@ -1067,6 +1134,7 @@ void tst_QSslSocket::connectToHostEncrypted()
socket->disconnectFromHost();
QVERIFY(socket->waitForDisconnected());
+ QVERIFY(!socket->isEncrypted());
QCOMPARE(socket->mode(), QSslSocket::SslClientMode);
@@ -1083,9 +1151,7 @@ void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName()
return;
QSslSocketPtr socket = newSocket();
-#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
- socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
-#endif
+
this->socket = socket.data();
auto config = socket->sslConfiguration();
@@ -1140,14 +1206,6 @@ void tst_QSslSocket::sessionCipher()
QVERIFY(socket->waitForDisconnected());
}
-void tst_QSslSocket::flush()
-{
-}
-
-void tst_QSslSocket::isEncrypted()
-{
-}
-
void tst_QSslSocket::localCertificate()
{
if (!QSslSocket::supportsSsl())
@@ -1191,7 +1249,7 @@ void tst_QSslSocket::peerCertificateChain()
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
QList<QSslCertificate> caCertificates = QSslCertificate::fromPath(httpServerCertChainPath());
- QCOMPARE(caCertificates.count(), 1);
+ QCOMPARE(caCertificates.size(), 1);
auto config = socket->sslConfiguration();
config.addCaCertificates(caCertificates);
socket->setSslConfiguration(config);
@@ -1208,7 +1266,7 @@ void tst_QSslSocket::peerCertificateChain()
QSKIP("Skipping flaky test - See QTBUG-29941");
QList<QSslCertificate> certChain = socket->peerCertificateChain();
- QVERIFY(certChain.count() > 0);
+ QVERIFY(certChain.size() > 0);
QCOMPARE(certChain.first(), socket->peerCertificate());
socket->disconnectFromHost();
@@ -1249,11 +1307,15 @@ void tst_QSslSocket::privateKey()
{
}
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
void tst_QSslSocket::privateKeyOpaque()
{
- if (!QSslSocket::supportsSsl())
- return;
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does not support private opaque keys");
+
+ if (!opensslResolved)
+ QSKIP("Failed to resolve OpenSSL symbols, required by this test");
QFile file(testDataDir + "certs/fluke.key");
QVERIFY(file.open(QIODevice::ReadOnly));
@@ -1282,8 +1344,9 @@ void tst_QSslSocket::privateKeyOpaque()
QFETCH_GLOBAL(bool, setProxy);
if (setProxy && !socket->waitForEncrypted(10000))
QSKIP("Skipping flaky test - See QTBUG-29941");
+#endif // OPENSSL_NO_DEPRECATED_3_0
}
-#endif
+#endif // Feature 'openssl'.
void tst_QSslSocket::protocol()
{
@@ -1307,38 +1370,38 @@ void tst_QSslSocket::protocol()
QFETCH_GLOBAL(bool, setProxy);
{
// qt-test-server allows TLSV1.
- socket->setProtocol(QSsl::TlsV1_0);
- QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
+ socket->setProtocol(Test::TlsV1_0);
+ QCOMPARE(socket->protocol(), Test::TlsV1_0);
socket->connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
if (setProxy && !socket->waitForEncrypted())
QSKIP("Skipping flaky test - See QTBUG-29941");
- QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
+ QCOMPARE(socket->protocol(), Test::TlsV1_0);
socket->abort();
- QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
+ QCOMPARE(socket->protocol(), Test::TlsV1_0);
socket->connectToHost(QtNetworkSettings::httpServerName(), 443);
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
socket->startClientEncryption();
if (setProxy && !socket->waitForEncrypted())
QSKIP("Skipping flaky test - See QTBUG-29941");
- QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
+ QCOMPARE(socket->protocol(), Test::TlsV1_0);
socket->abort();
}
{
// qt-test-server probably doesn't allow TLSV1.1
- socket->setProtocol(QSsl::TlsV1_1);
- QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
+ socket->setProtocol(Test::TlsV1_1);
+ QCOMPARE(socket->protocol(), Test::TlsV1_1);
socket->connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
if (setProxy && !socket->waitForEncrypted())
QSKIP("Skipping flaky test - See QTBUG-29941");
- QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
+ QCOMPARE(socket->protocol(), Test::TlsV1_1);
socket->abort();
- QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
+ QCOMPARE(socket->protocol(), Test::TlsV1_1);
socket->connectToHost(QtNetworkSettings::httpServerName(), 443);
QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString()));
socket->startClientEncryption();
if (setProxy && !socket->waitForEncrypted())
QSKIP("Skipping flaky test - See QTBUG-29941");
- QCOMPARE(socket->protocol(), QSsl::TlsV1_1);
+ QCOMPARE(socket->protocol(), Test::TlsV1_1);
socket->abort();
}
{
@@ -1409,7 +1472,7 @@ public:
config(QSslConfiguration::defaultConfiguration()),
ignoreSslErrors(true),
peerVerifyMode(QSslSocket::AutoVerifyPeer),
- protocol(QSsl::TlsV1_0),
+ protocol(QSsl::SecureProtocols),
m_keyFile(keyFile),
m_certFile(certFile),
m_interFile(interFile)
@@ -1431,6 +1494,7 @@ signals:
void handshakeInterruptedOnError(const QSslError& rrror);
void gotAlert(QSsl::AlertLevel level, QSsl::AlertType type, const QString &message);
void alertSent(QSsl::AlertLevel level, QSsl::AlertType type, const QString &message);
+ void socketEncrypted(QSslSocket *);
protected:
void incomingConnection(qintptr socketDescriptor) override
@@ -1448,6 +1512,7 @@ protected:
connect(socket, &QSslSocket::alertReceived, this, &SslServer::gotAlert);
connect(socket, &QSslSocket::alertSent, this, &SslServer::alertSent);
connect(socket, &QSslSocket::preSharedKeyAuthenticationRequired, this, &SslServer::preSharedKeyAuthenticationRequired);
+ connect(socket, &QSslSocket::encrypted, this, [this](){ emit socketEncrypted(socket); });
QFile file(m_keyFile);
QVERIFY(file.open(QIODevice::ReadOnly));
@@ -1512,41 +1577,34 @@ void tst_QSslSocket::protocolServerSide_data()
QTest::addColumn<QSsl::SslProtocol>("clientProtocol");
QTest::addColumn<bool>("works");
- QTest::newRow("tls1.0-tls1.0") << QSsl::TlsV1_0 << QSsl::TlsV1_0 << true;
QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true;
QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true;
- QTest::newRow("tls1.0-secure") << QSsl::TlsV1_0 << QSsl::SecureProtocols << true;
- QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << true;
-
- QTest::newRow("secure-tls1.0") << QSsl::SecureProtocols << QSsl::TlsV1_0 << true;
+ QTest::newRow("tls1.0-secure") << Test::TlsV1_0 << QSsl::SecureProtocols << false;
+ QTest::newRow("secure-tls1.0") << QSsl::SecureProtocols << Test::TlsV1_0 << false;
QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true;
- QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true;
- QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true;
- QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true;
+ QTest::newRow("tls1.0orlater-tls1.2") << Test::TlsV1_0OrLater << QSsl::TlsV1_2 << true;
if (supportsTls13())
- QTest::newRow("tls1.0orlater-tls1.3") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_3 << true;
+ QTest::newRow("tls1.0orlater-tls1.3") << Test::TlsV1_0OrLater << QSsl::TlsV1_3 << true;
- QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false;
- QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true;
- QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true;
+ QTest::newRow("tls1.1orlater-tls1.0") << Test::TlsV1_1OrLater << Test::TlsV1_0 << false;
+ QTest::newRow("tls1.1orlater-tls1.2") << Test::TlsV1_1OrLater << QSsl::TlsV1_2 << true;
if (supportsTls13())
- QTest::newRow("tls1.1orlater-tls1.3") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_3 << true;
+ QTest::newRow("tls1.1orlater-tls1.3") << Test::TlsV1_1OrLater << QSsl::TlsV1_3 << true;
- QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false;
- QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false;
+ QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << Test::TlsV1_0 << false;
+ QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << Test::TlsV1_1 << false;
QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true;
if (supportsTls13()) {
QTest::newRow("tls1.2orlater-tls1.3") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_3 << true;
- QTest::newRow("tls1.3orlater-tls1.0") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_0 << false;
- QTest::newRow("tls1.3orlater-tls1.1") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_1 << false;
+ QTest::newRow("tls1.3orlater-tls1.0") << QSsl::TlsV1_3OrLater << Test::TlsV1_0 << false;
+ QTest::newRow("tls1.3orlater-tls1.1") << QSsl::TlsV1_3OrLater << Test::TlsV1_1 << false;
QTest::newRow("tls1.3orlater-tls1.2") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_2 << false;
QTest::newRow("tls1.3orlater-tls1.3") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_3 << true;
}
- QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true;
QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true;
}
@@ -1603,23 +1661,37 @@ void tst_QSslSocket::protocolServerSide()
QCOMPARE(client.isEncrypted(), works);
}
-#ifndef QT_NO_OPENSSL
-
void tst_QSslSocket::serverCipherPreferences()
{
- if (!QSslSocket::supportsSsl()) {
- qWarning("SSL not supported, skipping test");
- return;
- }
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does not support server-side cipher preferences");
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
- // First using the default (server preference)
+ QSslCipher testedCiphers[2];
{
+ // First using the default (server preference)
+ const auto supportedCiphers = QSslConfiguration::supportedCiphers();
+ int nSet = 0;
+ for (const auto &cipher : supportedCiphers) {
+ // Ciphersuites from TLS 1.2 and 1.3 are set separately,
+ // let's select 1.3 or above explicitly.
+ if (cipher.protocol() < QSsl::TlsV1_3)
+ continue;
+
+ testedCiphers[nSet++] = cipher;
+ if (nSet == 2)
+ break;
+ }
+
+ if (nSet != 2)
+ QSKIP("Failed to find two proper ciphersuites to test, bailing out.");
+
SslServer server;
- server.ciphers = {QSslCipher("AES128-SHA"), QSslCipher("AES256-SHA")};
+ server.protocol = QSsl::TlsV1_2OrLater;
+ server.ciphers = {testedCiphers[0], testedCiphers[1]};
QVERIFY(server.listen());
QEventLoop loop;
@@ -1629,7 +1701,8 @@ void tst_QSslSocket::serverCipherPreferences()
socket = &client;
auto sslConfig = socket->sslConfiguration();
- sslConfig.setCiphers({QSslCipher("AES256-SHA"), QSslCipher("AES128-SHA")});
+ sslConfig.setProtocol(QSsl::TlsV1_2OrLater);
+ sslConfig.setCiphers({testedCiphers[1], testedCiphers[0]});
socket->setSslConfiguration(sslConfig);
// upon SSL wrong version error, errorOccurred will be triggered, not sslErrors
@@ -1642,16 +1715,19 @@ void tst_QSslSocket::serverCipherPreferences()
loop.exec();
QVERIFY(client.isEncrypted());
- QCOMPARE(client.sessionCipher().name(), QString("AES128-SHA"));
+ QCOMPARE(client.sessionCipher().name(), testedCiphers[0].name());
}
{
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("This test is known to crash on QEMU emulation for no good reason.");
// Now using the client preferences
SslServer server;
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setSslOption(QSsl::SslOptionDisableServerCipherPreference, true);
server.config = config;
- server.ciphers = {QSslCipher("AES128-SHA"), QSslCipher("AES256-SHA")};
+ server.protocol = QSsl::TlsV1_2OrLater;
+ server.ciphers = {testedCiphers[0], testedCiphers[1]};
QVERIFY(server.listen());
QEventLoop loop;
@@ -1661,7 +1737,8 @@ void tst_QSslSocket::serverCipherPreferences()
socket = &client;
auto sslConfig = socket->sslConfiguration();
- sslConfig.setCiphers({QSslCipher("AES256-SHA"), QSslCipher("AES128-SHA")});
+ sslConfig.setProtocol(QSsl::TlsV1_2OrLater);
+ sslConfig.setCiphers({testedCiphers[1], testedCiphers[0]});
socket->setSslConfiguration(sslConfig);
// upon SSL wrong version error, errorOccurred will be triggered, not sslErrors
@@ -1674,12 +1751,10 @@ void tst_QSslSocket::serverCipherPreferences()
loop.exec();
QVERIFY(client.isEncrypted());
- QCOMPARE(client.sessionCipher().name(), QString("AES256-SHA"));
+ QCOMPARE(client.sessionCipher().name(), testedCiphers[1].name());
}
}
-#endif // QT_NO_OPENSSL
-
void tst_QSslSocket::setCaCertificates()
{
@@ -1749,14 +1824,17 @@ void tst_QSslSocket::setLocalCertificateChain()
loop.exec();
QList<QSslCertificate> chain = socket->peerCertificateChain();
-#if QT_CONFIG(schannel)
- QEXPECT_FAIL("", "Schannel cannot send intermediate certificates not "
- "located in a system certificate store",
- Abort);
-#endif
+ if (isTestingSchannel) {
+ QEXPECT_FAIL("", "Schannel cannot send intermediate certificates not "
+ "located in a system certificate store",
+ Abort);
+ }
+
QCOMPARE(chain.size(), 2);
- QCOMPARE(chain[0].serialNumber(), QByteArray("10:a0:ad:77:58:f6:6e:ae:46:93:a3:43:f9:59:8a:9e"));
- QCOMPARE(chain[1].serialNumber(), QByteArray("3b:eb:99:c5:ea:d8:0b:5d:0b:97:5d:4f:06:75:4b:e1"));
+ QCOMPARE(chain[0].serialNumber(),
+ QByteArray("58:df:33:c1:9b:bc:c5:51:7a:00:86:64:43:94:41:e2:26:ef:3f:89"));
+ QCOMPARE(chain[1].serialNumber(),
+ QByteArray("11:72:34:bc:21:e6:ca:04:24:13:f8:35:48:84:a6:e9:de:96:22:15"));
}
void tst_QSslSocket::tlsConfiguration()
@@ -1772,7 +1850,7 @@ void tst_QSslSocket::tlsConfiguration()
QCOMPARE(tlsConfig.sessionProtocol(), QSsl::UnknownProtocol);
QSslConfiguration nullConfig;
QVERIFY(nullConfig.isNull());
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
nullConfig.setEllipticCurves(tlsConfig.ellipticCurves());
QCOMPARE(nullConfig.ellipticCurves(), tlsConfig.ellipticCurves());
#endif
@@ -1828,15 +1906,16 @@ void tst_QSslSocket::setSslConfiguration_data()
QTest::newRow("empty") << QSslConfiguration() << false;
QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
QTest::newRow("default") << conf << false; // does not contain test server cert
-#if !QT_CONFIG(securetransport)
- QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(httpServerCertChainPath());
- conf.setCaCertificates(testServerCert);
- QTest::newRow("set-root-cert") << conf << true;
- conf.setProtocol(QSsl::SecureProtocols);
- QTest::newRow("secure") << conf << true;
-#else
- qWarning("Skipping the cases with certificate, SecureTransport does not like old certificate on the test server");
-#endif
+
+ if (!isTestingSecureTransport) {
+ QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(httpServerCertChainPath());
+ conf.setCaCertificates(testServerCert);
+ QTest::newRow("set-root-cert") << conf << true;
+ conf.setProtocol(QSsl::SecureProtocols);
+ QTest::newRow("secure") << conf << true;
+ } else {
+ qWarning("Skipping the cases with certificate, SecureTransport does not like old certificate on the test server");
+ }
}
void tst_QSslSocket::setSslConfiguration()
@@ -1847,9 +1926,7 @@ void tst_QSslSocket::setSslConfiguration()
QSslSocketPtr socket = newSocket();
QFETCH(QSslConfiguration, configuration);
socket->setSslConfiguration(configuration);
-#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
- socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
-#endif
+
this->socket = socket.data();
socket->connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
QFETCH(bool, works);
@@ -1902,9 +1979,19 @@ void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
if (!QSslSocket::supportsSsl())
return;
+ // Starting from OpenSSL v 3.1.1 deprecated protocol versions (we want to use here) are not available by default.
+ if (isSecurityLevel0Required)
+ QSKIP("Testing with OpenSSL backend, but security level 0 is required for TLS v1.1 or earlier");
+
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
+ // Set TLS 1.0 or above because the server doesn't support TLS 1.2 or above
+ // QTQAINFRA-4499
+ QSslConfiguration config = socket->sslConfiguration();
+ config.setProtocol(Test::TlsV1_0OrLater);
+ socket->setSslConfiguration(config);
+
connect(this->socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
socket->connectToHostEncrypted(QtNetworkSettings::imapServerName(), 993);
@@ -2183,8 +2270,17 @@ void tst_QSslSocket::spontaneousWrite()
receiver->startClientEncryption();
// SSL handshake:
- connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
+ // Need to wait for both sides to emit encrypted as the ordering of which
+ // ones emits encrypted() changes depending on whether we use TLS 1.2 or 1.3
+ int waitFor = 2;
+ auto earlyQuitter = [&waitFor]() {
+ if (!--waitFor)
+ exitLoop();
+ };
+ connect(receiver, &QSslSocket::encrypted, this, earlyQuitter);
+ connect(sender, &QSslSocket::encrypted, this, earlyQuitter);
enterLoop(1);
+
QVERIFY(!timeout());
QVERIFY(sender->isEncrypted());
QVERIFY(receiver->isEncrypted());
@@ -2227,9 +2323,21 @@ void tst_QSslSocket::setReadBufferSize()
receiver->ignoreSslErrors();
receiver->startClientEncryption();
- // SSL handshake:
- connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
+ // Need to wait for both sides to emit encrypted as the ordering of which
+ // ones emits encrypted() changes depending on whether we use TLS 1.2 or 1.3
+ int waitFor = 2;
+ auto earlyQuitter = [&waitFor]() {
+ if (!--waitFor)
+ exitLoop();
+ };
+ connect(receiver, &QSslSocket::encrypted, this, earlyQuitter);
+ connect(sender, &QSslSocket::encrypted, this, earlyQuitter);
+
enterLoop(1);
+ if (!sender->isEncrypted()) {
+ connect(sender, &QSslSocket::encrypted, this, &tst_QSslSocket::exitLoop);
+ enterLoop(1);
+ }
QVERIFY(!timeout());
QVERIFY(sender->isEncrypted());
QVERIFY(receiver->isEncrypted());
@@ -2549,9 +2657,7 @@ void tst_QSslSocket::verifyMode()
return;
QSslSocket socket;
-#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
- socket.setProtocol(QSsl::SslProtocol::TlsV1_1);
-#endif
+
QCOMPARE(socket.peerVerifyMode(), QSslSocket::AutoVerifyPeer);
socket.setPeerVerifyMode(QSslSocket::VerifyNone);
QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyNone);
@@ -2564,7 +2670,7 @@ void tst_QSslSocket::verifyMode()
QSKIP("Skipping flaky test - See QTBUG-29941");
QList<QSslError> expectedErrors = QList<QSslError>()
- << QSslError(FLUKE_CERTIFICATE_ERROR, socket.peerCertificate());
+ << QSslError(flukeCertificateError, socket.peerCertificate());
QCOMPARE(socket.sslHandshakeErrors(), expectedErrors);
socket.abort();
@@ -2595,12 +2701,13 @@ void tst_QSslSocket::verifyDepth()
QCOMPARE(socket.peerVerifyDepth(), 1);
}
-#ifndef QT_NO_OPENSSL
void tst_QSslSocket::verifyAndDefaultConfiguration()
{
QFETCH_GLOBAL(const bool, setProxy);
if (setProxy)
return;
+ if (!QSslSocket::supportedFeatures().contains(QSsl::SupportedFeature::CertificateVerification))
+ QSKIP("This backend doesn't support manual certificate verification");
const auto defaultCACertificates = QSslConfiguration::defaultConfiguration().caCertificates();
const auto chainGuard = qScopeGuard([&defaultCACertificates]{
auto conf = QSslConfiguration::defaultConfiguration();
@@ -2630,7 +2737,6 @@ void tst_QSslSocket::verifyAndDefaultConfiguration()
QCOMPARE(QSslConfiguration::defaultConfiguration().caCertificates(), QList{caCert});
#endif
}
-#endif // QT_NO_OPENSSL
void tst_QSslSocket::disconnectFromHostWhenConnecting()
{
@@ -2676,7 +2782,7 @@ void tst_QSslSocket::disconnectFromHostWhenConnected()
QCOMPARE(socket->bytesToWrite(), qint64(0));
}
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
class BrokenPskHandshake : public QTcpServer
{
@@ -2707,6 +2813,9 @@ private:
void tst_QSslSocket::closeWhileEmittingSocketError()
{
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does not support this test");
+
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2727,17 +2836,17 @@ void tst_QSslSocket::closeWhileEmittingSocketError()
// Make sure we have some data buffered so that close will try to flush:
clientSocket.write(QByteArray(1000000, Qt::Uninitialized));
- QTestEventLoop::instance().enterLoopMSecs(1000);
+ QTestEventLoop::instance().enterLoop(1s);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(socketErrorSpy.count(), 1);
+ QCOMPARE(socketErrorSpy.size(), 1);
}
-#endif // QT_NO_OPENSSL
+#endif // Feature 'openssl'.
void tst_QSslSocket::resetProxy()
{
-#ifndef QT_NO_NETWORKPROXY
+#if QT_CONFIG(networkproxy)
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
@@ -2781,7 +2890,7 @@ void tst_QSslSocket::resetProxy()
socket2.setProxy(goodProxy);
socket2.connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
QVERIFY2(socket2.waitForConnected(10000), qPrintable(socket.errorString()));
-#endif // QT_NO_NETWORKPROXY
+#endif // QT_CONFIG(networkproxy)
}
void tst_QSslSocket::ignoreSslErrorsList_data()
@@ -2793,8 +2902,8 @@ void tst_QSslSocket::ignoreSslErrorsList_data()
QList<QSslError> expectedSslErrors;
// fromPath gives us a list of certs, but it actually only contains one
QList<QSslCertificate> certs = QSslCertificate::fromPath(httpServerCertChainPath());
- QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0));
- QSslError wrongError(FLUKE_CERTIFICATE_ERROR);
+ QSslError rightError(flukeCertificateError, certs.at(0));
+ QSslError wrongError(flukeCertificateError);
QTest::newRow("SSL-failure-empty-list") << expectedSslErrors << 1;
@@ -2827,7 +2936,7 @@ void tst_QSslSocket::ignoreSslErrorsList()
bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0);
if (socket.waitForEncrypted(10000) != expectEncryptionSuccess)
QSKIP("Skipping flaky test - See QTBUG-29941");
- QCOMPARE(sslErrorsSpy.count(), expectedSslErrorSignalCount);
+ QCOMPARE(sslErrorsSpy.size(), expectedSslErrorSignalCount);
}
void tst_QSslSocket::ignoreSslErrorsListWithSlot_data()
@@ -2888,9 +2997,7 @@ void tst_QSslSocket::abortOnSslErrors()
void tst_QSslSocket::readFromClosedSocket()
{
QSslSocketPtr socket = newSocket();
-#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
- socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
-#endif
+
socket->ignoreSslErrors();
socket->connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
socket->ignoreSslErrors();
@@ -2987,9 +3094,16 @@ void tst_QSslSocket::blacklistedCertificates()
connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop()));
enterLoop(1);
QList<QSslError> sslErrors = receiver->sslHandshakeErrors();
- QVERIFY(sslErrors.count() > 0);
+ QVERIFY(sslErrors.size() > 0);
// there are more errors (self signed cert and hostname mismatch), but we only care about the blacklist error
- QCOMPARE(sslErrors.at(0).error(), QSslError::CertificateBlacklisted);
+ std::optional<QSslError> blacklistedError;
+ for (const QSslError &error : sslErrors) {
+ if (error.error() == QSslError::CertificateBlacklisted) {
+ blacklistedError = error;
+ break;
+ }
+ }
+ QVERIFY2(blacklistedError, "CertificateBlacklisted error not found!");
}
void tst_QSslSocket::versionAccessors()
@@ -3001,60 +3115,6 @@ void tst_QSslSocket::versionAccessors()
qDebug() << QString::number(QSslSocket::sslLibraryVersionNumber(), 16);
}
-#ifndef QT_NO_OPENSSL
-void tst_QSslSocket::sslOptions()
-{
- if (!QSslSocket::supportsSsl())
- return;
-
-#ifdef SSL_OP_NO_COMPRESSION
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSslConfigurationPrivate::defaultSslOptions),
- long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION|SSL_OP_CIPHER_SERVER_PREFERENCE));
-#else
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSslConfigurationPrivate::defaultSslOptions),
- long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_CIPHER_SERVER_PREFERENCE));
-#endif
-
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSsl::SslOptionDisableEmptyFragments
- |QSsl::SslOptionDisableLegacyRenegotiation),
- long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_CIPHER_SERVER_PREFERENCE));
-
-#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSsl::SslOptionDisableEmptyFragments),
- long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION|SSL_OP_CIPHER_SERVER_PREFERENCE)));
-#endif
-
-#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSsl::SslOptionDisableLegacyRenegotiation),
- long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_CIPHER_SERVER_PREFERENCE) & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
-#endif
-
-#ifdef SSL_OP_NO_TICKET
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSsl::SslOptionDisableEmptyFragments
- |QSsl::SslOptionDisableLegacyRenegotiation
- |QSsl::SslOptionDisableSessionTickets),
- long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET|SSL_OP_CIPHER_SERVER_PREFERENCE)));
-#endif
-
-#ifdef SSL_OP_NO_TICKET
-#ifdef SSL_OP_NO_COMPRESSION
- QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols,
- QSsl::SslOptionDisableEmptyFragments
- |QSsl::SslOptionDisableLegacyRenegotiation
- |QSsl::SslOptionDisableSessionTickets
- |QSsl::SslOptionDisableCompression),
- long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET|SSL_OP_NO_COMPRESSION|SSL_OP_CIPHER_SERVER_PREFERENCE)));
-#endif
-#endif
-}
-#endif
-
void tst_QSslSocket::encryptWithoutConnecting()
{
if (!QSslSocket::supportsSsl())
@@ -3069,6 +3129,10 @@ void tst_QSslSocket::encryptWithoutConnecting()
void tst_QSslSocket::resume_data()
{
+ // Starting from OpenSSL v 3.1.1 deprecated protocol versions (we want to use in 'resume' test) are not available by default.
+ if (isSecurityLevel0Required)
+ QSKIP("Testing with OpenSSL backend, but security level 0 is required for TLS v1.1 or earlier");
+
QTest::addColumn<bool>("ignoreErrorsAfterPause");
QTest::addColumn<QList<QSslError> >("errorsToIgnore");
QTest::addColumn<bool>("expectSuccess");
@@ -3080,8 +3144,8 @@ void tst_QSslSocket::resume_data()
// Note, httpServerCertChainPath() it's ... because we use the same certificate on
// different services. We'll be actually connecting to IMAP server.
QList<QSslCertificate> certs = QSslCertificate::fromPath(httpServerCertChainPath());
- QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0));
- QSslError wrongError(FLUKE_CERTIFICATE_ERROR);
+ QSslError rightError(flukeCertificateError, certs.at(0));
+ QSslError wrongError(flukeCertificateError);
errorsList.append(wrongError);
QTest::newRow("ignoreSpecificErrors-Wrong") << true << errorsList << false;
errorsList.clear();
@@ -3104,6 +3168,12 @@ void tst_QSslSocket::resume()
QSslSocket socket;
socket.setPauseMode(QAbstractSocket::PauseOnSslErrors);
+ // Set TLS 1.0 or above because the server doesn't support TLS 1.2 or above
+ // QTQAINFRA-4499
+ QSslConfiguration config = socket.sslConfiguration();
+ config.setProtocol(Test::TlsV1_0OrLater);
+ socket.setSslConfiguration(config);
+
QSignalSpy sslErrorSpy(&socket, SIGNAL(sslErrors(QList<QSslError>)));
QSignalSpy encryptedSpy(&socket, SIGNAL(encrypted()));
QSignalSpy errorSpy(&socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)));
@@ -3119,9 +3189,9 @@ void tst_QSslSocket::resume()
QFETCH_GLOBAL(bool, setProxy);
if (setProxy && QTestEventLoop::instance().timeout())
QSKIP("Skipping flaky test - See QTBUG-29941");
- QCOMPARE(sslErrorSpy.count(), 1);
- QCOMPARE(errorSpy.count(), 0);
- QCOMPARE(encryptedSpy.count(), 0);
+ QCOMPARE(sslErrorSpy.size(), 1);
+ QCOMPARE(errorSpy.size(), 0);
+ QCOMPARE(encryptedSpy.size(), 0);
QVERIFY(!socket.isEncrypted());
if (ignoreErrorsAfterPause) {
if (errorsToIgnore.empty())
@@ -3133,15 +3203,15 @@ void tst_QSslSocket::resume()
QTestEventLoop::instance().enterLoop(10);
QVERIFY(!QTestEventLoop::instance().timeout()); // quit by encrypted() or error() signal
if (expectSuccess) {
- QCOMPARE(encryptedSpy.count(), 1);
+ QCOMPARE(encryptedSpy.size(), 1);
QVERIFY(socket.isEncrypted());
- QCOMPARE(errorSpy.count(), 0);
+ QCOMPARE(errorSpy.size(), 0);
socket.disconnectFromHost();
QVERIFY(socket.waitForDisconnected(10000));
} else {
- QCOMPARE(encryptedSpy.count(), 0);
+ QCOMPARE(encryptedSpy.size(), 0);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy.size(), 1);
QCOMPARE(socket.error(), QAbstractSocket::SslHandshakeFailedError);
}
}
@@ -3328,17 +3398,17 @@ void tst_QSslSocket::qtbug18498_peek2()
bigblock.fill('#', QIODEVICE_BUFFERSIZE + 1024);
QVERIFY(client->write(QByteArray("head")));
QVERIFY(client->write(bigblock));
- QTRY_COMPARE(server->bytesAvailable(), bigblock.length() + 4);
+ QTRY_COMPARE(server->bytesAvailable(), bigblock.size() + 4);
QCOMPARE(server->read(4), QByteArray("head"));
- QCOMPARE(server->peek(bigblock.length()), bigblock);
- b.reserve(bigblock.length());
- b.resize(server->peek(b.data(), bigblock.length()));
+ QCOMPARE(server->peek(bigblock.size()), bigblock);
+ b.reserve(bigblock.size());
+ b.resize(server->peek(b.data(), bigblock.size()));
QCOMPARE(b, bigblock);
//check oversized peek
- QCOMPARE(server->peek(bigblock.length() * 3), bigblock);
- b.reserve(bigblock.length() * 3);
- b.resize(server->peek(b.data(), bigblock.length() * 3));
+ QCOMPARE(server->peek(bigblock.size() * 3), bigblock);
+ b.reserve(bigblock.size() * 3);
+ b.resize(server->peek(b.data(), bigblock.size() * 3));
QCOMPARE(b, bigblock);
QCOMPARE(server->readAll(), bigblock);
@@ -3406,7 +3476,13 @@ void tst_QSslSocket::dhServer()
return;
SslServer server;
- server.ciphers = {QSslCipher("DHE-RSA-AES256-SHA"), QSslCipher("DHE-DSS-AES256-SHA")};
+ QSslCipher rsaCipher("DHE-RSA-AES256-SHA");
+ QSslCipher dssCipher("DHE-DSS-AES256-SHA");
+ if (rsaCipher.isNull())
+ QSKIP("The current backend doesn't support DHE-RSA-AES256-SHA");
+ if (dssCipher.isNull())
+ QSKIP("The current backend doesn't support DHE-DSS-AES256-SHA");
+ server.ciphers = { rsaCipher, dssCipher };
QVERIFY(server.listen());
QEventLoop loop;
@@ -3424,18 +3500,20 @@ void tst_QSslSocket::dhServer()
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
}
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
void tst_QSslSocket::dhServerCustomParamsNull()
{
- if (!QSslSocket::supportsSsl())
- QSKIP("No SSL support");
+ if (!isTestingOpenSsl)
+ QSKIP("This test requires OpenSSL as the active TLS backend");
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
+ const QSslCipher cipherWithDH("DHE-RSA-AES256-SHA256");
SslServer server;
- server.ciphers = {QSslCipher("DHE-RSA-AES256-SHA"), QSslCipher("DHE-DSS-AES256-SHA")};
+ server.ciphers = {cipherWithDH};
+ server.protocol = QSsl::TlsV1_2;
QSslConfiguration cfg = server.config;
cfg.setDiffieHellmanParameters(QSslDiffieHellmanParameters());
@@ -3447,6 +3525,8 @@ void tst_QSslSocket::dhServerCustomParamsNull()
QTimer::singleShot(5000, &loop, SLOT(quit()));
QSslSocket client;
+ QSslConfiguration config = client.sslConfiguration();
+ client.setSslConfiguration(config);
socket = &client;
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), &loop, SLOT(quit()));
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
@@ -3456,22 +3536,25 @@ void tst_QSslSocket::dhServerCustomParamsNull()
loop.exec();
- QVERIFY(client.state() != QAbstractSocket::ConnectedState);
+ QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
+ QCOMPARE(client.sessionCipher(), cipherWithDH);
}
-#endif // QT_NO_OPENSSL
-#ifndef QT_NO_OPENSSL
void tst_QSslSocket::dhServerCustomParams()
{
if (!QSslSocket::supportsSsl())
QSKIP("No SSL support");
+ if (!QSslSocket::isClassImplemented(QSsl::ImplementedClass::DiffieHellman))
+ QSKIP("The current backend doesn't support diffie hellman parameters");
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
SslServer server;
- server.ciphers = {QSslCipher("DHE-RSA-AES256-SHA"), QSslCipher("DHE-DSS-AES256-SHA")};
+ const QSslCipher cipherWithDH("DHE-RSA-AES256-SHA256");
+ server.ciphers = {cipherWithDH};
+ server.protocol = QSsl::TlsV1_2;
QSslConfiguration cfg = server.config;
@@ -3501,9 +3584,10 @@ void tst_QSslSocket::dhServerCustomParams()
loop.exec();
- QVERIFY(client.state() == QAbstractSocket::ConnectedState);
+ QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
+ QCOMPARE(client.sessionCipher(), cipherWithDH);
}
-#endif // QT_NO_OPENSSL
+#endif // QT_CONFIG(openssl)
void tst_QSslSocket::ecdhServer()
{
@@ -3517,7 +3601,10 @@ void tst_QSslSocket::ecdhServer()
return;
SslServer server;
- server.ciphers = {QSslCipher("ECDHE-RSA-AES128-SHA")};
+ QSslCipher cipher("ECDHE-RSA-AES128-SHA");
+ if (cipher.isNull())
+ QSKIP("The current backend doesn't support ECDHE-RSA-AES128-SHA");
+ server.ciphers = {cipher};
QVERIFY(server.listen());
QEventLoop loop;
@@ -3605,14 +3692,15 @@ void tst_QSslSocket::verifyClientCertificate_data()
void tst_QSslSocket::verifyClientCertificate()
{
-#if QT_CONFIG(securetransport)
- // We run both client and server on the same machine,
- // this means, client can update keychain with client's certificates,
- // and server later will use the same certificates from the same
- // keychain thus making tests fail (wrong number of certificates,
- // success instead of failure etc.).
- QSKIP("This test can not work with Secure Transport");
-#endif // QT_CONFIG(securetransport)
+ if (isTestingSecureTransport) {
+ // We run both client and server on the same machine,
+ // this means, client can update keychain with client's certificates,
+ // and server later will use the same certificates from the same
+ // keychain thus making tests fail (wrong number of certificates,
+ // success instead of failure etc.).
+ QSKIP("This test can not work with Secure Transport");
+ }
+
if (!QSslSocket::supportsSsl()) {
qWarning("SSL not supported, skipping test");
return;
@@ -3623,12 +3711,13 @@ void tst_QSslSocket::verifyClientCertificate()
return;
QFETCH(QSslSocket::PeerVerifyMode, peerVerifyMode);
-#if QT_CONFIG(schannel)
- if (peerVerifyMode == QSslSocket::QueryPeer || peerVerifyMode == QSslSocket::AutoVerifyPeer)
- QSKIP("Schannel doesn't tackle requesting a certificate and not receiving one.");
-#endif
+ if (isTestingSchannel) {
+ if (peerVerifyMode == QSslSocket::QueryPeer || peerVerifyMode == QSslSocket::AutoVerifyPeer)
+ QSKIP("Schannel doesn't tackle requesting a certificate and not receiving one.");
+ }
SslServer server;
+ server.protocol = QSsl::TlsV1_2;
server.addCaCertificates = testDataDir + "certs/bogus-ca.crt";
server.ignoreSslErrors = false;
server.peerVerifyMode = peerVerifyMode;
@@ -3642,6 +3731,9 @@ void tst_QSslSocket::verifyClientCertificate()
QSslSocket client;
client.setLocalCertificateChain(clientCerts);
client.setPrivateKey(clientKey);
+ QSslConfiguration config = client.sslConfiguration();
+ config.setProtocol(Test::TlsV1_0OrLater);
+ client.setSslConfiguration(config);
socket = &client;
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
@@ -3666,13 +3758,13 @@ void tst_QSslSocket::verifyClientCertificate()
QVERIFY(server.socket->peerCertificateChain().isEmpty());
} else {
QCOMPARE(server.socket->peerCertificate(), clientCerts.first());
-#if QT_CONFIG(schannel)
- if (clientCerts.count() == 1 && server.socket->peerCertificateChain().count() == 2) {
- QEXPECT_FAIL("",
- "Schannel includes the entire chain, not just the leaf and intermediates",
- Continue);
+ if (isTestingSchannel) {
+ if (clientCerts.size() == 1 && server.socket->peerCertificateChain().size() == 2) {
+ QEXPECT_FAIL("",
+ "Schannel includes the entire chain, not just the leaf and intermediates",
+ Continue);
+ }
}
-#endif
QCOMPARE(server.socket->peerCertificateChain(), clientCerts);
}
@@ -3683,7 +3775,18 @@ void tst_QSslSocket::verifyClientCertificate()
void tst_QSslSocket::readBufferMaxSize()
{
-#if QT_CONFIG(securetransport) || QT_CONFIG(schannel)
+ // QTBUG-94186: originally, only SecureTransport was
+ // running this test (since it was a bug in that backend,
+ // see comment below), after TLS plugins were introduced,
+ // we enabled this test on all backends, as a part of
+ // the clean up. This revealed the fact that this test
+ // is flaky, and it started to fail on Windows.
+ // TODO: this is a temporary solution, to be removed
+ // as soon as 94186 fixed for good.
+ if (!isTestingSecureTransport)
+ QSKIP("This test is flaky with TLS backend other than SecureTransport");
+
+
// QTBUG-55170:
// SecureTransport back-end was ignoring read-buffer
// size limit, resulting (potentially) in a constantly
@@ -3708,11 +3811,19 @@ void tst_QSslSocket::readBufferMaxSize()
socket = client.data();
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), &loop, SLOT(quit()));
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
- connect(socket, SIGNAL(encrypted()), &loop, SLOT(quit()));
client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(),
server.serverPort());
+ int waitFor = 2;
+ auto earlyQuitter = [&loop, &waitFor]() {
+ if (!--waitFor)
+ loop.exit();
+ };
+
+ connect(socket, &QSslSocket::encrypted, &loop, earlyQuitter);
+ connect(&server, &SslServer::socketEncrypted, &loop, earlyQuitter);
+
// Wait for 'encrypted' first:
QTimer::singleShot(5000, &loop, SLOT(quit()));
loop.exec();
@@ -3738,9 +3849,6 @@ void tst_QSslSocket::readBufferMaxSize()
loop.exec();
QCOMPARE(client->bytesAvailable() + readSoFar, message.size());
-#else
- // Not needed, QSslSocket works correctly with other back-ends.
-#endif // QT_CONFIG(securetransport) || QT_CONFIG(schannel)
}
void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, as it has some side effects
@@ -3765,20 +3873,13 @@ void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last,
void tst_QSslSocket::allowedProtocolNegotiation()
{
-#ifndef ALPN_SUPPORTED
- QSKIP("ALPN is unsupported, skipping test");
-#endif
-
-#if QT_CONFIG(schannel)
- if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
- QSKIP("ALPN is not supported on this version of Windows using Schannel.");
-#endif
+ if (!hasServerAlpn)
+ QSKIP("Server-side ALPN is unsupported, skipping test");
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
-
const QByteArray expectedNegotiated("cool-protocol");
QList<QByteArray> serverProtos;
serverProtos << expectedNegotiated << "not-so-cool-protocol";
@@ -3800,15 +3901,25 @@ void tst_QSslSocket::allowedProtocolNegotiation()
QEventLoop loop;
QTimer::singleShot(5000, &loop, SLOT(quit()));
- connect(&clientSocket, SIGNAL(encrypted()), &loop, SLOT(quit()));
+
+ // Need to wait for both sides to emit encrypted as the ordering of which
+ // ones emits encrypted() changes depending on whether we use TLS 1.2 or 1.3
+ int waitFor = 2;
+ auto earlyQuitter = [&loop, &waitFor]() {
+ if (!--waitFor)
+ loop.exit();
+ };
+ connect(&clientSocket, &QSslSocket::encrypted, &loop, earlyQuitter);
+ connect(&server, &SslServer::socketEncrypted, &loop, earlyQuitter);
+
loop.exec();
- QVERIFY(server.socket->sslConfiguration().nextNegotiatedProtocol() ==
- clientSocket.sslConfiguration().nextNegotiatedProtocol());
- QVERIFY(server.socket->sslConfiguration().nextNegotiatedProtocol() == expectedNegotiated);
+ QCOMPARE(server.socket->sslConfiguration().nextNegotiatedProtocol(),
+ clientSocket.sslConfiguration().nextNegotiatedProtocol());
+ QCOMPARE(server.socket->sslConfiguration().nextNegotiatedProtocol(), expectedNegotiated);
}
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
class PskProvider : public QObject
{
Q_OBJECT
@@ -3866,7 +3977,7 @@ public:
config(QSslConfiguration::defaultConfiguration()),
ignoreSslErrors(true),
peerVerifyMode(QSslSocket::AutoVerifyPeer),
- protocol(QSsl::TlsV1_0),
+ protocol(QSsl::TlsV1_2),
m_pskProvider()
{
m_pskProvider.m_server = true;
@@ -3912,8 +4023,12 @@ protected slots:
socket->ignoreSslErrors();
}
};
+
void tst_QSslSocket::simplePskConnect_data()
{
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does support PSK");
+
QTest::addColumn<PskConnectTestType>("pskTestType");
QTest::newRow("PskConnectDoNotHandlePsk") << PskConnectDoNotHandlePsk;
QTest::newRow("PskConnectEmptyCredentials") << PskConnectEmptyCredentials;
@@ -4004,14 +4119,14 @@ void tst_QSslSocket::simplePskConnect()
case PskConnectWrongCredentials:
// provide totally wrong credentials
- provider.setIdentity(PSK_CLIENT_IDENTITY.left(PSK_CLIENT_IDENTITY.length() - 1));
- provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY.left(PSK_CLIENT_PRESHAREDKEY.length() - 1));
+ provider.setIdentity(PSK_CLIENT_IDENTITY.left(PSK_CLIENT_IDENTITY.size() - 1));
+ provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY.left(PSK_CLIENT_PRESHAREDKEY.size() - 1));
connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*)));
break;
case PskConnectWrongIdentity:
// right PSK, wrong identity
- provider.setIdentity(PSK_CLIENT_IDENTITY.left(PSK_CLIENT_IDENTITY.length() - 1));
+ provider.setIdentity(PSK_CLIENT_IDENTITY.left(PSK_CLIENT_IDENTITY.size() - 1));
provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY);
connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*)));
break;
@@ -4019,7 +4134,7 @@ void tst_QSslSocket::simplePskConnect()
case PskConnectWrongPreSharedKey:
// right identity, wrong PSK
provider.setIdentity(PSK_CLIENT_IDENTITY);
- provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY.left(PSK_CLIENT_PRESHAREDKEY.length() - 1));
+ provider.setPreSharedKey(PSK_CLIENT_PRESHAREDKEY.left(PSK_CLIENT_PRESHAREDKEY.size() - 1));
connect(&socket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), &provider, SLOT(providePsk(QSslPreSharedKeyAuthenticator*)));
break;
@@ -4071,32 +4186,32 @@ void tst_QSslSocket::simplePskConnect()
// Entered connecting state
QCOMPARE(socket.state(), QAbstractSocket::ConnectingState);
- QCOMPARE(connectedSpy.count(), 0);
- QCOMPARE(hostFoundSpy.count(), 1);
- QCOMPARE(disconnectedSpy.count(), 0);
+ QCOMPARE(connectedSpy.size(), 0);
+ QCOMPARE(hostFoundSpy.size(), 1);
+ QCOMPARE(disconnectedSpy.size(), 0);
enterLoop(10);
// Entered connected state
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(connectedSpy.count(), 1);
- QCOMPARE(hostFoundSpy.count(), 1);
- QCOMPARE(disconnectedSpy.count(), 0);
+ QCOMPARE(connectedSpy.size(), 1);
+ QCOMPARE(hostFoundSpy.size(), 1);
+ QCOMPARE(disconnectedSpy.size(), 0);
// Enter encrypted mode
socket.startClientEncryption();
QCOMPARE(socket.mode(), QSslSocket::SslClientMode);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(connectionEncryptedSpy.count(), 0);
- QCOMPARE(sslErrorsSpy.count(), 0);
- QCOMPARE(peerVerifyErrorSpy.count(), 0);
+ QCOMPARE(connectionEncryptedSpy.size(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 0);
+ QCOMPARE(peerVerifyErrorSpy.size(), 0);
// Start handshake.
enterLoop(10);
// We must get the PSK signal in all cases
- QCOMPARE(pskAuthenticationRequiredSpy.count(), 1);
+ QCOMPARE(pskAuthenticationRequiredSpy.size(), 1);
switch (pskTestType) {
case PskConnectDoNotHandlePsk:
@@ -4105,40 +4220,40 @@ void tst_QSslSocket::simplePskConnect()
case PskConnectWrongIdentity:
case PskConnectWrongPreSharedKey:
// Handshake failure
- QCOMPARE(socketErrorsSpy.count(), 1);
+ QCOMPARE(socketErrorsSpy.size(), 1);
QCOMPARE(qvariant_cast<QAbstractSocket::SocketError>(socketErrorsSpy.at(0).at(0)), QAbstractSocket::SslHandshakeFailedError);
- QCOMPARE(sslErrorsSpy.count(), 0);
- QCOMPARE(peerVerifyErrorSpy.count(), 0);
- QCOMPARE(connectionEncryptedSpy.count(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 0);
+ QCOMPARE(peerVerifyErrorSpy.size(), 0);
+ QCOMPARE(connectionEncryptedSpy.size(), 0);
QVERIFY(!socket.isEncrypted());
break;
case PskConnectRightCredentialsPeerVerifyFailure:
// Peer verification failure
- QCOMPARE(socketErrorsSpy.count(), 1);
+ QCOMPARE(socketErrorsSpy.size(), 1);
QCOMPARE(qvariant_cast<QAbstractSocket::SocketError>(socketErrorsSpy.at(0).at(0)), QAbstractSocket::SslHandshakeFailedError);
- QCOMPARE(sslErrorsSpy.count(), 1);
- QCOMPARE(peerVerifyErrorSpy.count(), 1);
- QCOMPARE(connectionEncryptedSpy.count(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 1);
+ QCOMPARE(peerVerifyErrorSpy.size(), 1);
+ QCOMPARE(connectionEncryptedSpy.size(), 0);
QVERIFY(!socket.isEncrypted());
break;
case PskConnectRightCredentialsVerifyPeer:
// Peer verification failure, but ignore it and keep connecting
- QCOMPARE(socketErrorsSpy.count(), 0);
- QCOMPARE(sslErrorsSpy.count(), 1);
- QCOMPARE(peerVerifyErrorSpy.count(), 1);
- QCOMPARE(connectionEncryptedSpy.count(), 1);
+ QCOMPARE(socketErrorsSpy.size(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 1);
+ QCOMPARE(peerVerifyErrorSpy.size(), 1);
+ QCOMPARE(connectionEncryptedSpy.size(), 1);
QVERIFY(socket.isEncrypted());
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
break;
case PskConnectRightCredentialsDoNotVerifyPeer:
// No peer verification => no failure
- QCOMPARE(socketErrorsSpy.count(), 0);
- QCOMPARE(sslErrorsSpy.count(), 0);
- QCOMPARE(peerVerifyErrorSpy.count(), 0);
- QCOMPARE(connectionEncryptedSpy.count(), 1);
+ QCOMPARE(socketErrorsSpy.size(), 0);
+ QCOMPARE(sslErrorsSpy.size(), 0);
+ QCOMPARE(peerVerifyErrorSpy.size(), 0);
+ QCOMPARE(connectionEncryptedSpy.size(), 1);
QVERIFY(socket.isEncrypted());
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
break;
@@ -4179,11 +4294,14 @@ void tst_QSslSocket::simplePskConnect()
}
QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
- QCOMPARE(disconnectedSpy.count(), 1);
+ QCOMPARE(disconnectedSpy.size(), 1);
}
void tst_QSslSocket::ephemeralServerKey_data()
{
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does not support ephemeral keys");
+
QTest::addColumn<QString>("cipher");
QTest::addColumn<bool>("emptyKey");
@@ -4209,16 +4327,16 @@ void tst_QSslSocket::ephemeralServerKey()
client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort());
spy.wait();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(server.config.ephemeralServerKey().isNull());
QCOMPARE(client->sslConfiguration().ephemeralServerKey().isNull(), emptyKey);
}
void tst_QSslSocket::pskServer()
{
-#if QT_CONFIG(schannel)
- QSKIP("Schannel does not have PSK support implemented.");
-#endif
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS-backend does not have PSK support implemented.");
+
QFETCH_GLOBAL(bool, setProxy);
if (!QSslSocket::supportsSsl() || setProxy)
return;
@@ -4272,22 +4390,22 @@ void tst_QSslSocket::pskServer()
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socket.mode(), QSslSocket::UnencryptedMode);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(connectedSpy.count(), 1);
- QCOMPARE(disconnectedSpy.count(), 0);
+ QCOMPARE(connectedSpy.size(), 1);
+ QCOMPARE(disconnectedSpy.size(), 0);
// Enter encrypted mode
socket.startClientEncryption();
QCOMPARE(socket.mode(), QSslSocket::SslClientMode);
QVERIFY(!socket.isEncrypted());
- QCOMPARE(connectionEncryptedSpy.count(), 0);
+ QCOMPARE(connectionEncryptedSpy.size(), 0);
// Start handshake.
enterLoop(10);
// We must get the PSK signal in all cases
- QCOMPARE(pskAuthenticationRequiredSpy.count(), 1);
+ QCOMPARE(pskAuthenticationRequiredSpy.size(), 1);
- QCOMPARE(connectionEncryptedSpy.count(), 1);
+ QCOMPARE(connectionEncryptedSpy.size(), 1);
QVERIFY(socket.isEncrypted());
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
@@ -4300,13 +4418,13 @@ void tst_QSslSocket::pskServer()
enterLoop(10);
QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
- QCOMPARE(disconnectedSpy.count(), 1);
+ QCOMPARE(disconnectedSpy.size(), 1);
}
void tst_QSslSocket::signatureAlgorithm_data()
{
- if (!QSslSocket::supportsSsl())
- QSKIP("Signature algorithms cannot be tested without SSL support");
+ if (!isTestingOpenSsl)
+ QSKIP("Signature algorithms cannot be tested with a non-OpenSSL TLS backend");
if (QSslSocket::sslLibraryVersionNumber() >= 0x10101000L) {
// FIXME: investigate if this test makes any sense with TLS 1.3.
@@ -4372,7 +4490,7 @@ void tst_QSslSocket::signatureAlgorithm_data()
// signature algorithms do not match, but are ignored because the tls version is not v1.2
QTest::newRow("client_ignore_TlsV1_1")
<< QByteArrayList({rsaSha256})
- << QSsl::TlsV1_1
+ << Test::TlsV1_1
<< QByteArrayList({rsaSha512})
<< QSsl::AnyProtocol
<< QAbstractSocket::ConnectedState;
@@ -4380,11 +4498,11 @@ void tst_QSslSocket::signatureAlgorithm_data()
<< QByteArrayList({rsaSha256})
<< QSsl::AnyProtocol
<< QByteArrayList({rsaSha512})
- << QSsl::TlsV1_1
+ << Test::TlsV1_1
<< QAbstractSocket::ConnectedState;
QTest::newRow("client_ignore_TlsV1_0")
<< QByteArrayList({rsaSha256})
- << QSsl::TlsV1_0
+ << Test::TlsV1_0
<< QByteArrayList({rsaSha512})
<< QSsl::AnyProtocol
<< QAbstractSocket::ConnectedState;
@@ -4392,7 +4510,7 @@ void tst_QSslSocket::signatureAlgorithm_data()
<< QByteArrayList({rsaSha256})
<< QSsl::AnyProtocol
<< QByteArrayList({rsaSha512})
- << QSsl::TlsV1_0
+ << Test::TlsV1_0
<< QAbstractSocket::ConnectedState;
}
@@ -4435,8 +4553,9 @@ void tst_QSslSocket::signatureAlgorithm()
void tst_QSslSocket::forwardReadChannelFinished()
{
- if (!QSslSocket::supportsSsl())
- QSKIP("Needs SSL");
+ if (!isTestingOpenSsl)
+ QSKIP("This test requires the OpenSSL backend");
+
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
QSKIP("This test doesn't work via a proxy");
@@ -4452,17 +4571,17 @@ void tst_QSslSocket::forwardReadChannelFinished()
&QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
socket.connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
enterLoop(10);
- QVERIFY(readChannelFinishedSpy.count());
+ QVERIFY(readChannelFinishedSpy.size());
}
-#endif // QT_NO_OPENSSL
+#endif // QT_CONFIG(openssl)
void tst_QSslSocket::unsupportedProtocols_data()
{
QTest::addColumn<QSsl::SslProtocol>("unsupportedProtocol");
- QTest::newRow("DtlsV1_0") << QSsl::DtlsV1_0;
+ QTest::newRow("DtlsV1_0") << Test::DtlsV1_0;
QTest::newRow("DtlsV1_2") << QSsl::DtlsV1_2;
- QTest::newRow("DtlsV1_0OrLater") << QSsl::DtlsV1_0OrLater;
+ QTest::newRow("DtlsV1_0OrLater") << Test::DtlsV1_0OrLater;
QTest::newRow("DtlsV1_2OrLater") << QSsl::DtlsV1_2OrLater;
QTest::newRow("UnknownProtocol") << QSsl::UnknownProtocol;
}
@@ -4474,7 +4593,7 @@ void tst_QSslSocket::unsupportedProtocols()
return;
QFETCH(const QSsl::SslProtocol, unsupportedProtocol);
- const int timeoutMS = 500;
+ constexpr auto timeout = 500ms;
// Test a client socket.
{
// 0. connectToHostEncrypted: client-side, non-blocking API, error is discovered
@@ -4496,7 +4615,7 @@ void tst_QSslSocket::unsupportedProtocols()
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
- QVERIFY(socket.waitForConnected(timeoutMS));
+ QVERIFY(socket.waitForConnected(int(timeout.count())));
socket.setProtocol(unsupportedProtocol);
socket.startClientEncryption();
@@ -4521,7 +4640,7 @@ void tst_QSslSocket::unsupportedProtocols()
QTcpSocket client;
client.connectToHost(QHostAddress::LocalHost, server.serverPort());
- loop.enterLoopMSecs(timeoutMS);
+ loop.enterLoop(timeout);
QVERIFY(!loop.timeout());
QVERIFY(server.socket);
QCOMPARE(server.socket->error(), QAbstractSocket::SslInvalidUserDataError);
@@ -4534,13 +4653,15 @@ void tst_QSslSocket::oldErrorsOnSocketReuse()
if (setProxy)
return; // not relevant
SslServer server;
- server.protocol = QSsl::TlsV1_1;
+ if (!isTestingOpenSsl)
+ server.protocol = Test::TlsV1_1;
server.m_certFile = testDataDir + "certs/fluke.cert";
server.m_keyFile = testDataDir + "certs/fluke.key";
QVERIFY(server.listen(QHostAddress::SpecialAddress::LocalHost));
QSslSocket socket;
- socket.setProtocol(QSsl::TlsV1_1);
+ if (!isTestingOpenSsl)
+ socket.setProtocol(Test::TlsV1_1);
QList<QSslError> errorList;
auto connection = connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
[&socket, &errorList](const QList<QSslError> &errors) {
@@ -4575,8 +4696,6 @@ void tst_QSslSocket::oldErrorsOnSocketReuse()
}
}
-#endif // QT_NO_SSL
-
#if QT_CONFIG(openssl)
void tst_QSslSocket::alertMissingCertificate()
@@ -4584,6 +4703,8 @@ void tst_QSslSocket::alertMissingCertificate()
// In this test we want a server to abort the connection due to the failing
// client authentication. The server expected to send an alert before closing
// the connection, and the client expected to receive this alert and report it.
+ if (!isTestingOpenSsl)
+ QSKIP("This test requires the OpenSSL backend");
QFETCH_GLOBAL(const bool, setProxy);
if (setProxy) // Not what we test here, bail out.
@@ -4626,10 +4747,19 @@ void tst_QSslSocket::alertMissingCertificate()
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
connect(&server, &SslServer::socketError, earlyQuitter);
- runner.enterLoopMSecs(1000);
+ runner.enterLoop(1s);
- QVERIFY(serverSpy.count() > 0);
- QVERIFY(clientSpy.count() > 0);
+ if (clientSocket.isEncrypted()) {
+ // When using TLS 1.3 the client side thinks it is connected very
+ // quickly, before the server has finished processing. So wait for the
+ // inevitable disconnect.
+ QCOMPARE(clientSocket.sessionProtocol(), QSsl::TlsV1_3);
+ connect(&clientSocket, &QSslSocket::disconnected, &runner, &QTestEventLoop::exitLoop);
+ runner.enterLoop(10s);
+ }
+
+ QVERIFY(serverSpy.size() > 0);
+ QVERIFY(clientSpy.size() > 0);
QVERIFY(server.socket && !server.socket->isEncrypted());
QVERIFY(!clientSocket.isEncrypted());
}
@@ -4640,6 +4770,9 @@ void tst_QSslSocket::alertInvalidCertificate()
// it also will do 'early' checks, meaning the reported and
// not ignored _during_ the hanshake, not after. This ensures
// OpenSSL sends an alert.
+ if (!isTestingOpenSsl)
+ QSKIP("This test requires the OpenSSL backend");
+
QFETCH_GLOBAL(const bool, setProxy);
if (setProxy) // Not what we test here, bail out.
return;
@@ -4677,17 +4810,20 @@ void tst_QSslSocket::alertInvalidCertificate()
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
connect(&server, &SslServer::socketError, earlyQuitter);
- runner.enterLoopMSecs(1000);
+ runner.enterLoop(1s);
- QVERIFY(serverSpy.count() > 0);
- QVERIFY(clientSpy.count() > 0);
- QVERIFY(interruptedSpy.count() > 0);
+ QVERIFY(serverSpy.size() > 0);
+ QVERIFY(clientSpy.size() > 0);
+ QVERIFY(interruptedSpy.size() > 0);
QVERIFY(server.socket && !server.socket->isEncrypted());
QVERIFY(!clientSocket.isEncrypted());
}
void tst_QSslSocket::selfSignedCertificates_data()
{
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does not detect the required error");
+
QTest::addColumn<bool>("clientKnown");
QTest::newRow("Client known") << true;
@@ -4802,17 +4938,17 @@ void tst_QSslSocket::selfSignedCertificates()
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
connect(&server, &SslServer::socketError, earlyQuitter);
- runner.enterLoopMSecs(1000);
+ runner.enterLoop(1s);
if (clientKnown) {
- QCOMPARE(serverSpy.count(), 0);
- QCOMPARE(clientSpy.count(), 0);
+ QCOMPARE(serverSpy.size(), 0);
+ QCOMPARE(clientSpy.size(), 0);
QVERIFY(server.socket && server.socket->isEncrypted());
QVERIFY(clientSocket.isEncrypted());
} else {
- QVERIFY(serverSpy.count() > 0);
+ QVERIFY(serverSpy.size() > 0);
QEXPECT_FAIL("", "Failing to trigger signal, QTBUG-81661", Continue);
- QVERIFY(clientSpy.count() > 0);
+ QVERIFY(clientSpy.size() > 0);
QVERIFY(server.socket && !server.socket->isEncrypted());
QVERIFY(!clientSocket.isEncrypted());
}
@@ -4820,6 +4956,9 @@ void tst_QSslSocket::selfSignedCertificates()
void tst_QSslSocket::pskHandshake_data()
{
+ if (!isTestingOpenSsl)
+ QSKIP("The active TLS backend does not support PSK");
+
QTest::addColumn<bool>("pskRight");
QTest::newRow("Psk right") << true;
@@ -4937,18 +5076,18 @@ void tst_QSslSocket::pskHandshake()
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
connect(&server, &SslServer::socketError, earlyQuitter);
- runner.enterLoopMSecs(1000);
+ runner.enterLoop(1s);
if (pskRight) {
- QCOMPARE(serverSpy.count(), 0);
- QCOMPARE(clientSpy.count(), 0);
+ QCOMPARE(serverSpy.size(), 0);
+ QCOMPARE(clientSpy.size(), 0);
QVERIFY(server.socket && server.socket->isEncrypted());
QVERIFY(clientSocket.isEncrypted());
} else {
- QVERIFY(serverSpy.count() > 0);
+ QVERIFY(serverSpy.size() > 0);
QCOMPARE(serverSpy.first().at(0).toInt(), static_cast<int>(QSsl::AlertLevel::Fatal));
QCOMPARE(serverSpy.first().at(1).toInt(), static_cast<int>(QSsl::AlertType::BadRecordMac));
- QVERIFY(clientSpy.count() > 0);
+ QVERIFY(clientSpy.size() > 0);
QCOMPARE(clientSpy.first().at(0).toInt(), static_cast<int>(QSsl::AlertLevel::Fatal));
QCOMPARE(clientSpy.first().at(1).toInt(), static_cast<int>(QSsl::AlertType::BadRecordMac));
QVERIFY(server.socket && !server.socket->isEncrypted());
@@ -4956,7 +5095,9 @@ void tst_QSslSocket::pskHandshake()
}
}
-#endif // openssl
+#endif // QT_CONFIG(openssl)
+#endif // QT_CONFIG(ssl)
+
QTEST_MAIN(tst_QSslSocket)