From 3fd2d9eff8c1f948306ee5fbfe364ccded1c4b84 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Oct 2014 15:44:43 +0200 Subject: Update QSsl::SecureProtocols to not include Sslv3 After the poodle vulnerability SSLv3 should like SSLv2 no longer be considered safe, so when a user request a safe protocol we should only allow TLS versions. [ChangeLog][QtNetwork][QSsl] QSsl::SecureProtocols now also excludes SSLv3 Change-Id: If825f6beb599294b028d706903b39db6b20be519 Reviewed-by: Richard J. Moore --- src/network/ssl/qssl.cpp | 10 +++++----- src/network/ssl/qsslcontext_openssl.cpp | 7 +++++-- src/network/ssl/qsslsocket_openssl.cpp | 4 +++- tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 18 +++++++++--------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 63c826a3d7..740131797c 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -119,12 +119,12 @@ QT_BEGIN_NAMESPACE 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 like TlsV1SslV3. + currently behaves similar to TlsV1Ssl3 except denying SSLv3 connections that does + not upgrade to TLS. - \note most servers using SSL understand both versions (2 and 3), - but it is recommended to use the latest version only for security - reasons. However, SSL and TLS are not compatible with each other: - if you get unexpected handshake failures, verify that you chose + \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. */ diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 6daddebba3..c042d98056 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -139,8 +139,11 @@ init_context: case QSsl::SslV3: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); break; - case QSsl::SecureProtocols: // SslV2 will be disabled below - case QSsl::TlsV1SslV3: // SslV2 will be disabled below + 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()); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 1d675edbbb..84b0d9c75e 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -280,8 +280,10 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx) long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions) { long options; - if (protocol == QSsl::TlsV1SslV3 || protocol == QSsl::SecureProtocols) + if (protocol == QSsl::TlsV1SslV3) 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 options = SSL_OP_ALL; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 6e915f89fb..aa954429de 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1088,7 +1088,7 @@ void tst_QSslSocket::protocolServerSide_data() #endif 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 << true; + QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << false; #ifndef OPENSSL_NO_SSL2 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 @@ -1120,7 +1120,7 @@ void tst_QSslSocket::protocolServerSide_data() #ifndef OPENSSL_NO_SSL2 QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false; #endif - QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << true; + QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << false; 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; @@ -2300,28 +2300,28 @@ void tst_QSslSocket::sslOptions() #ifdef SSL_OP_NO_COMPRESSION QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, QSslConfigurationPrivate::defaultSslOptions), - long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_COMPRESSION)); + long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION)); #else QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, QSslConfigurationPrivate::defaultSslOptions), - long(SSL_OP_ALL|SSL_OP_NO_SSLv2)); + long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3)); #endif QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, QSsl::SslOptionDisableEmptyFragments |QSsl::SslOptionDisableLegacyRenegotiation), - long(SSL_OP_ALL|SSL_OP_NO_SSLv2)); + long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3)); #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, QSsl::SslOptionDisableEmptyFragments), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))); + long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))); #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_DONT_INSERT_EMPTY_FRAGMENTS)); + long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3) & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)); #endif #ifdef SSL_OP_NO_TICKET @@ -2329,7 +2329,7 @@ void tst_QSslSocket::sslOptions() QSsl::SslOptionDisableEmptyFragments |QSsl::SslOptionDisableLegacyRenegotiation |QSsl::SslOptionDisableSessionTickets), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET))); + long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET))); #endif #ifdef SSL_OP_NO_TICKET @@ -2339,7 +2339,7 @@ void tst_QSslSocket::sslOptions() |QSsl::SslOptionDisableLegacyRenegotiation |QSsl::SslOptionDisableSessionTickets |QSsl::SslOptionDisableCompression), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET|SSL_OP_NO_COMPRESSION))); + long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET|SSL_OP_NO_COMPRESSION))); #endif #endif } -- cgit v1.2.3