summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMikkel Krautz <mikkel@krautz.dk>2016-05-25 21:24:25 +0200
committerTimur Pocheptsov <timur.pocheptsov@theqtcompany.com>2016-05-25 20:00:12 +0000
commit2cf63c71ebe139890526057dcc51b24ea6df6c30 (patch)
treee444f983ebd0a0de69278c68834863f56e32afa8 /src
parent6d9f648d0ed591a0afba018adfbb089871f67b38 (diff)
Add settable QSslDiffieHellmanParameters for QSslSocket-based servers.
Only the OpenSSL backend is supported right now. [ChangeLog][QtNetwork][SSL/TLS support] It is now possible to set custom Diffie-Hellman parameters for QSslSocket-based servers. Change-Id: I50148873132cd0ec7e414250b107b6b4cbde02ea Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/network/ssl/qsslconfiguration.cpp29
-rw-r--r--src/network/ssl/qsslconfiguration.h4
-rw-r--r--src/network/ssl/qsslconfiguration_p.h4
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp39
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters.cpp313
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters.h117
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters_dummy.cpp59
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters_openssl.cpp164
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters_p.h78
-rw-r--r--src/network/ssl/qsslsocket.cpp1
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp14
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h21
-rw-r--r--src/network/ssl/ssl.pri6
13 files changed, 829 insertions, 20 deletions
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index edcaef7b0c..e009824a69 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -214,6 +214,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->ciphers == other.d->ciphers &&
d->ellipticCurves == other.d->ellipticCurves &&
d->ephemeralServerKey == other.d->ephemeralServerKey &&
+ d->dhParams == other.d->dhParams &&
d->caCertificates == other.d->caCertificates &&
d->protocol == other.d->protocol &&
d->peerVerifyMode == other.d->peerVerifyMode &&
@@ -256,6 +257,7 @@ bool QSslConfiguration::isNull() const
d->ciphers.count() == 0 &&
d->ellipticCurves.isEmpty() &&
d->ephemeralServerKey.isNull() &&
+ d->dhParams == QSslDiffieHellmanParameters::defaultParameters() &&
d->localCertificateChain.isEmpty() &&
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
@@ -840,6 +842,33 @@ void QSslConfiguration::setPreSharedKeyIdentityHint(const QByteArray &hint)
}
/*!
+ \since 5.8
+
+ Retrieves the current set of Diffie-Hellman parameters.
+
+ If no Diffie-Hellman parameters have been set, the QSslConfiguration object
+ defaults to using the 1024-bit MODP group from RFC 2409.
+ */
+QSslDiffieHellmanParameters QSslConfiguration::diffieHellmanParameters() const
+{
+ return d->dhParams;
+}
+
+/*!
+ \since 5.8
+
+ Sets a custom set of Diffie-Hellman parameters to be used by this socket when functioning as
+ a server.
+
+ If no Diffie-Hellman parameters have been set, the QSslConfiguration object
+ defaults to using the 1024-bit MODP group from RFC 2409.
+ */
+void QSslConfiguration::setDiffieHellmanParameters(const QSslDiffieHellmanParameters &dhparams)
+{
+ d->dhParams = dhparams;
+}
+
+/*!
\since 5.3
This function returns the protocol negotiated with the server
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 1f39e1a06f..61246e1009 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -69,6 +69,7 @@ class QSslCertificate;
class QSslCipher;
class QSslKey;
class QSslEllipticCurve;
+class QSslDiffieHellmanParameters;
class QSslConfigurationPrivate;
class Q_NETWORK_EXPORT QSslConfiguration
@@ -144,6 +145,9 @@ public:
QByteArray preSharedKeyIdentityHint() const;
void setPreSharedKeyIdentityHint(const QByteArray &hint);
+ QSslDiffieHellmanParameters diffieHellmanParameters() const;
+ void setDiffieHellmanParameters(const QSslDiffieHellmanParameters &dhparams);
+
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 5ab0ef36e4..139a9fc32b 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -73,6 +73,7 @@
#include "qsslcipher.h"
#include "qsslkey.h"
#include "qsslellipticcurve.h"
+#include "qssldiffiehellmanparameters.h"
QT_BEGIN_NAMESPACE
@@ -87,6 +88,7 @@ public:
allowRootCertOnDemandLoading(true),
peerSessionShared(false),
sslOptions(QSslConfigurationPrivate::defaultSslOptions),
+ dhParams(QSslDiffieHellmanParameters::defaultParameters()),
sslSessionTicketLifeTimeHint(-1),
ephemeralServerKey(),
preSharedKeyIdentityHint(),
@@ -118,6 +120,8 @@ public:
QVector<QSslEllipticCurve> ellipticCurves;
+ QSslDiffieHellmanParameters dhParams;
+
QByteArray sslSession;
int sslSessionTicketLifeTimeHint;
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index cbf290a05c..5a80d08e24 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -41,6 +41,7 @@
#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qssldiffiehellmanparameters.h>
#include <QtCore/qmutex.h>
#include "private/qssl_p.h"
@@ -48,6 +49,7 @@
#include "private/qsslsocket_p.h"
#include "private/qsslsocket_openssl_p.h"
#include "private/qsslsocket_openssl_symbols_p.h"
+#include "private/qssldiffiehellmanparameters_p.h"
QT_BEGIN_NAMESPACE
@@ -55,22 +57,6 @@ QT_BEGIN_NAMESPACE
extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
extern QString getErrorsFromOpenSsl();
-static DH *get_dh1024()
-{
- // Default DH params
- // 1024-bit MODP Group
- // From RFC 2409
- QByteArray params = QByteArray::fromBase64(
- QByteArrayLiteral("MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR" \
- "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL" \
- "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC"));
-
- const char *ptr = params.constData();
- DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length());
-
- return dh;
-}
-
QSslContext::QSslContext()
: ctx(0),
pkey(0),
@@ -325,10 +311,23 @@ init_context:
sslContext->setSessionASN1(configuration.sessionTicket());
// Set temp DH params
- DH *dh = 0;
- dh = get_dh1024();
- q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
- q_DH_free(dh);
+ QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters();
+
+ if (!dhparams.isValid()) {
+ sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid");
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ if (!dhparams.isEmpty()) {
+ const QByteArray &params = dhparams.d.data()->derData;
+ const char *ptr = params.constData();
+ DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length());
+ if (dh == NULL)
+ qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form");
+ q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
+ q_DH_free(dh);
+ }
#ifndef OPENSSL_NO_EC
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp
new file mode 100644
index 0000000000..74424117dc
--- /dev/null
+++ b/src/network/ssl/qssldiffiehellmanparameters.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+/*!
+ \class QSslDiffieHellmanParameters
+ \brief The QSslDiffieHellmanParameters class provides an interface for Diffie-Hellman parameters for servers.
+ \since 5.8
+
+ \reentrant
+ \ingroup network
+ \ingroup ssl
+ \ingroup shared
+ \inmodule QtNetwork
+
+ QSslDiffieHellmanParameters provides an interface for setting Diffie-Hellman parameters to servers based on QSslSocket.
+
+ \sa QSslSocket, QSslCipher, QSslConfiguration
+*/
+
+#include "qssldiffiehellmanparameters.h"
+#include "qssldiffiehellmanparameters_p.h"
+#include "qsslsocket.h"
+#include "qsslsocket_p.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qatomic.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qbytearraymatcher.h>
+#include <QtCore/qiodevice.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Returns the default QSslDiffieHellmanParameters used by QSslSocket.
+
+ This is currently the 1024-bit MODP group from RFC 2459, also
+ known as the Second Oakley Group.
+*/
+QSslDiffieHellmanParameters QSslDiffieHellmanParameters::defaultParameters()
+{
+ // The 1024-bit MODP group from RFC 2459 (Second Oakley Group)
+ return QSslDiffieHellmanParameters(
+ QByteArray::fromBase64(QByteArrayLiteral(
+ "MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR"
+ "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL"
+ "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC"
+ )),
+ QSsl::Der
+ );
+}
+
+/*!
+ Constructs an empty QSslDiffieHellmanParameters instance.
+
+ If an empty QSslDiffieHellmanParameters instance is set on a
+ QSslConfiguration object, Diffie-Hellman negotiation will
+ be disabled.
+
+ \sa isValid()
+ \sa QSslConfiguration
+*/
+QSslDiffieHellmanParameters::QSslDiffieHellmanParameters()
+ : d(new QSslDiffieHellmanParametersPrivate)
+{
+}
+
+/*!
+ Constructs a QSslDiffieHellmanParameters object using
+ the byte array \encoded in either PEM or DER form.
+
+ After construction, the isValid() method should be used to
+ check whether the Diffie-Hellman parameters were valid and
+ loaded correctly.
+
+ \sa isValid()
+ \sa QSslConfiguration
+*/
+QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(const QByteArray &encoded, QSsl::EncodingFormat encoding)
+ : d(new QSslDiffieHellmanParametersPrivate)
+{
+ switch (encoding) {
+ case QSsl::Der:
+ d->decodeDer(encoded);
+ break;
+ case QSsl::Pem:
+ d->decodePem(encoded);
+ break;
+ }
+}
+
+/*!
+ Constructs a QSslDiffieHellmanParameters object by
+ reading from \device in either PEM or DER form.
+
+ After construction, the isValid() method should be used
+ to check whether the Diffie-Hellman parameters were valid
+ and loaded correctly.
+
+ \sa isValid()
+ \sa QSslConfiguration
+*/
+QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(QIODevice *device, QSsl::EncodingFormat encoding)
+ : d(new QSslDiffieHellmanParametersPrivate)
+{
+ if (!device)
+ return;
+
+ const QByteArray encoded = device->readAll();
+
+ switch (encoding) {
+ case QSsl::Der:
+ d->decodeDer(encoded);
+ break;
+ case QSsl::Pem:
+ d->decodePem(encoded);
+ break;
+ }
+}
+
+/*!
+ Constructs an identical copy of \a other.
+*/
+QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(const QSslDiffieHellmanParameters &other) : d(other.d)
+{
+}
+
+/*!
+ Destroys the QSslDiffieHellmanParameters object.
+*/
+QSslDiffieHellmanParameters::~QSslDiffieHellmanParameters()
+{
+}
+
+/*!
+ Copies the contents of \a other into this QSslDiffieHellmanParameters, making the two QSslDiffieHellmanParameters
+ identical.
+
+ Returns a reference to this QSslDiffieHellmanParameters.
+*/
+QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(const QSslDiffieHellmanParameters &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(QSslDiffieHellmanParameters &&other)
+
+ Move-assigns \a other to this QSslDiffieHellmanParameters instance.
+*/
+
+/*!
+ \fn void QSslDiffieHellmanParameters::swap(QSslDiffieHellmanParameters &other)
+
+ Swaps this QSslDiffieHellmanParameters with \a other. This function is very fast and
+ never fails.
+*/
+
+/*!
+ Returns \c true if this is a an empty QSslDiffieHellmanParameters instance.
+
+ Setting an empty QSslDiffieHellmanParameters instance on a QSslSocket-based
+ server will disable Diffie-Hellman key exchange.
+*/
+bool QSslDiffieHellmanParameters::isEmpty() const Q_DECL_NOTHROW
+{
+ return d->derData.isNull() && d->error == QSslDiffieHellmanParameters::NoError;
+}
+
+/*!
+ Returns \c true if this is a valid QSslDiffieHellmanParameters; otherwise false.
+
+ This method should be used after constructing a QSslDiffieHellmanParameters
+ object to determine its validity.
+
+ If a QSslDiffieHellmanParameters object is not valid, you can use the error()
+ method to determine what error prevented the object from being constructed.
+
+ \sa clear()
+ \sa error()
+*/
+bool QSslDiffieHellmanParameters::isValid() const Q_DECL_NOTHROW
+{
+ return d->error == QSslDiffieHellmanParameters::NoError;
+}
+
+/*!
+ \enum QSslDiffieHellmanParameters::Error
+
+ Describes a QSslDiffieHellmanParameters error.
+
+ \value ErrorInvalidInputData The given input data could not be used to
+ construct a QSslDiffieHellmanParameters
+ object.
+
+ \value ErrorUnsafeParameters The Diffie-Hellman parameters are unsafe
+ and should not be used.
+*/
+
+/*!
+ Returns the error that caused the QSslDiffieHellmanParameters object
+ to be invalid.
+*/
+QSslDiffieHellmanParameters::Error QSslDiffieHellmanParameters::error() const Q_DECL_NOTHROW
+{
+ return d->error;
+}
+
+/*!
+ Returns a human-readable description of the error that caused the
+ QSslDiffieHellmanParameters object to be invalid.
+*/
+QString QSslDiffieHellmanParameters::errorString() const Q_DECL_NOTHROW
+{
+ switch (d->error) {
+ case QSslDiffieHellmanParameters::NoError:
+ return QCoreApplication::translate("QSslDiffieHellmanParameter", "No error");
+ case QSslDiffieHellmanParameters::InvalidInputDataError:
+ return QCoreApplication::translate("QSslDiffieHellmanParameter", "Invalid input data");
+ case QSslDiffieHellmanParameters::UnsafeParametersError:
+ return QCoreApplication::translate("QSslDiffieHellmanParameter", "The given Diffie-Hellman parameters are deemed unsafe");
+ }
+
+ Q_UNREACHABLE();
+ return QString();
+}
+
+/*!
+ \relates QSslDiffieHellmanParameters
+
+ Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false.
+*/
+bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->derData == rhs.d->derData;
+}
+
+/*! \fn bool QSslDiffieHellmanParameters::operator!=(const QSslDiffieHellmanParameters &other) const
+
+ Returns \c true if this QSslDiffieHellmanParameters is not equal to \a other; otherwise
+ returns \c false.
+*/
+
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ \relates QSslDiffieHellmanParameters
+
+ Writes the set of Diffie-Hellman parameters in \a dhparm into the debug object \a debug for
+ debugging purposes.
+
+ The Diffie-Hellman parameters will be represented in Base64-encoded DER form.
+
+ \sa {Debugging Techniques}
+*/
+QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam)
+{
+ QDebugStateSaver saver(debug);
+ debug.resetFormat().nospace();
+ debug << "QSslDiffieHellmanParameters(" << dhparam.d->derData.toBase64() << ')';
+ return debug;
+}
+#endif
+
+/*!
+ \relates QHash
+
+ Returns an hash value for \a dhparam, using \a seed to seed
+ the calculation.
+*/
+uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) Q_DECL_NOTHROW
+{
+ return qHash(dhparam.d->derData, seed);
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qssldiffiehellmanparameters.h b/src/network/ssl/qssldiffiehellmanparameters.h
new file mode 100644
index 0000000000..aa40be83a6
--- /dev/null
+++ b/src/network/ssl/qssldiffiehellmanparameters.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QSSLDIFFIEHELLMANPARAMETERS_H
+#define QSSLDIFFIEHELLMANPARAMETERS_H
+
+#include <QtNetwork/qssl.h>
+#include <QtCore/qnamespace.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_SSL
+
+class QIODevice;
+class QSslContext;
+class QSslDiffieHellmanParametersPrivate;
+
+class QSslDiffieHellmanParameters;
+// qHash is a friend, but we can't use default arguments for friends (ยง8.3.6.4)
+Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed = 0) Q_DECL_NOTHROW;
+
+#ifndef QT_NO_DEBUG_STREAM
+class QDebug;
+Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparams);
+#endif
+
+Q_NETWORK_EXPORT bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW;
+
+inline bool operator!=(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW
+{
+ return !operator==(lhs, rhs);
+}
+
+class QSslDiffieHellmanParameters
+{
+public:
+ enum Error {
+ NoError,
+ InvalidInputDataError,
+ UnsafeParametersError
+ };
+
+ Q_NETWORK_EXPORT static QSslDiffieHellmanParameters defaultParameters();
+
+ Q_NETWORK_EXPORT QSslDiffieHellmanParameters();
+ Q_NETWORK_EXPORT explicit QSslDiffieHellmanParameters(const QByteArray &encoded, QSsl::EncodingFormat format = QSsl::Pem);
+ Q_NETWORK_EXPORT explicit QSslDiffieHellmanParameters(QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem);
+ Q_NETWORK_EXPORT QSslDiffieHellmanParameters(const QSslDiffieHellmanParameters &other);
+ Q_NETWORK_EXPORT ~QSslDiffieHellmanParameters();
+ Q_NETWORK_EXPORT QSslDiffieHellmanParameters &operator=(const QSslDiffieHellmanParameters &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QSslDiffieHellmanParameters &operator=(QSslDiffieHellmanParameters &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
+
+ void swap(QSslDiffieHellmanParameters &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
+ Q_NETWORK_EXPORT bool isEmpty() const Q_DECL_NOTHROW;
+ Q_NETWORK_EXPORT bool isValid() const Q_DECL_NOTHROW;
+ Q_NETWORK_EXPORT QSslDiffieHellmanParameters::Error error() const Q_DECL_NOTHROW;
+ Q_NETWORK_EXPORT QString errorString() const Q_DECL_NOTHROW;
+
+private:
+ QExplicitlySharedDataPointer<QSslDiffieHellmanParametersPrivate> d;
+ friend class QSslContext;
+ friend Q_NETWORK_EXPORT bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) Q_DECL_NOTHROW;
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam);
+#endif
+ friend Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) Q_DECL_NOTHROW;
+};
+
+Q_DECLARE_SHARED(QSslDiffieHellmanParameters)
+
+#endif // QT_NO_SSL
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/network/ssl/qssldiffiehellmanparameters_dummy.cpp b/src/network/ssl/qssldiffiehellmanparameters_dummy.cpp
new file mode 100644
index 0000000000..42222f3f38
--- /dev/null
+++ b/src/network/ssl/qssldiffiehellmanparameters_dummy.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qssldiffiehellmanparameters.h"
+#include "qssldiffiehellmanparameters_p.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+void QSslDiffieHellmanParametersPrivate::decodeDer(const QByteArray &)
+{
+ Q_UNIMPLEMENTED();
+}
+
+void QSslDiffieHellmanParametersPrivate::decodePem(const QByteArray &)
+{
+ Q_UNIMPLEMENTED();
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
new file mode 100644
index 0000000000..949da1b7df
--- /dev/null
+++ b/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qssldiffiehellmanparameters.h"
+#include "qssldiffiehellmanparameters_p.h"
+#include "qsslsocket_openssl_symbols_p.h"
+#include "qsslsocket.h"
+#include "qsslsocket_p.h"
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qiodevice.h>
+#ifndef QT_NO_DEBUG_STREAM
+#include <QtCore/qdebug.h>
+#endif
+
+// For q_BN_is_word.
+#include <openssl/bn.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool isSafeDH(DH *dh)
+{
+ int status = 0;
+ int bad = 0;
+
+ QSslSocketPrivate::ensureInitialized();
+
+ // Mark p < 1024 bits as unsafe.
+ if (q_BN_num_bits(dh->p) < 1024) {
+ return false;
+ }
+
+ if (q_DH_check(dh, &status) != 1)
+ return false;
+
+ // From https://wiki.openssl.org/index.php/Diffie-Hellman_parameters:
+ //
+ // The additional call to BN_mod_word(dh->p, 24)
+ // (and unmasking of DH_NOT_SUITABLE_GENERATOR)
+ // is performed to ensure your program accepts
+ // IETF group parameters. OpenSSL checks the prime
+ // is congruent to 11 when g = 2; while the IETF's
+ // primes are congruent to 23 when g = 2.
+ // Without the test, the IETF parameters would
+ // fail validation. For details, see Diffie-Hellman
+ // Parameter Check (when g = 2, must p mod 24 == 11?).
+ if (q_BN_is_word(dh->g, DH_GENERATOR_2)) {
+ long residue = q_BN_mod_word(dh->p, 24);
+ if (residue == 11 || residue == 23)
+ status &= ~DH_NOT_SUITABLE_GENERATOR;
+ }
+
+ bad |= DH_CHECK_P_NOT_PRIME;
+ bad |= DH_CHECK_P_NOT_SAFE_PRIME;
+ bad |= DH_NOT_SUITABLE_GENERATOR;
+
+ return !(status & bad);
+}
+
+void QSslDiffieHellmanParametersPrivate::decodeDer(const QByteArray &der)
+{
+ if (der.isEmpty()) {
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ return;
+ }
+
+ const unsigned char *data = reinterpret_cast<const unsigned char *>(der.data());
+ int len = der.size();
+
+ QSslSocketPrivate::ensureInitialized();
+
+ DH *dh = q_d2i_DHparams(NULL, &data, len);
+ if (dh) {
+ if (isSafeDH(dh))
+ derData = der;
+ else
+ error = QSslDiffieHellmanParameters::UnsafeParametersError;
+ } else {
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ }
+
+ q_DH_free(dh);
+}
+
+void QSslDiffieHellmanParametersPrivate::decodePem(const QByteArray &pem)
+{
+ if (pem.isEmpty()) {
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ return;
+ }
+
+ if (!QSslSocket::supportsSsl()) {
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ return;
+ }
+
+ QSslSocketPrivate::ensureInitialized();
+
+ BIO *bio = q_BIO_new_mem_buf(const_cast<char *>(pem.data()), pem.size());
+ if (!bio) {
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ return;
+ }
+
+ DH *dh = Q_NULLPTR;
+ q_PEM_read_bio_DHparams(bio, &dh, 0, 0);
+
+ if (dh) {
+ if (isSafeDH(dh)) {
+ char *buf = Q_NULLPTR;
+ int len = q_i2d_DHparams(dh, reinterpret_cast<unsigned char **>(&buf));
+ if (len > 0)
+ derData = QByteArray(buf, len);
+ else
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ } else {
+ error = QSslDiffieHellmanParameters::UnsafeParametersError;
+ }
+ } else {
+ error = QSslDiffieHellmanParameters::InvalidInputDataError;
+ }
+
+ q_DH_free(dh);
+ q_BIO_free(bio);
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qssldiffiehellmanparameters_p.h b/src/network/ssl/qssldiffiehellmanparameters_p.h
new file mode 100644
index 0000000000..a5da4e51fc
--- /dev/null
+++ b/src/network/ssl/qssldiffiehellmanparameters_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QSSLDIFFIEHELLMANPARAMETERS_P_H
+#define QSSLDIFFIEHELLMANPARAMETERS_P_H
+
+#include "qsslkey.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qssldiffiehellmanparameters.cpp. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QSharedData>
+
+#include "qssldiffiehellmanparameters.h"
+#include "qsslsocket_p.h" // includes wincrypt.h
+
+QT_BEGIN_NAMESPACE
+
+class QSslDiffieHellmanParametersPrivate : public QSharedData
+{
+public:
+ QSslDiffieHellmanParametersPrivate() : error(QSslDiffieHellmanParameters::NoError) {};
+
+ void decodeDer(const QByteArray &der);
+ void decodePem(const QByteArray &pem);
+
+ QSslDiffieHellmanParameters::Error error;
+ QByteArray derData;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSSLDIFFIEHELLMANPARAMETERS_P_H
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 7fd2a361e3..75a38db5f9 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -916,6 +916,7 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.ciphers = configuration.ciphers();
d->configuration.ellipticCurves = configuration.ellipticCurves();
d->configuration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
+ d->configuration.dhParams = configuration.diffieHellmanParameters();
d->configuration.caCertificates = configuration.caCertificates();
d->configuration.peerVerifyDepth = configuration.peerVerifyDepth();
d->configuration.peerVerifyMode = configuration.peerVerifyMode();
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 66654e2a0d..0f9241e470 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -151,6 +151,10 @@ DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return)
+#endif
+DEFINEFUNC2(BN_ULONG, BN_mod_word, const BIGNUM *a, a, BN_ULONG w, w, return -1, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return 0, return)
DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return)
@@ -207,6 +211,7 @@ DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_passwo
#ifndef OPENSSL_NO_EC
DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
#endif
+DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#ifndef OPENSSL_NO_EC
@@ -436,6 +441,8 @@ DEFINEFUNC3(void, SSL_get0_alpn_selected, const SSL *s, s, const unsigned char *
DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return 0, return)
@@ -782,6 +789,10 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EC_GROUP_get_degree)
#endif
RESOLVEFUNC(BN_num_bits)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ RESOLVEFUNC(BN_is_word)
+#endif
+ RESOLVEFUNC(BN_mod_word)
RESOLVEFUNC(CRYPTO_free)
RESOLVEFUNC(CRYPTO_num_locks)
RESOLVEFUNC(CRYPTO_set_id_callback)
@@ -830,6 +841,7 @@ bool q_resolveOpenSslSymbols()
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(PEM_read_bio_ECPrivateKey)
#endif
+ RESOLVEFUNC(PEM_read_bio_DHparams)
RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
#ifndef OPENSSL_NO_EC
@@ -991,6 +1003,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DH_new)
RESOLVEFUNC(DH_free)
RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+ RESOLVEFUNC(DH_check)
RESOLVEFUNC(BN_bin2bn)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EC_KEY_dup)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 45e4380580..c0ddb8e888 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -227,6 +227,21 @@ int q_BIO_read(BIO *a, void *b, int c);
BIO_METHOD *q_BIO_s_mem();
int q_BIO_write(BIO *a, const void *b, int c);
int q_BN_num_bits(const BIGNUM *a);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+int q_BN_is_word(BIGNUM *a, BN_ULONG w);
+#else
+// BN_is_word is implemented purely as a
+// macro in OpenSSL < 1.1. It doesn't
+// call any functions.
+//
+// The implementation of BN_is_word is
+// 100% the same between 1.0.0, 1.0.1
+// and 1.0.2.
+//
+// Users are required to include <openssl/bn.h>.
+#define q_BN_is_word BN_is_word
+#endif // OPENSSL_VERSION_NUMBER >= 0x10100000L
+BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w);
#ifndef OPENSSL_NO_EC
const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k);
int q_EC_GROUP_get_degree(const EC_GROUP* g);
@@ -284,6 +299,7 @@ RSA *q_PEM_read_bio_RSAPrivateKey(BIO *a, RSA **b, pem_password_cb *c, void *d);
#ifndef OPENSSL_NO_EC
EC_KEY *q_PEM_read_bio_ECPrivateKey(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
#endif
+DH *q_PEM_read_bio_DHparams(BIO *a, DH **b, pem_password_cb *c, void *d);
int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d,
@@ -475,6 +491,8 @@ STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
DH *q_DH_new();
void q_DH_free(DH *dh);
DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+int q_i2d_DHparams(DH *a, unsigned char **p);
+int q_DH_check(DH *dh, int *codes);
BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
#define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
@@ -521,6 +539,9 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
bp,(char *)x,enc,kstr,klen,cb,u)
+#define q_PEM_read_bio_DHparams(bp, dh, cb, u) \
+ (DH *)q_PEM_ASN1_read_bio( \
+ (void *(*)(void**, const unsigned char**, long int))q_d2i_DHparams, PEM_STRING_DHPARAMS, bp, (void **)x, cb, u)
#endif
#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
#define q_SSL_CTX_set_mode(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index c70664ef9b..803d70a257 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -9,6 +9,8 @@ contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, op
ssl/qsslconfiguration_p.h \
ssl/qsslcipher.h \
ssl/qsslcipher_p.h \
+ ssl/qssldiffiehellmanparameters.h \
+ ssl/qssldiffiehellmanparameters_p.h \
ssl/qsslellipticcurve.h \
ssl/qsslerror.h \
ssl/qsslkey.h \
@@ -24,6 +26,7 @@ contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, op
ssl/qsslcertificate.cpp \
ssl/qsslconfiguration.cpp \
ssl/qsslcipher.cpp \
+ ssl/qssldiffiehellmanparameters.cpp \
ssl/qsslellipticcurve.cpp \
ssl/qsslkey_p.cpp \
ssl/qsslerror.cpp \
@@ -35,6 +38,7 @@ contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, op
HEADERS += ssl/qsslsocket_winrt_p.h
SOURCES += ssl/qsslcertificate_qt.cpp \
ssl/qsslcertificate_winrt.cpp \
+ ssl/qssldiffiehellmanparameters_dummy.cpp \
ssl/qsslkey_qt.cpp \
ssl/qsslkey_winrt.cpp \
ssl/qsslsocket_winrt.cpp \
@@ -44,6 +48,7 @@ contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, op
contains(QT_CONFIG, securetransport) {
HEADERS += ssl/qsslsocket_mac_p.h
SOURCES += ssl/qsslcertificate_qt.cpp \
+ ssl/qssldiffiehellmanparameters_dummy.cpp \
ssl/qsslkey_qt.cpp \
ssl/qsslkey_mac.cpp \
ssl/qsslsocket_mac_shared.cpp \
@@ -58,6 +63,7 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
ssl/qsslsocket_openssl_symbols_p.h
SOURCES += ssl/qsslcertificate_openssl.cpp \
ssl/qsslcontext_openssl.cpp \
+ ssl/qssldiffiehellmanparameters_openssl.cpp \
ssl/qsslellipticcurve_openssl.cpp \
ssl/qsslkey_openssl.cpp \
ssl/qsslsocket_openssl.cpp \