diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2018-11-29 02:57:15 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-12-13 15:59:37 +0000 |
commit | 455951f59074d6457fd2d10720ac3cbdaa966076 (patch) | |
tree | f214024d0551594712da3d33717a4af3a5e2b07e | |
parent | 3364be785930548bde2e6dfebe3aabed9e3f780d (diff) |
OpenSSL: drop support for SSLv2 and SSLv3
As per RFC 6176 (2011) and RFC 7568 (2015).
Code-wise, we're left with the decision of what to do with a few
enumerators in QSsl::Protocol; I've made TlsV1SslV3 act as TlsV1,
and adjusted the description of AnyProtocol.
A new test was introduced - deprecatedProtocol() - to test that
we, indeed, do not allow use of SSL v2 and v3. protocol() and
protocolServerSide() were reduced to exclude the (now) no-op
and meaningless tests - neither client nor server side can
start a handshake now, since we bail out early in initSslContext().
[ChangeLog][QtNetwork][SSL] Support for SSLv2 and SSLv3
sockets has been dropped, as per RFC 6176 (2011)
and RFC 7568 (2015).
Change-Id: I2fe4e8c3e82adf7aa10d4bdc9e3f7b8c299f77b6
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r-- | src/network/ssl/qssl.cpp | 20 | ||||
-rw-r--r-- | src/network/ssl/qsslcontext_openssl11.cpp | 17 | ||||
-rw-r--r-- | src/network/ssl/qsslcontext_opensslpre11.cpp | 17 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_mac.cpp | 24 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl_symbols.cpp | 36 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_opensslpre11_symbols_p.h | 24 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_winrt.cpp | 12 | ||||
-rw-r--r-- | tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 192 |
9 files changed, 97 insertions, 247 deletions
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index ea2b73bad5..6b5dbdfeac 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -117,8 +117,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); Describes the protocol of the cipher. - \value SslV3 SSLv3. When using the WinRT backend this option will also enable TLSv1.0 - \value SslV2 SSLv2. Note, SSLv2 support was removed in OpenSSL 1.1. + \value SslV3 SSLv3; not supported by QSslSocket. + \value SslV2 SSLv2; not supported by QSslSocket. \value TlsV1_0 TLSv1.0 \value TlsV1_0OrLater TLSv1.0 and later versions. This option is not available when using the WinRT backend due to platform limitations. \value TlsV1 Obsolete, means the same as TlsV1_0 @@ -133,19 +133,9 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value TlsV1_3 TLSv1.3. (Since Qt 5.12) \value TlsV1_3OrLater TLSv1.3 and later versions. (Since Qt 5.12) \value UnknownProtocol The cipher's protocol cannot be determined. - \value AnyProtocol The socket understands SSLv2, SSLv3, TLSv1.0 and all - supported later versions of TLS. This value is used by QSslSocket only. - \value TlsV1SslV3 On the client side, this will send - a TLS 1.0 Client Hello, enabling TLSv1_0 and SSLv3 connections. - On the server side, this will enable both SSLv3 and TLSv1_0 connections. - \value SecureProtocols The default option, using protocols known to be secure; - currently behaves similar to TlsV1Ssl3 except denying SSLv3 connections that does - not upgrade to TLS. - - \note most servers understand both SSL and TLS, but it is recommended to use - TLS only for security reasons. However, SSL and TLS are not compatible with - each other: if you get unexpected handshake failures, verify that you chose - the correct setting for your protocol. + \value AnyProtocol Any supported protocol. This value is used by QSslSocket only. + \value TlsV1SslV3 Same as TlsV1_0. + \value SecureProtocols The default option, using protocols known to be secure. */ /*! diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index c96a48dac1..21a5c779f7 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -95,6 +95,10 @@ init_context: // SSL 2 is no longer supported, but chosen deliberately -> error sslContext->ctx = nullptr; unsupportedProtocol = true; + } else if (sslContext->sslConfiguration.protocol() == QSsl::SslV3) { + // SSL 3 is no longer supported, but chosen deliberately -> error + sslContext->ctx = nullptr; + unsupportedProtocol = true; } else { switch (sslContext->sslConfiguration.protocol()) { case QSsl::DtlsV1_0: @@ -151,11 +155,6 @@ init_context: long maxVersion = anyVersion; switch (sslContext->sslConfiguration.protocol()) { - // The single-protocol versions first: - case QSsl::SslV3: - minVersion = SSL3_VERSION; - maxVersion = SSL3_VERSION; - break; case QSsl::TlsV1_0: minVersion = TLS1_VERSION; maxVersion = TLS1_VERSION; @@ -181,9 +180,6 @@ init_context: // Ranges: case QSsl::TlsV1SslV3: case QSsl::AnyProtocol: - minVersion = SSL3_VERSION; - maxVersion = 0; - break; case QSsl::SecureProtocols: case QSsl::TlsV1_0OrLater: minVersion = TLS1_VERSION; @@ -227,8 +223,9 @@ init_context: break; #endif // TLS1_3_VERSION case QSsl::SslV2: - // This protocol is not supported by OpenSSL 1.1 and we handle - // it as an error (see the code above). + case QSsl::SslV3: + // These protocols are not supported, and we handle + // them as an error (see the code above). Q_UNREACHABLE(); break; case QSsl::UnknownProtocol: diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp index 34537d1da4..f952d06f75 100644 --- a/src/network/ssl/qsslcontext_opensslpre11.cpp +++ b/src/network/ssl/qsslcontext_opensslpre11.cpp @@ -115,32 +115,19 @@ init_context: break; #endif // dtls case QSsl::SslV2: -#ifndef OPENSSL_NO_SSL2 - sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method()); -#else - // SSL 2 not supported by the system, but chosen deliberately -> error - sslContext->ctx = 0; - unsupportedProtocol = true; -#endif - break; case QSsl::SslV3: -#ifndef OPENSSL_NO_SSL3_METHOD - sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); -#else - // SSL 3 not supported by the system, but chosen deliberately -> error + // We don't support SSLv2 / SSLv3. sslContext->ctx = 0; unsupportedProtocol = true; -#endif break; case QSsl::SecureProtocols: // SSLv2 and SSLv3 will be disabled by SSL options // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32. - case QSsl::TlsV1SslV3: - // SSLv2 will will be disabled by SSL options case QSsl::AnyProtocol: default: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); break; + case QSsl::TlsV1SslV3: case QSsl::TlsV1_0: sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method()); break; diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index f92eaf872b..9c3c98e390 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -1107,6 +1107,12 @@ bool QSslSocketBackendPrivate::setSessionProtocol() return false; } + // SslV3 is unsupported. + if (configuration.protocol == QSsl::SslV3) { + qCDebug(lcSsl) << "protocol QSsl::SslV3 is disabled"; + return false; + } + // SecureTransport has kTLSProtocol13 constant and also, kTLSProtocolMaxSupported. // Calling SSLSetProtocolVersionMax/Min with any of these two constants results // in errInvalidParam and a failure to set the protocol version. This means @@ -1121,14 +1127,7 @@ bool QSslSocketBackendPrivate::setSessionProtocol() OSStatus err = errSecSuccess; - if (configuration.protocol == QSsl::SslV3) { - #ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl) << plainSocket << "requesting : SSLv3"; - #endif - err = SSLSetProtocolVersionMin(context, kSSLProtocol3); - if (err == errSecSuccess) - err = SSLSetProtocolVersionMax(context, kSSLProtocol3); - } else if (configuration.protocol == QSsl::TlsV1_0) { + if (configuration.protocol == QSsl::TlsV1_0) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0"; #endif @@ -1153,17 +1152,16 @@ bool QSslSocketBackendPrivate::setSessionProtocol() #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : any"; #endif - // kSSLProtocol3, since kSSLProtocol2 is disabled: - err = SSLSetProtocolVersionMin(context, kSSLProtocol3); + err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == errSecSuccess) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::TlsV1SslV3) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2"; #endif - err = SSLSetProtocolVersionMin(context, kSSLProtocol3); + err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == errSecSuccess) - err = SSLSetProtocolVersionMax(context, kTLSProtocol12); + err = SSLSetProtocolVersionMax(context, kTLSProtocol1); } else if (configuration.protocol == QSsl::SecureProtocols) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2"; @@ -1217,7 +1215,7 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const if (configuration.protocol == QSsl::AnyProtocol) protocolOk = true; else if (configuration.protocol == QSsl::TlsV1SslV3) - protocolOk = (sessionProtocol() >= QSsl::SslV3); + protocolOk = (sessionProtocol() == QSsl::TlsV1_0); else if (configuration.protocol == QSsl::SecureProtocols) protocolOk = (sessionProtocol() >= QSsl::TlsV1_0); else if (configuration.protocol == QSsl::TlsV1_0OrLater) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index f6ee067c15..9b93915672 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -395,7 +395,7 @@ long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, Q { long options; if (protocol == QSsl::TlsV1SslV3) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2; + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; else if (protocol == QSsl::SecureProtocols) options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; else if (protocol == QSsl::TlsV1_0OrLater) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 01aa06446c..953b01d01a 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -285,24 +285,12 @@ DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO #endif // OPENSSL_VERSION_NUMBER >= 0x10001000L #if OPENSSL_VERSION_NUMBER >= 0x10000000L -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -310,20 +298,8 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif #else -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif @@ -1130,24 +1106,12 @@ bool q_resolveOpenSslSymbols() #if OPENSSL_VERSION_NUMBER >= 0x10001000L RESOLVEFUNC(SSL_get_ex_new_index) #endif -#ifndef OPENSSL_NO_SSL2 - RESOLVEFUNC(SSLv2_client_method) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - RESOLVEFUNC(SSLv3_client_method) -#endif RESOLVEFUNC(SSLv23_client_method) RESOLVEFUNC(TLSv1_client_method) #if OPENSSL_VERSION_NUMBER >= 0x10001000L RESOLVEFUNC(TLSv1_1_client_method) RESOLVEFUNC(TLSv1_2_client_method) #endif -#ifndef OPENSSL_NO_SSL2 - RESOLVEFUNC(SSLv2_server_method) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - RESOLVEFUNC(SSLv3_server_method) -#endif RESOLVEFUNC(SSLv23_server_method) RESOLVEFUNC(TLSv1_server_method) #if OPENSSL_VERSION_NUMBER >= 0x10001000L diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h index daf46f485c..abfa2e7004 100644 --- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h +++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h @@ -136,43 +136,19 @@ int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPT #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L -#ifndef OPENSSL_NO_SSL2 -const SSL_METHOD *q_SSLv2_client_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -const SSL_METHOD *q_SSLv3_client_method(); -#endif const SSL_METHOD *q_SSLv23_client_method(); const SSL_METHOD *q_TLSv1_client_method(); const SSL_METHOD *q_TLSv1_1_client_method(); const SSL_METHOD *q_TLSv1_2_client_method(); -#ifndef OPENSSL_NO_SSL2 -const SSL_METHOD *q_SSLv2_server_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -const SSL_METHOD *q_SSLv3_server_method(); -#endif const SSL_METHOD *q_SSLv23_server_method(); const SSL_METHOD *q_TLSv1_server_method(); const SSL_METHOD *q_TLSv1_1_server_method(); const SSL_METHOD *q_TLSv1_2_server_method(); #else -#ifndef OPENSSL_NO_SSL2 -SSL_METHOD *q_SSLv2_client_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -SSL_METHOD *q_SSLv3_client_method(); -#endif SSL_METHOD *q_SSLv23_client_method(); SSL_METHOD *q_TLSv1_client_method(); SSL_METHOD *q_TLSv1_1_client_method(); SSL_METHOD *q_TLSv1_2_client_method(); -#ifndef OPENSSL_NO_SSL2 -SSL_METHOD *q_SSLv2_server_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -SSL_METHOD *q_SSLv3_server_method(); -#endif SSL_METHOD *q_SSLv23_server_method(); SSL_METHOD *q_TLSv1_server_method(); SSL_METHOD *q_TLSv1_1_server_method(); diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index cc69b9ac96..d54ac2ad73 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -207,9 +207,9 @@ void QSslSocketPrivate::resetDefaultCiphers() QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers() { QList<QSslCipher> ciphers; - const QString protocolStrings[] = { QStringLiteral("SSLv3"), QStringLiteral("TLSv1"), + const QString protocolStrings[] = { QStringLiteral("TLSv1"), QStringLiteral("TLSv1.1"), QStringLiteral("TLSv1.2") }; - const QSsl::SslProtocol protocols[] = { QSsl::SslV3, QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 }; + const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 }; const int size = static_cast<int>(ARRAYSIZE(protocols)); ciphers.reserve(size); for (int i = 0; i < size; ++i) { @@ -234,10 +234,14 @@ void QSslSocketBackendPrivate::startClientEncryption() QSsl::SslProtocol protocol = q->protocol(); switch (q->protocol()) { - case QSsl::AnyProtocol: + case QSsl::SslV2: case QSsl::SslV3: + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QStringLiteral("unsupported protocol")); + return; + case QSsl::AnyProtocol: case QSsl::TlsV1SslV3: - protectionLevel = SocketProtectionLevel_Ssl; // Only use this value if weak cipher support is required + protectionLevel = SocketProtectionLevel_Tls10; break; case QSsl::TlsV1_0: protectionLevel = SocketProtectionLevel_Tls10; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 3e55278b4f..0523f2591f 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -245,6 +245,9 @@ private slots: void signatureAlgorithm(); #endif + void deprecatedProtocols_data(); + void deprecatedProtocols(); + void setEmptyDefaultConfiguration(); // this test should be last protected slots: @@ -952,24 +955,6 @@ void tst_QSslSocket::protocol() QCOMPARE(socket->protocol(), QSsl::SecureProtocols); QFETCH_GLOBAL(bool, setProxy); { - // qt-test-server allows SSLv3. - socket->setProtocol(QSsl::SslV3); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->abort(); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->connectToHost(QtNetworkSettings::serverName(), 443); - QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString())); - socket->startClientEncryption(); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->abort(); - } - { // qt-test-server allows TLSV1. socket->setProtocol(QSsl::TlsV1_0); QCOMPARE(socket->protocol(), QSsl::TlsV1_0); @@ -1045,26 +1030,6 @@ void tst_QSslSocket::protocol() socket->abort(); } #endif // TLS1_3_VERSION -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - { - // qt-test-server allows SSLV2. - socket->setProtocol(QSsl::SslV2); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->abort(); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->connectToHost(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForConnected()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - socket->startClientEncryption(); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - socket->abort(); - } -#endif { // qt-test-server allows SSLV3, so it allows AnyProtocol. socket->setProtocol(QSsl::AnyProtocol); @@ -1084,7 +1049,7 @@ void tst_QSslSocket::protocol() socket->abort(); } { - // qt-test-server allows SSLV3, so it allows NoSslV2 + // qt-test-server allows TlsV1, so it allows TlsV1SslV3 socket->setProtocol(QSsl::TlsV1SslV3); QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); @@ -1207,120 +1172,38 @@ void tst_QSslSocket::protocolServerSide_data() QTest::addColumn<QSsl::SslProtocol>("clientProtocol"); QTest::addColumn<bool>("works"); -#if QT_CONFIG(opensslv11) -#if !defined(OPENSSL_NO_SSL2) - // OpenSSL 1.1 has removed SSL2 support. But there is no OPENSSL_NO_SSL2 macro ... -#define OPENSSL_NO_SSL2 -#endif // OPENSSL_NO_SSL2 -#endif // opensslv11 - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true; -#endif QTest::newRow("tls1.0-tls1.0") << QSsl::TlsV1_0 << QSsl::TlsV1_0 << true; QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true; QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true; QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false; - QTest::newRow("ssl2-tls1.0") << QSsl::SslV2 << QSsl::TlsV1_0 << false; - QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false; - QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false; - QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2 -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) && !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-tls1.0") << QSsl::SslV3 << QSsl::TlsV1_0 << false; - QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true; - QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << false; -#endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) && !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a - // numerical IP, so OpenSSL will send a SSL 2 handshake -#elif !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << true; -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0-ssl2") << QSsl::TlsV1_0 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.0-ssl3") << QSsl::TlsV1_0 << QSsl::SslV3 << false; -#endif QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1_0 << QSsl::TlsV1SslV3 << true; QTest::newRow("tls1.0-secure") << QSsl::TlsV1_0 << QSsl::SecureProtocols << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a - // numerical IP, so OpenSSL will send a SSL 2 handshake -#else QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << true; -#endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true; -#endif QTest::newRow("tls1ssl3-tls1.0") << QSsl::TlsV1SslV3 << QSsl::TlsV1_0 << true; QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true; QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << false; -#endif QTest::newRow("secure-tls1.0") << QSsl::SecureProtocols << QSsl::TlsV1_0 << true; QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true; QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0orlater-ssl2") << QSsl::TlsV1_0OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.0orlater-ssl3") << QSsl::TlsV1_0OrLater << QSsl::SslV3 << false; -#endif 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; #ifdef TLS1_3_VERSION QTest::newRow("tls1.0orlater-tls1.3") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_3 << true; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false; -#endif 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; + #ifdef TLS1_3_VERSION QTest::newRow("tls1.1orlater-tls1.3") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_3 << true; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false; -#endif + 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.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; @@ -1328,12 +1211,6 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.2orlater-tls1.3") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_3 << true; #endif #ifdef TLS1_3_VERSION -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.3orlater-ssl2") << QSsl::TlsV1_3OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.3orlater-ssl3") << QSsl::TlsV1_3OrLater << QSsl::SslV3 << false; -#endif 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.2") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_2 << false; @@ -4174,6 +4051,63 @@ void tst_QSslSocket::forwardReadChannelFinished() #endif // QT_NO_OPENSSL +void tst_QSslSocket::deprecatedProtocols_data() +{ + QTest::addColumn<QSsl::SslProtocol>("protocol"); + QTest::addColumn<bool>("succeeds"); + QTest::newRow("SecureProtocols") << QSsl::SecureProtocols << true; + QTest::newRow("SslV2") << QSsl::SslV2 << false; + QTest::newRow("SslV3") << QSsl::SslV3 << false; +} + +void tst_QSslSocket::deprecatedProtocols() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + QSKIP("This test does not work under a proxy"); + + QFETCH(QSsl::SslProtocol, protocol); + QFETCH(bool, succeeds); + + QSslSocket socket; + socket.setProtocol(protocol); + + QSignalSpy connectedSpy(&socket, &QSslSocket::connected); + QVERIFY(connectedSpy.isValid()); + + QSignalSpy encryptedSpy(&socket, &QSslSocket::encrypted); + QVERIFY(encryptedSpy.isValid()); + + QSignalSpy errorSpy(&socket, QOverload<QAbstractSocket::SocketError>::of(&QSslSocket::error)); + QVERIFY(errorSpy.isValid()); + + connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), + &socket, QOverload<>::of(&QSslSocket::ignoreSslErrors)); + + SslServer server; + QVERIFY(server.listen()); + + socket.connectToHost(server.serverAddress(), server.serverPort()); + + // Can't use waitForConnected / waitForEncrypted as they wait forever, + // so do this asynchronously via QTRY_ macros (QTBUG-72179) + QTRY_COMPARE(connectedSpy.size(), 1); + QCOMPARE(encryptedSpy.size(), 0); + QCOMPARE(errorSpy.size(), 0); + + socket.startClientEncryption(); + + if (succeeds) { + QTRY_COMPARE(encryptedSpy.size(), 1); + QCOMPARE(errorSpy.size(), 0); + } else { + // The various backends differ in the errors fired here (QTBUG-72196), + // so just check that we did get an error (and we're not encrypted) + QTRY_VERIFY(errorSpy.size() > 0); + QCOMPARE(encryptedSpy.size(), 0); + } +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslSocket) |