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 <rich@kde.org>
This commit is contained in:
Allan Sandfeld Jensen 2014-10-21 15:44:43 +02:00 committed by Kai Koehne
parent 88e7a4f661
commit 3fd2d9eff8
4 changed files with 22 additions and 17 deletions

View File

@ -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.
*/

View File

@ -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());

View File

@ -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;

View File

@ -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
}