Add the ability to do unsafe SSL renegotiation as a fallback.

This commit adds the ability to perform legacy SSL renegotiation as
a fallback via QSsl::SslOptions. This is something that used to work,
but has been disabled by default in newer versions of openssl. The
need for this has been reported by users (eg. in QTBUG-14983).

Change-Id: I5b80f3ffd07e0c5faddc469f6a8f857bac5740f7
Reviewed-by: Corentin Chary <corentin.chary@gmail.com>
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
This commit is contained in:
Richard Moore 2011-11-14 21:56:40 +00:00 committed by Qt by Nokia
parent e1ca68077a
commit 75b2a4960b
6 changed files with 23 additions and 4 deletions

View File

@ -141,9 +141,15 @@ QT_BEGIN_NAMESPACE
\value SslOptionDisableServerNameIndication Disables the SSL server
name indication extension. When enabled, this tells the server the virtual
host being accessed allowing it to respond with the correct certificate.
\value SslOptionDisableLegacyRenegotiation Disables the older insecure
mechanism for renegotiating the connection parameters. When enabled, this
option can allow connections for legacy servers, but it introduces the
possibility that an attacker could inject plaintext into the SSL session.
By default, SslOptionDisableEmptyFragments is turned on since this causes
problems with a large number of servers, but the other options are disabled.
problems with a large number of servers. SslOptionDisableLegacyRenegotiation
is also turned on, since it introduces a security risk. The other options
are turned off.
Note: Availability of above options depends on the version of the SSL
backend in use.

View File

@ -92,7 +92,8 @@ namespace QSsl {
SslOptionDisableEmptyFragments = 0x01,
SslOptionDisableSessionTickets = 0x02,
SslOptionDisableCompression = 0x04,
SslOptionDisableServerNameIndication = 0x08
SslOptionDisableServerNameIndication = 0x08,
SslOptionDisableLegacyRenegotiation = 0x10
};
Q_DECLARE_FLAGS(SslOptions, SslOption)
}

View File

@ -201,7 +201,7 @@ bool QSslConfiguration::isNull() const
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
d->sslOptions == 0);
d->sslOptions == QSsl::SslOptionDisableEmptyFragments|QSsl::SslOptionDisableLegacyRenegotiation);
}
/*!

View File

@ -82,7 +82,8 @@ public:
QSslConfigurationPrivate()
: protocol(QSsl::SecureProtocols),
peerVerifyMode(QSslSocket::AutoVerifyPeer),
peerVerifyDepth(0)
peerVerifyDepth(0),
sslOptions(QSsl::SslOptionDisableEmptyFragments|QSsl::SslOptionDisableLegacyRenegotiation)
{ }
QSslCertificate peerCertificate;

View File

@ -287,6 +287,14 @@ init_context:
else
options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
// This option is disabled by default, so we need to be able to clear it
if (configuration.sslOptions & QSsl::SslOptionDisableLegacyRenegotiation)
options &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
else
options |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
#endif
#ifdef SSL_OP_NO_TICKET
if (configuration.sslOptions & QSsl::SslOptionDisableSessionTickets)
options |= SSL_OP_NO_TICKET;

View File

@ -56,6 +56,7 @@ int main(int argc, char **argv)
out << "disable_session_tickets" << endl;
out << "disable_compression" << endl;
out << "disable_sni" << endl;
out << "enable_unsafe_reneg" << endl;
return 1;
}
@ -75,6 +76,8 @@ int main(int argc, char **argv)
config.setSslOption(QSsl::SslOptionDisableCompression, true);
else if (option == QStringLiteral("disable_sni"))
config.setSslOption(QSsl::SslOptionDisableServerNameIndication, true);
else if (option == QStringLiteral("enable_unsafe_reneg"))
config.setSslOption(QSsl::SslOptionDisableLegacyRenegotiation, false);
}
QSslConfiguration::setDefaultConfiguration(config);