summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qasn1element_p.h1
-rw-r--r--src/network/ssl/qssl.h2
-rw-r--r--src/network/ssl/qssl_p.h1
-rw-r--r--src/network/ssl/qsslcertificate.h1
-rw-r--r--src/network/ssl/qsslcertificate_p.h1
-rw-r--r--src/network/ssl/qsslcertificateextension.h1
-rw-r--r--src/network/ssl/qsslcertificateextension_p.h1
-rw-r--r--src/network/ssl/qsslcipher.h1
-rw-r--r--src/network/ssl/qsslcipher_p.h1
-rw-r--r--src/network/ssl/qsslconfiguration.cpp78
-rw-r--r--src/network/ssl/qsslconfiguration.h9
-rw-r--r--src/network/ssl/qsslconfiguration_p.h8
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp61
-rw-r--r--src/network/ssl/qsslcontext_openssl_p.h1
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters.cpp308
-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/qsslellipticcurve.h2
-rw-r--r--src/network/ssl/qsslerror.h1
-rw-r--r--src/network/ssl/qsslkey.h1
-rw-r--r--src/network/ssl/qsslkey_p.h4
-rw-r--r--src/network/ssl/qsslpresharedkeyauthenticator.h2
-rw-r--r--src/network/ssl/qsslpresharedkeyauthenticator_p.h1
-rw-r--r--src/network/ssl/qsslsocket.cpp28
-rw-r--r--src/network/ssl/qsslsocket.h3
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp187
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp73
-rw-r--r--src/network/ssl/qsslsocket_openssl_android.cpp1
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp35
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h38
-rw-r--r--src/network/ssl/qsslsocket_p.h6
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp4
-rw-r--r--src/network/ssl/qsslsocket_winrt_p.h1
-rw-r--r--src/network/ssl/ssl.pri62
38 files changed, 1071 insertions, 274 deletions
diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h
index c636351bf9..f532cec530 100644
--- a/src/network/ssl/qasn1element_p.h
+++ b/src/network/ssl/qasn1element_p.h
@@ -52,6 +52,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qmap.h>
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 7742844246..c2a468c97c 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -41,7 +41,7 @@
#ifndef QSSL_H
#define QSSL_H
-#include <QtCore/qglobal.h>
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/QFlags>
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qssl_p.h b/src/network/ssl/qssl_p.h
index 85eb59ae35..83ccdc7fc3 100644
--- a/src/network/ssl/qssl_p.h
+++ b/src/network/ssl/qssl_p.h
@@ -53,6 +53,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 814c6a701d..8b051a5c88 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -45,6 +45,7 @@
#undef verify
#endif
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qcryptographichash.h>
diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
index 8b83f754e4..616b5aec6d 100644
--- a/src/network/ssl/qsslcertificate_p.h
+++ b/src/network/ssl/qsslcertificate_p.h
@@ -41,6 +41,7 @@
#ifndef QSSLCERTIFICATE_OPENSSL_P_H
#define QSSLCERTIFICATE_OPENSSL_P_H
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslcertificate.h"
//
diff --git a/src/network/ssl/qsslcertificateextension.h b/src/network/ssl/qsslcertificateextension.h
index 795dd0ce80..2ce2112687 100644
--- a/src/network/ssl/qsslcertificateextension.h
+++ b/src/network/ssl/qsslcertificateextension.h
@@ -40,6 +40,7 @@
#ifndef QSSLCERTIFICATEEXTENSION_H
#define QSSLCERTIFICATEEXTENSION_H
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
diff --git a/src/network/ssl/qsslcertificateextension_p.h b/src/network/ssl/qsslcertificateextension_p.h
index a7ff53d4a3..373f92a5cf 100644
--- a/src/network/ssl/qsslcertificateextension_p.h
+++ b/src/network/ssl/qsslcertificateextension_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslcertificateextension.h"
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h
index 8bb404ffa7..c6328e0169 100644
--- a/src/network/ssl/qsslcipher.h
+++ b/src/network/ssl/qsslcipher.h
@@ -41,6 +41,7 @@
#ifndef QSSLCIPHER_H
#define QSSLCIPHER_H
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qstring.h>
#include <QtCore/qscopedpointer.h>
#include <QtNetwork/qssl.h>
diff --git a/src/network/ssl/qsslcipher_p.h b/src/network/ssl/qsslcipher_p.h
index 1714617361..b8629f9f96 100644
--- a/src/network/ssl/qsslcipher_p.h
+++ b/src/network/ssl/qsslcipher_p.h
@@ -40,6 +40,7 @@
#ifndef QSSLCIPHER_P_H
#define QSSLCIPHER_P_H
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslcipher.h"
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index c8040dec7f..75a880f115 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -53,6 +53,7 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
|QSsl::SslOptionDisableCompression
|QSsl::SslOptionDisableSessionPersistence;
+const char QSslConfiguration::ALPNProtocolHTTP2[] = "h2";
const char QSslConfiguration::NextProtocolSpdy3_0[] = "spdy/3";
const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
@@ -119,7 +120,8 @@ const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
/*!
\enum QSslConfiguration::NextProtocolNegotiationStatus
- Describes the status of the Next Protocol Negotiation (NPN).
+ Describes the status of the Next Protocol Negotiation (NPN) or
+ Application-Layer Protocol Negotiation (ALPN).
\value NextProtocolNegotiationNone No application protocol
has been negotiated (yet).
@@ -209,9 +211,11 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->privateKey == other.d->privateKey &&
d->sessionCipher == other.d->sessionCipher &&
d->sessionProtocol == other.d->sessionProtocol &&
+ d->preSharedKeyIdentityHint == other.d->preSharedKeyIdentityHint &&
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 &&
@@ -254,6 +258,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() &&
@@ -261,6 +266,7 @@ bool QSslConfiguration::isNull() const
d->sslOptions == QSslConfigurationPrivate::defaultSslOptions &&
d->sslSession.isNull() &&
d->sslSessionTicketLifeTimeHint == -1 &&
+ d->preSharedKeyIdentityHint.isNull() &&
d->nextAllowedProtocols.isEmpty() &&
d->nextNegotiatedProtocol.isNull() &&
d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone);
@@ -811,11 +817,65 @@ QVector<QSslEllipticCurve> QSslConfiguration::supportedEllipticCurves()
}
/*!
+ \since 5.8
+
+ Returns the identity hint.
+
+ \sa setPreSharedKeyIdentityHint()
+*/
+QByteArray QSslConfiguration::preSharedKeyIdentityHint() const
+{
+ return d->preSharedKeyIdentityHint;
+}
+
+/*!
+ \since 5.8
+
+ Sets the identity hint for a preshared key authentication to \a hint. This will
+ affect the next initiated handshake; calling this function on an already-encrypted
+ socket will not affect the socket's identity hint.
+
+ The identity hint is used in QSslSocket::SslServerMode only!
+*/
+void QSslConfiguration::setPreSharedKeyIdentityHint(const QByteArray &hint)
+{
+ d->preSharedKeyIdentityHint = 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 to \a dhparams.
+
+ 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
- if the Next Protocol Negotiation (NPN) TLS extension was enabled.
- In order for the NPN extension to be enabled, setAllowedNextProtocols()
+ if the Next Protocol Negotiation (NPN) or Application-Layer Protocol
+ Negotiation (ALPN) TLS extension was enabled.
+ In order for the NPN/ALPN extension to be enabled, setAllowedNextProtocols()
needs to be called explicitly before connecting to the server.
If no protocol could be negotiated or the extension was not enabled,
@@ -832,9 +892,10 @@ QByteArray QSslConfiguration::nextNegotiatedProtocol() const
\since 5.3
This function sets the allowed \a protocols to be negotiated with the
- server through the Next Protocol Negotiation (NPN) TLS extension; each
+ server through the Next Protocol Negotiation (NPN) or Application-Layer
+ Protocol Negotiation (ALPN) TLS extension; each
element in \a protocols must define one allowed protocol.
- The function must be called explicitly before connecting to send the NPN
+ The function must be called explicitly before connecting to send the NPN/ALPN
extension in the SSL handshake.
Whether or not the negotiation succeeded can be queried through
nextProtocolNegotiationStatus().
@@ -854,8 +915,8 @@ void QSslConfiguration::setAllowedNextProtocols(QList<QByteArray> protocols)
\since 5.3
This function returns the allowed protocols to be negotiated with the
- server through the Next Protocol Negotiation (NPN) TLS extension, as set
- by setAllowedNextProtocols().
+ server through the Next Protocol Negotiation (NPN) or Application-Layer
+ Protocol Negotiation (ALPN) TLS extension, as set by setAllowedNextProtocols().
\sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
*/
@@ -867,7 +928,8 @@ QList<QByteArray> QSslConfiguration::allowedNextProtocols() const
/*!
\since 5.3
- This function returns the status of the Next Protocol Negotiation (NPN).
+ This function returns the status of the Next Protocol Negotiation (NPN)
+ or Application-Layer Protocol Negotiation (ALPN).
If the feature has not been enabled through setAllowedNextProtocols(),
this function returns NextProtocolNegotiationNone.
The status will be set before emitting the encrypted() signal.
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index f0754d7ef5..1c57bebd65 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -56,6 +56,7 @@
#ifndef QSSLCONFIGURATION_H
#define QSSLCONFIGURATION_H
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qshareddata.h>
#include <QtNetwork/qsslsocket.h>
#include <QtNetwork/qssl.h>
@@ -69,6 +70,7 @@ class QSslCertificate;
class QSslCipher;
class QSslKey;
class QSslEllipticCurve;
+class QSslDiffieHellmanParameters;
class QSslConfigurationPrivate;
class Q_NETWORK_EXPORT QSslConfiguration
@@ -141,6 +143,12 @@ public:
void setEllipticCurves(const QVector<QSslEllipticCurve> &curves);
static QVector<QSslEllipticCurve> supportedEllipticCurves();
+ 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);
@@ -160,6 +168,7 @@ public:
QByteArray nextNegotiatedProtocol() const;
NextProtocolNegotiationStatus nextProtocolNegotiationStatus() const;
+ static const char ALPNProtocolHTTP2[];
static const char NextProtocolSpdy3_0[];
static const char NextProtocolHttp1_1[];
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 364bba92ec..6adf2c9b54 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -67,12 +67,14 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslconfiguration.h"
#include "qlist.h"
#include "qsslcertificate.h"
#include "qsslcipher.h"
#include "qsslkey.h"
#include "qsslellipticcurve.h"
+#include "qssldiffiehellmanparameters.h"
QT_BEGIN_NAMESPACE
@@ -87,8 +89,10 @@ public:
allowRootCertOnDemandLoading(true),
peerSessionShared(false),
sslOptions(QSslConfigurationPrivate::defaultSslOptions),
+ dhParams(QSslDiffieHellmanParameters::defaultParameters()),
sslSessionTicketLifeTimeHint(-1),
ephemeralServerKey(),
+ preSharedKeyIdentityHint(),
nextProtocolNegotiationStatus(QSslConfiguration::NextProtocolNegotiationNone)
{ }
@@ -117,11 +121,15 @@ public:
QVector<QSslEllipticCurve> ellipticCurves;
+ QSslDiffieHellmanParameters dhParams;
+
QByteArray sslSession;
int sslSessionTicketLifeTimeHint;
QSslKey ephemeralServerKey;
+ QByteArray preSharedKeyIdentityHint;
+
QList<QByteArray> nextAllowedProtocols;
QByteArray nextNegotiatedProtocol;
QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus;
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index f132d0228c..dec8e12abb 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
@@ -345,6 +344,11 @@ init_context:
}
#endif // OPENSSL_NO_EC
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+ if (!client)
+ q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData());
+#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+
const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
if (!qcurves.isEmpty()) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
@@ -458,6 +462,23 @@ SSL* QSslContext::createSsl()
m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
m_npnContext.len = m_supportedNPNVersions.count();
m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ if (q_SSLeay() >= 0x10002000L) {
+ // Callback's type has a parameter 'const unsigned char ** out'
+ // since it was introduced in 1.0.2. Internally, OpenSSL's own code
+ // (tests/examples) cast it to unsigned char * (since it's 'out').
+ // We just re-use our NPN callback and cast here:
+ typedef int (*alpn_callback_t) (SSL *, const unsigned char **, unsigned char *,
+ const unsigned char *, unsigned int, void *);
+ // With ALPN callback is for a server side only, for a client m_npnContext.status
+ // will stay in NextProtocolNegotiationNone.
+ q_SSL_CTX_set_alpn_select_cb(ctx, alpn_callback_t(next_proto_cb), &m_npnContext);
+ // Client:
+ q_SSL_set_alpn_protos(ssl, m_npnContext.data, m_npnContext.len);
+ }
+#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
+
+ // And in case our peer does not support ALPN, but supports NPN:
q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
}
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
diff --git a/src/network/ssl/qsslcontext_openssl_p.h b/src/network/ssl/qsslcontext_openssl_p.h
index ef4dc6f815..06a31af5e5 100644
--- a/src/network/ssl/qsslcontext_openssl_p.h
+++ b/src/network/ssl/qsslcontext_openssl_p.h
@@ -53,6 +53,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/qvariant.h>
#include <QtNetwork/qsslcertificate.h>
#include <QtNetwork/qsslconfiguration.h>
diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp
new file mode 100644
index 0000000000..e6a2fe8a2a
--- /dev/null
+++ b/src/network/ssl/qssldiffiehellmanparameters.cpp
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** 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 \a encoded in either PEM or DER form as specified by \a encoding.
+
+ 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 \a 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 error()
+*/
+bool QSslDiffieHellmanParameters::isValid() const Q_DECL_NOTHROW
+{
+ return d->error == QSslDiffieHellmanParameters::NoError;
+}
+
+/*!
+ \enum QSslDiffieHellmanParameters::Error
+
+ Describes a QSslDiffieHellmanParameters error.
+
+ \value NoError No error occurred.
+
+ \value InvalidInputDataError The given input data could not be used to
+ construct a QSslDiffieHellmanParameters
+ object.
+
+ \value UnsafeParametersError 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;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ \relates QSslDiffieHellmanParameters
+
+ Writes the set of Diffie-Hellman parameters in \a dhparam 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..06ecf292ff
--- /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
+
+//
+// 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 <QtNetwork/private/qtnetworkglobal_p.h>
+#include <QSharedData>
+
+#include "qsslkey.h"
+#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/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h
index 6ee66d1ec1..0e7cc60e31 100644
--- a/src/network/ssl/qsslellipticcurve.h
+++ b/src/network/ssl/qsslellipticcurve.h
@@ -40,7 +40,7 @@
#ifndef QSSLELLIPTICCURVE_H
#define QSSLELLIPTICCURVE_H
-#include <QtCore/QtGlobal>
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/QString>
#include <QtCore/QMetaType>
#if QT_DEPRECATED_SINCE(5, 6)
diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h
index 82db2e58e4..d7c959423d 100644
--- a/src/network/ssl/qsslerror.h
+++ b/src/network/ssl/qsslerror.h
@@ -41,6 +41,7 @@
#ifndef QSSLERROR_H
#define QSSLERROR_H
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qvariant.h>
#include <QtNetwork/qsslcertificate.h>
diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h
index 39c3659fb8..6de02b1e44 100644
--- a/src/network/ssl/qsslkey.h
+++ b/src/network/ssl/qsslkey.h
@@ -41,6 +41,7 @@
#ifndef QSSLKEY_H
#define QSSLKEY_H
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qsharedpointer.h>
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index c17183a059..c93941c198 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -41,8 +41,6 @@
#ifndef QSSLKEY_OPENSSL_P_H
#define QSSLKEY_OPENSSL_P_H
-#include "qsslkey.h"
-
//
// W A R N I N G
// -------------
@@ -54,6 +52,8 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
+#include "qsslkey.h"
#include "qsslsocket_p.h" // includes wincrypt.h
#ifndef QT_NO_OPENSSL
diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.h b/src/network/ssl/qsslpresharedkeyauthenticator.h
index f34a2cee75..a012ff489a 100644
--- a/src/network/ssl/qsslpresharedkeyauthenticator.h
+++ b/src/network/ssl/qsslpresharedkeyauthenticator.h
@@ -40,7 +40,7 @@
#ifndef QSSLPRESHAREDKEYAUTHENTICATOR_H
#define QSSLPRESHAREDKEYAUTHENTICATOR_H
-#include <QtCore/QtGlobal>
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/QString>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QMetaType>
diff --git a/src/network/ssl/qsslpresharedkeyauthenticator_p.h b/src/network/ssl/qsslpresharedkeyauthenticator_p.h
index b9aa6eb28c..e5566c3b3c 100644
--- a/src/network/ssl/qsslpresharedkeyauthenticator_p.h
+++ b/src/network/ssl/qsslpresharedkeyauthenticator_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QSharedData>
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ccb11de7e0..2371dd7212 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -837,15 +837,7 @@ bool QSslSocket::atEnd() const
// Note! docs copied from QAbstractSocket::flush()
bool QSslSocket::flush()
{
- Q_D(QSslSocket);
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "QSslSocket::flush()";
-#endif
- if (d->mode != UnencryptedMode)
- // encrypt any unencrypted bytes in our buffer
- d->transmit();
-
- return d->plainSocket ? d->plainSocket->flush() : false;
+ return d_func()->flush();
}
/*!
@@ -924,6 +916,8 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.privateKey = configuration.privateKey();
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();
@@ -2623,6 +2617,22 @@ QByteArray QSslSocketPrivate::peek(qint64 maxSize)
/*!
\internal
*/
+bool QSslSocketPrivate::flush()
+{
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "QSslSocketPrivate::flush()";
+#endif
+ if (mode != QSslSocket::UnencryptedMode) {
+ // encrypt any unencrypted bytes in our buffer
+ transmit();
+ }
+
+ return plainSocket && plainSocket->flush();
+}
+
+/*!
+ \internal
+*/
bool QSslSocketPrivate::rootCertOnDemandLoadingSupported()
{
return s_loadRootCertsOnDemand;
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index c069ff2f9d..1b29cd4637 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -41,6 +41,7 @@
#ifndef QSSLSOCKET_H
#define QSSLSOCKET_H
+#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qlist.h>
#include <QtCore/qregexp.h>
#ifndef QT_NO_SSL
@@ -116,7 +117,7 @@ public:
bool canReadLine() const Q_DECL_OVERRIDE;
void close() Q_DECL_OVERRIDE;
bool atEnd() const Q_DECL_OVERRIDE;
- bool flush();
+ bool flush(); // ### Qt6: remove me (implementation moved to private flush())
void abort();
// From QAbstractSocket:
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index fd82d53fa8..438ea9a38e 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -68,57 +68,18 @@ QT_BEGIN_NAMESPACE
static SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode)
{
const bool isServer = mode == QSslSocket::SslServerMode;
- SSLContextRef context = Q_NULLPTR;
-
-#ifndef Q_OS_OSX
const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
// We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
- context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ SSLContextRef context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
if (!context)
qCWarning(lcSsl) << "SSLCreateContext failed";
-#else // Q_OS_OSX
-
-#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
- // We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
- context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
- if (!context)
- qCWarning(lcSsl) << "SSLCreateContext failed";
- } else {
-#else
- {
-#endif
- const OSStatus errCode = SSLNewContext(isServer, &context);
- if (errCode != noErr || !context)
- qCWarning(lcSsl) << "SSLNewContext failed with error:" << errCode;
- }
-#endif // !Q_OS_OSX
-
return context;
}
static void qt_releaseSecureTransportContext(SSLContextRef context)
{
- if (!context)
- return;
-
-#ifndef Q_OS_OSX
- CFRelease(context);
-#else
-
-#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ if (context)
CFRelease(context);
- } else {
-#else
- {
-#endif // QT_MAC_PLATFORM_...
- const OSStatus errCode = SSLDisposeContext(context);
- if (errCode != noErr)
- qCWarning(lcSsl) << "SSLDisposeContext failed with error:" << errCode;
- }
-#endif // !Q_OS_OSX
}
static bool qt_setSessionProtocol(SSLContextRef context, const QSslConfigurationPrivate &configuration,
@@ -132,7 +93,6 @@ static bool qt_setSessionProtocol(SSLContextRef context, const QSslConfiguration
OSStatus err = noErr;
-#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_5_0)
if (configuration.protocol == QSsl::SslV3) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
@@ -210,117 +170,10 @@ static bool qt_setSessionProtocol(SSLContextRef context, const QSslConfiguration
#endif
return false;
}
-#endif
return err == noErr;
}
-#ifdef Q_OS_OSX
-
-static bool qt_setSessionProtocolOSX(SSLContextRef context, const QSslConfigurationPrivate &configuration,
- QTcpSocket *plainSocket)
-{
- // This function works with (now) deprecated API that does not even exist on
- // iOS but is the only API we have on OS X below 10.8
-
- // Without SSLSetProtocolVersionMin/Max functions it's quite difficult
- // to have the required result:
- // If we use SSLSetProtocolVersion - any constant except the ones with 'Only' suffix -
- // allows a negotiation and we can not set the lower limit.
- // SSLSetProtocolVersionEnabled supports only a limited subset of constants, if you believe their docs:
- // kSSLProtocol2
- // kSSLProtocol3
- // kTLSProtocol1
- // kSSLProtocolAll
- // Here we can only have a look into the SecureTransport's code and hope that what we see there
- // and what we have on 10.7 is similar:
- // SSLSetProtocoLVersionEnabled actually accepts other constants also,
- // called twice with two different protocols it sets a range,
- // called once with a protocol (when all protocols were disabled)
- // - only this protocol is enabled (without a lower limit negotiation).
-
- Q_ASSERT(context);
-
-#ifndef QSSLSOCKET_DEBUG
- Q_UNUSED(plainSocket)
-#endif
-
- OSStatus err = noErr;
-
- // First, disable ALL:
- if (SSLSetProtocolVersionEnabled(context, kSSLProtocolAll, false) != noErr)
- return false;
-
- if (configuration.protocol == QSsl::SslV3) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
- #endif
- err = SSLSetProtocolVersion(context, kSSLProtocol3Only);
- } else if (configuration.protocol == QSsl::TlsV1_0) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0";
- #endif
- err = SSLSetProtocolVersion(context, kTLSProtocol1Only);
- } else if (configuration.protocol == QSsl::TlsV1_1) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol11, true);
- } else if (configuration.protocol == QSsl::TlsV1_2) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
- } else if (configuration.protocol == QSsl::AnyProtocol) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : any";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kSSLProtocolAll, true);
- } else if (configuration.protocol == QSsl::TlsV1SslV3) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
- if (err == noErr)
- err = SSLSetProtocolVersionEnabled(context, kSSLProtocol3, true);
- } else if (configuration.protocol == QSsl::SecureProtocols) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
- if (err == noErr)
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol1, true);
- } else if (configuration.protocol == QSsl::TlsV1_0OrLater) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
- if (err == noErr)
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol1, true);
- } else if (configuration.protocol == QSsl::TlsV1_1OrLater) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1 - TLSv1.2";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
- if (err == noErr)
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol11, true);
- } else if (configuration.protocol == QSsl::TlsV1_2OrLater) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
- #endif
- err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
- } else {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "no protocol version found in the configuration";
- #endif
- return false;
- }
-
- return err == noErr;
-}
-
-#endif // Q_OS_OSX
-
QSecureTransportContext::QSecureTransportContext(SSLContextRef c)
: context(c)
{
@@ -351,7 +204,7 @@ bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
bool QSslSocketPrivate::s_loadRootCertsOnDemand = false;
-#ifndef Q_OS_IOS // dhparam is not used on iOS. (see the SSLSetDiffieHellmanParams call below)
+#if !defined(QT_PLATFORM_UIKIT) // dhparam is not used on iOS or tvOS. (see the SSLSetDiffieHellmanParams call below)
static const uint8_t dhparam[] =
"\x30\x82\x01\x08\x02\x82\x01\x01\x00\x97\xea\xd0\x46\xf7\xae\xa7\x76\x80"
"\x9c\x74\x56\x98\xd8\x56\x97\x2b\x20\x6c\x77\xe2\x82\xbb\xc8\x84\xbe\xe7"
@@ -370,8 +223,8 @@ static const uint8_t dhparam[] =
"\x90\x0b\x35\x64\xff\xd9\xe3\xac\xf2\xf2\xeb\x3a\x63\x02\x01\x02";
#endif
-// No ioErr on iOS. (defined in MacErrors.h on OS X)
-#ifdef Q_OS_IOS
+// No ioErr on iOS/tvOS. (defined in MacErrors.h on OS X)
+#if defined(QT_PLATFORM_UIKIT)
# define ioErr -36
#endif
@@ -959,21 +812,6 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
-#ifdef Q_OS_OSX
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_8) {
- // Starting from OS X 10.8 SSLSetSessionOption with kSSLSessionOptionBreakOnServerAuth/
- // kSSLSessionOptionBreakOnClientAuth disables automatic certificate validation.
- // But for OS X versions below 10.8 we have to do it explicitly:
- const OSStatus err = SSLSetEnableCertVerify(context, false);
- if (err != noErr) {
- destroySslContext();
- setErrorAndEmit(QSslSocket::SslInternalError,
- QStringLiteral("SSLSetEnableCertVerify failed: %1").arg(err));
- return false;
- }
- }
-#endif
-
if (mode == QSslSocket::SslClientMode) {
// enable Server Name Indication (SNI)
QString tlsHostName(verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName);
@@ -1011,7 +849,7 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
}
-#ifndef Q_OS_IOS
+#if !defined(QT_PLATFORM_UIKIT)
// No SSLSetDiffieHellmanParams on iOS; calling it is optional according to docs.
SSLSetDiffieHellmanParams(context, dhparam, sizeof(dhparam));
#endif
@@ -1128,20 +966,7 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
return false;
}
-#ifndef Q_OS_OSX
return qt_setSessionProtocol(context, configuration, plainSocket);
-#else
-
-#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- return qt_setSessionProtocol(context, configuration, plainSocket);
- } else {
-#else
- {
-#endif
- return qt_setSessionProtocolOSX(context, configuration, plainSocket);
- }
-#endif
}
bool QSslSocketBackendPrivate::canIgnoreTrustVerificationFailure() const
diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h
index b96011f655..5210fb7f30 100644
--- a/src/network/ssl/qsslsocket_mac_p.h
+++ b/src/network/ssl/qsslsocket_mac_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtCore/qstring.h>
#include <QtCore/qglobal.h>
#include <QtCore/qlist.h>
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index b3820aea97..aca7507d13 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -201,6 +201,15 @@ static unsigned int q_ssl_psk_client_callback(SSL *ssl,
Q_ASSERT(d);
return d->tlsPskClientCallback(hint, identity, max_identity_len, psk, max_psk_len);
}
+
+static unsigned int q_ssl_psk_server_callback(SSL *ssl,
+ const char *identity,
+ unsigned char *psk, unsigned int max_psk_len)
+{
+ QSslSocketBackendPrivate *d = reinterpret_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ Q_ASSERT(d);
+ return d->tlsPskServerCallback(identity, psk, max_psk_len);
+}
#endif
} // extern "C"
@@ -436,8 +445,12 @@ bool QSslSocketBackendPrivate::initSslContext()
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
// Set the client callback for PSK
- if (q_SSLeay() >= 0x10001000L && mode == QSslSocket::SslClientMode)
- q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
+ if (q_SSLeay() >= 0x10001000L) {
+ if (mode == QSslSocket::SslClientMode)
+ q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
+ else if (mode == QSslSocket::SslServerMode)
+ q_SSL_set_psk_server_callback(ssl, &q_ssl_psk_server_callback);
+ }
#endif
return true;
@@ -522,15 +535,9 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
#if defined(Q_OS_WIN)
HINSTANCE hLib = LoadLibraryW(L"Crypt32");
if (hLib) {
-#if defined(Q_OS_WINCE)
- ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, L"CertOpenStore");
- ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, L"CertFindCertificateInStore");
- ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, L"CertCloseStore");
-#else
ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW");
ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore");
ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore");
-#endif
if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen
} else {
@@ -691,15 +698,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
#if defined(Q_OS_WIN)
if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) {
HCERTSTORE hSystemStore;
-#if defined(Q_OS_WINCE)
- hSystemStore = ptrCertOpenSystemStoreW(CERT_STORE_PROV_SYSTEM_W,
- 0,
- 0,
- CERT_STORE_NO_CRYPT_RELEASE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,
- L"ROOT");
-#else
hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT");
-#endif
if(hSystemStore) {
PCCERT_CONTEXT pc = NULL;
while(1) {
@@ -1278,6 +1277,31 @@ unsigned int QSslSocketBackendPrivate::tlsPskClientCallback(const char *hint,
return pskLength;
}
+unsigned int QSslSocketBackendPrivate::tlsPskServerCallback(const char *identity,
+ unsigned char *psk, unsigned int max_psk_len)
+{
+ QSslPreSharedKeyAuthenticator authenticator;
+
+ // Fill in some read-only fields (for the user)
+ authenticator.d->identityHint = configuration.preSharedKeyIdentityHint;
+ authenticator.d->identity = identity;
+ authenticator.d->maximumIdentityLength = 0; // user cannot set an identity
+ authenticator.d->maximumPreSharedKeyLength = int(max_psk_len);
+
+ // Let the client provide the remaining bits...
+ Q_Q(QSslSocket);
+ emit q->preSharedKeyAuthenticationRequired(&authenticator);
+
+ // No PSK set? Return now to make the handshake fail
+ if (authenticator.preSharedKey().isEmpty())
+ return 0;
+
+ // Copy data back into OpenSSL
+ const int pskLength = qMin(authenticator.preSharedKey().length(), authenticator.maximumPreSharedKeyLength());
+ ::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
+ return pskLength;
+}
+
#ifdef Q_OS_WIN
void QSslSocketBackendPrivate::fetchCaRootForCert(const QSslCertificate &cert)
@@ -1579,7 +1603,22 @@ void QSslSocketBackendPrivate::continueHandshake()
} else {
const unsigned char *proto = 0;
unsigned int proto_len = 0;
- q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ if (q_SSLeay() >= 0x10002000L) {
+ q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
+ if (proto_len && mode == QSslSocket::SslClientMode) {
+ // Client does not have a callback that sets it ...
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
+ }
+ }
+
+ if (!proto_len) { // Test if NPN was more lucky ...
+#else
+ {
+#endif
+ q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
+ }
+
if (proto_len)
configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
else
diff --git a/src/network/ssl/qsslsocket_openssl_android.cpp b/src/network/ssl/qsslsocket_openssl_android.cpp
index d73ed8995e..b5d2458d56 100644
--- a/src/network/ssl/qsslsocket_openssl_android.cpp
+++ b/src/network/ssl/qsslsocket_openssl_android.cpp
@@ -70,6 +70,7 @@ QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
QJNIEnvironmentPrivate env;
jobjectArray jcertificates = static_cast<jobjectArray>(certificates.object());
const jint nCertificates = env->GetArrayLength(jcertificates);
+ certificateData.reserve(static_cast<int>(nCertificates));
for (int i = 0; i < nCertificates; ++i) {
jbyteArray jCert = static_cast<jbyteArray>(env->GetObjectArrayElement(jcertificates, i));
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 0674c05d71..755a08ef6e 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -66,6 +66,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslsocket_p.h"
#ifdef Q_OS_WIN
@@ -143,6 +144,7 @@ public:
bool checkSslErrors();
void storePeerCertificates();
unsigned int tlsPskClientCallback(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len);
+ unsigned int tlsPskServerCallback(const char *identity, unsigned char *psk, unsigned int max_psk_len);
#ifdef Q_OS_WIN
void fetchCaRootForCert(const QSslCertificate &cert);
void _q_caRootLoaded(QSslCertificate,QSslCertificate) Q_DECL_OVERRIDE;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index d420f78dc7..f75df0466f 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
@@ -300,6 +305,8 @@ DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return N
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
DEFINEFUNC2(void, SSL_set_psk_client_callback, SSL* ssl, ssl, q_psk_client_callback_t callback, callback, return, DUMMYARG)
+DEFINEFUNC2(void, SSL_set_psk_server_callback, SSL* ssl, ssl, q_psk_server_callback_t callback, callback, return, DUMMYARG)
+DEFINEFUNC2(int, SSL_CTX_use_psk_identity_hint, SSL_CTX* ctx, ctx, const char *hint, hint, return 0, return)
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#ifndef OPENSSL_NO_SSL2
@@ -418,10 +425,24 @@ DEFINEFUNC3(void, SSL_CTX_set_next_proto_select_cb, SSL_CTX *s, s,
void *arg, arg, return, DUMMYARG)
DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s,
const unsigned char **data, data, unsigned *len, len, return, DUMMYARG)
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+DEFINEFUNC3(int, SSL_set_alpn_protos, SSL *s, s, const unsigned char *protos, protos,
+ unsigned protos_len, protos_len, return -1, return)
+DEFINEFUNC3(void, SSL_CTX_set_alpn_select_cb, SSL_CTX *s, s,
+ int (*cb) (SSL *ssl, const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen, void *arg), cb,
+ void *arg, arg, return, DUMMYARG)
+DEFINEFUNC3(void, SSL_get0_alpn_selected, const SSL *s, s, const unsigned char **data, data,
+ unsigned *len, len, return, DUMMYARG)
+#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
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)
@@ -768,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)
@@ -816,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
@@ -889,6 +915,8 @@ bool q_resolveOpenSslSymbols()
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
RESOLVEFUNC(SSL_set_psk_client_callback)
+ RESOLVEFUNC(SSL_set_psk_server_callback)
+ RESOLVEFUNC(SSL_CTX_use_psk_identity_hint)
#endif
RESOLVEFUNC(SSL_write)
#ifndef OPENSSL_NO_SSL2
@@ -972,9 +1000,16 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_set_next_proto_select_cb)
RESOLVEFUNC(SSL_get0_next_proto_negotiated)
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ RESOLVEFUNC(SSL_set_alpn_protos)
+ RESOLVEFUNC(SSL_CTX_set_alpn_select_cb)
+ RESOLVEFUNC(SSL_get0_alpn_selected)
+#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
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 df17fd8a9c..f912d8609b 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -67,6 +67,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslsocket_openssl_p.h"
#include <QtCore/qglobal.h>
@@ -227,6 +228,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 +300,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,
@@ -376,6 +393,9 @@ void *q_SSL_get_ex_data(const SSL *ssl, int idx);
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
typedef unsigned int (*q_psk_client_callback_t)(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len);
void q_SSL_set_psk_client_callback(SSL *ssl, q_psk_client_callback_t callback);
+typedef unsigned int (*q_psk_server_callback_t)(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len);
+void q_SSL_set_psk_server_callback(SSL *ssl, q_psk_server_callback_t callback);
+int q_SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint);
#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#ifndef OPENSSL_NO_SSL2
@@ -472,6 +492,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)
@@ -518,6 +540,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)
@@ -558,6 +583,19 @@ void q_SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
void *arg);
void q_SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
unsigned *len);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+int q_SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
+ unsigned protos_len);
+void q_SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
+ int (*cb) (SSL *ssl,
+ const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg), void *arg);
+void q_SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+ unsigned *len);
+#endif
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
// Helper function
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 5d4d52cd6d..696827daff 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -54,6 +54,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <private/qtcpsocket_p.h>
#include "qsslkey.h"
#include "qsslconfiguration_p.h"
@@ -89,11 +90,7 @@ QT_BEGIN_NAMESPACE
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-#if defined(Q_OS_WINCE)
- typedef HCERTSTORE (WINAPI *PtrCertOpenSystemStoreW)(LPCSTR, DWORD, HCRYPTPROV_LEGACY, DWORD, const void*);
-#else
typedef HCERTSTORE (WINAPI *PtrCertOpenSystemStoreW)(HCRYPTPROV_LEGACY, LPCWSTR);
-#endif
typedef PCCERT_CONTEXT (WINAPI *PtrCertFindCertificateInStore)(HCERTSTORE, DWORD, DWORD, DWORD, const void*, PCCERT_CONTEXT);
typedef BOOL (WINAPI *PtrCertCloseStore)(HCERTSTORE, DWORD);
#endif // Q_OS_WIN && !Q_OS_WINRT
@@ -193,6 +190,7 @@ public:
virtual qint64 peek(char *data, qint64 maxSize) Q_DECL_OVERRIDE;
virtual QByteArray peek(qint64 maxSize) Q_DECL_OVERRIDE;
+ bool flush() Q_DECL_OVERRIDE;
// Platform specific functions
virtual void startClientEncryption() = 0;
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index edc8ca0bbb..f5dc9fcdcd 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -215,7 +215,9 @@ QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers()
const QString protocolStrings[] = { QStringLiteral("SSLv3"), QStringLiteral("TLSv1"),
QStringLiteral("TLSv1.1"), QStringLiteral("TLSv1.2") };
const QSsl::SslProtocol protocols[] = { QSsl::SslV3, QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 };
- for (int i = 0; i < ARRAYSIZE(protocols); ++i) {
+ const int size = static_cast<int>(ARRAYSIZE(protocols));
+ ciphers.reserve(size);
+ for (int i = 0; i < size; ++i) {
QSslCipher cipher;
cipher.d->isNull = false;
cipher.d->name = QStringLiteral("WINRT");
diff --git a/src/network/ssl/qsslsocket_winrt_p.h b/src/network/ssl/qsslsocket_winrt_p.h
index 3946a0e60b..1043aeee11 100644
--- a/src/network/ssl/qsslsocket_winrt_p.h
+++ b/src/network/ssl/qsslsocket_winrt_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslsocket_p.h"
#include <wrl.h>
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index c70664ef9b..edbbeadf51 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -1,5 +1,5 @@
# OpenSSL support; compile in QSslSocket.
-contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
+contains(QT_CONFIG, ssl) {
HEADERS += ssl/qasn1element_p.h \
ssl/qssl.h \
ssl/qssl_p.h \
@@ -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,43 +48,45 @@ 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 \
ssl/qsslsocket_mac.cpp \
ssl/qsslellipticcurve_dummy.cpp
}
-}
-contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
- HEADERS += ssl/qsslcontext_openssl_p.h \
- ssl/qsslsocket_openssl_p.h \
- ssl/qsslsocket_openssl_symbols_p.h
- SOURCES += ssl/qsslcertificate_openssl.cpp \
- ssl/qsslcontext_openssl.cpp \
- ssl/qsslellipticcurve_openssl.cpp \
- ssl/qsslkey_openssl.cpp \
- ssl/qsslsocket_openssl.cpp \
- ssl/qsslsocket_openssl_symbols.cpp
+ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
+ HEADERS += ssl/qsslcontext_openssl_p.h \
+ ssl/qsslsocket_openssl_p.h \
+ 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 \
+ ssl/qsslsocket_openssl_symbols.cpp
- darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
+ darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
- android: SOURCES += ssl/qsslsocket_openssl_android.cpp
+ android: SOURCES += ssl/qsslsocket_openssl_android.cpp
- # Add optional SSL libs
- # Static linking of OpenSSL with msvc:
- # - Binaries http://slproweb.com/products/Win32OpenSSL.html
- # - also needs -lUser32 -lAdvapi32 -lGdi32 -lCrypt32
- # - libs in <OPENSSL_DIR>\lib\VC\static
- # - configure: -openssl -openssl-linked -I <OPENSSL_DIR>\include -L <OPENSSL_DIR>\lib\VC\static OPENSSL_LIBS="-lUser32 -lAdvapi32 -lGdi32" OPENSSL_LIBS_DEBUG="-lssleay32MDd -llibeay32MDd" OPENSSL_LIBS_RELEASE="-lssleay32MD -llibeay32MD"
+ # Add optional SSL libs
+ # Static linking of OpenSSL with msvc:
+ # - Binaries http://slproweb.com/products/Win32OpenSSL.html
+ # - also needs -lUser32 -lAdvapi32 -lGdi32 -lCrypt32
+ # - libs in <OPENSSL_DIR>\lib\VC\static
+ # - configure: -openssl -openssl-linked -I <OPENSSL_DIR>\include -L <OPENSSL_DIR>\lib\VC\static OPENSSL_LIBS="-lUser32 -lAdvapi32 -lGdi32" OPENSSL_LIBS_DEBUG="-lssleay32MDd -llibeay32MDd" OPENSSL_LIBS_RELEASE="-lssleay32MD -llibeay32MD"
- CONFIG(debug, debug|release) {
- LIBS_PRIVATE += $$OPENSSL_LIBS_DEBUG
- } else {
- LIBS_PRIVATE += $$OPENSSL_LIBS_RELEASE
- }
+ CONFIG(debug, debug|release) {
+ LIBS_PRIVATE += $$OPENSSL_LIBS_DEBUG
+ } else {
+ LIBS_PRIVATE += $$OPENSSL_LIBS_RELEASE
+ }
- QMAKE_CXXFLAGS += $$OPENSSL_CFLAGS
- LIBS_PRIVATE += $$OPENSSL_LIBS
- win32: LIBS_PRIVATE += -lcrypt32
+ QMAKE_CXXFLAGS += $$OPENSSL_CFLAGS
+ LIBS_PRIVATE += $$OPENSSL_LIBS
+ win32: LIBS_PRIVATE += -lcrypt32
+ }
}