QSslSocket: move default cipher, EC and default CA APIs to QSslConfiguration

QSslConfiguration is better suited for these APIs. The ones
in QSslSocket that already have a counterpart have been deprecated.

[ChangeLog][QtNetwork][SSL/TLS Support] Most of the QSslSocket
functions to deal with ciphersuites, certification authorities
as well as elliptic curves have been deprecated in favor of the
corresponding counterparts in QSslConfiguration.

Task-number: QTBUG-46558
Change-Id: I1de03379efcbcab931c20e876e252769fe4279e0
Reviewed-by: Liang Qi <liang.qi@theqtcompany.com>
Reviewed-by: Richard J. Moore <rich@kde.org>
Reviewed-by: Jani Heikkinen <jani.heikkinen@theqtcompany.com>
This commit is contained in:
Giuseppe D'Angelo 2015-06-08 11:55:10 +02:00 committed by Jani Heikkinen
parent 5818ba4b0b
commit 92cda94742
8 changed files with 116 additions and 160 deletions

View File

@ -54,6 +54,7 @@
#include "qsslcipher.h"
#include "qsslcipher_p.h"
#include "qsslsocket.h"
#include "qsslconfiguration.h"
#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/qdebug.h>
@ -81,7 +82,7 @@ QSslCipher::QSslCipher()
QSslCipher::QSslCipher(const QString &name)
: d(new QSslCipherPrivate)
{
foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) {
foreach (const QSslCipher &cipher, QSslConfiguration::supportedCiphers()) {
if (cipher.name() == name) {
*this = cipher;
return;
@ -102,7 +103,7 @@ QSslCipher::QSslCipher(const QString &name)
QSslCipher::QSslCipher(const QString &name, QSsl::SslProtocol protocol)
: d(new QSslCipherPrivate)
{
foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) {
foreach (const QSslCipher &cipher, QSslConfiguration::supportedCiphers()) {
if (cipher.name() == name && cipher.protocol() == protocol) {
*this = cipher;
return;

View File

@ -36,6 +36,7 @@
#include "qsslconfiguration.h"
#include "qsslconfiguration_p.h"
#include "qsslsocket.h"
#include "qsslsocket_p.h"
#include "qmutex.h"
#include "qdebug.h"
@ -589,6 +590,20 @@ void QSslConfiguration::setCiphers(const QList<QSslCipher> &ciphers)
d->ciphers = ciphers;
}
/*!
\since 5.5
Returns the list of cryptographic ciphers supported by this
system. This list is set by the system's SSL libraries and may
vary from system to system.
\sa ciphers(), setCiphers()
*/
QList<QSslCipher> QSslConfiguration::supportedCiphers()
{
return QSslSocketPrivate::supportedCiphers();
}
/*!
Returns this connection's CA certificate database. The CA certificate
database is used by the socket during the handshake phase to
@ -618,6 +633,22 @@ void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certific
d->allowRootCertOnDemandLoading = false;
}
/*!
\since 5.5
This function provides the CA certificate database
provided by the operating system. The CA certificate database
returned by this function is used to initialize the database
returned by caCertificates() on the default QSslConfiguration.
\sa caCertificates(), setCaCertificates(), defaultConfiguration()
*/
QList<QSslCertificate> QSslConfiguration::systemCaCertificates()
{
// we are calling ensureInitialized() in the method below
return QSslSocketPrivate::systemCaCertificates();
}
/*!
Enables or disables an SSL compatibility \a option. If \a on
is true, the \a option is enabled. If \a on is false, the
@ -743,6 +774,20 @@ void QSslConfiguration::setEllipticCurves(const QVector<QSslEllipticCurve> &curv
d->ellipticCurves = curves;
}
/*!
\since 5.5
Returns the list of elliptic curves supported by this
system. This list is set by the system's SSL libraries and may
vary from system to system.
\sa ellipticCurves(), setEllipticCurves()
*/
QVector<QSslEllipticCurve> QSslConfiguration::supportedEllipticCurves()
{
return QSslSocketPrivate::supportedEllipticCurves();
}
/*!
\since 5.3

View File

@ -111,10 +111,12 @@ public:
// Cipher settings
QList<QSslCipher> ciphers() const;
void setCiphers(const QList<QSslCipher> &ciphers);
static QList<QSslCipher> supportedCiphers();
// Certificate Authority (CA) settings
QList<QSslCertificate> caCertificates() const;
void setCaCertificates(const QList<QSslCertificate> &certificates);
static QList<QSslCertificate> systemCaCertificates();
void setSslOption(QSsl::SslOption option, bool on);
bool testSslOption(QSsl::SslOption option) const;
@ -126,6 +128,7 @@ public:
// EC settings
QVector<QSslEllipticCurve> ellipticCurves() const;
void setEllipticCurves(const QVector<QSslEllipticCurve> &curves);
static QVector<QSslEllipticCurve> supportedEllipticCurves();
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);

View File

@ -1166,6 +1166,10 @@ QSslKey QSslSocket::privateKey() const
}
/*!
\deprecated
Use QSslConfiguration::ciphers() instead.
Returns this socket's current cryptographic cipher suite. This
list is used during the socket's handshake phase for choosing a
session cipher. The returned list of ciphers is ordered by
@ -1197,6 +1201,10 @@ QList<QSslCipher> QSslSocket::ciphers() const
}
/*!
\deprecated
USe QSslConfiguration::setCiphers() instead.
Sets the cryptographic cipher suite for this socket to \a ciphers,
which must contain a subset of the ciphers in the list returned by
supportedCiphers().
@ -1213,6 +1221,10 @@ void QSslSocket::setCiphers(const QList<QSslCipher> &ciphers)
}
/*!
\deprecated
Use QSslConfiguration::setCiphers() instead.
Sets the cryptographic cipher suite for this socket to \a ciphers, which
is a colon-separated list of cipher suite names. The ciphers are listed in
order of preference, starting with the most preferred cipher. For example:
@ -1238,6 +1250,10 @@ void QSslSocket::setCiphers(const QString &ciphers)
}
/*!
\deprecated
Use QSslConfiguration::setCiphers() on the default QSslConfiguration instead.
Sets the default cryptographic cipher suite for all sockets in
this application to \a ciphers, which must contain a subset of the
ciphers in the list returned by supportedCiphers().
@ -1254,6 +1270,10 @@ void QSslSocket::setDefaultCiphers(const QList<QSslCipher> &ciphers)
}
/*!
\deprecated
Use QSslConfiguration::ciphers() on the default QSslConfiguration instead.
Returns the default cryptographic cipher suite for all sockets in
this application. This list is used during the socket's handshake
phase when negotiating with the peer to choose a session cipher.
@ -1273,6 +1293,10 @@ QList<QSslCipher> QSslSocket::defaultCiphers()
}
/*!
\deprecated
Use QSslConfiguration::supportedCiphers() instead.
Returns the list of cryptographic ciphers supported by this
system. This list is set by the system's SSL libraries and may
vary from system to system.
@ -1284,120 +1308,6 @@ QList<QSslCipher> QSslSocket::supportedCiphers()
return QSslSocketPrivate::supportedCiphers();
}
/*!
\since 5.5
Returns this socket's current list of elliptic curves. This
list is used during the socket's handshake phase for choosing an
elliptic curve (when using an elliptic curve cipher).
The returned list of curves is ordered by descending preference
(i.e., the first curve in the list is the most preferred one).
By default, this list is empty. An empty default list means that the
handshake phase can choose any of the curves supported by this system's SSL
libraries (which may vary from system to system). The list of curves
supported by this system's SSL libraries is returned by
supportedEllipticCurves().
You can restrict the list of curves used for choosing the session cipher
for this socket by calling setEllipticCurves() with a subset of the
supported ciphers. You can revert to using the entire set by calling
setEllipticCurves() with the list returned by supportedEllipticCurves().
\sa setEllipticCurves(), defaultEllipticCurves(), setDefaultEllipticCurves(), supportedEllipticCurves()
*/
QVector<QSslEllipticCurve> QSslSocket::ellipticCurves() const
{
Q_D(const QSslSocket);
return d->configuration.ellipticCurves;
}
/*!
\since 5.5
Sets the list of elliptic curves to be used by this socket to \a curves,
which must contain a subset of the curves in the list returned by
supportedEllipticCurves().
Restricting the elliptic curves must be done before the handshake
phase, where the session cipher is chosen.
If an empty list is set, then the handshake phase can choose any of the
curves supported by this system's SSL libraries (which may vary from system
to system). The list of curves supported by this system's SSL libraries is
returned by supportedEllipticCurves().
Use setCipher() in order to disable the usage of elliptic curve ciphers.
\sa ellipticCurves(), setDefaultEllipticCurves(), supportedEllipticCurves()
*/
void QSslSocket::setEllipticCurves(const QVector<QSslEllipticCurve> &curves)
{
Q_D(QSslSocket);
d->configuration.ellipticCurves = curves;
}
/*!
\since 5.5
Sets the list of elliptic curves to be used by all sockets in this
application to \a curves, which must contain a subset of the curves in the
list returned by supportedEllipticCurves().
Restricting the default elliptic curves only affects SSL sockets
that perform their handshake phase after the default list has been changed.
If an empty list is set, then the handshake phase can choose any of the
curves supported by this system's SSL libraries (which may vary from system
to system). The list of curves supported by this system's SSL libraries is
returned by supportedEllipticCurves().
Use setDefaultCiphers() in order to disable the usage of elliptic curve ciphers.
\sa setEllipticCurves(), defaultEllipticCurves(), supportedEllipticCurves()
*/
void QSslSocket::setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves)
{
QSslSocketPrivate::setDefaultEllipticCurves(curves);
}
/*!
\since 5.5
Returns the default elliptic curves list for all sockets in
this application. This list is used during the socket's handshake
phase when negotiating with the peer to choose a session cipher.
The list is ordered by preference (i.e., the first curve in the
list is the most preferred one).
By default, this list is empty. An empty default list means that the
handshake phase can choose any of the curves supported by this system's SSL
libraries (which may vary from system to system). The list of curves
supported by this system's SSL libraries is returned by
supportedEllipticCurves().
\sa setDefaultEllipticCurves(), supportedEllipticCurves()
*/
QVector<QSslEllipticCurve> QSslSocket::defaultEllipticCurves()
{
return QSslSocketPrivate::defaultEllipticCurves();
}
/*!
\since 5.5
Returns the list of elliptic curves supported by this
system. This list is set by the system's SSL libraries and may
vary from system to system.
\sa ellipticCurves(), setEllipticCurves(), defaultEllipticCurves()
*/
QVector<QSslEllipticCurve> QSslSocket::supportedEllipticCurves()
{
return QSslSocketPrivate::supportedEllipticCurves();
}
/*!
Searches all files in the \a path for certificates encoded in the
specified \a format and adds them to this socket's CA certificate
@ -1456,6 +1366,10 @@ void QSslSocket::addCaCertificates(const QList<QSslCertificate> &certificates)
}
/*!
\deprecated
Use QSslConfiguration::setCaCertificates() instead.
Sets this socket's CA certificate database to be \a certificates.
The certificate database must be set prior to the SSL handshake.
The CA certificate database is used by the socket during the
@ -1475,6 +1389,10 @@ void QSslSocket::setCaCertificates(const QList<QSslCertificate> &certificates)
}
/*!
\deprecated
Use QSslConfiguration::caCertificates() instead.
Returns this socket's CA certificate database. The CA certificate
database is used by the socket during the handshake phase to
validate the peer's certificate. It can be moodified prior to the
@ -1535,6 +1453,10 @@ void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certific
}
/*!
\deprecated
Use QSslConfiguration::setCaCertificates() on the default QSslConfiguration instead.
Sets the default CA certificate database to \a certificates. The
default CA certificate database is originally set to your system's
default CA certificate database. You can override the default CA
@ -1552,6 +1474,10 @@ void QSslSocket::setDefaultCaCertificates(const QList<QSslCertificate> &certific
}
/*!
\deprecated
Use QSslConfiguration::caCertificates() on the default QSslConfiguration instead.
Returns the current default CA certificate database. This database
is originally set to your system's default CA certificate database.
If no system default database is found, an empty database will be
@ -1572,6 +1498,10 @@ QList<QSslCertificate> QSslSocket::defaultCaCertificates()
}
/*!
\deprecated
Use QSslConfiguration::systemDefaultCaCertificates instead.
This function provides the CA certificate database
provided by the operating system. The CA certificate database
returned by this function is used to initialize the database
@ -2163,16 +2093,6 @@ void QSslSocketPrivate::setDefaultSupportedCiphers(const QList<QSslCipher> &ciph
globalData()->supportedCiphers = ciphers;
}
/*!
\internal
*/
QVector<QSslEllipticCurve> QSslSocketPrivate::defaultEllipticCurves()
{
QSslSocketPrivate::ensureInitialized();
const QMutexLocker locker(&globalData()->mutex);
return globalData()->config->ellipticCurves;
}
/*!
\internal
*/
@ -2183,16 +2103,6 @@ QVector<QSslEllipticCurve> QSslSocketPrivate::supportedEllipticCurves()
return globalData()->supportedEllipticCurves;
}
/*!
\internal
*/
void QSslSocketPrivate::setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves)
{
const QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
globalData()->config->ellipticCurves = curves;
}
/*!
\internal
*/

View File

@ -144,34 +144,33 @@ public:
QSslKey privateKey() const;
// Cipher settings.
QList<QSslCipher> ciphers() const;
void setCiphers(const QList<QSslCipher> &ciphers);
void setCiphers(const QString &ciphers);
static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
static QList<QSslCipher> defaultCiphers();
static QList<QSslCipher> supportedCiphers();
// EC settings.
QVector<QSslEllipticCurve> ellipticCurves() const;
void setEllipticCurves(const QVector<QSslEllipticCurve> &curves);
static void setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves);
static QVector<QSslEllipticCurve> defaultEllipticCurves();
static QVector<QSslEllipticCurve> supportedEllipticCurves();
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED_X("Use QSslConfiguration::ciphers()") QList<QSslCipher> ciphers() const;
QT_DEPRECATED_X("Use QSslConfiguration::setCiphers()") void setCiphers(const QList<QSslCipher> &ciphers);
QT_DEPRECATED void setCiphers(const QString &ciphers);
QT_DEPRECATED static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
QT_DEPRECATED static QList<QSslCipher> defaultCiphers();
QT_DEPRECATED_X("Use QSslConfiguration::supportedCiphers()") static QList<QSslCipher> supportedCiphers();
#endif // QT_DEPRECATED_SINCE(5, 5)
// CA settings.
bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
void addCaCertificate(const QSslCertificate &certificate);
void addCaCertificates(const QList<QSslCertificate> &certificates);
void setCaCertificates(const QList<QSslCertificate> &certificates);
QList<QSslCertificate> caCertificates() const;
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED_X("Use QSslConfiguration::setCaCertificates()") void setCaCertificates(const QList<QSslCertificate> &certificates);
QT_DEPRECATED_X("Use QSslConfiguration::caCertificates()") QList<QSslCertificate> caCertificates() const;
#endif // QT_DEPRECATED_SINCE(5, 5)
static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
static void addDefaultCaCertificate(const QSslCertificate &certificate);
static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates);
static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates);
static QList<QSslCertificate> defaultCaCertificates();
static QList<QSslCertificate> systemCaCertificates();
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates);
QT_DEPRECATED static QList<QSslCertificate> defaultCaCertificates();
QT_DEPRECATED_X("Use QSslConfiguration::systemCaCertificates()") static QList<QSslCertificate> systemCaCertificates();
#endif // QT_DEPRECATED_SINCE(5, 5)
bool waitForConnected(int msecs = 30000) Q_DECL_OVERRIDE;
bool waitForEncrypted(int msecs = 30000);

View File

@ -1685,7 +1685,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
setDefaultCaCertificates(defaultCaCertificates() + systemCaCertificates());
}
foreach (const QSslCertificate &caCertificate, QSslSocket::defaultCaCertificates()) {
foreach (const QSslCertificate &caCertificate, QSslConfiguration::defaultConfiguration().caCertificates()) {
// From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
//
// If several CA certificates matching the name, key identifier, and

View File

@ -137,9 +137,7 @@ public:
static void setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers);
static void resetDefaultCiphers();
static QVector<QSslEllipticCurve> defaultEllipticCurves();
static QVector<QSslEllipticCurve> supportedEllipticCurves();
static void setDefaultEllipticCurves(const QVector<QSslEllipticCurve> &curves);
static void setDefaultSupportedEllipticCurves(const QVector<QSslEllipticCurve> &curves);
static void resetDefaultEllipticCurves();

View File

@ -34,7 +34,7 @@
#include <QtTest/QtTest>
#include <QSslEllipticCurve>
#include <QSslSocket>
#include <QSslConfiguration>
class tst_QSslEllipticCurve : public QObject
{
@ -84,7 +84,7 @@ void tst_QSslEllipticCurve::fromShortName_data()
QTest::newRow("QString()") << QString() << QSslEllipticCurve() << false;
QTest::newRow("\"\"") << QString("") << QSslEllipticCurve() << false;
QTest::newRow("does-not-exist") << QStringLiteral("does-not-exist") << QSslEllipticCurve() << false;
Q_FOREACH (QSslEllipticCurve ec, QSslSocket::supportedEllipticCurves()) {
Q_FOREACH (QSslEllipticCurve ec, QSslConfiguration::supportedEllipticCurves()) {
const QString sN = ec.shortName();
QTest::newRow(qPrintable("supported EC \"" + sN + '"')) << sN << ec << true;
// At least in the OpenSSL impl, the short name is case-sensitive. That feels odd.
@ -117,7 +117,7 @@ void tst_QSslEllipticCurve::fromLongName_data()
QTest::newRow("QString()") << QString() << QSslEllipticCurve() << false;
QTest::newRow("\"\"") << QString("") << QSslEllipticCurve() << false;
QTest::newRow("does-not-exist") << QStringLiteral("does-not-exist") << QSslEllipticCurve() << false;
Q_FOREACH (QSslEllipticCurve ec, QSslSocket::supportedEllipticCurves()) {
Q_FOREACH (QSslEllipticCurve ec, QSslConfiguration::supportedEllipticCurves()) {
const QString lN = ec.longName();
QTest::newRow(qPrintable("supported EC \"" + lN + '"')) << lN << ec << true;
}