summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2018-11-29 02:57:15 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2018-12-13 15:59:37 +0000
commit455951f59074d6457fd2d10720ac3cbdaa966076 (patch)
treef214024d0551594712da3d33717a4af3a5e2b07e /src/network/ssl
parent3364be785930548bde2e6dfebe3aabed9e3f780d (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>
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qssl.cpp20
-rw-r--r--src/network/ssl/qsslcontext_openssl11.cpp17
-rw-r--r--src/network/ssl/qsslcontext_opensslpre11.cpp17
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp24
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp36
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h24
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp12
8 files changed, 34 insertions, 118 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;