diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index e5bee352212..26381fcb8ec 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -113,9 +113,12 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value SslV3 SSLv3 \value SslV2 SSLv2 \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 \value TlsV1_1 TLSv1.1 + \value TlsV1_1OrLater TLSv1.1 and later versions. This option is not available when using the WinRT backend due to platform limitations. \value TlsV1_2 TLSv1.2 + \value TlsV1_2OrLater TLSv1.2 and later versions. This option is not available when using the WinRT backend due to platform limitations. \value UnknownProtocol The cipher's protocol cannot be determined. \value AnyProtocol The socket understands SSLv2, SSLv3, and TLSv1.0. This value is used by QSslSocket only. diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h index 62b8327a9e9..f56c36b219d 100644 --- a/src/network/ssl/qssl.h +++ b/src/network/ssl/qssl.h @@ -80,6 +80,11 @@ namespace QSsl { AnyProtocol, TlsV1SslV3, SecureProtocols, + + TlsV1_0OrLater, + TlsV1_1OrLater, + TlsV1_2OrLater, + UnknownProtocol = -1 }; diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 71fa36b9218..f91af9db744 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -175,9 +175,25 @@ init_context: // TLS 1.2 not supported by the system, but chosen deliberately -> error sslContext->ctx = 0; unsupportedProtocol = true; +#endif + break; + case QSsl::TlsV1_0OrLater: + // Specific protocols will be specified via SSL options. + sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); + break; + case QSsl::TlsV1_1OrLater: + case QSsl::TlsV1_2OrLater: +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + // Specific protocols will be specified via SSL options. + sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); +#else + // TLS 1.1/1.2 not supported by the system, but chosen deliberately -> error + sslContext->ctx = 0; + unsupportedProtocol = true; #endif break; } + if (!sslContext->ctx) { // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them // by re-initializing the library. diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 71a2c2ea18d..4c1fc0f768d 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -307,6 +307,17 @@ long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, Q options = SSL_OP_ALL|SSL_OP_NO_SSLv2; else if (protocol == QSsl::SecureProtocols) options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; + else if (protocol == QSsl::TlsV1_0OrLater) + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + // Choosing Tlsv1_1OrLater or TlsV1_2OrLater on OpenSSL < 1.0.1 + // will cause an error in QSslContext::fromConfiguration, meaning + // we will never get here. + else if (protocol == QSsl::TlsV1_1OrLater) + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1; + else if (protocol == QSsl::TlsV1_2OrLater) + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1; +#endif else options = SSL_OP_ALL; diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index 03bcb4f710c..b8248818bc3 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -246,6 +246,15 @@ void QSslSocketBackendPrivate::startClientEncryption() case QSsl::TlsV1_2: protectionLevel = SocketProtectionLevel_Tls12; break; + case QSsl::TlsV1_0OrLater: + case QSsl::TlsV1_1OrLater: + case QSsl::TlsV1_2OrLater: + // TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater are disabled on WinRT + // because there is no good way to map them to the native API. + q->setErrorString(QStringLiteral("unsupported protocol")); + q->setSocketError(QAbstractSocket::SslInvalidUserDataError); + emit q->error(QAbstractSocket::SslInvalidUserDataError); + return; default: protectionLevel = SocketProtectionLevel_Tls12; // default to highest protocol = QSsl::TlsV1_2;