summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/corelib/tools/customtype/message.cpp15
-rw-r--r--examples/corelib/tools/customtype/message.h7
-rw-r--r--examples/corelib/tools/customtypesending/message.cpp13
-rw-r--r--examples/corelib/tools/customtypesending/message.h7
-rw-r--r--examples/corelib/tools/doc/src/customtype.qdoc5
-rw-r--r--src/3rdparty/double-conversion/double-conversion.cc5
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp2
-rw-r--r--src/corelib/time/qmilankoviccalendar.cpp2
-rw-r--r--src/gui/painting/qdrawhelper.cpp4
-rw-r--r--src/network/configure.json23
-rw-r--r--src/network/ssl/qdtls_openssl.cpp71
-rw-r--r--src/network/ssl/qdtls_openssl_p.h5
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp550
-rw-r--r--src/network/ssl/qsslcontext_openssl11.cpp467
-rw-r--r--src/network/ssl/qsslcontext_openssl_p.h8
-rw-r--r--src/network/ssl/qsslcontext_opensslpre11.cpp407
-rw-r--r--src/network/ssl/qsslellipticcurve_openssl.cpp4
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp24
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp276
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp271
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h195
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp325
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h214
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11.cpp408
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h202
-rw-r--r--src/network/ssl/qsslsocket_p.h1
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp5
-rw-r--r--src/network/ssl/ssl.pri12
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm9
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp2
-rw-r--r--src/xml/dom/dom.pri7
-rw-r--r--src/xml/dom/qdom.cpp704
-rw-r--r--src/xml/dom/qdom_p.h533
-rw-r--r--src/xml/dom/qdomhelpers.cpp247
-rw-r--r--src/xml/dom/qdomhelpers_p.h121
-rw-r--r--tests/auto/gui/rhi/qrhi/tst_qrhi.cpp3
-rw-r--r--tests/auto/network/ssl/qdtls/tst_qdtls.cpp4
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp14
39 files changed, 1845 insertions, 3329 deletions
diff --git a/examples/corelib/tools/customtype/message.cpp b/examples/corelib/tools/customtype/message.cpp
index cc96aee978..e83697cb74 100644
--- a/examples/corelib/tools/customtype/message.cpp
+++ b/examples/corelib/tools/customtype/message.cpp
@@ -52,21 +52,6 @@
#include <QDebug>
-//! [Message class implementation]
-Message::Message()
-{
-}
-
-Message::Message(const Message &other)
- : m_body(other.m_body), m_headers(other.m_headers)
-{
-}
-
-Message::~Message()
-{
-}
-//! [Message class implementation]
-
Message::Message(const QString &body, const QStringList &headers)
: m_body(body), m_headers(headers)
{
diff --git a/examples/corelib/tools/customtype/message.h b/examples/corelib/tools/customtype/message.h
index c1b8243237..bc30c45425 100644
--- a/examples/corelib/tools/customtype/message.h
+++ b/examples/corelib/tools/customtype/message.h
@@ -58,9 +58,10 @@
class Message
{
public:
- Message();
- Message(const Message &other);
- ~Message();
+ Message() = default;
+ ~Message() = default;
+ Message(const Message &) = default;
+ Message &operator=(const Message &) = default;
Message(const QString &body, const QStringList &headers);
diff --git a/examples/corelib/tools/customtypesending/message.cpp b/examples/corelib/tools/customtypesending/message.cpp
index 9386b93898..76f90e5144 100644
--- a/examples/corelib/tools/customtypesending/message.cpp
+++ b/examples/corelib/tools/customtypesending/message.cpp
@@ -50,19 +50,6 @@
#include "message.h"
-Message::Message()
-{
-}
-
-Message::Message(const Message &other)
- : m_body(other.m_body), m_headers(other.m_headers)
-{
-}
-
-Message::~Message()
-{
-}
-
Message::Message(const QString &body, const QStringList &headers)
: m_body(body), m_headers(headers)
{
diff --git a/examples/corelib/tools/customtypesending/message.h b/examples/corelib/tools/customtypesending/message.h
index a93f111e45..38b5c8205f 100644
--- a/examples/corelib/tools/customtypesending/message.h
+++ b/examples/corelib/tools/customtypesending/message.h
@@ -58,9 +58,10 @@
class Message
{
public:
- Message();
- Message(const Message &other);
- ~Message();
+ Message() = default;
+ ~Message() = default;
+ Message(const Message &) = default;
+ Message &operator=(const Message &) = default;
Message(const QString &body, const QStringList &headers);
diff --git a/examples/corelib/tools/doc/src/customtype.qdoc b/examples/corelib/tools/doc/src/customtype.qdoc
index 7ccfc95c70..fb63bc539c 100644
--- a/examples/corelib/tools/doc/src/customtype.qdoc
+++ b/examples/corelib/tools/doc/src/customtype.qdoc
@@ -81,11 +81,6 @@
\section1 The Message Class Implementation
- The implementation of the default constructor, copy constructor and destructor
- are straightforward for the \c Message class:
-
- \snippet tools/customtype/message.cpp Message class implementation
-
The streaming operator is implemented in the following way:
\snippet tools/customtype/message.cpp custom type streaming operator
diff --git a/src/3rdparty/double-conversion/double-conversion.cc b/src/3rdparty/double-conversion/double-conversion.cc
index 9cf13bdbf7..8c52755cfb 100644
--- a/src/3rdparty/double-conversion/double-conversion.cc
+++ b/src/3rdparty/double-conversion/double-conversion.cc
@@ -38,6 +38,11 @@
#include <double-conversion/strtod.h>
#include <double-conversion/utils.h>
+// Fix warning C4244: 'argument': conversion from 'const uc16' to 'char', possible loss of data
+#ifdef _MSC_VER
+ __pragma(warning(disable: 4244))
+#endif
+
namespace double_conversion {
const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 3c03cf40e4..009659d998 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -2599,7 +2599,7 @@ void QStateMachine::setGlobalRestorePolicy(QState::RestorePolicy restorePolicy)
/*!
Adds the given \a state to this state machine. The state becomes a top-level
- state.
+ state and the state machine takes ownership of the state.
If the state is already in a different machine, it will first be removed
from its old machine, and then added to this machine.
diff --git a/src/corelib/time/qmilankoviccalendar.cpp b/src/corelib/time/qmilankoviccalendar.cpp
index 68d74947b9..673713a266 100644
--- a/src/corelib/time/qmilankoviccalendar.cpp
+++ b/src/corelib/time/qmilankoviccalendar.cpp
@@ -56,8 +56,6 @@ using namespace QRoundingDown;
\brief The QMilankovicCalendar class provides Milanković calendar system
implementation.
- \section1
-
The Revised Julian calendar, also known as the Milanković calendar, or,
less formally, new calendar, is a calendar, developed and proposed by the
Serbian scientist Milutin Milanković in 1923, which effectively discontinued
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index e5f752b94e..e8d129d047 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6044,11 +6044,11 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
// nothing
} else if (coverage == 0xffffffff && qAlpha(src) == 255) {
blend_pixel(*dst, src);
- } else if (!colorProfile) {
- *dst = rgbBlend(*dst, src, coverage);
} else if (*dst < 0xff000000) {
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
blend_pixel(*dst, src, qRgbAvg(coverage));
+ } else if (!colorProfile) {
+ *dst = rgbBlend(*dst, src, coverage);
} else if (srcLinear.isOpaque()) {
rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
diff --git a/src/network/configure.json b/src/network/configure.json
index f501465c91..6bc71469dc 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -61,11 +61,11 @@
"export": "openssl",
"test": {
"tail": [
- "#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10000000L",
- "# error OpenSSL >= 1.0.0 is required",
+ "#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L",
+ "# error OpenSSL >= 1.1.0 is required",
"#endif",
- "#if OPENSSL_VERSION_NUMBER-0 >= 0x10002000L && !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES)",
- "# error OpenSSL was reported as >= 1.0.2 but is missing required features, possibly it's libressl which is unsupported",
+ "#if !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES)",
+ "# error OpenSSL was reported as >= 1.1.0 but is missing required features, possibly it's libressl which is unsupported",
"#endif"
]
},
@@ -185,19 +185,6 @@
},
"use": "network"
},
- "openssl11": {
- "label": "OpenSSL 1.1 support",
- "type": "compile",
- "test": {
- "include": "openssl/opensslv.h",
- "tail": [
- "#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L",
- "# error OpenSSL >= 1.1 is required",
- "#endif"
- ]
- },
- "use": "openssl"
- },
"dtls": {
"label": "DTLS support in OpenSSL",
"type": "compile",
@@ -335,7 +322,7 @@
},
"opensslv11": {
"label": "OpenSSL 1.1",
- "condition": "features.openssl && tests.openssl11",
+ "condition": "features.openssl",
"output": [ "publicFeature" ]
},
"sctp": {
diff --git a/src/network/ssl/qdtls_openssl.cpp b/src/network/ssl/qdtls_openssl.cpp
index d9ddcceb40..25a6c5f49c 100644
--- a/src/network/ssl/qdtls_openssl.cpp
+++ b/src/network/ssl/qdtls_openssl.cpp
@@ -156,8 +156,6 @@ void delete_connection(SSL *ssl)
q_SSL_free(ssl);
}
-#if QT_CONFIG(opensslv11)
-
void delete_BIO_ADDR(BIO_ADDR *bio)
{
// A deleter for QSharedPointer<BIO_ADDR>
@@ -172,8 +170,6 @@ void delete_bio_method(BIO_METHOD *method)
q_BIO_meth_free(method);
}
-#endif // openssl 1.1
-
// The 'deleter' for QScopedPointer<BIO>.
struct bio_deleter
{
@@ -411,10 +407,6 @@ extern "C" long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
auto dtls = static_cast<dtlsopenssl::DtlsState *>(q_BIO_get_app_data(bio));
Q_ASSERT(dtls);
-#if !QT_CONFIG(opensslv11)
- Q_UNUSED(num)
-#endif
-
switch (cmd) {
// Let's start from the most generic ones, in the order in which they are
// documented (as BIO_ctrl):
@@ -578,11 +570,9 @@ extern "C" long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
// so that OpenSSL does not start suddenly fragmenting the first
// client hello (which will result in DTLSv1_listen rejecting it).
return 0;
-#if QT_CONFIG(opensslv11)
case BIO_CTRL_DGRAM_SET_PEEK_MODE:
dtls->peeking = num;
return 1;
-#endif
default:;
#if QT_DTLS_VERBOSE
qWarning() << "Unexpected cmd (" << cmd << ")";
@@ -594,15 +584,11 @@ extern "C" long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
extern "C" int q_dgram_create(BIO *bio)
{
-#if QT_CONFIG(opensslv11)
+
q_BIO_set_init(bio, 1);
-#else
- bio->init = 1;
-#endif
// With a custom BIO you'd normally allocate some implementation-specific
- // data and append it to this new BIO: bio->ptr = ... (pre 1.0.2) or
- // BIO_set_data (1.1). We don't need it and thus q_dgram_destroy below
- // is a noop.
+ // data and append it to this new BIO using BIO_set_data. We don't need
+ // it and thus q_dgram_destroy below is a noop.
return 1;
}
@@ -614,39 +600,6 @@ extern "C" int q_dgram_destroy(BIO *bio)
const char * const qdtlsMethodName = "qdtlsbio";
-#if !QT_CONFIG(opensslv11)
-
-/*
-typedef struct bio_method_st {
- int type;
- const char *name;
- int (*bwrite) (BIO *, const char *, int);
- int (*bread) (BIO *, char *, int);
- int (*bputs) (BIO *, const char *);
- int (*bgets) (BIO *, char *, int);
- long (*ctrl) (BIO *, int, long, void *);
- int (*create) (BIO *);
- int (*destroy) (BIO *);
- long (*callback_ctrl) (BIO *, int, bio_info_cb *);
-} BIO_METHOD;
-*/
-
-bio_method_st qdtlsCustomBioMethod =
-{
- BIO_TYPE_DGRAM,
- qdtlsMethodName,
- q_dgram_write,
- q_dgram_read,
- q_dgram_puts,
- nullptr,
- q_dgram_ctrl,
- q_dgram_create,
- q_dgram_destroy,
- nullptr
-};
-
-#endif // openssl < 1.1
-
} // namespace dtlsbio
namespace dtlsopenssl
@@ -777,7 +730,6 @@ bool DtlsState::initBIO(QDtlsBasePrivate *dtlsBase)
Q_ASSERT(dtlsBase);
Q_ASSERT(tlsContext.data() && tlsConnection.data());
-#if QT_CONFIG(opensslv11)
BioMethod customMethod(q_BIO_meth_new(BIO_TYPE_DGRAM, dtlsbio::qdtlsMethodName),
dtlsutil::delete_bio_method);
if (!customMethod.data()) {
@@ -793,9 +745,6 @@ bool DtlsState::initBIO(QDtlsBasePrivate *dtlsBase)
q_BIO_meth_set_write(biom, dtlsbio::q_dgram_write);
q_BIO_meth_set_puts(biom, dtlsbio::q_dgram_puts);
q_BIO_meth_set_ctrl(biom, dtlsbio::q_dgram_ctrl);
-#else
- BIO_METHOD *biom = &dtlsbio::qdtlsCustomBioMethod;
-#endif // openssl 1.1
QScopedPointer<BIO, dtlsutil::bio_deleter> newBio(q_BIO_new(biom));
BIO *bio = newBio.data();
@@ -808,9 +757,7 @@ bool DtlsState::initBIO(QDtlsBasePrivate *dtlsBase)
q_SSL_set_bio(tlsConnection.data(), bio, bio);
newBio.take();
-#if QT_CONFIG(opensslv11)
bioMethod.swap(customMethod);
-#endif // openssl 1.1
return true;
}
@@ -869,7 +816,6 @@ bool QDtlsClientVerifierOpenSSL::verifyClient(QUdpSocket *socket, const QByteArr
dtls.hashAlgorithm = hashAlgorithm;
Q_ASSERT(dtls.tlsConnection.data());
-#if QT_CONFIG(opensslv11)
QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
if (!peer.data()) {
setDtlsError(QDtlsError::TlsInitializationError,
@@ -883,10 +829,7 @@ bool QDtlsClientVerifierOpenSSL::verifyClient(QUdpSocket *socket, const QByteArr
setDtlsError(QDtlsError::TlsFatalError, QSslSocketBackendPrivate::getErrorsFromOpenSsl());
return false;
}
-#else
- qt_sockaddr peer;
- const int ret = q_DTLSv1_listen(dtls.tlsConnection.data(), &peer);
-#endif
+
if (ret > 0) {
verifiedClientHello = dgram;
return true;
@@ -953,7 +896,6 @@ bool QDtlsPrivateOpenSSL::startHandshake(QUdpSocket *socket, const QByteArray &d
// surprise DTLS/OpenSSL (such a message would be disregarded as
// 'stale or future' in SSL_accept otherwise):
int result = 0;
-#if QT_CONFIG(opensslv11)
QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
if (!peer.data()) {
setDtlsError(QDtlsError::TlsInitializationError,
@@ -967,10 +909,7 @@ bool QDtlsPrivateOpenSSL::startHandshake(QUdpSocket *socket, const QByteArray &d
dtls.writeSuppressed = true;
result = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
dtls.writeSuppressed = false;
-#else
- qt_sockaddr peer;
- result = q_DTLSv1_listen(dtls.tlsConnection.data(), &peer);
-#endif
+
if (result <= 0) {
setDtlsError(QDtlsError::TlsFatalError,
QDtls::tr("Cannot start the handshake, verified client hello expected"));
diff --git a/src/network/ssl/qdtls_openssl_p.h b/src/network/ssl/qdtls_openssl_p.h
index 9306fa2433..35e9f29a5d 100644
--- a/src/network/ssl/qdtls_openssl_p.h
+++ b/src/network/ssl/qdtls_openssl_p.h
@@ -84,9 +84,8 @@ namespace dtlsopenssl
class DtlsState
{
public:
- // Note, bioMethod, if allocated (i.e. OpenSSL version >= 1.1) _must_
- // outlive BIOs it was used to create. Thus the order of declarations
- // here matters.
+ // Note, bioMethod _must_ outlive BIOs it was used to create. Thus
+ // the order of declarations here matters.
using BioMethod = QSharedPointer<BIO_METHOD>;
BioMethod bioMethod;
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index 8566d78aef..562aa4f518 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -3,6 +3,7 @@
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Copyright (C) 2014 Governikus GmbH & Co. KG.
+** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -39,21 +40,49 @@
**
****************************************************************************/
-
#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qssldiffiehellmanparameters.h>
#include "private/qssl_p.h"
+#include "private/qsslsocket_p.h"
#include "private/qsslcontext_openssl_p.h"
#include "private/qsslsocket_openssl_p.h"
#include "private/qsslsocket_openssl_symbols_p.h"
+#include "private/qssldiffiehellmanparameters_p.h"
+
+#include <vector>
QT_BEGIN_NAMESPACE
+// defined in qsslsocket_openssl.cpp:
+extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
+extern QString getErrorsFromOpenSsl();
+
+#if QT_CONFIG(dtls)
+// defined in qdtls_openssl.cpp:
+namespace dtlscallbacks
+{
+extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx);
+extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
+ unsigned *cookieLength);
+extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ unsigned cookieLength);
+}
+#endif // dtls
+
+// Defined in qsslsocket.cpp
+QList<QSslCipher> q_getDefaultDtlsCiphers();
+
static inline QString msgErrorSettingBackendConfig(const QString &why)
{
return QSslSocket::tr("Error when setting the OpenSSL configuration (%1)").arg(why);
}
+static inline QString msgErrorSettingEllipticCurves(const QString &why)
+{
+ return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
+}
+
QSslContext::QSslContext()
: ctx(nullptr),
pkey(nullptr),
@@ -89,7 +118,7 @@ QSharedPointer<QSslContext> QSslContext::sharedFromConfiguration(QSslSocket::Ssl
return sslContext;
}
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+#ifndef OPENSSL_NO_NEXTPROTONEG
static int next_proto_cb(SSL *, unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, void *arg)
@@ -126,7 +155,9 @@ QSslContext::NPNContext QSslContext::npnContext() const
{
return m_npnContext;
}
-#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
+
+
// Needs to be deleted by caller
SSL* QSslContext::createSsl()
@@ -150,7 +181,7 @@ SSL* QSslContext::createSsl()
}
}
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+#ifndef OPENSSL_NO_NEXTPROTONEG
QList<QByteArray> protocols = sslConfiguration.d->nextAllowedProtocols;
if (!protocols.isEmpty()) {
m_supportedNPNVersions.clear();
@@ -168,27 +199,22 @@ 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 (QSslSocket::sslLibraryVersionNumber() >= 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 ...
-
+ // 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);
// 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 ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
return ssl;
}
@@ -247,6 +273,392 @@ QString QSslContext::errorString() const
return errorStr;
}
+void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode,
+ const QSslConfiguration &configuration,
+ bool allowRootCertOnDemandLoading)
+{
+ sslContext->sslConfiguration = configuration;
+ sslContext->errorCode = QSslError::NoError;
+
+ bool client = (mode == QSslSocket::SslClientMode);
+
+ bool reinitialized = false;
+ bool unsupportedProtocol = false;
+ bool isDtls = false;
+init_context:
+ if (sslContext->sslConfiguration.protocol() == QSsl::SslV2) {
+ // SSL 2 is no longer supported, but chosen deliberately -> error
+ sslContext->ctx = nullptr;
+ unsupportedProtocol = true;
+ } else if (sslContext->sslConfiguration.protocol() == QSsl::SslV3) {
+ // SSL 3 is no longer supported, but chosen deliberately -> error
+ sslContext->ctx = nullptr;
+ unsupportedProtocol = true;
+ } else {
+ switch (sslContext->sslConfiguration.protocol()) {
+ case QSsl::DtlsV1_0:
+ case QSsl::DtlsV1_0OrLater:
+ case QSsl::DtlsV1_2:
+ case QSsl::DtlsV1_2OrLater:
+#if QT_CONFIG(dtls)
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method());
+#else // dtls
+ sslContext->ctx = nullptr;
+ unsupportedProtocol = true;
+ qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled");
+
+#endif // dtls
+ break;
+ case QSsl::TlsV1_3:
+ case QSsl::TlsV1_3OrLater:
+#if !defined(TLS1_3_VERSION)
+ qCWarning(lcSsl, "TLS 1.3 is not supported");
+ sslContext->ctx = nullptr;
+ unsupportedProtocol = true;
+ break;
+#endif // TLS1_3_VERSION
+ default:
+ // The ssl options will actually control the supported methods
+ sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method());
+ }
+ }
+
+ if (!sslContext->ctx) {
+ // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
+ // by re-initializing the library.
+ if (!reinitialized) {
+ reinitialized = true;
+ if (q_OPENSSL_init_ssl(0, nullptr) == 1)
+ goto init_context;
+ }
+
+ sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
+ unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
+ );
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ const long anyVersion =
+#if QT_CONFIG(dtls)
+ isDtls ? DTLS_ANY_VERSION : TLS_ANY_VERSION;
+#else
+ TLS_ANY_VERSION;
+#endif // dtls
+ long minVersion = anyVersion;
+ long maxVersion = anyVersion;
+
+ switch (sslContext->sslConfiguration.protocol()) {
+ case QSsl::TlsV1_0:
+ minVersion = TLS1_VERSION;
+ maxVersion = TLS1_VERSION;
+ break;
+ case QSsl::TlsV1_1:
+ minVersion = TLS1_1_VERSION;
+ maxVersion = TLS1_1_VERSION;
+ break;
+ case QSsl::TlsV1_2:
+ minVersion = TLS1_2_VERSION;
+ maxVersion = TLS1_2_VERSION;
+ break;
+ case QSsl::TlsV1_3:
+#ifdef TLS1_3_VERSION
+ minVersion = TLS1_3_VERSION;
+ maxVersion = TLS1_3_VERSION;
+#else
+ // This protocol is not supported by OpenSSL 1.1 and we handle
+ // it as an error (see the code above).
+ Q_UNREACHABLE();
+#endif // TLS1_3_VERSION
+ break;
+ // Ranges:
+ case QSsl::TlsV1SslV3:
+ case QSsl::AnyProtocol:
+ case QSsl::SecureProtocols:
+ case QSsl::TlsV1_0OrLater:
+ minVersion = TLS1_VERSION;
+ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_1OrLater:
+ minVersion = TLS1_1_VERSION;
+ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_2OrLater:
+ minVersion = TLS1_2_VERSION;
+ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_0:
+ minVersion = DTLS1_VERSION;
+ maxVersion = DTLS1_VERSION;
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+ maxVersion = DTLS_MAX_VERSION;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+ maxVersion = DTLS1_2_VERSION;
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+ maxVersion = DTLS_MAX_VERSION;
+ break;
+ case QSsl::TlsV1_3OrLater:
+#ifdef TLS1_3_VERSION
+ minVersion = TLS1_3_VERSION;
+ maxVersion = 0;
+ break;
+#else
+ // This protocol is not supported by OpenSSL 1.1 and we handle
+ // it as an error (see the code above).
+ Q_UNREACHABLE();
+ break;
+#endif // TLS1_3_VERSION
+ case QSsl::SslV2:
+ case QSsl::SslV3:
+ // These protocols are not supported, and we handle
+ // them as an error (see the code above).
+ Q_UNREACHABLE();
+ break;
+ case QSsl::UnknownProtocol:
+ break;
+ }
+
+ if (minVersion != anyVersion
+ && !q_SSL_CTX_set_min_proto_version(sslContext->ctx, minVersion)) {
+ sslContext->errorStr = QSslSocket::tr("Error while setting the minimal protocol version");
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ if (maxVersion != anyVersion
+ && !q_SSL_CTX_set_max_proto_version(sslContext->ctx, maxVersion)) {
+ sslContext->errorStr = QSslSocket::tr("Error while setting the maximum protocol version");
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ // Enable bug workarounds.
+ long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+ // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
+ q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
+
+ auto filterCiphers = [](const QList<QSslCipher> &ciphers, bool selectTls13)
+ {
+ QByteArray cipherString;
+ bool first = true;
+
+ for (const QSslCipher &cipher : qAsConst(ciphers)) {
+ const bool isTls13Cipher = cipher.protocol() == QSsl::TlsV1_3 || cipher.protocol() == QSsl::TlsV1_3OrLater;
+ if (selectTls13 != isTls13Cipher)
+ continue;
+
+ if (first)
+ first = false;
+ else
+ cipherString.append(':');
+ cipherString.append(cipher.name().toLatin1());
+ }
+ return cipherString;
+ };
+
+ // Initialize ciphers
+ QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
+ if (ciphers.isEmpty())
+ ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers();
+
+ const QByteArray preTls13Ciphers = filterCiphers(ciphers, false);
+
+ if (preTls13Ciphers.size()) {
+ if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, preTls13Ciphers.data())) {
+ sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+ }
+
+ const QByteArray tls13Ciphers = filterCiphers(ciphers, true);
+#ifdef TLS1_3_VERSION
+ if (tls13Ciphers.size()) {
+ if (!q_SSL_CTX_set_ciphersuites(sslContext->ctx, tls13Ciphers.data())) {
+ sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+ }
+#endif // TLS1_3_VERSION
+ if (!preTls13Ciphers.size() && !tls13Ciphers.size()) {
+ sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QStringLiteral(""));
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ const QDateTime now = QDateTime::currentDateTimeUtc();
+
+ // Add all our CAs to this store.
+ const auto caCertificates = sslContext->sslConfiguration.caCertificates();
+ for (const QSslCertificate &caCertificate : caCertificates) {
+ // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
+ //
+ // If several CA certificates matching the name, key identifier, and
+ // serial number condition are available, only the first one will be
+ // examined. This may lead to unexpected results if the same CA
+ // certificate is available with different expiration dates. If a
+ // ``certificate expired'' verification error occurs, no other
+ // certificate will be searched. Make sure to not have expired
+ // certificates mixed with valid ones.
+ //
+ // See also: QSslSocketBackendPrivate::verify()
+ if (caCertificate.expiryDate() >= now) {
+ q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle());
+ }
+ }
+
+ if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
+ // tell OpenSSL the directories where to look up the root certs on demand
+ const QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
+ for (const QByteArray &unixDir : unixDirs)
+ q_SSL_CTX_load_verify_locations(sslContext->ctx, nullptr, unixDir.constData());
+ }
+
+ if (!sslContext->sslConfiguration.localCertificate().isNull()) {
+ // Require a private key as well.
+ if (sslContext->sslConfiguration.privateKey().isNull()) {
+ sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ // Load certificate
+ if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
+ sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
+ sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
+ } else {
+ // Load private key
+ sslContext->pkey = q_EVP_PKEY_new();
+ // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
+ // this lead to a memory leak. Now we use the *_set1_* functions which do not
+ // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
+ if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
+ q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
+ else if (configuration.d->privateKey.algorithm() == QSsl::Dsa)
+ q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
+#ifndef OPENSSL_NO_EC
+ else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
+ q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
+#endif
+ }
+
+ if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
+ sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+ if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
+ sslContext->pkey = nullptr; // Don't free the private key, it belongs to QSslKey
+
+ // Check if the certificate matches the private key.
+ if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
+ sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
+ // If we have any intermediate certificates then we need to add them to our chain
+ bool first = true;
+ for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) {
+ if (first) {
+ first = false;
+ continue;
+ }
+ q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
+ q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
+ }
+ }
+
+ // Initialize peer verification.
+ if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr);
+ } else {
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER,
+#if QT_CONFIG(dtls)
+ isDtls ? dtlscallbacks::q_X509DtlsCallback :
+#endif // dtls
+ q_X509Callback);
+ }
+
+#if QT_CONFIG(dtls)
+ if (mode == QSslSocket::SslServerMode && isDtls && configuration.dtlsCookieVerificationEnabled()) {
+ q_SSL_CTX_set_cookie_generate_cb(sslContext->ctx, dtlscallbacks::q_generate_cookie_callback);
+ q_SSL_CTX_set_cookie_verify_cb(sslContext->ctx, dtlscallbacks::q_verify_cookie_callback);
+ }
+#endif // dtls
+
+ // Set verification depth.
+ if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
+ q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
+
+ // set persisted session if the user set it
+ if (!configuration.sessionTicket().isEmpty())
+ sslContext->setSessionASN1(configuration.sessionTicket());
+
+ // Set temp DH params
+ 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->derData;
+ const char *ptr = params.constData();
+ DH *dh = q_d2i_DHparams(nullptr, reinterpret_cast<const unsigned char **>(&ptr),
+ params.length());
+ if (dh == nullptr)
+ 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_PSK
+ if (!client)
+ q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData());
+#endif // !OPENSSL_NO_PSK
+
+ const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
+ if (!qcurves.isEmpty()) {
+#ifdef OPENSSL_NO_EC
+ sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version with disabled elliptic curves"));
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+#else
+ // Set the curves to be used.
+ std::vector<int> curves;
+ curves.reserve(qcurves.size());
+ for (const auto &sslCurve : qcurves)
+ curves.push_back(sslCurve.id);
+ if (!q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_CURVES, long(curves.size()), &curves[0])) {
+ sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+#endif
+ }
+
+ applyBackendConfig(sslContext);
+}
+
#if QT_CONFIG(ocsp)
extern "C" int qt_OCSP_status_server_callback(SSL *ssl, void *); // Defined in qsslsocket_openssl.cpp.
#endif // ocsp
@@ -269,65 +681,55 @@ void QSslContext::applyBackendConfig(QSslContext *sslContext)
}
#endif // ocsp
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
- QSharedPointer<SSL_CONF_CTX> cctx(q_SSL_CONF_CTX_new(), &q_SSL_CONF_CTX_free);
- if (cctx) {
- q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx);
- q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE);
-
- for (auto i = conf.constBegin(); i != conf.constEnd(); ++i) {
- if (i.key() == "Qt-OCSP-response") // This never goes to SSL_CONF_cmd().
- continue;
-
- if (!i.value().canConvert(QMetaType::QByteArray)) {
- sslContext->errorCode = QSslError::UnspecifiedError;
- sslContext->errorStr = msgErrorSettingBackendConfig(
- QSslSocket::tr("Expecting QByteArray for %1").arg(
- QString::fromUtf8(i.key())));
- return;
- }
-
- const QByteArray &value = i.value().toByteArray();
- const int result = q_SSL_CONF_cmd(cctx.data(), i.key().constData(), value.constData());
- if (result == 2)
- continue;
+ QSharedPointer<SSL_CONF_CTX> cctx(q_SSL_CONF_CTX_new(), &q_SSL_CONF_CTX_free);
+ if (cctx) {
+ q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx);
+ q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE);
+
+ for (auto i = conf.constBegin(); i != conf.constEnd(); ++i) {
+ if (i.key() == "Qt-OCSP-response") // This never goes to SSL_CONF_cmd().
+ continue;
+ if (!i.value().canConvert(QMetaType::QByteArray)) {
sslContext->errorCode = QSslError::UnspecifiedError;
- switch (result) {
- case 0:
- sslContext->errorStr = msgErrorSettingBackendConfig(
- QSslSocket::tr("An error occurred attempting to set %1 to %2").arg(
- QString::fromUtf8(i.key()), QString::fromUtf8(value)));
- return;
- case 1:
- sslContext->errorStr = msgErrorSettingBackendConfig(
- QSslSocket::tr("Wrong value for %1 (%2)").arg(
- QString::fromUtf8(i.key()), QString::fromUtf8(value)));
- return;
- default:
- sslContext->errorStr = msgErrorSettingBackendConfig(
- QSslSocket::tr("Unrecognized command %1 = %2").arg(
- QString::fromUtf8(i.key()), QString::fromUtf8(value)));
- return;
- }
+ sslContext->errorStr = msgErrorSettingBackendConfig(
+ QSslSocket::tr("Expecting QByteArray for %1").arg(
+ QString::fromUtf8(i.key())));
+ return;
}
- if (q_SSL_CONF_CTX_finish(cctx.data()) == 0) {
- sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_finish() failed"));
- sslContext->errorCode = QSslError::UnspecifiedError;
+ const QByteArray &value = i.value().toByteArray();
+ const int result = q_SSL_CONF_cmd(cctx.data(), i.key().constData(), value.constData());
+ if (result == 2)
+ continue;
+
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ switch (result) {
+ case 0:
+ sslContext->errorStr = msgErrorSettingBackendConfig(
+ QSslSocket::tr("An error occurred attempting to set %1 to %2").arg(
+ QString::fromUtf8(i.key()), QString::fromUtf8(value)));
+ return;
+ case 1:
+ sslContext->errorStr = msgErrorSettingBackendConfig(
+ QSslSocket::tr("Wrong value for %1 (%2)").arg(
+ QString::fromUtf8(i.key()), QString::fromUtf8(value)));
+ return;
+ default:
+ sslContext->errorStr = msgErrorSettingBackendConfig(
+ QSslSocket::tr("Unrecognized command %1 = %2").arg(
+ QString::fromUtf8(i.key()), QString::fromUtf8(value)));
+ return;
}
- } else {
- sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_CTX_new() failed"));
- sslContext->errorCode = QSslError::UnspecifiedError;
- }
- } else
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
- {
- // specific algorithms requested, but not possible to set
+ }
+
+ if (q_SSL_CONF_CTX_finish(cctx.data()) == 0) {
+ sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_finish() failed"));
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ }
+ } else {
+ sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_CTX_new() failed"));
sslContext->errorCode = QSslError::UnspecifiedError;
- sslContext->errorStr = msgErrorSettingBackendConfig(
- QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
}
}
diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp
deleted file mode 100644
index db023b7331..0000000000
--- a/src/network/ssl/qsslcontext_openssl11.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2014 Governikus GmbH & Co. KG.
-** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
-** Contact: https://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 <QtNetwork/qsslsocket.h>
-#include <QtNetwork/qssldiffiehellmanparameters.h>
-
-#include "private/qssl_p.h"
-#include "private/qsslcontext_openssl_p.h"
-#include "private/qsslsocket_p.h"
-#include "private/qsslsocket_openssl_p.h"
-#include "private/qsslsocket_openssl_symbols_p.h"
-#include "private/qssldiffiehellmanparameters_p.h"
-
-#include <vector>
-
-QT_BEGIN_NAMESPACE
-
-// defined in qsslsocket_openssl.cpp:
-extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
-extern QString getErrorsFromOpenSsl();
-
-#if QT_CONFIG(dtls)
-// defined in qdtls_openssl.cpp:
-namespace dtlscallbacks
-{
-extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx);
-extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
- unsigned *cookieLength);
-extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
- unsigned cookieLength);
-}
-#endif // dtls
-
-static inline QString msgErrorSettingEllipticCurves(const QString &why)
-{
- return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
-}
-
-// Defined in qsslsocket.cpp
-QList<QSslCipher> q_getDefaultDtlsCiphers();
-
-// static
-void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
-{
- sslContext->sslConfiguration = configuration;
- sslContext->errorCode = QSslError::NoError;
-
- bool client = (mode == QSslSocket::SslClientMode);
-
- bool reinitialized = false;
- bool unsupportedProtocol = false;
- bool isDtls = false;
-init_context:
- if (sslContext->sslConfiguration.protocol() == QSsl::SslV2) {
- // SSL 2 is no longer supported, but chosen deliberately -> error
- sslContext->ctx = nullptr;
- unsupportedProtocol = true;
- } else if (sslContext->sslConfiguration.protocol() == QSsl::SslV3) {
- // SSL 3 is no longer supported, but chosen deliberately -> error
- sslContext->ctx = nullptr;
- unsupportedProtocol = true;
- } else {
- switch (sslContext->sslConfiguration.protocol()) {
- case QSsl::DtlsV1_0:
- case QSsl::DtlsV1_0OrLater:
- case QSsl::DtlsV1_2:
- case QSsl::DtlsV1_2OrLater:
-#if QT_CONFIG(dtls)
- isDtls = true;
- sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method());
-#else // dtls
- sslContext->ctx = nullptr;
- unsupportedProtocol = true;
- qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled");
-
-#endif // dtls
- break;
- case QSsl::TlsV1_3:
- case QSsl::TlsV1_3OrLater:
-#if !defined(TLS1_3_VERSION)
- qCWarning(lcSsl, "TLS 1.3 is not supported");
- sslContext->ctx = nullptr;
- unsupportedProtocol = true;
- break;
-#endif // TLS1_3_VERSION
- default:
- // The ssl options will actually control the supported methods
- sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method());
- }
- }
-
- if (!sslContext->ctx) {
- // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
- // by re-initializing the library.
- if (!reinitialized) {
- reinitialized = true;
- if (q_OPENSSL_init_ssl(0, nullptr) == 1)
- goto init_context;
- }
-
- sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
- unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
- );
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- const long anyVersion =
-#if QT_CONFIG(dtls)
- isDtls ? DTLS_ANY_VERSION : TLS_ANY_VERSION;
-#else
- TLS_ANY_VERSION;
-#endif // dtls
- long minVersion = anyVersion;
- long maxVersion = anyVersion;
-
- switch (sslContext->sslConfiguration.protocol()) {
- case QSsl::TlsV1_0:
- minVersion = TLS1_VERSION;
- maxVersion = TLS1_VERSION;
- break;
- case QSsl::TlsV1_1:
- minVersion = TLS1_1_VERSION;
- maxVersion = TLS1_1_VERSION;
- break;
- case QSsl::TlsV1_2:
- minVersion = TLS1_2_VERSION;
- maxVersion = TLS1_2_VERSION;
- break;
- case QSsl::TlsV1_3:
-#ifdef TLS1_3_VERSION
- minVersion = TLS1_3_VERSION;
- maxVersion = TLS1_3_VERSION;
-#else
- // This protocol is not supported by OpenSSL 1.1 and we handle
- // it as an error (see the code above).
- Q_UNREACHABLE();
-#endif // TLS1_3_VERSION
- break;
- // Ranges:
- case QSsl::TlsV1SslV3:
- case QSsl::AnyProtocol:
- case QSsl::SecureProtocols:
- case QSsl::TlsV1_0OrLater:
- minVersion = TLS1_VERSION;
- maxVersion = 0;
- break;
- case QSsl::TlsV1_1OrLater:
- minVersion = TLS1_1_VERSION;
- maxVersion = 0;
- break;
- case QSsl::TlsV1_2OrLater:
- minVersion = TLS1_2_VERSION;
- maxVersion = 0;
- break;
- case QSsl::DtlsV1_0:
- minVersion = DTLS1_VERSION;
- maxVersion = DTLS1_VERSION;
- break;
- case QSsl::DtlsV1_0OrLater:
- minVersion = DTLS1_VERSION;
- maxVersion = DTLS_MAX_VERSION;
- break;
- case QSsl::DtlsV1_2:
- minVersion = DTLS1_2_VERSION;
- maxVersion = DTLS1_2_VERSION;
- break;
- case QSsl::DtlsV1_2OrLater:
- minVersion = DTLS1_2_VERSION;
- maxVersion = DTLS_MAX_VERSION;
- break;
- case QSsl::TlsV1_3OrLater:
-#ifdef TLS1_3_VERSION
- minVersion = TLS1_3_VERSION;
- maxVersion = 0;
- break;
-#else
- // This protocol is not supported by OpenSSL 1.1 and we handle
- // it as an error (see the code above).
- Q_UNREACHABLE();
- break;
-#endif // TLS1_3_VERSION
- case QSsl::SslV2:
- case QSsl::SslV3:
- // These protocols are not supported, and we handle
- // them as an error (see the code above).
- Q_UNREACHABLE();
- break;
- case QSsl::UnknownProtocol:
- break;
- }
-
- if (minVersion != anyVersion
- && !q_SSL_CTX_set_min_proto_version(sslContext->ctx, minVersion)) {
- sslContext->errorStr = QSslSocket::tr("Error while setting the minimal protocol version");
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- if (maxVersion != anyVersion
- && !q_SSL_CTX_set_max_proto_version(sslContext->ctx, maxVersion)) {
- sslContext->errorStr = QSslSocket::tr("Error while setting the maximum protocol version");
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- // Enable bug workarounds.
- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
- q_SSL_CTX_set_options(sslContext->ctx, options);
-
- // Tell OpenSSL to release memory early
- // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
- q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
-
- auto filterCiphers = [](const QList<QSslCipher> &ciphers, bool selectTls13)
- {
- QByteArray cipherString;
- bool first = true;
-
- for (const QSslCipher &cipher : qAsConst(ciphers)) {
- const bool isTls13Cipher = cipher.protocol() == QSsl::TlsV1_3 || cipher.protocol() == QSsl::TlsV1_3OrLater;
- if (selectTls13 != isTls13Cipher)
- continue;
-
- if (first)
- first = false;
- else
- cipherString.append(':');
- cipherString.append(cipher.name().toLatin1());
- }
- return cipherString;
- };
-
- // Initialize ciphers
- QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
- if (ciphers.isEmpty())
- ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers();
-
- const QByteArray preTls13Ciphers = filterCiphers(ciphers, false);
-
- if (preTls13Ciphers.size()) {
- if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, preTls13Ciphers.data())) {
- sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
- }
-
- const QByteArray tls13Ciphers = filterCiphers(ciphers, true);
-#ifdef TLS1_3_VERSION
- if (tls13Ciphers.size()) {
- if (!q_SSL_CTX_set_ciphersuites(sslContext->ctx, tls13Ciphers.data())) {
- sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
- }
-#endif // TLS1_3_VERSION
- if (!preTls13Ciphers.size() && !tls13Ciphers.size()) {
- sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QStringLiteral(""));
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- const QDateTime now = QDateTime::currentDateTimeUtc();
-
- // Add all our CAs to this store.
- const auto caCertificates = sslContext->sslConfiguration.caCertificates();
- for (const QSslCertificate &caCertificate : caCertificates) {
- // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
- //
- // If several CA certificates matching the name, key identifier, and
- // serial number condition are available, only the first one will be
- // examined. This may lead to unexpected results if the same CA
- // certificate is available with different expiration dates. If a
- // ``certificate expired'' verification error occurs, no other
- // certificate will be searched. Make sure to not have expired
- // certificates mixed with valid ones.
- //
- // See also: QSslSocketBackendPrivate::verify()
- if (caCertificate.expiryDate() >= now) {
- q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle());
- }
- }
-
- if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
- // tell OpenSSL the directories where to look up the root certs on demand
- const QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
- for (const QByteArray &unixDir : unixDirs)
- q_SSL_CTX_load_verify_locations(sslContext->ctx, nullptr, unixDir.constData());
- }
-
- if (!sslContext->sslConfiguration.localCertificate().isNull()) {
- // Require a private key as well.
- if (sslContext->sslConfiguration.privateKey().isNull()) {
- sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- // Load certificate
- if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
- sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
- sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
- } else {
- // Load private key
- sslContext->pkey = q_EVP_PKEY_new();
- // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
- // this lead to a memory leak. Now we use the *_set1_* functions which do not
- // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
- if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
- q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
- else if (configuration.d->privateKey.algorithm() == QSsl::Dsa)
- q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
-#ifndef OPENSSL_NO_EC
- else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
- q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
-#endif
- }
-
- if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
- sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
- if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
- sslContext->pkey = nullptr; // Don't free the private key, it belongs to QSslKey
-
- // Check if the certificate matches the private key.
- if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
- sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- // If we have any intermediate certificates then we need to add them to our chain
- bool first = true;
- for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) {
- if (first) {
- first = false;
- continue;
- }
- q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
- q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
- }
- }
-
- // Initialize peer verification.
- if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr);
- } else {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER,
-#if QT_CONFIG(dtls)
- isDtls ? dtlscallbacks::q_X509DtlsCallback :
-#endif // dtls
- q_X509Callback);
- }
-
-#if QT_CONFIG(dtls)
- if (mode == QSslSocket::SslServerMode && isDtls && configuration.dtlsCookieVerificationEnabled()) {
- q_SSL_CTX_set_cookie_generate_cb(sslContext->ctx, dtlscallbacks::q_generate_cookie_callback);
- q_SSL_CTX_set_cookie_verify_cb(sslContext->ctx, dtlscallbacks::q_verify_cookie_callback);
- }
-#endif // dtls
-
- // Set verification depth.
- if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
- q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
-
- // set persisted session if the user set it
- if (!configuration.sessionTicket().isEmpty())
- sslContext->setSessionASN1(configuration.sessionTicket());
-
- // Set temp DH params
- 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->derData;
- const char *ptr = params.constData();
- DH *dh = q_d2i_DHparams(nullptr, reinterpret_cast<const unsigned char **>(&ptr),
- params.length());
- if (dh == nullptr)
- 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_PSK
- if (!client)
- q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData());
-#endif // !OPENSSL_NO_PSK
-
- const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
- if (!qcurves.isEmpty()) {
-#ifdef OPENSSL_NO_EC
- sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version with disabled elliptic curves"));
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
-#else
- // Set the curves to be used.
- std::vector<int> curves;
- curves.reserve(qcurves.size());
- for (const auto &sslCurve : qcurves)
- curves.push_back(sslCurve.id);
- if (!q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_CURVES, long(curves.size()), &curves[0])) {
- sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-#endif
- }
-
- applyBackendConfig(sslContext);
-}
-
-QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslcontext_openssl_p.h b/src/network/ssl/qsslcontext_openssl_p.h
index 1fa27279c7..70cb97aad8 100644
--- a/src/network/ssl/qsslcontext_openssl_p.h
+++ b/src/network/ssl/qsslcontext_openssl_p.h
@@ -86,7 +86,7 @@ public:
void setSessionASN1(const QByteArray &sessionASN1);
int sessionTicketLifeTimeHint() const;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+#ifndef OPENSSL_NO_NEXTPROTONEG
// must be public because we want to use it from an OpenSSL callback
struct NPNContext {
NPNContext() : data(nullptr),
@@ -98,7 +98,7 @@ public:
QSslConfiguration::NextProtocolNegotiationStatus status;
};
NPNContext npnContext() const;
-#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
protected:
QSslContext();
@@ -118,10 +118,10 @@ private:
QSslError::SslError errorCode;
QString errorStr;
QSslConfiguration sslConfiguration;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+#ifndef OPENSSL_NO_NEXTPROTONEG
QByteArray m_supportedNPNVersions;
NPNContext m_npnContext;
-#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
};
#endif // QT_NO_SSL
diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp
deleted file mode 100644
index 956c5c32ec..0000000000
--- a/src/network/ssl/qsslcontext_opensslpre11.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2014 Governikus GmbH & Co. KG.
-** Contact: https://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 <QtNetwork/qsslsocket.h>
-#include <QtNetwork/qssldiffiehellmanparameters.h>
-
-#include "private/qssl_p.h"
-#include "private/qsslcontext_openssl_p.h"
-#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
-
-// defined in qsslsocket_openssl.cpp:
-extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
-extern QString getErrorsFromOpenSsl();
-
-#if QT_CONFIG(dtls)
-// defined in qdtls_openssl.cpp:
-namespace dtlscallbacks
-{
-extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx);
-extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
- unsigned *cookieLength);
-extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
- unsigned cookieLength);
-}
-#endif // dtls
-
-static inline QString msgErrorSettingEllipticCurves(const QString &why)
-{
- return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
-}
-
-// Defined in qsslsocket.cpp
-QList<QSslCipher> q_getDefaultDtlsCiphers();
-
-// static
-void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
-{
- sslContext->sslConfiguration = configuration;
- sslContext->errorCode = QSslError::NoError;
-
- bool client = (mode == QSslSocket::SslClientMode);
- bool reinitialized = false;
- bool unsupportedProtocol = false;
- bool isDtls = false;
-init_context:
- switch (sslContext->sslConfiguration.protocol()) {
-#if QT_CONFIG(dtls)
- case QSsl::DtlsV1_0:
- isDtls = true;
- sslContext->ctx = q_SSL_CTX_new(client ? q_DTLSv1_client_method() : q_DTLSv1_server_method());
- break;
- case QSsl::DtlsV1_2:
- case QSsl::DtlsV1_2OrLater:
- // OpenSSL 1.0.2 and below will probably never receive TLS 1.3, so
- // technically 1.2 or later is 1.2 and will stay so.
- isDtls = true;
- sslContext->ctx = q_SSL_CTX_new(client ? q_DTLSv1_2_client_method() : q_DTLSv1_2_server_method());
- break;
- case QSsl::DtlsV1_0OrLater:
- isDtls = true;
- sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method());
- break;
-#else // dtls
- case QSsl::DtlsV1_0:
- case QSsl::DtlsV1_0OrLater:
- case QSsl::DtlsV1_2:
- case QSsl::DtlsV1_2OrLater:
- sslContext->ctx = nullptr;
- unsupportedProtocol = true;
- qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled");
- break;
-#endif // dtls
- case QSsl::SslV2:
- case QSsl::SslV3:
- // We don't support SSLv2 / SSLv3.
- sslContext->ctx = 0;
- unsupportedProtocol = true;
- break;
- case QSsl::SecureProtocols:
- // SSLv2 and SSLv3 will be disabled by SSL options
- // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32.
- case QSsl::AnyProtocol:
- default:
- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
- break;
- case QSsl::TlsV1SslV3:
- case QSsl::TlsV1_0:
- sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
- break;
- case QSsl::TlsV1_1:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
-#else
- // TLS 1.1 not supported by the system, but chosen deliberately -> error
- sslContext->ctx = 0;
- unsupportedProtocol = true;
-#endif
- break;
- case QSsl::TlsV1_2:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
-#else
- // TLS 1.2 not supported by the system, but chosen deliberately -> error
- sslContext->ctx = 0;
- unsupportedProtocol = true;
-#endif
- break;
- case QSsl::TlsV1_0OrLater:
- // Specific protocols will be specified via SSL options.
- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
- break;
- case QSsl::TlsV1_1OrLater:
- case QSsl::TlsV1_2OrLater:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- // Specific protocols will be specified via SSL options.
- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
-#else
- // TLS 1.1/1.2 not supported by the system, but chosen deliberately -> error
- sslContext->ctx = 0;
- unsupportedProtocol = true;
-#endif
- break;
- case QSsl::TlsV1_3:
- case QSsl::TlsV1_3OrLater:
- // TLS 1.3 is not supported by the system, but chosen deliberately -> error
- sslContext->ctx = nullptr;
- unsupportedProtocol = true;
- break;
- }
-
- if (!client && isDtls && configuration.peerVerifyMode() != QSslSocket::VerifyNone) {
- sslContext->errorStr = QSslSocket::tr("DTLS server requires a 'VerifyNone' mode with your version of OpenSSL");
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- if (!sslContext->ctx) {
- // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
- // by re-initializing the library.
- if (!reinitialized) {
- reinitialized = true;
- if (q_SSL_library_init() == 1)
- goto init_context;
- }
-
- sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
- unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
- );
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- // Enable bug workarounds.
- // DTLSTODO: check this setupOpenSslOptions ...
- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
- q_SSL_CTX_set_options(sslContext->ctx, options);
-
- // Tell OpenSSL to release memory early
- // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
- q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
-
- // Initialize ciphers
- QByteArray cipherString;
- bool first = true;
- QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
- if (ciphers.isEmpty())
- ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers();
- for (const QSslCipher &cipher : qAsConst(ciphers)) {
- if (first)
- first = false;
- else
- cipherString.append(':');
- cipherString.append(cipher.name().toLatin1());
- }
-
- if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) {
- sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- const QDateTime now = QDateTime::currentDateTimeUtc();
-
- // Add all our CAs to this store.
- const auto caCertificates = sslContext->sslConfiguration.caCertificates();
- for (const QSslCertificate &caCertificate : caCertificates) {
- // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
- //
- // If several CA certificates matching the name, key identifier, and
- // serial number condition are available, only the first one will be
- // examined. This may lead to unexpected results if the same CA
- // certificate is available with different expiration dates. If a
- // ``certificate expired'' verification error occurs, no other
- // certificate will be searched. Make sure to not have expired
- // certificates mixed with valid ones.
- //
- // See also: QSslSocketBackendPrivate::verify()
- if (caCertificate.expiryDate() >= now) {
- q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle());
- }
- }
-
- if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
- // tell OpenSSL the directories where to look up the root certs on demand
- const QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
- for (const QByteArray &unixDir : unixDirs)
- q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDir.constData());
- }
-
- if (!sslContext->sslConfiguration.localCertificate().isNull()) {
- // Require a private key as well.
- if (sslContext->sslConfiguration.privateKey().isNull()) {
- sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- // Load certificate
- if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
- sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
- sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
- } else {
- // Load private key
- sslContext->pkey = q_EVP_PKEY_new();
- // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
- // this lead to a memory leak. Now we use the *_set1_* functions which do not
- // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
- if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
- q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
- else if (configuration.d->privateKey.algorithm() == QSsl::Dsa)
- q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
-#ifndef OPENSSL_NO_EC
- else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
- q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
-#endif
- }
-
- if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
- sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
- if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
- sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey
-
- // Check if the certificate matches the private key.
- if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
- sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
-
- // If we have any intermediate certificates then we need to add them to our chain
- bool first = true;
- for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) {
- if (first) {
- first = false;
- continue;
- }
- q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
- q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
- }
- }
-
- // Initialize peer verification.
- if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
- } else {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER,
-#if QT_CONFIG(dtls)
- isDtls ? dtlscallbacks::q_X509DtlsCallback :
-#endif // dtls
- q_X509Callback);
- }
-
-#if QT_CONFIG(dtls)
- if (mode == QSslSocket::SslServerMode && isDtls && configuration.dtlsCookieVerificationEnabled()) {
- q_SSL_CTX_set_cookie_generate_cb(sslContext->ctx, dtlscallbacks::q_generate_cookie_callback);
- q_SSL_CTX_set_cookie_verify_cb(sslContext->ctx, CookieVerifyCallback(dtlscallbacks::q_verify_cookie_callback));
- }
-#endif // dtls
-
- // Set verification depth.
- if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
- q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
-
- // set persisted session if the user set it
- if (!configuration.sessionTicket().isEmpty())
- sslContext->setSessionASN1(configuration.sessionTicket());
-
- // Set temp DH params
- 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->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
- if (q_SSLeay() >= 0x10002000L) {
- q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
- } else
-#endif
- {
- // Set temp ECDH params
- EC_KEY *ecdh = 0;
- ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
- q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh);
- q_EC_KEY_free(ecdh);
- }
-#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)
- // Set the curves to be used
- if (q_SSLeay() >= 0x10002000L) {
- // SSL_CTX_ctrl wants a non-const pointer as last argument,
- // but let's avoid a copy into a temporary array
- if (!q_SSL_CTX_ctrl(sslContext->ctx,
- SSL_CTRL_SET_CURVES,
- qcurves.size(),
- const_cast<int *>(reinterpret_cast<const int *>(qcurves.data())))) {
- sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
- } else
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
- {
- // specific curves requested, but not possible to set -> error
- sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
- sslContext->errorCode = QSslError::UnspecifiedError;
- return;
- }
- }
-
- applyBackendConfig(sslContext);
-}
-
-QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslellipticcurve_openssl.cpp b/src/network/ssl/qsslellipticcurve_openssl.cpp
index b5e38ada53..bb7ad66bd2 100644
--- a/src/network/ssl/qsslellipticcurve_openssl.cpp
+++ b/src/network/ssl/qsslellipticcurve_openssl.cpp
@@ -83,10 +83,8 @@ QSslEllipticCurve QSslEllipticCurve::fromShortName(const QString &name)
const QByteArray curveNameLatin1 = name.toLatin1();
int nid = q_OBJ_sn2nid(curveNameLatin1.data());
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- if (nid == 0 && QSslSocket::sslLibraryVersionNumber() >= 0x10002000L)
+ if (nid == 0)
nid = q_EC_curve_nist2nid(curveNameLatin1.data());
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
result.id = nid;
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 888058df22..43cb8c6de8 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -93,11 +93,7 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
if (pkey == nullptr)
return false;
-#if QT_CONFIG(opensslv11)
const int keyType = q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey));
-#else
- const int keyType = pkey->type;
-#endif
if (keyType == EVP_PKEY_RSA) {
isNull = false;
algorithm = QSsl::Rsa;
@@ -350,33 +346,17 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data,
QByteArray output;
output.resize(data.size() + EVP_MAX_BLOCK_LENGTH);
-#if QT_CONFIG(opensslv11)
EVP_CIPHER_CTX *ctx = q_EVP_CIPHER_CTX_new();
q_EVP_CIPHER_CTX_reset(ctx);
-#else
- EVP_CIPHER_CTX evpCipherContext;
- EVP_CIPHER_CTX *ctx = &evpCipherContext;
- q_EVP_CIPHER_CTX_init(ctx);
-#endif
-
q_EVP_CipherInit(ctx, type, nullptr, nullptr, enc);
q_EVP_CIPHER_CTX_set_key_length(ctx, key.size());
if (cipher == QSslKeyPrivate::Rc2Cbc)
q_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), nullptr);
-#if QT_CONFIG(opensslv11)
- // EVP_CipherInit in 1.1 resets the context thus making the calls above useless.
- // We call EVP_CipherInit_ex instead.
q_EVP_CipherInit_ex(ctx, nullptr, nullptr,
reinterpret_cast<const unsigned char *>(key.constData()),
reinterpret_cast<const unsigned char *>(iv.constData()),
enc);
-#else
- q_EVP_CipherInit(ctx, NULL,
- reinterpret_cast<const unsigned char *>(key.constData()),
- reinterpret_cast<const unsigned char *>(iv.constData()), enc);
-#endif // opensslv11
-
q_EVP_CipherUpdate(ctx,
reinterpret_cast<unsigned char *>(output.data()), &len,
reinterpret_cast<const unsigned char *>(data.constData()), data.size());
@@ -384,12 +364,8 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data,
reinterpret_cast<unsigned char *>(output.data()) + len, &i);
len += i;
-#if QT_CONFIG(opensslv11)
q_EVP_CIPHER_CTX_reset(ctx);
q_EVP_CIPHER_CTX_free(ctx);
-#else
- q_EVP_CIPHER_CTX_cleanup(ctx);
-#endif
return output.left(len);
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index d4bad1b1a5..8cd0724d83 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -66,15 +66,12 @@
#include "qsslpresharedkeyauthenticator.h"
#include "qsslpresharedkeyauthenticator_p.h"
#include "qocspresponse_p.h"
+#include "qsslkey.h"
#ifdef Q_OS_WIN
#include "qwindowscarootfetcher_p.h"
#endif
-#if !QT_CONFIG(opensslv11)
-#include <openssl/x509_vfy.h>
-#endif
-
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
@@ -87,6 +84,8 @@
#include <QtCore/qurl.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qscopedvaluerollback.h>
+#include <QtCore/qlibrary.h>
+#include <QtCore/qoperatingsystemversion.h>
#if QT_CONFIG(ocsp)
#include "qocsp_p.h"
@@ -98,13 +97,12 @@
QT_BEGIN_NAMESPACE
+Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex)
+
bool QSslSocketPrivate::s_libraryLoaded = false;
bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
bool QSslSocketPrivate::s_loadRootCertsOnDemand = false;
-
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
int QSslSocketBackendPrivate::s_indexForSSLExtraData = -1;
-#endif
QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
{
@@ -122,7 +120,7 @@ QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
extern "C" {
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+#ifndef OPENSSL_NO_PSK
static unsigned int q_ssl_psk_client_callback(SSL *ssl,
const char *hint,
char *identity, unsigned int max_identity_len,
@@ -143,7 +141,6 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
}
#ifdef TLS1_3_VERSION
-#ifndef OPENSSL_NO_PSK
static unsigned int q_ssl_psk_restore_client(SSL *ssl,
const char *hint,
char *identity, unsigned int max_identity_len,
@@ -164,7 +161,6 @@ static unsigned int q_ssl_psk_restore_client(SSL *ssl,
return 0;
}
-#endif // !OPENSSL_NO_PSK
static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id,
size_t *idlen, SSL_SESSION **sess)
@@ -175,7 +171,6 @@ static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsi
Q_UNUSED(idlen);
Q_UNUSED(sess);
-#ifndef OPENSSL_NO_PSK
#ifdef QT_DEBUG
QSslSocketBackendPrivate *d = reinterpret_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
Q_ASSERT(d);
@@ -184,13 +179,12 @@ static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsi
// Temporarily rebind the psk because it will be called next. The function will restore it.
q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client);
-#endif
return 1; // need to return 1 or else "the connection setup fails."
}
#endif // TLS1_3_VERSION
-#endif
+#endif // !OPENSSL_NO_PSK
#if QT_CONFIG(ocsp)
@@ -407,13 +401,8 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx)
ErrorListPtr errors = nullptr;
// Error list is attached to either 'SSL' or 'X509_STORE'.
- if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) { // We try store first:
-#if QT_CONFIG(opensslv11)
+ if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) // We try store first:
errors = ErrorListPtr(q_X509_STORE_get_ex_data(store, 0));
-#else
- errors = ErrorListPtr(q_CRYPTO_get_ex_data(&store->ex_data, 0));
-#endif // opensslv11
- }
if (!errors) {
// Not found on store? Try SSL and its external data then. According to the OpenSSL's
@@ -476,17 +465,12 @@ long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, Q
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
else if (protocol == QSsl::TlsV1_0OrLater)
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- // Choosing Tlsv1_1OrLater or TlsV1_2OrLater on OpenSSL < 1.0.1
- // will cause an error in QSslContext::fromConfiguration, meaning
- // we will never get here.
else if (protocol == QSsl::TlsV1_1OrLater)
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1;
else if (protocol == QSsl::TlsV1_2OrLater)
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1;
else if (protocol == QSsl::TlsV1_3OrLater)
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2;
-#endif
else
options = SSL_OP_ALL;
@@ -590,15 +574,13 @@ bool QSslSocketBackendPrivate::initSslContext()
q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+#ifndef OPENSSL_NO_PSK
// Set the client callback for PSK
- if (QSslSocket::sslLibraryVersionNumber() >= 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
+ 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);
+
#if OPENSSL_VERSION_NUMBER >= 0x10101006L
// Set the client callback for TLSv1.3 PSK
if (mode == QSslSocket::SslClientMode
@@ -607,6 +589,9 @@ bool QSslSocketBackendPrivate::initSslContext()
}
#endif // openssl version >= 0x10101006L
+#endif // OPENSSL_NO_PSK
+
+
#if QT_CONFIG(ocsp)
if (configuration.ocspStaplingEnabled) {
if (mode == QSslSocket::SslServerMode) {
@@ -673,10 +658,43 @@ bool QSslSocketPrivate::supportsSsl()
/*!
\internal
+ Returns the version number of the SSL library in use. Note that
+ this is the version of the library in use at run-time, not compile
+ time.
+*/
+long QSslSocketPrivate::sslLibraryVersionNumber()
+{
+ if (!supportsSsl())
+ return 0;
+
+ return q_OpenSSL_version_num();
+}
+
+/*!
+ \internal
+
+ Returns the version string of the SSL library in use. Note that
+ this is the version of the library in use at run-time, not compile
+ time. If no SSL support is available then this will return an empty value.
+*/
+QString QSslSocketPrivate::sslLibraryVersionString()
+{
+ if (!supportsSsl())
+ return QString();
+
+ const char *versionString = q_OpenSSL_version(OPENSSL_VERSION);
+ if (!versionString)
+ return QString();
+
+ return QString::fromLatin1(versionString);
+}
+
+/*!
+ \internal
+
Declared static in QSslSocketPrivate, makes sure the SSL libraries have
been initialized.
*/
-
void QSslSocketPrivate::ensureInitialized()
{
if (!supportsSsl())
@@ -685,11 +703,23 @@ void QSslSocketPrivate::ensureInitialized()
ensureCiphersAndCertsLoaded();
}
+/*!
+ \internal
+
+ Returns the version number of the SSL library in use at compile
+ time.
+*/
long QSslSocketPrivate::sslLibraryBuildVersionNumber()
{
return OPENSSL_VERSION_NUMBER;
}
+/*!
+ \internal
+
+ Returns the version string of the SSL library in use at compile
+ time.
+*/
QString QSslSocketPrivate::sslLibraryBuildVersionString()
{
// Using QStringLiteral to store the version string as unicode and
@@ -706,11 +736,7 @@ QString QSslSocketPrivate::sslLibraryBuildVersionString()
*/
void QSslSocketPrivate::resetDefaultCiphers()
{
-#if QT_CONFIG(opensslv11)
SSL_CTX *myCtx = q_SSL_CTX_new(q_TLS_client_method());
-#else
- SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method());
-#endif
// Note, we assert, not just silently return/bail out early:
// this should never happen and problems with OpenSSL's initialization
// must be caught before this (see supportsSsl()).
@@ -1737,6 +1763,174 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const
return QSsl::UnknownProtocol;
}
+
+void QSslSocketBackendPrivate::continueHandshake()
+{
+ Q_Q(QSslSocket);
+ // if we have a max read buffer size, reset the plain socket's to match
+ if (readBufferMaxSize)
+ plainSocket->setReadBufferSize(readBufferMaxSize);
+
+ if (q_SSL_session_reused(ssl))
+ configuration.peerSessionShared = true;
+
+#ifdef QT_DECRYPT_SSL_TRAFFIC
+ if (q_SSL_get_session(ssl)) {
+ size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), 0, 0);
+ size_t client_random_len = q_SSL_get_client_random(ssl, 0, 0);
+ QByteArray masterKey(int(master_key_len), 0); // Will not overflow
+ QByteArray clientRandom(int(client_random_len), 0); // Will not overflow
+
+ q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
+ reinterpret_cast<unsigned char*>(masterKey.data()),
+ masterKey.size());
+ q_SSL_get_client_random(ssl, reinterpret_cast<unsigned char *>(clientRandom.data()),
+ clientRandom.size());
+
+ QByteArray debugLineClientRandom("CLIENT_RANDOM ");
+ debugLineClientRandom.append(clientRandom.toHex().toUpper());
+ debugLineClientRandom.append(" ");
+ debugLineClientRandom.append(masterKey.toHex().toUpper());
+ debugLineClientRandom.append("\n");
+
+ QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
+ QFile file(sslKeyFile);
+ if (!file.open(QIODevice::Append))
+ qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
+ if (!file.write(debugLineClientRandom))
+ qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
+ file.close();
+ } else {
+ qCWarning(lcSsl, "could not decrypt SSL traffic");
+ }
+#endif
+
+ // Cache this SSL session inside the QSslContext
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
+ if (!sslContextPointer->cacheSession(ssl)) {
+ sslContextPointer.clear(); // we could not cache the session
+ } else {
+ // Cache the session for permanent usage as well
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
+ if (!sslContextPointer->sessionASN1().isEmpty())
+ configuration.sslSession = sslContextPointer->sessionASN1();
+ configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
+ }
+ }
+ }
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+
+ configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
+ if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
+ // we could not agree -> be conservative and use HTTP/1.1
+ configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
+ } else {
+ const unsigned char *proto = nullptr;
+ unsigned int proto_len = 0;
+
+ 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 ...
+ q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
+ }
+
+ if (proto_len)
+ configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
+ else
+ configuration.nextNegotiatedProtocol.clear();
+ }
+#endif // !defined(OPENSSL_NO_NEXTPROTONEG)
+
+ if (mode == QSslSocket::SslClientMode) {
+ EVP_PKEY *key;
+ if (q_SSL_get_server_tmp_key(ssl, &key))
+ configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
+ }
+
+ connectionEncrypted = true;
+ emit q->encrypted();
+ if (autoStartHandshake && pendingClose) {
+ pendingClose = false;
+ q->disconnectFromHost();
+ }
+}
+
+bool QSslSocketPrivate::ensureLibraryLoaded()
+{
+ if (!q_resolveOpenSslSymbols())
+ return false;
+
+ const QMutexLocker locker(qt_opensslInitMutex);
+
+ if (!s_libraryLoaded) {
+ // Initialize OpenSSL.
+ if (q_OPENSSL_init_ssl(0, nullptr) != 1)
+ return false;
+ q_SSL_load_error_strings();
+ q_OpenSSL_add_all_algorithms();
+
+ QSslSocketBackendPrivate::s_indexForSSLExtraData
+ = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
+ nullptr, nullptr);
+
+ // Initialize OpenSSL's random seed.
+ if (!q_RAND_status()) {
+ qWarning("Random number generator not seeded, disabling SSL support");
+ return false;
+ }
+
+ s_libraryLoaded = true;
+ }
+ return true;
+}
+
+void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
+{
+ const QMutexLocker locker(qt_opensslInitMutex);
+
+ if (s_loadedCiphersAndCerts)
+ return;
+ s_loadedCiphersAndCerts = true;
+
+ resetDefaultCiphers();
+ resetDefaultEllipticCurves();
+
+#if QT_CONFIG(library)
+ //load symbols needed to receive certificates from system store
+#if defined(Q_OS_QNX)
+ s_loadRootCertsOnDemand = true;
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
+ // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
+ QList<QByteArray> dirs = unixRootCertDirectories();
+ QStringList symLinkFilter;
+ symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
+ for (int a = 0; a < dirs.count(); ++a) {
+ QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
+ if (iterator.hasNext()) {
+ s_loadRootCertsOnDemand = true;
+ break;
+ }
+ }
+#endif
+#endif // QT_CONFIG(library)
+ // if on-demand loading was not enabled, load the certs now
+ if (!s_loadRootCertsOnDemand)
+ setDefaultCaCertificates(systemCaCertificates());
+#ifdef Q_OS_WIN
+ //Enabled for fetching additional root certs from windows update on windows.
+ //This flag is set false by setDefaultCaCertificates() indicating the app uses
+ //its own cert bundle rather than the system one.
+ //Same logic that disables the unix on demand cert loading.
+ //Unlike unix, we do preload the certificates from the cert store.
+ s_loadRootCertsOnDemand = true;
+#endif
+}
+
QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509)
{
ensureInitialized();
@@ -1788,19 +1982,11 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
QVector<QSslErrorEntry> lastErrors;
-#if QT_CONFIG(opensslv11)
if (!q_X509_STORE_set_ex_data(certStore, 0, &lastErrors)) {
qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
errors << QSslError(QSslError::UnspecifiedError);
return errors;
}
-#else
- if (!q_CRYPTO_set_ex_data(&certStore->ex_data, 0, &lastErrors)) {
- qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
- errors << QSslError(QSslError::UnspecifiedError);
- return errors;
- }
-#endif // opensslv11
// Register a custom callback to get all verification errors.
q_X509_STORE_set_verify_cb(certStore, q_X509Callback);
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
deleted file mode 100644
index 1d935c5217..0000000000
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2014 Governikus GmbH & Co. KG
-** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
-** Contact: https://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$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** In addition, as a special exception, the copyright holders listed above give
-** permission to link the code of its release of Qt with the OpenSSL project's
-** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
-** same license as the original version), and distribute the linked executables.
-**
-** You must comply with the GNU General Public License version 2 in all
-** respects for all of the code used other than the "OpenSSL" code. If you
-** modify this file, you may extend this exception to your version of the file,
-** but you are not obligated to do so. If you do not wish to do so, delete
-** this exception statement from your version of this file.
-**
-****************************************************************************/
-
-//#define QT_DECRYPT_SSL_TRAFFIC
-
-#include "qssl_p.h"
-#include "qsslsocket_openssl_p.h"
-#include "qsslsocket_openssl_symbols_p.h"
-#include "qsslsocket.h"
-#include "qsslkey.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qdiriterator.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qlibrary.h>
-#include <QtCore/qoperatingsystemversion.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex)
-
-void QSslSocketPrivate::deinitialize()
-{
- // This function exists only for compatibility with the pre-11 code,
- // where deinitialize() actually does some cleanup. To be discarded
- // once we retire < 1.1.
-}
-
-bool QSslSocketPrivate::ensureLibraryLoaded()
-{
- if (!q_resolveOpenSslSymbols())
- return false;
-
- const QMutexLocker locker(qt_opensslInitMutex);
-
- if (!s_libraryLoaded) {
- // Initialize OpenSSL.
- if (q_OPENSSL_init_ssl(0, nullptr) != 1)
- return false;
- q_SSL_load_error_strings();
- q_OpenSSL_add_all_algorithms();
-
- QSslSocketBackendPrivate::s_indexForSSLExtraData
- = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
- nullptr, nullptr);
-
- // Initialize OpenSSL's random seed.
- if (!q_RAND_status()) {
- qWarning("Random number generator not seeded, disabling SSL support");
- return false;
- }
-
- s_libraryLoaded = true;
- }
- return true;
-}
-
-void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
-{
- const QMutexLocker locker(qt_opensslInitMutex);
-
- if (s_loadedCiphersAndCerts)
- return;
- s_loadedCiphersAndCerts = true;
-
- resetDefaultCiphers();
- resetDefaultEllipticCurves();
-
-#if QT_CONFIG(library)
- //load symbols needed to receive certificates from system store
-#if defined(Q_OS_QNX)
- s_loadRootCertsOnDemand = true;
-#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
- // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
- QList<QByteArray> dirs = unixRootCertDirectories();
- QStringList symLinkFilter;
- symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
- for (int a = 0; a < dirs.count(); ++a) {
- QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
- if (iterator.hasNext()) {
- s_loadRootCertsOnDemand = true;
- break;
- }
- }
-#endif
-#endif // QT_CONFIG(library)
- // if on-demand loading was not enabled, load the certs now
- if (!s_loadRootCertsOnDemand)
- setDefaultCaCertificates(systemCaCertificates());
-#ifdef Q_OS_WIN
- //Enabled for fetching additional root certs from windows update on windows.
- //This flag is set false by setDefaultCaCertificates() indicating the app uses
- //its own cert bundle rather than the system one.
- //Same logic that disables the unix on demand cert loading.
- //Unlike unix, we do preload the certificates from the cert store.
- s_loadRootCertsOnDemand = true;
-#endif
-}
-
-long QSslSocketPrivate::sslLibraryVersionNumber()
-{
- if (!supportsSsl())
- return 0;
-
- return q_OpenSSL_version_num();
-}
-
-QString QSslSocketPrivate::sslLibraryVersionString()
-{
- if (!supportsSsl())
- return QString();
-
- const char *versionString = q_OpenSSL_version(OPENSSL_VERSION);
- if (!versionString)
- return QString();
-
- return QString::fromLatin1(versionString);
-}
-
-void QSslSocketBackendPrivate::continueHandshake()
-{
- Q_Q(QSslSocket);
- // if we have a max read buffer size, reset the plain socket's to match
- if (readBufferMaxSize)
- plainSocket->setReadBufferSize(readBufferMaxSize);
-
- if (q_SSL_session_reused(ssl))
- configuration.peerSessionShared = true;
-
-#ifdef QT_DECRYPT_SSL_TRAFFIC
- if (q_SSL_get_session(ssl)) {
- size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), 0, 0);
- size_t client_random_len = q_SSL_get_client_random(ssl, 0, 0);
- QByteArray masterKey(int(master_key_len), 0); // Will not overflow
- QByteArray clientRandom(int(client_random_len), 0); // Will not overflow
-
- q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
- reinterpret_cast<unsigned char*>(masterKey.data()),
- masterKey.size());
- q_SSL_get_client_random(ssl, reinterpret_cast<unsigned char *>(clientRandom.data()),
- clientRandom.size());
-
- QByteArray debugLineClientRandom("CLIENT_RANDOM ");
- debugLineClientRandom.append(clientRandom.toHex().toUpper());
- debugLineClientRandom.append(" ");
- debugLineClientRandom.append(masterKey.toHex().toUpper());
- debugLineClientRandom.append("\n");
-
- QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
- QFile file(sslKeyFile);
- if (!file.open(QIODevice::Append))
- qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
- if (!file.write(debugLineClientRandom))
- qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
- file.close();
- } else {
- qCWarning(lcSsl, "could not decrypt SSL traffic");
- }
-#endif
-
- // Cache this SSL session inside the QSslContext
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
- if (!sslContextPointer->cacheSession(ssl)) {
- sslContextPointer.clear(); // we could not cache the session
- } else {
- // Cache the session for permanent usage as well
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
- if (!sslContextPointer->sessionASN1().isEmpty())
- configuration.sslSession = sslContextPointer->sessionASN1();
- configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
- }
- }
- }
-
-#if !defined(OPENSSL_NO_NEXTPROTONEG)
-
- configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
- if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
- // we could not agree -> be conservative and use HTTP/1.1
- configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
- } else {
- const unsigned char *proto = nullptr;
- unsigned int proto_len = 0;
-
- 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 ...
- q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
- }
-
- if (proto_len)
- configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
- else
- configuration.nextNegotiatedProtocol.clear();
- }
-#endif // !defined(OPENSSL_NO_NEXTPROTONEG)
-
- if (mode == QSslSocket::SslClientMode) {
- EVP_PKEY *key;
- if (q_SSL_get_server_tmp_key(ssl, &key))
- configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
- }
-
- connectionEncrypted = true;
- emit q->encrypted();
- if (autoStartHandshake && pendingClose) {
- pendingClose = false;
- q->disconnectFromHost();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
deleted file mode 100644
index 0fe0899d4f..0000000000
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
-** Contact: https://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$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** In addition, as a special exception, the copyright holders listed above give
-** permission to link the code of its release of Qt with the OpenSSL project's
-** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
-** same license as the original version), and distribute the linked executables.
-**
-** You must comply with the GNU General Public License version 2 in all
-** respects for all of the code used other than the "OpenSSL" code. If you
-** modify this file, you may extend this exception to your version of the file,
-** but you are not obligated to do so. If you do not wish to do so, delete
-** this exception statement from your version of this file.
-**
-****************************************************************************/
-
-#ifndef QSSLSOCKET_OPENSSL11_SYMBOLS_P_H
-#define QSSLSOCKET_OPENSSL11_SYMBOLS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-// Note: this file does not have QT_BEGIN_NAMESPACE/QT_END_NAMESPACE, it's done
-// in qsslsocket_openssl_symbols_p.h.
-
-#ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H
-#error "You are not supposed to use this header file, include qsslsocket_openssl_symbols_p.h instead"
-#endif
-
-const unsigned char * q_ASN1_STRING_get0_data(const ASN1_STRING *x);
-
-Q_AUTOTEST_EXPORT BIO *q_BIO_new(const BIO_METHOD *a);
-Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem();
-
-int q_DSA_bits(DSA *a);
-int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
-Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
-int q_EVP_PKEY_base_id(EVP_PKEY *a);
-int q_RSA_bits(RSA *a);
-Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
-Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
-Q_AUTOTEST_EXPORT OPENSSL_STACK *q_OPENSSL_sk_new_null();
-Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
-Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
-Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
-int q_SSL_session_reused(SSL *a);
-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
-int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
-size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
-size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
-int q_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-const SSL_METHOD *q_TLS_method();
-const SSL_METHOD *q_TLS_client_method();
-const SSL_METHOD *q_TLS_server_method();
-ASN1_TIME *q_X509_getm_notBefore(X509 *a);
-ASN1_TIME *q_X509_getm_notAfter(X509 *a);
-
-Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
-long q_X509_get_version(X509 *a);
-EVP_PKEY *q_X509_get_pubkey(X509 *a);
-void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
-int q_X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
-void *q_X509_STORE_get_ex_data(X509_STORE *r, int idx);
-STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
-void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
-int q_DH_bits(DH *dh);
-
-# define q_SSL_load_error_strings() q_OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
- | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
-
-#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_OPENSSL_sk_num)(st)
-#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_OPENSSL_sk_value)(st, i)
-
-#define q_OPENSSL_add_all_algorithms_conf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
- | OPENSSL_INIT_ADD_ALL_DIGESTS \
- | OPENSSL_INIT_LOAD_CONFIG, NULL)
-#define q_OPENSSL_add_all_algorithms_noconf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
- | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)
-
-int q_OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
-void q_CRYPTO_free(void *str, const char *file, int line);
-
-long q_OpenSSL_version_num();
-const char *q_OpenSSL_version(int type);
-
-unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session);
-unsigned long q_SSL_set_options(SSL *s, unsigned long op);
-
-#ifdef TLS1_3_VERSION
-int q_SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str);
-#endif
-
-#if QT_CONFIG(dtls)
-// Functions and types required for DTLS support:
-extern "C"
-{
-
-typedef int (*CookieVerifyCallback)(SSL *, const unsigned char *, unsigned);
-typedef int (*DgramWriteCallback) (BIO *, const char *, int);
-typedef int (*DgramReadCallback) (BIO *, char *, int);
-typedef int (*DgramPutsCallback) (BIO *, const char *);
-typedef long (*DgramCtrlCallback) (BIO *, int, long, void *);
-typedef int (*DgramCreateCallback) (BIO *);
-typedef int (*DgramDestroyCallback) (BIO *);
-
-}
-
-int q_DTLSv1_listen(SSL *s, BIO_ADDR *client);
-BIO_ADDR *q_BIO_ADDR_new();
-void q_BIO_ADDR_free(BIO_ADDR *ap);
-
-// API we need for a custom dgram BIO:
-
-BIO_METHOD *q_BIO_meth_new(int type, const char *name);
-void q_BIO_meth_free(BIO_METHOD *biom);
-int q_BIO_meth_set_write(BIO_METHOD *biom, DgramWriteCallback);
-int q_BIO_meth_set_read(BIO_METHOD *biom, DgramReadCallback);
-int q_BIO_meth_set_puts(BIO_METHOD *biom, DgramPutsCallback);
-int q_BIO_meth_set_ctrl(BIO_METHOD *biom, DgramCtrlCallback);
-int q_BIO_meth_set_create(BIO_METHOD *biom, DgramCreateCallback);
-int q_BIO_meth_set_destroy(BIO_METHOD *biom, DgramDestroyCallback);
-
-#endif // dtls
-
-void q_BIO_set_data(BIO *a, void *ptr);
-void *q_BIO_get_data(BIO *a);
-void q_BIO_set_init(BIO *a, int init);
-int q_BIO_get_shutdown(BIO *a);
-void q_BIO_set_shutdown(BIO *a, int shut);
-
-#if QT_CONFIG(ocsp)
-const OCSP_CERTID *q_OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x);
-#endif // ocsp
-
-#define q_SSL_CTX_set_min_proto_version(ctx, version) \
- q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nullptr)
-
-#define q_SSL_CTX_set_max_proto_version(ctx, version) \
- q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nullptr)
-
-extern "C" {
-typedef int (*q_SSL_psk_use_session_cb_func_t)(SSL *, const EVP_MD *, const unsigned char **, size_t *,
- SSL_SESSION **);
-}
-void q_SSL_set_psk_use_session_callback(SSL *s, q_SSL_psk_use_session_cb_func_t);
-
-#endif
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index c23234e291..0370a7d2ac 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -130,9 +130,7 @@ public:
BIO *writeBio;
SSL_SESSION *session;
QVector<QSslErrorEntry> errorList;
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
static int s_indexForSSLExtraData; // index used in SSL_get_ex_data to get the matching QSslSocketBackendPrivate
-#endif
bool inSetAndEmitError = false;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 1fcfdf9f16..3504924888 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -137,10 +137,6 @@ void qsslSocketCannotResolveSymbolWarning(const char *functionName)
#endif // QT_LINKED_OPENSSL
-#if QT_CONFIG(opensslv11)
-
-// Below are the functions first introduced in version 1.1:
-
DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return nullptr, return)
DEFINEFUNC2(int, OPENSSL_init_ssl, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
DEFINEFUNC2(int, OPENSSL_init_crypto, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
@@ -237,93 +233,6 @@ DEFINEFUNC2(void, BIO_set_init, BIO *a, a, int init, init, return, DUMMYARG)
DEFINEFUNC(int, BIO_get_shutdown, BIO *a, a, return -1, return)
DEFINEFUNC2(void, BIO_set_shutdown, BIO *a, a, int shut, shut, return, DUMMYARG)
-#else // QT_CONFIG(opensslv11)
-
-// Functions below are either deprecated or removed in OpenSSL >= 1.1:
-
-DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return nullptr, return)
-
-#ifdef SSLEAY_MACROS
-DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return nullptr, return)
-#endif
-DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return nullptr, return)
-DEFINEFUNC(void, ERR_clear_error, DUMMYARG, DUMMYARG, return, DUMMYARG)
-DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return nullptr, return)
-DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return)
-DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
-DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
-DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
-DEFINEFUNC3(int, CRYPTO_set_ex_data, CRYPTO_EX_DATA *ad, ad, int idx, idx, void *val, val, return 0, return)
-DEFINEFUNC2(void *, CRYPTO_get_ex_data, const CRYPTO_EX_DATA *ad, ad, int idx, idx, return nullptr, return)
-DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
-DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
-DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
-
-#ifdef SSLEAY_MACROS
-DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return nullptr, return)
-DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return nullptr, return)
-#endif // SSLEAY_MACROS
-
-DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
-DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
-
-DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
-DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return nullptr, return)
-
-DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
-DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
-
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
-#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L
-
-DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-
-DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return nullptr, return)
-
-#ifdef SSLEAY_MACROS
-DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
-DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
-#ifndef OPENSSL_NO_EC
-DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return)
-#endif
-DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return nullptr, return)
-DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return nullptr, return)
-#ifndef OPENSSL_NO_EC
-DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return nullptr, return)
-#endif
-#endif
-
-#if QT_CONFIG(dtls)
-DEFINEFUNC(const SSL_METHOD *, DTLSv1_server_method, void, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, DTLSv1_client_method, void, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, DTLSv1_2_server_method, void, DUMMYARG, return nullptr, return)
-DEFINEFUNC(const SSL_METHOD *, DTLSv1_2_client_method, void, DUMMYARG, return nullptr, return)
-#endif // dtls
-
-DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
-DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
-DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
-DEFINEFUNC(const char *, SSLeay_version, int a, a, return nullptr, return)
-
-#endif // QT_CONFIG(opensslv11)
-
DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return)
DEFINEFUNC2(int, ASN1_INTEGER_cmp, const ASN1_INTEGER *a, a, const ASN1_INTEGER *b, b, return 1, return)
DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
@@ -392,36 +301,28 @@ DEFINEFUNC(int, OBJ_sn2nid, const char *s, s, return 0, return)
DEFINEFUNC(int, OBJ_ln2nid, const char *s, s, return 0, return)
DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, return -1, return)
DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d, return -1, return)
-
DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
-
-#ifndef SSLEAY_MACROS
DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+
#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 nullptr, return)
-#endif
+DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *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)
+DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return)
+#endif // OPENSSL_NO_EC
+
DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, 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)
DEFINEFUNC7(int, PEM_write_bio_PrivateKey, BIO *a, a, EVP_PKEY *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
-DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *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)
-#endif
-#endif // !SSLEAY_MACROS
DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
-#ifndef OPENSSL_NO_EC
-DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
-#endif
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_PUBKEY, BIO *a, a, EVP_PKEY *b, b, return 0, return)
-#ifndef OPENSSL_NO_EC
-DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return)
-#endif
DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
DEFINEFUNC2(int, RAND_bytes, unsigned char *b, b, int n, n, return 0, return)
@@ -448,14 +349,12 @@ DEFINEFUNC2(int, SSL_CTX_use_PrivateKey, SSL_CTX *a, a, EVP_PKEY *b, b, return -
DEFINEFUNC2(int, SSL_CTX_use_RSAPrivateKey, SSL_CTX *a, a, RSA *b, b, return -1, return)
DEFINEFUNC3(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
DEFINEFUNC(X509_STORE *, SSL_CTX_get_cert_store, const SSL_CTX *a, a, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
DEFINEFUNC(SSL_CONF_CTX *, SSL_CONF_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return);
DEFINEFUNC(void, SSL_CONF_CTX_free, SSL_CONF_CTX *a, a, return ,return);
DEFINEFUNC2(void, SSL_CONF_CTX_set_ssl_ctx, SSL_CONF_CTX *a, a, SSL_CTX *b, b, return, return);
DEFINEFUNC2(unsigned int, SSL_CONF_CTX_set_flags, SSL_CONF_CTX *a, a, unsigned int b, b, return 0, return);
DEFINEFUNC(int, SSL_CONF_CTX_finish, SSL_CONF_CTX *a, a, return 0, return);
DEFINEFUNC3(int, SSL_CONF_cmd, SSL_CONF_CTX *a, a, const char *b, b, const char *c, c, return 0, return);
-#endif
DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return nullptr, return)
DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
@@ -477,21 +376,19 @@ DEFINEFUNC2(int, SSL_set_session, SSL* to, to, SSL_SESSION *session, session, re
DEFINEFUNC(void, SSL_SESSION_free, SSL_SESSION *ses, ses, return, DUMMYARG)
DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return nullptr, return)
DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC3(int, SSL_set_ex_data, SSL *ssl, ssl, int idx, idx, void *arg, arg, return 0, return)
DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return nullptr, return)
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+
+#ifndef 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
+#endif // !OPENSSL_NO_PSK
+
DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return)
DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
DEFINEFUNC4(int, X509_digest, const X509 *x509, x509, const EVP_MD *type, type, unsigned char *md, md, unsigned int *len, len, return -1, return)
-#ifndef SSLEAY_MACROS
DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return nullptr, return)
-#endif
DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
@@ -535,7 +432,8 @@ DEFINEFUNC(int, SSL_get_ex_data_X509_STORE_CTX_idx, DUMMYARG, DUMMYARG, return -
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
DEFINEFUNC6(int, SSL_select_next_proto, unsigned char **out, out, unsigned char *outlen, outlen,
const unsigned char *in, in, unsigned int inlen, inlen,
const unsigned char *client, client, unsigned int client_len, client_len,
@@ -548,7 +446,6 @@ 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,
@@ -559,8 +456,7 @@ DEFINEFUNC3(void, SSL_CTX_set_alpn_select_cb, SSL_CTX *s, s,
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 ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
// DTLS:
#if QT_CONFIG(dtls)
@@ -581,14 +477,13 @@ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long len
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 nullptr, return)
+
#ifndef OPENSSL_NO_EC
DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return nullptr, return)
DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return nullptr, return)
DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG)
DEFINEFUNC2(size_t, EC_get_builtin_curves, EC_builtin_curve * r, r, size_t nitems, nitems, return 0, return)
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
DEFINEFUNC(int, EC_curve_nist2nid, const char *name, name, return 0, return)
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
#endif // OPENSSL_NO_EC
DEFINEFUNC5(int, PKCS12_parse, PKCS12 *p12, p12, const char *pass, pass, EVP_PKEY **pkey, pkey, \
@@ -760,7 +655,6 @@ static LoadedOpenSsl loadOpenSsl()
{
LoadedOpenSsl result;
-#if QT_CONFIG(opensslv11)
// With OpenSSL 1.1 the names have changed to libssl-1_1(-x64) and libcrypto-1_1(-x64), for builds using
// MSVC and GCC, (-x64 suffix for 64-bit builds).
@@ -774,21 +668,6 @@ static LoadedOpenSsl loadOpenSsl()
QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), result);
#undef QT_SSL_SUFFIX
-
-#else // QT_CONFIG(opensslv11)
-
- // When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'.
- // When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version)
- // The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007)
- if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), result)) {
- if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), result)) {
- if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), result)) {
- tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), result);
- }
- }
- }
-#endif // !QT_CONFIG(opensslv11)
-
return result;
}
#else
@@ -852,27 +731,6 @@ static LoadedOpenSsl loadOpenSsl()
libssl->unload();
libcrypto->unload();
}
-
-#if !QT_CONFIG(opensslv11)
- // first-and-half attempts: for OpenSSL 1.0 try to load some hardcoded sonames:
- // - "1.0.0" is the official upstream one
- // - "1.0.2" is found on some distributions (e.g. Debian) that patch OpenSSL
- static const QLatin1String fallbackSonames[] = {
- QLatin1String("1.0.0"),
- QLatin1String("1.0.2")
- };
-
- for (auto fallbackSoname : fallbackSonames) {
- libssl->setFileNameAndVersion(QLatin1String("ssl"), fallbackSoname);
- libcrypto->setFileNameAndVersion(QLatin1String("crypto"), fallbackSoname);
- if (libcrypto->load() && libssl->load()) {
- return result;
- } else {
- libssl->unload();
- libcrypto->unload();
- }
- }
-#endif
#endif
#ifndef Q_OS_DARWIN
@@ -890,11 +748,9 @@ static LoadedOpenSsl loadOpenSsl()
return defaultSuffix;
return suffix;
};
-# if QT_CONFIG(opensslv11)
+
static QString suffix = QString::fromLatin1(openSSLSuffix("_1_1"));
-# else
- static QString suffix = QString::fromLatin1(openSSLSuffix());
-# endif
+
libssl->setFileNameAndVersion(QLatin1String("ssl") + suffix, -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto") + suffix, -1);
# else
@@ -968,8 +824,6 @@ bool q_resolveOpenSslSymbols()
// failed to load them
return false;
-#if QT_CONFIG(opensslv11)
-
RESOLVEFUNC(OPENSSL_init_ssl)
RESOLVEFUNC(OPENSSL_init_crypto)
RESOLVEFUNC(ASN1_STRING_get0_data)
@@ -985,10 +839,12 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OPENSSL_sk_value)
RESOLVEFUNC(DH_get0_pqg)
RESOLVEFUNC(SSL_CTX_set_options)
+
#ifdef TLS1_3_VERSION
RESOLVEFUNC(SSL_CTX_set_ciphersuites)
RESOLVEFUNC(SSL_set_psk_use_session_callback)
#endif // TLS 1.3 or OpenSSL > 1.1.1
+
RESOLVEFUNC(SSL_get_client_random)
RESOLVEFUNC(SSL_SESSION_get_master_key)
RESOLVEFUNC(SSL_session_reused)
@@ -1010,6 +866,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(CRYPTO_free)
RESOLVEFUNC(OpenSSL_version_num)
RESOLVEFUNC(OpenSSL_version)
+
if (!_q_OpenSSL_version) {
// Apparently, we were built with OpenSSL 1.1 enabled but are now using
// a wrong library.
@@ -1034,6 +891,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(BIO_meth_set_create)
RESOLVEFUNC(BIO_meth_set_destroy)
#endif // dtls
+
#if QT_CONFIG(ocsp)
RESOLVEFUNC(OCSP_SINGLERESP_get0_id)
RESOLVEFUNC(d2i_OCSP_RESPONSE)
@@ -1058,99 +916,12 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OCSP_cert_to_id)
RESOLVEFUNC(OCSP_id_cmp)
#endif // ocsp
+
RESOLVEFUNC(BIO_set_data)
RESOLVEFUNC(BIO_get_data)
RESOLVEFUNC(BIO_set_init)
RESOLVEFUNC(BIO_get_shutdown)
RESOLVEFUNC(BIO_set_shutdown)
-#else // !opensslv11
-
- RESOLVEFUNC(ASN1_STRING_data)
-
-#ifdef SSLEAY_MACROS
- RESOLVEFUNC(ASN1_dup)
-#endif // SSLEAY_MACROS
- RESOLVEFUNC(BIO_new_file)
- RESOLVEFUNC(ERR_clear_error)
- RESOLVEFUNC(CRYPTO_free)
- RESOLVEFUNC(CRYPTO_num_locks)
- RESOLVEFUNC(CRYPTO_set_id_callback)
- RESOLVEFUNC(CRYPTO_set_locking_callback)
- RESOLVEFUNC(CRYPTO_set_ex_data)
- RESOLVEFUNC(CRYPTO_get_ex_data)
- RESOLVEFUNC(ERR_peek_last_error)
- RESOLVEFUNC(ERR_free_strings)
- RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
- RESOLVEFUNC(EVP_CIPHER_CTX_init)
-
-#ifdef SSLEAY_MACROS // ### verify
- RESOLVEFUNC(PEM_ASN1_read_bio)
-#endif // SSLEAY_MACROS
-
- RESOLVEFUNC(sk_new_null)
- RESOLVEFUNC(sk_push)
- RESOLVEFUNC(sk_free)
- RESOLVEFUNC(sk_num)
- RESOLVEFUNC(sk_pop_free)
- RESOLVEFUNC(sk_value)
- RESOLVEFUNC(SSL_library_init)
- RESOLVEFUNC(SSL_load_error_strings)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- RESOLVEFUNC(SSL_get_ex_new_index)
-#endif
- RESOLVEFUNC(SSLv23_client_method)
- RESOLVEFUNC(TLSv1_client_method)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- RESOLVEFUNC(TLSv1_1_client_method)
- RESOLVEFUNC(TLSv1_2_client_method)
-#endif
- RESOLVEFUNC(SSLv23_server_method)
- RESOLVEFUNC(TLSv1_server_method)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- RESOLVEFUNC(TLSv1_1_server_method)
- RESOLVEFUNC(TLSv1_2_server_method)
-#endif
- RESOLVEFUNC(X509_STORE_CTX_get_chain)
-#ifdef SSLEAY_MACROS
- RESOLVEFUNC(i2d_DSAPrivateKey)
- RESOLVEFUNC(i2d_RSAPrivateKey)
- RESOLVEFUNC(d2i_DSAPrivateKey)
- RESOLVEFUNC(d2i_RSAPrivateKey)
-#endif
-
-#if QT_CONFIG(dtls)
- RESOLVEFUNC(DTLSv1_server_method)
- RESOLVEFUNC(DTLSv1_client_method)
- RESOLVEFUNC(DTLSv1_2_server_method)
- RESOLVEFUNC(DTLSv1_2_client_method)
-#endif // dtls
-
- RESOLVEFUNC(CONF_get1_default_config_file)
- RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
- RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
- RESOLVEFUNC(SSLeay)
-
- if (!_q_SSLeay || q_SSLeay() >= 0x10100000L) {
- // OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to
- // resolve this symbol as a failure to resolve symbols.
- // The right operand of '||' above is ... a bit of paranoia.
- qCWarning(lcSsl, "Incompatible version of OpenSSL");
- return false;
- }
-
-
- RESOLVEFUNC(SSLeay_version)
-
-#ifndef OPENSSL_NO_EC
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- if (q_SSLeay() >= 0x10002000L)
- RESOLVEFUNC(EC_curve_nist2nid)
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
-#endif // OPENSSL_NO_EC
-
-
-#endif // !opensslv11
-
RESOLVEFUNC(ASN1_INTEGER_get)
RESOLVEFUNC(ASN1_INTEGER_cmp)
RESOLVEFUNC(ASN1_STRING_length)
@@ -1172,9 +943,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EC_GROUP_get_degree)
#endif
RESOLVEFUNC(BN_num_bits)
-#if QT_CONFIG(opensslv11)
RESOLVEFUNC(BN_is_word)
-#endif
RESOLVEFUNC(BN_mod_word)
RESOLVEFUNC(DSA_new)
RESOLVEFUNC(DSA_free)
@@ -1207,17 +976,21 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_set1_RSA)
RESOLVEFUNC(EVP_PKEY_set1_DSA)
RESOLVEFUNC(EVP_PKEY_set1_DH)
+
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_set1_EC_KEY)
-#endif
+ RESOLVEFUNC(EVP_PKEY_get1_EC_KEY)
+ RESOLVEFUNC(PEM_read_bio_ECPrivateKey)
+ RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
+ RESOLVEFUNC(PEM_read_bio_EC_PUBKEY)
+ RESOLVEFUNC(PEM_write_bio_EC_PUBKEY)
+#endif // OPENSSL_NO_EC
+
RESOLVEFUNC(EVP_PKEY_cmp)
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
RESOLVEFUNC(EVP_PKEY_get1_DH)
-#ifndef OPENSSL_NO_EC
- RESOLVEFUNC(EVP_PKEY_get1_EC_KEY)
-#endif
RESOLVEFUNC(EVP_PKEY_new)
RESOLVEFUNC(EVP_PKEY_type)
RESOLVEFUNC(OBJ_nid2sn)
@@ -1227,35 +1000,19 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(i2t_ASN1_OBJECT)
RESOLVEFUNC(OBJ_obj2txt)
RESOLVEFUNC(OBJ_obj2nid)
-
-#ifndef SSLEAY_MACROS
RESOLVEFUNC(PEM_read_bio_PrivateKey)
RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
-#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)
RESOLVEFUNC(PEM_write_bio_PrivateKey)
-#ifndef OPENSSL_NO_EC
- RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
-#endif
-#endif // !SSLEAY_MACROS
-
RESOLVEFUNC(PEM_read_bio_PUBKEY)
RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
-#ifndef OPENSSL_NO_EC
- RESOLVEFUNC(PEM_read_bio_EC_PUBKEY)
-#endif
RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_PUBKEY)
-#ifndef OPENSSL_NO_EC
- RESOLVEFUNC(PEM_write_bio_EC_PUBKEY)
-#endif
RESOLVEFUNC(RAND_seed)
RESOLVEFUNC(RAND_status)
RESOLVEFUNC(RAND_bytes)
@@ -1279,14 +1036,12 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey)
RESOLVEFUNC(SSL_CTX_use_PrivateKey_file)
RESOLVEFUNC(SSL_CTX_get_cert_store);
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
RESOLVEFUNC(SSL_CONF_CTX_new);
RESOLVEFUNC(SSL_CONF_CTX_free);
RESOLVEFUNC(SSL_CONF_CTX_set_ssl_ctx);
RESOLVEFUNC(SSL_CONF_CTX_set_flags);
RESOLVEFUNC(SSL_CONF_CTX_finish);
RESOLVEFUNC(SSL_CONF_cmd);
-#endif
RESOLVEFUNC(SSL_accept)
RESOLVEFUNC(SSL_clear)
RESOLVEFUNC(SSL_connect)
@@ -1311,16 +1066,16 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_SESSION_free)
RESOLVEFUNC(SSL_get1_session)
RESOLVEFUNC(SSL_get_session)
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(SSL_set_ex_data)
RESOLVEFUNC(SSL_get_ex_data)
RESOLVEFUNC(SSL_get_ex_data_X509_STORE_CTX_idx)
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+
+#ifndef OPENSSL_NO_PSK
RESOLVEFUNC(SSL_set_psk_client_callback)
RESOLVEFUNC(SSL_set_psk_server_callback)
RESOLVEFUNC(SSL_CTX_use_psk_identity_hint)
-#endif
+#endif // !OPENSSL_NO_PSK
+
RESOLVEFUNC(SSL_write)
RESOLVEFUNC(X509_NAME_entry_count)
RESOLVEFUNC(X509_NAME_get_entry)
@@ -1340,10 +1095,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_STORE_CTX_get0_store)
RESOLVEFUNC(X509_cmp)
RESOLVEFUNC(X509_STORE_CTX_get_ex_data)
-
-#ifndef SSLEAY_MACROS
RESOLVEFUNC(X509_dup)
-#endif
RESOLVEFUNC(X509_print)
RESOLVEFUNC(X509_digest)
RESOLVEFUNC(X509_EXTENSION_get_object)
@@ -1371,22 +1123,23 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_load_verify_locations)
RESOLVEFUNC(i2d_SSL_SESSION)
RESOLVEFUNC(d2i_SSL_SESSION)
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
RESOLVEFUNC(SSL_select_next_proto)
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 ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
+
#if QT_CONFIG(dtls)
RESOLVEFUNC(SSL_CTX_set_cookie_generate_cb)
RESOLVEFUNC(SSL_CTX_set_cookie_verify_cb)
RESOLVEFUNC(DTLS_server_method)
RESOLVEFUNC(DTLS_client_method)
#endif // dtls
+
RESOLVEFUNC(CRYPTO_malloc)
RESOLVEFUNC(DH_new)
RESOLVEFUNC(DH_free)
@@ -1394,12 +1147,14 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(i2d_DHparams)
RESOLVEFUNC(DH_check)
RESOLVEFUNC(BN_bin2bn)
+
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EC_KEY_dup)
RESOLVEFUNC(EC_KEY_new_by_curve_name)
RESOLVEFUNC(EC_KEY_free)
RESOLVEFUNC(EC_get_builtin_curves)
#endif // OPENSSL_NO_EC
+
RESOLVEFUNC(PKCS12_parse)
RESOLVEFUNC(d2i_PKCS12_bio)
RESOLVEFUNC(PKCS12_free)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 69b2b90fbd..baf1a43113 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -220,11 +220,129 @@ QT_BEGIN_NAMESPACE
#endif // !defined QT_LINKED_OPENSSL
-#if QT_CONFIG(opensslv11)
-#include "qsslsocket_openssl11_symbols_p.h"
-#else
-#include "qsslsocket_opensslpre11_symbols_p.h"
-#endif // QT_CONFIG
+// TODO: the following lines previously were a part of 1.1 - specific header.
+// To reduce the amount of the change, I'm directly copying and pasting the
+// content of the header here. Later, can be better sorted/split into groups,
+// depending on the functionality.
+//#include "qsslsocket_openssl11_symbols_p.h"
+
+const unsigned char * q_ASN1_STRING_get0_data(const ASN1_STRING *x);
+
+Q_AUTOTEST_EXPORT BIO *q_BIO_new(const BIO_METHOD *a);
+Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem();
+
+int q_DSA_bits(DSA *a);
+int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+int q_EVP_PKEY_base_id(EVP_PKEY *a);
+int q_RSA_bits(RSA *a);
+Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+Q_AUTOTEST_EXPORT OPENSSL_STACK *q_OPENSSL_sk_new_null();
+Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+int q_SSL_session_reused(SSL *a);
+unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
+int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+int q_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+const SSL_METHOD *q_TLS_method();
+const SSL_METHOD *q_TLS_client_method();
+const SSL_METHOD *q_TLS_server_method();
+ASN1_TIME *q_X509_getm_notBefore(X509 *a);
+ASN1_TIME *q_X509_getm_notAfter(X509 *a);
+
+Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
+long q_X509_get_version(X509 *a);
+EVP_PKEY *q_X509_get_pubkey(X509 *a);
+void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
+int q_X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
+void *q_X509_STORE_get_ex_data(X509_STORE *r, int idx);
+STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
+void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int q_DH_bits(DH *dh);
+
+# define q_SSL_load_error_strings() q_OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
+ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
+
+#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_OPENSSL_sk_num)(st)
+#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_OPENSSL_sk_value)(st, i)
+
+#define q_OPENSSL_add_all_algorithms_conf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+ | OPENSSL_INIT_ADD_ALL_DIGESTS \
+ | OPENSSL_INIT_LOAD_CONFIG, NULL)
+#define q_OPENSSL_add_all_algorithms_noconf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+ | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)
+
+int q_OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+void q_CRYPTO_free(void *str, const char *file, int line);
+
+long q_OpenSSL_version_num();
+const char *q_OpenSSL_version(int type);
+
+unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session);
+unsigned long q_SSL_set_options(SSL *s, unsigned long op);
+
+#ifdef TLS1_3_VERSION
+int q_SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str);
+#endif
+
+#if QT_CONFIG(dtls)
+// Functions and types required for DTLS support:
+extern "C"
+{
+
+typedef int (*CookieVerifyCallback)(SSL *, const unsigned char *, unsigned);
+typedef int (*DgramWriteCallback) (BIO *, const char *, int);
+typedef int (*DgramReadCallback) (BIO *, char *, int);
+typedef int (*DgramPutsCallback) (BIO *, const char *);
+typedef long (*DgramCtrlCallback) (BIO *, int, long, void *);
+typedef int (*DgramCreateCallback) (BIO *);
+typedef int (*DgramDestroyCallback) (BIO *);
+
+}
+
+int q_DTLSv1_listen(SSL *s, BIO_ADDR *client);
+BIO_ADDR *q_BIO_ADDR_new();
+void q_BIO_ADDR_free(BIO_ADDR *ap);
+
+// API we need for a custom dgram BIO:
+
+BIO_METHOD *q_BIO_meth_new(int type, const char *name);
+void q_BIO_meth_free(BIO_METHOD *biom);
+int q_BIO_meth_set_write(BIO_METHOD *biom, DgramWriteCallback);
+int q_BIO_meth_set_read(BIO_METHOD *biom, DgramReadCallback);
+int q_BIO_meth_set_puts(BIO_METHOD *biom, DgramPutsCallback);
+int q_BIO_meth_set_ctrl(BIO_METHOD *biom, DgramCtrlCallback);
+int q_BIO_meth_set_create(BIO_METHOD *biom, DgramCreateCallback);
+int q_BIO_meth_set_destroy(BIO_METHOD *biom, DgramDestroyCallback);
+
+#endif // dtls
+
+void q_BIO_set_data(BIO *a, void *ptr);
+void *q_BIO_get_data(BIO *a);
+void q_BIO_set_init(BIO *a, int init);
+int q_BIO_get_shutdown(BIO *a);
+void q_BIO_set_shutdown(BIO *a, int shut);
+
+#if QT_CONFIG(ocsp)
+const OCSP_CERTID *q_OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x);
+#endif // ocsp
+
+#define q_SSL_CTX_set_min_proto_version(ctx, version) \
+ q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nullptr)
+
+#define q_SSL_CTX_set_max_proto_version(ctx, version) \
+ q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nullptr)
+
+extern "C" {
+typedef int (*q_SSL_psk_use_session_cb_func_t)(SSL *, const EVP_MD *, const unsigned char **, size_t *,
+ SSL_SESSION **);
+}
+void q_SSL_set_psk_use_session_callback(SSL *s, q_SSL_psk_use_session_cb_func_t);
+// Here the content of the 1.1 header ends.
bool q_resolveOpenSslSymbols();
long q_ASN1_INTEGER_get(ASN1_INTEGER *a);
@@ -237,27 +355,14 @@ BIO *q_BIO_new_mem_buf(void *a, int b);
int q_BIO_read(BIO *a, void *b, int c);
Q_AUTOTEST_EXPORT int q_BIO_write(BIO *a, const void *b, int c);
int q_BN_num_bits(const BIGNUM *a);
-
-#if QT_CONFIG(opensslv11)
int q_BN_is_word(BIGNUM *a, BN_ULONG w);
-#else // opensslv11
-// 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 // !opensslv11
-
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);
-#endif
+#endif // OPENSSL_NO_EC
+
DSA *q_DSA_new();
void q_DSA_free(DSA *a);
X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c);
@@ -277,23 +382,28 @@ const EVP_MD *q_EVP_get_digestbyname(const char *name);
#ifndef OPENSSL_NO_DES
const EVP_CIPHER *q_EVP_des_cbc();
const EVP_CIPHER *q_EVP_des_ede3_cbc();
-#endif
+#endif // OPENSSL_NO_DES
+
#ifndef OPENSSL_NO_RC2
const EVP_CIPHER *q_EVP_rc2_cbc();
-#endif
+#endif // OPENSSL_NO_RC2
+
#ifndef OPENSSL_NO_AES
const EVP_CIPHER *q_EVP_aes_128_cbc();
const EVP_CIPHER *q_EVP_aes_192_cbc();
const EVP_CIPHER *q_EVP_aes_256_cbc();
-#endif
+#endif // OPENSSL_NO_AES
+
Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
+
#ifndef OPENSSL_NO_EC
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
#endif
+
Q_AUTOTEST_EXPORT int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
@@ -313,18 +423,18 @@ int q_i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *obj);
int q_OBJ_obj2txt(char *buf, int buf_len, ASN1_OBJECT *obj, int no_name);
int q_OBJ_obj2nid(const ASN1_OBJECT *a);
#define q_EVP_get_digestbynid(a) q_EVP_get_digestbyname(q_OBJ_nid2sn(a))
-#ifdef SSLEAY_MACROS
-// ### verify
-void *q_PEM_ASN1_read_bio(d2i_of_void *a, const char *b, BIO *c, void **d, pem_password_cb *e,
- void *f);
-// ### ditto for write
-#else
Q_AUTOTEST_EXPORT EVP_PKEY *q_PEM_read_bio_PrivateKey(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
DSA *q_PEM_read_bio_DSAPrivateKey(BIO *a, DSA **b, pem_password_cb *c, void *d);
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
+int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
+ int e, pem_password_cb *f, void *g);
+EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
+int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
+#endif // OPENSSL_NO_EC
+
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);
@@ -332,23 +442,13 @@ int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_PrivateKey(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
-#ifndef OPENSSL_NO_EC
-int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
- int e, pem_password_cb *f, void *g);
-#endif
-#endif // SSLEAY_MACROS
Q_AUTOTEST_EXPORT EVP_PKEY *q_PEM_read_bio_PUBKEY(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d);
RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d);
-#ifndef OPENSSL_NO_EC
-EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d);
-#endif
int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b);
int q_PEM_write_bio_PUBKEY(BIO *a, EVP_PKEY *b);
-#ifndef OPENSSL_NO_EC
-int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
-#endif
+
void q_RAND_seed(const void *a, int b);
int q_RAND_status();
int q_RAND_bytes(unsigned char *b, int n);
@@ -378,14 +478,12 @@ int q_SSL_CTX_use_PrivateKey(SSL_CTX *a, EVP_PKEY *b);
int q_SSL_CTX_use_RSAPrivateKey(SSL_CTX *a, RSA *b);
int q_SSL_CTX_use_PrivateKey_file(SSL_CTX *a, const char *b, int c);
X509_STORE *q_SSL_CTX_get_cert_store(const SSL_CTX *a);
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CONF_CTX *q_SSL_CONF_CTX_new();
void q_SSL_CONF_CTX_free(SSL_CONF_CTX *a);
void q_SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *a, SSL_CTX *b);
unsigned int q_SSL_CONF_CTX_set_flags(SSL_CONF_CTX *a, unsigned int b);
int q_SSL_CONF_CTX_finish(SSL_CONF_CTX *a);
int q_SSL_CONF_cmd(SSL_CONF_CTX *a, const char *b, const char *c);
-#endif
void q_SSL_free(SSL *a);
STACK_OF(SSL_CIPHER) *q_SSL_get_ciphers(const SSL *a);
const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
@@ -407,26 +505,18 @@ int q_SSL_set_session(SSL *to, SSL_SESSION *session);
void q_SSL_SESSION_free(SSL_SESSION *ses);
SSL_SESSION *q_SSL_get1_session(SSL *ssl);
SSL_SESSION *q_SSL_get_session(const SSL *ssl);
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
int q_SSL_set_ex_data(SSL *ssl, int idx, void *arg);
void *q_SSL_get_ex_data(const SSL *ssl, int idx);
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
+#ifndef 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)
+#endif // !OPENSSL_NO_PSK
int q_SSL_write(SSL *a, const void *b, int c);
int q_X509_cmp(X509 *a, X509 *b);
-#ifdef SSLEAY_MACROS
-void *q_ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
-#define q_X509_dup(x509) (X509 *)q_ASN1_dup((i2d_of_void *)q_i2d_X509, \
- (d2i_of_void *)q_d2i_X509,(char *)x509)
-#else
X509 *q_X509_dup(X509 *a);
-#endif
void q_X509_print(BIO *a, X509*b);
int q_X509_digest(const X509 *x509, const EVP_MD *type, unsigned char *md, unsigned int *len);
ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a);
@@ -485,13 +575,10 @@ void q_EC_KEY_free(EC_KEY *ecdh);
// EC curves management
size_t q_EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
int q_EC_curve_nist2nid(const char *name);
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
#endif // OPENSSL_NO_EC
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+
#define q_SSL_get_server_tmp_key(ssl, key) q_SSL_ctrl((ssl), SSL_CTRL_GET_SERVER_TMP_KEY, 0, (char *)key)
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
// PKCS#12 support
int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
@@ -521,7 +608,7 @@ int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char
int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
+#ifndef OPENSSL_NO_NEXTPROTONEG
int q_SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen,
const unsigned char *client, unsigned int client_len);
@@ -533,7 +620,6 @@ 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,
@@ -545,8 +631,8 @@ void q_SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
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 ...
+#endif // !OPENSSL_NO_NEXTPROTONEG
+
#if QT_CONFIG(dtls)
@@ -586,13 +672,9 @@ int q_BIO_set_ex_data(BIO *b, int idx, void *data);
class QDateTime;
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime);
-#ifndef OPENSSL_NO_TLSEXT
-
#define q_SSL_set_tlsext_status_type(ssl, type) \
q_SSL_ctrl((ssl), SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, (type), nullptr)
-#endif // OPENSSL_NO_TLSEXT
-
#if QT_CONFIG(ocsp)
OCSP_RESPONSE *q_d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len);
diff --git a/src/network/ssl/qsslsocket_opensslpre11.cpp b/src/network/ssl/qsslsocket_opensslpre11.cpp
deleted file mode 100644
index 2af437f0fa..0000000000
--- a/src/network/ssl/qsslsocket_opensslpre11.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2014 Governikus GmbH & Co. KG
-** Contact: https://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$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** In addition, as a special exception, the copyright holders listed above give
-** permission to link the code of its release of Qt with the OpenSSL project's
-** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
-** same license as the original version), and distribute the linked executables.
-**
-** You must comply with the GNU General Public License version 2 in all
-** respects for all of the code used other than the "OpenSSL" code. If you
-** modify this file, you may extend this exception to your version of the file,
-** but you are not obligated to do so. If you do not wish to do so, delete
-** this exception statement from your version of this file.
-**
-****************************************************************************/
-
-//#define QT_DECRYPT_SSL_TRAFFIC
-
-#include "qssl_p.h"
-#include "qsslsocket_openssl_p.h"
-#include "qsslsocket_openssl_symbols_p.h"
-#include "qsslsocket.h"
-#include "qsslkey.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qdiriterator.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qmutex.h>
-
-QT_BEGIN_NAMESPACE
-
-/* \internal
-
- From OpenSSL's thread(3) manual page:
-
- OpenSSL can safely be used in multi-threaded applications provided that at
- least two callback functions are set.
-
- locking_function(int mode, int n, const char *file, int line) is needed to
- perform locking on shared data structures. (Note that OpenSSL uses a
- number of global data structures that will be implicitly shared
- whenever multiple threads use OpenSSL.) Multi-threaded
- applications will crash at random if it is not set. ...
- ...
- id_function(void) is a function that returns a thread ID. It is not
- needed on Windows nor on platforms where getpid() returns a different
- ID for each thread (most notably Linux)
-*/
-
-class QOpenSslLocks
-{
-public:
- QOpenSslLocks()
- : initLocker(QMutex::Recursive),
- locksLocker(QMutex::Recursive)
- {
- QMutexLocker locker(&locksLocker);
- int numLocks = q_CRYPTO_num_locks();
- locks = new QMutex *[numLocks];
- memset(locks, 0, numLocks * sizeof(QMutex *));
- }
- ~QOpenSslLocks()
- {
- QMutexLocker locker(&locksLocker);
- for (int i = 0; i < q_CRYPTO_num_locks(); ++i)
- delete locks[i];
- delete [] locks;
-
- QSslSocketPrivate::deinitialize();
- }
- QMutex *lock(int num)
- {
- QMutexLocker locker(&locksLocker);
- QMutex *tmp = locks[num];
- if (!tmp)
- tmp = locks[num] = new QMutex(QMutex::Recursive);
- return tmp;
- }
-
- QMutex *globalLock()
- {
- return &locksLocker;
- }
-
- QMutex *initLock()
- {
- return &initLocker;
- }
-
-private:
- QMutex initLocker;
- QMutex locksLocker;
- QMutex **locks;
-};
-
-Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks)
-
-extern "C" {
-static void locking_function(int mode, int lockNumber, const char *, int)
-{
- QMutex *mutex = openssl_locks()->lock(lockNumber);
-
- // Lock or unlock it
- if (mode & CRYPTO_LOCK)
- mutex->lock();
- else
- mutex->unlock();
-}
-static unsigned long id_function()
-{
- return (quintptr)QThread::currentThreadId();
-}
-
-} // extern "C"
-
-static void q_OpenSSL_add_all_algorithms_safe()
-{
-#ifdef Q_OS_WIN
- // Prior to version 1.0.1m an attempt to call OpenSSL_add_all_algorithms on
- // Windows could result in 'exit' call from OPENSSL_config (QTBUG-43843).
- // We can predict this and avoid OPENSSL_add_all_algorithms call.
- // From OpenSSL docs:
- // "An application does not need to add algorithms to use them explicitly,
- // for example by EVP_sha1(). It just needs to add them if it (or any of
- // the functions it calls) needs to lookup algorithms.
- // The cipher and digest lookup functions are used in many parts of the
- // library. If the table is not initialized several functions will
- // misbehave and complain they cannot find algorithms. This includes the
- // PEM, PKCS#12, SSL and S/MIME libraries. This is a common query in
- // the OpenSSL mailing lists."
- //
- // Anyway, as a result, we chose not to call this function if it would exit.
-
- if (q_SSLeay() < 0x100010DFL)
- {
- // Now, before we try to call it, check if an attempt to open config file
- // will result in exit:
- if (char *confFileName = q_CONF_get1_default_config_file()) {
- BIO *confFile = q_BIO_new_file(confFileName, "r");
- const auto lastError = q_ERR_peek_last_error();
- q_CRYPTO_free(confFileName);
- if (confFile) {
- q_BIO_free(confFile);
- } else {
- q_ERR_clear_error();
- if (ERR_GET_REASON(lastError) == ERR_R_SYS_LIB) {
- qCWarning(lcSsl, "failed to open openssl.conf file");
- return;
- }
- }
- }
- }
-#endif // Q_OS_WIN
-
- q_OpenSSL_add_all_algorithms();
-}
-
-
-void QSslSocketPrivate::deinitialize()
-{
- q_CRYPTO_set_id_callback(0);
- q_CRYPTO_set_locking_callback(0);
- q_ERR_free_strings();
-}
-
-
-bool QSslSocketPrivate::ensureLibraryLoaded()
-{
- if (!q_resolveOpenSslSymbols())
- return false;
-
- // Check if the library itself needs to be initialized.
- QMutexLocker locker(openssl_locks()->initLock());
-
- if (!s_libraryLoaded) {
- // Initialize OpenSSL.
- q_CRYPTO_set_id_callback(id_function);
- q_CRYPTO_set_locking_callback(locking_function);
- if (q_SSL_library_init() != 1)
- return false;
- q_SSL_load_error_strings();
- q_OpenSSL_add_all_algorithms_safe();
-
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- if (q_SSLeay() >= 0x10001000L)
- QSslSocketBackendPrivate::s_indexForSSLExtraData = q_SSL_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
-#endif
-
- // Initialize OpenSSL's random seed.
- if (!q_RAND_status()) {
- qWarning("Random number generator not seeded, disabling SSL support");
- return false;
- }
-
- s_libraryLoaded = true;
- }
- return true;
-}
-
-void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
-{
- QMutexLocker locker(openssl_locks()->initLock());
- if (s_loadedCiphersAndCerts)
- return;
- s_loadedCiphersAndCerts = true;
-
- resetDefaultCiphers();
- resetDefaultEllipticCurves();
-
-#if QT_CONFIG(library)
- //load symbols needed to receive certificates from system store
-#if defined(Q_OS_QNX)
- s_loadRootCertsOnDemand = true;
-#elif defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
- // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
- QList<QByteArray> dirs = unixRootCertDirectories();
- QStringList symLinkFilter;
- symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
- for (int a = 0; a < dirs.count(); ++a) {
- QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
- if (iterator.hasNext()) {
- s_loadRootCertsOnDemand = true;
- break;
- }
- }
-#endif
-#endif // QT_CONFIG(library)
- // if on-demand loading was not enabled, load the certs now
- if (!s_loadRootCertsOnDemand)
- setDefaultCaCertificates(systemCaCertificates());
-#ifdef Q_OS_WIN
- //Enabled for fetching additional root certs from windows update on windows 6+
- //This flag is set false by setDefaultCaCertificates() indicating the app uses
- //its own cert bundle rather than the system one.
- //Same logic that disables the unix on demand cert loading.
- //Unlike unix, we do preload the certificates from the cert store.
- s_loadRootCertsOnDemand = true;
-#endif
-}
-
-long QSslSocketPrivate::sslLibraryVersionNumber()
-{
- if (!supportsSsl())
- return 0;
-
- return q_SSLeay();
-}
-
-QString QSslSocketPrivate::sslLibraryVersionString()
-{
- if (!supportsSsl())
- return QString();
-
- const char *versionString = q_SSLeay_version(SSLEAY_VERSION);
- if (!versionString)
- return QString();
-
- return QString::fromLatin1(versionString);
-}
-
-void QSslSocketBackendPrivate::continueHandshake()
-{
- Q_Q(QSslSocket);
- // if we have a max read buffer size, reset the plain socket's to match
- if (readBufferMaxSize)
- plainSocket->setReadBufferSize(readBufferMaxSize);
-
- if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL))
- configuration.peerSessionShared = true;
-
-#ifdef QT_DECRYPT_SSL_TRAFFIC
- if (ssl->session && ssl->s3) {
- const char *mk = reinterpret_cast<const char *>(ssl->session->master_key);
- QByteArray masterKey(mk, ssl->session->master_key_length);
- const char *random = reinterpret_cast<const char *>(ssl->s3->client_random);
- QByteArray clientRandom(random, SSL3_RANDOM_SIZE);
-
- // different format, needed for e.g. older Wireshark versions:
-// const char *sid = reinterpret_cast<const char *>(ssl->session->session_id);
-// QByteArray sessionID(sid, ssl->session->session_id_length);
-// QByteArray debugLineRSA("RSA Session-ID:");
-// debugLineRSA.append(sessionID.toHex().toUpper());
-// debugLineRSA.append(" Master-Key:");
-// debugLineRSA.append(masterKey.toHex().toUpper());
-// debugLineRSA.append("\n");
-
- QByteArray debugLineClientRandom("CLIENT_RANDOM ");
- debugLineClientRandom.append(clientRandom.toHex().toUpper());
- debugLineClientRandom.append(" ");
- debugLineClientRandom.append(masterKey.toHex().toUpper());
- debugLineClientRandom.append("\n");
-
- QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
- QFile file(sslKeyFile);
- if (!file.open(QIODevice::Append))
- qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
- if (!file.write(debugLineClientRandom))
- qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
- file.close();
- } else {
- qCWarning(lcSsl, "could not decrypt SSL traffic");
- }
-#endif
-
- // Cache this SSL session inside the QSslContext
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
- if (!sslContextPointer->cacheSession(ssl)) {
- sslContextPointer.clear(); // we could not cache the session
- } else {
- // Cache the session for permanent usage as well
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
- if (!sslContextPointer->sessionASN1().isEmpty())
- configuration.sslSession = sslContextPointer->sessionASN1();
- configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
- }
- }
- }
-
-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
-
- configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
- if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
- // we could not agree -> be conservative and use HTTP/1.1
- configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
- } else {
- const unsigned char *proto = 0;
- unsigned int proto_len = 0;
-#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
- configuration.nextNegotiatedProtocol.clear();
- }
-#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
-
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) {
- EVP_PKEY *key;
- if (q_SSL_get_server_tmp_key(ssl, &key))
- configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
- }
-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
-
- connectionEncrypted = true;
- emit q->encrypted();
- if (autoStartHandshake && pendingClose) {
- pendingClose = false;
- q->disconnectFromHost();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
deleted file mode 100644
index f5626d5d16..0000000000
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: https://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$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** In addition, as a special exception, the copyright holders listed above give
-** permission to link the code of its release of Qt with the OpenSSL project's
-** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
-** same license as the original version), and distribute the linked executables.
-**
-** You must comply with the GNU General Public License version 2 in all
-** respects for all of the code used other than the "OpenSSL" code. If you
-** modify this file, you may extend this exception to your version of the file,
-** but you are not obligated to do so. If you do not wish to do so, delete
-** this exception statement from your version of this file.
-**
-****************************************************************************/
-
-
-#ifndef QSSLSOCKET_OPENSSLPRE11_SYMBOLS_P_H
-#define QSSLSOCKET_OPENSSLPRE11_SYMBOLS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-// Note: this file does not have QT_BEGIN_NAMESPACE/QT_END_NAMESPACE, it's done
-// in qsslsocket_openssl_symbols_p.h.
-
-#ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H
-#error "You are not supposed to use this header file, include qsslsocket_openssl_symbols_p.h instead"
-#endif
-
-unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
-BIO *q_BIO_new_file(const char *filename, const char *mode);
-void q_ERR_clear_error();
-Q_AUTOTEST_EXPORT BIO *q_BIO_new(BIO_METHOD *a);
-Q_AUTOTEST_EXPORT BIO_METHOD *q_BIO_s_mem();
-int q_CRYPTO_num_locks();
-void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
-void q_CRYPTO_set_id_callback(unsigned long (*a)());
-void q_CRYPTO_free(void *a);
-int q_CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
-void *q_CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
-unsigned long q_ERR_peek_last_error();
-void q_ERR_free_strings();
-void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
-void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
-
-typedef _STACK STACK;
-
-// The typedef we use to make our pre 1.1 code look more like 1.1 (less ifdefs).
-typedef STACK OPENSSL_STACK;
-
-// We resolve q_sk_ functions, but use q_OPENSSL_sk_ macros in code to reduce
-// the amount of #ifdefs.
-int q_sk_num(STACK *a);
-#define q_OPENSSL_sk_num(a) q_sk_num(a)
-void q_sk_pop_free(STACK *a, void (*b)(void *));
-#define q_OPENSSL_sk_pop_free(a, b) q_sk_pop_free(a, b)
-STACK *q_sk_new_null();
-#define q_OPENSSL_sk_new_null() q_sk_new_null()
-
-void q_sk_free(STACK *a);
-
-// Just a name alias (not a function call expression) since in code we take an
-// address of this:
-#define q_OPENSSL_sk_free q_sk_free
-
-void *q_sk_value(STACK *a, int b);
-void q_sk_push(STACK *st, void *data);
-
-#define q_OPENSSL_sk_value(a, b) q_sk_value(a, b)
-#define q_OPENSSL_sk_push(st, data) q_sk_push(st, data)
-
-SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a);
-
-int q_SSL_library_init();
-void q_SSL_load_error_strings();
-
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-#endif
-
-const SSL_METHOD *q_SSLv23_client_method();
-const SSL_METHOD *q_TLSv1_client_method();
-const SSL_METHOD *q_TLSv1_1_client_method();
-const SSL_METHOD *q_TLSv1_2_client_method();
-const SSL_METHOD *q_SSLv23_server_method();
-const SSL_METHOD *q_TLSv1_server_method();
-const SSL_METHOD *q_TLSv1_1_server_method();
-const SSL_METHOD *q_TLSv1_2_server_method();
-
-STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
-
-#ifdef SSLEAY_MACROS
-int q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
-int q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
-RSA *q_d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
-DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
-#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
- (RSA *)q_PEM_ASN1_read_bio( \
- (void *(*)(void**, const unsigned char**, long int))q_d2i_RSAPrivateKey, PEM_STRING_RSA, bp, (void **)x, cb, u)
-#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
- (DSA *)q_PEM_ASN1_read_bio( \
- (void *(*)(void**, const unsigned char**, long int))q_d2i_DSAPrivateKey, PEM_STRING_DSA, bp, (void **)x, cb, u)
-#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
- bp,(char *)x,enc,kstr,klen,cb,u)
-#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 // SSLEAY_MACROS
-
-#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
-#define q_SSL_set_options(ssl,op) q_SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),nullptr)
-#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_sk_num)(st)
-#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_sk_value)(st, i)
-#define q_X509_getm_notAfter(x) X509_get_notAfter(x)
-#define q_X509_getm_notBefore(x) X509_get_notBefore(x)
-
-// "Forward compatibility" with OpenSSL 1.1 (to save on #if-ery elsewhere):
-#define q_X509_get_version(x509) q_ASN1_INTEGER_get((x509)->cert_info->version)
-#define q_ASN1_STRING_get0_data(x) q_ASN1_STRING_data(x)
-#define q_EVP_PKEY_base_id(pkey) ((pkey)->type)
-#define q_X509_get_pubkey(x509) q_X509_PUBKEY_get((x509)->cert_info->key)
-#define q_SSL_SESSION_get_ticket_lifetime_hint(s) ((s)->tlsext_tick_lifetime_hint)
-#define q_RSA_bits(rsa) q_BN_num_bits((rsa)->n)
-#define q_DSA_bits(dsa) q_BN_num_bits((dsa)->p)
-#define q_DH_bits(dsa) q_BN_num_bits((dh)->p)
-#define q_X509_STORE_set_verify_cb(s,c) X509_STORE_set_verify_cb_func((s),(c))
-
-char *q_CONF_get1_default_config_file();
-void q_OPENSSL_add_all_algorithms_noconf();
-void q_OPENSSL_add_all_algorithms_conf();
-
-long q_SSLeay();
-const char *q_SSLeay_version(int type);
-
-#if QT_CONFIG(dtls)
-// DTLS:
-extern "C"
-{
-typedef int (*CookieVerifyCallback)(SSL *, unsigned char *, unsigned);
-}
-
-#define q_DTLSv1_listen(ssl, peer) q_SSL_ctrl(ssl, DTLS_CTRL_LISTEN, 0, (void *)peer)
-
-const SSL_METHOD *q_DTLSv1_server_method();
-const SSL_METHOD *q_DTLSv1_client_method();
-const SSL_METHOD *q_DTLSv1_2_server_method();
-const SSL_METHOD *q_DTLSv1_2_client_method();
-#endif // dtls
-
-#endif // QSSLSOCKET_OPENSSL_PRE11_SYMBOLS_P_H
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index daa9be23f4..1abd18bb32 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -127,7 +127,6 @@ public:
static long sslLibraryBuildVersionNumber();
static QString sslLibraryBuildVersionString();
static void ensureInitialized();
- static void deinitialize();
static QList<QSslCipher> defaultCiphers();
static QList<QSslCipher> supportedCiphers();
static void setDefaultCiphers(const QList<QSslCipher> &ciphers);
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index cb0e86fa1f..4286b5ea42 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -157,11 +157,6 @@ QSslSocketBackendPrivate::~QSslSocketBackendPrivate()
g->syncCaCertificates(QSet<QSslCertificate>(), previousCaCertificates);
}
-void QSslSocketPrivate::deinitialize()
-{
- Q_UNIMPLEMENTED();
-}
-
bool QSslSocketPrivate::supportsSsl()
{
return true;
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 8bb70a2aed..0c8b9ccd40 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -102,17 +102,7 @@ qtConfig(ssl) {
qtConfig(ocsp): HEADERS += ssl/qocsp_p.h
- qtConfig(opensslv11) {
- HEADERS += ssl/qsslsocket_openssl11_symbols_p.h
- SOURCES += ssl/qsslsocket_openssl11.cpp \
- ssl/qsslcontext_openssl11.cpp
-
- QMAKE_CXXFLAGS += -DOPENSSL_API_COMPAT=0x10100000L
- } else {
- HEADERS += ssl/qsslsocket_opensslpre11_symbols_p.h
- SOURCES += ssl/qsslsocket_opensslpre11.cpp \
- ssl/qsslcontext_opensslpre11.cpp
- }
+ QMAKE_CXXFLAGS += -DOPENSSL_API_COMPAT=0x10100000L
darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index 40273bac84..bd5c95b9d0 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -375,15 +375,6 @@ void QCocoaScreen::deliverUpdateRequests()
// it on the main thread yet, because the processing of the update request is taking
// too long, or because the update request was deferred due to window live resizing.
qDeferredDebug(screenUpdates) << ", " << framesAheadOfDelivery << " frame(s) ahead";
-
- // We skip the frame completely if we're live-resizing, to not put any extra
- // strain on the main thread runloop. Otherwise we assume we should push frames
- // as fast as possible, and hopefully the callback will be delivered on the
- // main thread just when the previous finished.
- if (qt_apple_sharedApplication().keyWindow.inLiveResize) {
- qDeferredDebug(screenUpdates) << "; waiting for main thread to catch up";
- return;
- }
}
qDeferredDebug(screenUpdates) << "; signaling dispatch source";
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index be4abf1ae2..f5d3f2f9c0 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2481,7 +2481,7 @@ void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelectio
{
Q_D(QWidgetTextControl);
- QHash<int, int> hash;
+ QMultiHash<int, int> hash;
for (int i = 0; i < d->extraSelections.count(); ++i) {
const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(i);
hash.insert(esel.cursor.anchor(), i);
diff --git a/src/xml/dom/dom.pri b/src/xml/dom/dom.pri
index d86071e84e..36b6087ede 100644
--- a/src/xml/dom/dom.pri
+++ b/src/xml/dom/dom.pri
@@ -1,2 +1,5 @@
-HEADERS += $$PWD/qdom.h
-SOURCES += $$PWD/qdom.cpp
+HEADERS += $$PWD/qdom.h \
+ $$PWD/qdom_p.h \
+ $$PWD/qdomhelpers_p.h
+SOURCES += $$PWD/qdom.cpp \
+ $$PWD/qdomhelpers.cpp
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 3e8b18d449..7dbf864a7c 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -39,15 +39,15 @@
#include <qplatformdefs.h>
#include <qdom.h>
+#include "qdom_p.h"
+#include "qdomhelpers_p.h"
#include "private/qxmlutils_p.h"
#ifndef QT_NO_DOM
#include <qatomic.h>
#include <qbuffer.h>
-#include <qhash.h>
#include <qiodevice.h>
-#include <qlist.h>
#if QT_CONFIG(regularexpression)
#include <qregularexpression.h>
#endif
@@ -56,9 +56,7 @@
#endif
#include <qtextstream.h>
#include <qxml.h>
-#include "private/qxml_p.h"
#include <qvariant.h>
-#include <qmap.h>
#include <qshareddata.h>
#include <qdebug.h>
#include <stdio.h>
@@ -119,510 +117,6 @@ static void qt_split_namespace(QString& prefix, QString& name, const QString& qN
/**************************************************************
*
- * Private class declerations
- *
- **************************************************************/
-
-class QDomImplementationPrivate
-{
-public:
- inline QDomImplementationPrivate() {}
-
- QDomImplementationPrivate* clone();
- QAtomicInt ref;
- static QDomImplementation::InvalidDataPolicy invalidDataPolicy;
-};
-
-class QDomNodePrivate
-{
-public:
- QDomNodePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = nullptr);
- QDomNodePrivate(QDomNodePrivate* n, bool deep);
- virtual ~QDomNodePrivate();
-
- QString nodeName() const { return name; }
- QString nodeValue() const { return value; }
- virtual void setNodeValue(const QString& v) { value = v; }
-
- QDomDocumentPrivate* ownerDocument();
- void setOwnerDocument(QDomDocumentPrivate* doc);
-
- virtual QDomNodePrivate* insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild);
- virtual QDomNodePrivate* insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild);
- virtual QDomNodePrivate* replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild);
- virtual QDomNodePrivate* removeChild(QDomNodePrivate* oldChild);
- virtual QDomNodePrivate* appendChild(QDomNodePrivate* newChild);
-
- QDomNodePrivate* namedItem(const QString& name);
-
- virtual QDomNodePrivate* cloneNode(bool deep = true);
- virtual void normalize();
- virtual void clear();
-
- inline QDomNodePrivate* parent() const { return hasParent ? ownerNode : nullptr; }
- inline void setParent(QDomNodePrivate *p) { ownerNode = p; hasParent = true; }
-
- void setNoParent() {
- ownerNode = hasParent ? (QDomNodePrivate*)ownerDocument() : nullptr;
- hasParent = false;
- }
-
- // Dynamic cast
- bool isAttr() const { return nodeType() == QDomNode::AttributeNode; }
- bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; }
- bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; }
- bool isDocument() const { return nodeType() == QDomNode::DocumentNode; }
- bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; }
- bool isElement() const { return nodeType() == QDomNode::ElementNode; }
- bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; }
- bool isText() const { const QDomNode::NodeType nt = nodeType();
- return (nt == QDomNode::TextNode)
- || (nt == QDomNode::CDATASectionNode); }
- bool isEntity() const { return nodeType() == QDomNode::EntityNode; }
- bool isNotation() const { return nodeType() == QDomNode::NotationNode; }
- bool isProcessingInstruction() const { return nodeType() == QDomNode::ProcessingInstructionNode; }
- bool isCharacterData() const { const QDomNode::NodeType nt = nodeType();
- return (nt == QDomNode::CharacterDataNode)
- || (nt == QDomNode::TextNode)
- || (nt == QDomNode::CommentNode); }
- bool isComment() const { return nodeType() == QDomNode::CommentNode; }
-
- virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; }
-
- virtual void save(QTextStream&, int, int) const;
-
- void setLocation(int lineNumber, int columnNumber);
-
- // Variables
- QAtomicInt ref;
- QDomNodePrivate* prev;
- QDomNodePrivate* next;
- QDomNodePrivate* ownerNode; // either the node's parent or the node's owner document
- QDomNodePrivate* first;
- QDomNodePrivate* last;
-
- QString name; // this is the local name if prefix != null
- QString value;
- QString prefix; // set this only for ElementNode and AttributeNode
- QString namespaceURI; // set this only for ElementNode and AttributeNode
- bool createdWithDom1Interface : 1;
- bool hasParent : 1;
-
- int lineNumber;
- int columnNumber;
-};
-
-class QDomNodeListPrivate
-{
-public:
- QDomNodeListPrivate(QDomNodePrivate*);
- QDomNodeListPrivate(QDomNodePrivate*, const QString& );
- QDomNodeListPrivate(QDomNodePrivate*, const QString&, const QString& );
- ~QDomNodeListPrivate();
-
- bool operator== (const QDomNodeListPrivate&) const;
- bool operator!= (const QDomNodeListPrivate&) const;
-
- void createList();
- QDomNodePrivate* item(int index);
- int length() const;
-
- QAtomicInt ref;
- /*
- This list contains the children of this node.
- */
- QDomNodePrivate* node_impl;
- QString tagname;
- QString nsURI;
- QList<QDomNodePrivate*> list;
- long timestamp;
-};
-
-class QDomNamedNodeMapPrivate
-{
-public:
- QDomNamedNodeMapPrivate(QDomNodePrivate*);
- ~QDomNamedNodeMapPrivate();
-
- QDomNodePrivate* namedItem(const QString& name) const;
- QDomNodePrivate* namedItemNS(const QString& nsURI, const QString& localName) const;
- QDomNodePrivate* setNamedItem(QDomNodePrivate* arg);
- QDomNodePrivate* setNamedItemNS(QDomNodePrivate* arg);
- QDomNodePrivate* removeNamedItem(const QString& name);
- QDomNodePrivate* item(int index) const;
- int length() const;
- bool contains(const QString& name) const;
- bool containsNS(const QString& nsURI, const QString & localName) const;
-
- /**
- * Remove all children from the map.
- */
- void clearMap();
- bool isReadOnly() { return readonly; }
- void setReadOnly(bool r) { readonly = r; }
- bool isAppendToParent() { return appendToParent; }
- /**
- * If true, then the node will redirect insert/remove calls
- * to its parent by calling QDomNodePrivate::appendChild or removeChild.
- * In addition the map won't increase or decrease the reference count
- * of the nodes it contains.
- *
- * By default this value is false and the map will handle reference counting
- * by itself.
- */
- void setAppendToParent(bool b) { appendToParent = b; }
-
- /**
- * Creates a copy of the map. It is a deep copy
- * that means that all children are cloned.
- */
- QDomNamedNodeMapPrivate* clone(QDomNodePrivate* parent);
-
- // Variables
- QAtomicInt ref;
- QHash<QString, QDomNodePrivate *> map;
- QDomNodePrivate* parent;
- bool readonly;
- bool appendToParent;
-};
-
-class QDomDocumentTypePrivate : public QDomNodePrivate
-{
-public:
- QDomDocumentTypePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = nullptr);
- QDomDocumentTypePrivate(QDomDocumentTypePrivate* n, bool deep);
- ~QDomDocumentTypePrivate();
- void init();
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNodePrivate* insertBefore(QDomNodePrivate* newChild, QDomNodePrivate* refChild) override;
- QDomNodePrivate* insertAfter(QDomNodePrivate* newChild, QDomNodePrivate* refChild) override;
- QDomNodePrivate* replaceChild(QDomNodePrivate* newChild, QDomNodePrivate* oldChild) override;
- QDomNodePrivate* removeChild(QDomNodePrivate* oldChild) override;
- QDomNodePrivate* appendChild(QDomNodePrivate* newChild) override;
-
- QDomNode::NodeType nodeType() const override { return QDomNode::DocumentTypeNode; }
-
- void save(QTextStream& s, int, int) const override;
-
- // Variables
- QDomNamedNodeMapPrivate* entities;
- QDomNamedNodeMapPrivate* notations;
- QString publicId;
- QString systemId;
- QString internalSubset;
-};
-
-class QDomDocumentFragmentPrivate : public QDomNodePrivate
-{
-public:
- QDomDocumentFragmentPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent = nullptr);
- QDomDocumentFragmentPrivate(QDomNodePrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- virtual QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; }
-};
-
-class QDomCharacterDataPrivate : public QDomNodePrivate
-{
-public:
- QDomCharacterDataPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& data);
- QDomCharacterDataPrivate(QDomCharacterDataPrivate* n, bool deep);
-
- int dataLength() const;
- QString substringData(unsigned long offset, unsigned long count) const;
- void appendData(const QString& arg);
- void insertData(unsigned long offset, const QString& arg);
- void deleteData(unsigned long offset, unsigned long count);
- void replaceData(unsigned long offset, unsigned long count, const QString& arg);
-
- // Reimplemented from QDomNodePrivate
- QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; }
- QDomNodePrivate* cloneNode(bool deep = true) override;
-};
-
-class QDomTextPrivate : public QDomCharacterDataPrivate
-{
-public:
- QDomTextPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val);
- QDomTextPrivate(QDomTextPrivate* n, bool deep);
-
- QDomTextPrivate* splitText(int offset);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; }
- virtual void save(QTextStream& s, int, int) const override;
-};
-
-class QDomAttrPrivate : public QDomNodePrivate
-{
-public:
- QDomAttrPrivate(QDomDocumentPrivate*, QDomNodePrivate*, const QString& name);
- QDomAttrPrivate(QDomDocumentPrivate*, QDomNodePrivate*, const QString& nsURI, const QString& qName);
- QDomAttrPrivate(QDomAttrPrivate* n, bool deep);
-
- bool specified() const;
-
- // Reimplemented from QDomNodePrivate
- void setNodeValue(const QString& v) override;
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::AttributeNode; }
- virtual void save(QTextStream& s, int, int) const override;
-
- // Variables
- bool m_specified;
-};
-
-class QDomElementPrivate : public QDomNodePrivate
-{
-public:
- QDomElementPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name);
- QDomElementPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& nsURI, const QString& qName);
- QDomElementPrivate(QDomElementPrivate* n, bool deep);
- ~QDomElementPrivate();
-
- QString attribute(const QString& name, const QString& defValue) const;
- QString attributeNS(const QString& nsURI, const QString& localName, const QString& defValue) const;
- void setAttribute(const QString& name, const QString& value);
- void setAttributeNS(const QString& nsURI, const QString& qName, const QString& newValue);
- void removeAttribute(const QString& name);
- QDomAttrPrivate* attributeNode(const QString& name);
- QDomAttrPrivate* attributeNodeNS(const QString& nsURI, const QString& localName);
- QDomAttrPrivate* setAttributeNode(QDomAttrPrivate* newAttr);
- QDomAttrPrivate* setAttributeNodeNS(QDomAttrPrivate* newAttr);
- QDomAttrPrivate* removeAttributeNode(QDomAttrPrivate* oldAttr);
- bool hasAttribute(const QString& name);
- bool hasAttributeNS(const QString& nsURI, const QString& localName);
-
- QString text();
-
- // Reimplemented from QDomNodePrivate
- QDomNamedNodeMapPrivate* attributes() { return m_attr; }
- bool hasAttributes() { return (m_attr->length() > 0); }
- QDomNode::NodeType nodeType() const override { return QDomNode::ElementNode; }
- QDomNodePrivate* cloneNode(bool deep = true) override;
- virtual void save(QTextStream& s, int, int) const override;
-
- // Variables
- QDomNamedNodeMapPrivate* m_attr;
-};
-
-
-class QDomCommentPrivate : public QDomCharacterDataPrivate
-{
-public:
- QDomCommentPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val);
- QDomCommentPrivate(QDomCommentPrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; }
- virtual void save(QTextStream& s, int, int) const override;
-};
-
-class QDomCDATASectionPrivate : public QDomTextPrivate
-{
-public:
- QDomCDATASectionPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& val);
- QDomCDATASectionPrivate(QDomCDATASectionPrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; }
- virtual void save(QTextStream& s, int, int) const override;
-};
-
-class QDomNotationPrivate : public QDomNodePrivate
-{
-public:
- QDomNotationPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name,
- const QString& pub, const QString& sys);
- QDomNotationPrivate(QDomNotationPrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::NotationNode; }
- virtual void save(QTextStream& s, int, int) const override;
-
- // Variables
- QString m_sys;
- QString m_pub;
-};
-
-class QDomEntityPrivate : public QDomNodePrivate
-{
-public:
- QDomEntityPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name,
- const QString& pub, const QString& sys, const QString& notation);
- QDomEntityPrivate(QDomEntityPrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::EntityNode; }
- virtual void save(QTextStream& s, int, int) const override;
-
- // Variables
- QString m_sys;
- QString m_pub;
- QString m_notationName;
-};
-
-class QDomEntityReferencePrivate : public QDomNodePrivate
-{
-public:
- QDomEntityReferencePrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& name);
- QDomEntityReferencePrivate(QDomNodePrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; }
- virtual void save(QTextStream& s, int, int) const override;
-};
-
-class QDomProcessingInstructionPrivate : public QDomNodePrivate
-{
-public:
- QDomProcessingInstructionPrivate(QDomDocumentPrivate*, QDomNodePrivate* parent, const QString& target,
- const QString& data);
- QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate* n, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; }
- virtual void save(QTextStream& s, int, int) const override;
-};
-
-class QDomDocumentPrivate : public QDomNodePrivate
-{
-public:
- QDomDocumentPrivate();
- QDomDocumentPrivate(const QString& name);
- QDomDocumentPrivate(QDomDocumentTypePrivate* dt);
- QDomDocumentPrivate(QDomDocumentPrivate* n, bool deep);
- ~QDomDocumentPrivate();
-
- bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn);
- bool setContent(QXmlInputSource *source, QXmlReader *reader, QXmlSimpleReader *simpleReader, QString *errorMsg, int *errorLine, int *errorColumn);
-
- // Attributes
- QDomDocumentTypePrivate* doctype() { return type.data(); }
- QDomImplementationPrivate* implementation() { return impl.data(); }
- QDomElementPrivate* documentElement();
-
- // Factories
- QDomElementPrivate* createElement(const QString& tagName);
- QDomElementPrivate* createElementNS(const QString& nsURI, const QString& qName);
- QDomDocumentFragmentPrivate* createDocumentFragment();
- QDomTextPrivate* createTextNode(const QString& data);
- QDomCommentPrivate* createComment(const QString& data);
- QDomCDATASectionPrivate* createCDATASection(const QString& data);
- QDomProcessingInstructionPrivate* createProcessingInstruction(const QString& target, const QString& data);
- QDomAttrPrivate* createAttribute(const QString& name);
- QDomAttrPrivate* createAttributeNS(const QString& nsURI, const QString& qName);
- QDomEntityReferencePrivate* createEntityReference(const QString& name);
-
- QDomNodePrivate* importNode(QDomNodePrivate* importedNode, bool deep);
-
- // Reimplemented from QDomNodePrivate
- QDomNodePrivate* cloneNode(bool deep = true) override;
- QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; }
- void clear() override;
-
- // Variables
- QExplicitlySharedDataPointer<QDomImplementationPrivate> impl;
- QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type;
-
- void saveDocument(QTextStream& stream, const int indent, QDomNode::EncodingPolicy encUsed) const;
-
- /* \internal
- Counter for the QDomNodeListPrivate timestamps.
-
- This is a cache optimization, that might in some cases be effective. The
- dilemma is that QDomNode::childNodes() returns a list, but the
- implementation stores the children in a linked list. Hence, in order to
- get the children out through childNodes(), a list must be populated each
- time, which is O(N).
-
- DOM has the requirement of node references being live, see DOM Core
- Level 3, 1.1.1 The DOM Structure Model, which means that changes to the
- underlying documents must be reflected in node lists.
-
- This mechanism, nodeListTime, is a caching optimization that reduces the
- amount of times the node list is rebuilt, by only doing so when the
- document actually changes. However, a change to anywhere in any document
- invalidate all lists, since no dependency tracking is done.
-
- It functions by that all modifying functions(insertBefore() and so on)
- increment the count; each QDomNodeListPrivate copies nodeListTime on
- construction, and compares its own value to nodeListTime in order to
- determine whether it needs to rebuild.
-
- This is reentrant. The nodeListTime may overflow, but that's ok since we
- check for equalness, not whether nodeListTime is smaller than the list's
- stored timestamp.
- */
- long nodeListTime;
-};
-
-/**************************************************************
- *
- * QDomHandler
- *
- **************************************************************/
-
-class QDomHandler : public QXmlDefaultHandler
-{
-public:
- QDomHandler(QDomDocumentPrivate* d, QXmlSimpleReader *reader, bool namespaceProcessing);
- ~QDomHandler();
-
- // content handler
- bool endDocument() override;
- bool startElement(const QString& nsURI, const QString& localName, const QString& qName, const QXmlAttributes& atts) override;
- bool endElement(const QString& nsURI, const QString& localName, const QString& qName) override;
- bool characters(const QString& ch) override;
- bool processingInstruction(const QString& target, const QString& data) override;
- bool skippedEntity(const QString& name) override;
-
- // error handler
- bool fatalError(const QXmlParseException& exception) override;
-
- // lexical handler
- bool startCDATA() override;
- bool endCDATA() override;
- bool startEntity(const QString &) override;
- bool endEntity(const QString &) override;
- bool startDTD(const QString& name, const QString& publicId, const QString& systemId) override;
- bool comment(const QString& ch) override;
-
- // decl handler
- bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId) override ;
-
- // DTD handler
- bool notationDecl(const QString & name, const QString & publicId, const QString & systemId) override;
- bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName) override ;
-
- void setDocumentLocator(QXmlLocator *locator) override;
-
- QString errorMsg;
- int errorLine;
- int errorColumn;
-
-private:
- QDomDocumentPrivate *doc;
- QDomNodePrivate *node;
- QString entityName;
- bool cdata;
- bool nsProcessing;
- QXmlLocator *locator;
- QXmlSimpleReader *reader;
-};
-
-/**************************************************************
- *
* Functions for verifying legal data
*
**************************************************************/
@@ -7361,200 +6855,6 @@ QDomComment QDomNode::toComment() const
return QDomComment();
}
-/**************************************************************
- *
- * QDomHandler
- *
- **************************************************************/
-
-QDomHandler::QDomHandler(QDomDocumentPrivate* adoc, QXmlSimpleReader* areader, bool namespaceProcessing)
- : errorLine(0), errorColumn(0), doc(adoc), node(adoc), cdata(false),
- nsProcessing(namespaceProcessing), locator(nullptr), reader(areader)
-{
-}
-
-QDomHandler::~QDomHandler()
-{
-}
-
-bool QDomHandler::endDocument()
-{
- // ### is this really necessary? (rms)
- if (node != doc)
- return false;
- return true;
-}
-
-bool QDomHandler::startDTD(const QString& name, const QString& publicId, const QString& systemId)
-{
- doc->doctype()->name = name;
- doc->doctype()->publicId = publicId;
- doc->doctype()->systemId = systemId;
- return true;
-}
-
-bool QDomHandler::startElement(const QString& nsURI, const QString&, const QString& qName, const QXmlAttributes& atts)
-{
- // tag name
- QDomNodePrivate* n;
- if (nsProcessing) {
- n = doc->createElementNS(nsURI, qName);
- } else {
- n = doc->createElement(qName);
- }
-
- if (!n)
- return false;
-
- n->setLocation(locator->lineNumber(), locator->columnNumber());
-
- node->appendChild(n);
- node = n;
-
- // attributes
- for (int i=0; i<atts.length(); i++)
- {
- if (nsProcessing) {
- ((QDomElementPrivate*)node)->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i));
- } else {
- ((QDomElementPrivate*)node)->setAttribute(atts.qName(i), atts.value(i));
- }
- }
-
- return true;
-}
-
-bool QDomHandler::endElement(const QString&, const QString&, const QString&)
-{
- if (!node || node == doc)
- return false;
- node = node->parent();
-
- return true;
-}
-
-bool QDomHandler::characters(const QString& ch)
-{
- // No text as child of some document
- if (node == doc)
- return false;
-
- QScopedPointer<QDomNodePrivate> n;
- if (cdata) {
- n.reset(doc->createCDATASection(ch));
- } else if (!entityName.isEmpty()) {
- QScopedPointer<QDomEntityPrivate> e(new QDomEntityPrivate(doc, nullptr, entityName,
- QString(), QString(), QString()));
- e->value = ch;
- e->ref.deref();
- doc->doctype()->appendChild(e.data());
- e.take();
- n.reset(doc->createEntityReference(entityName));
- } else {
- n.reset(doc->createTextNode(ch));
- }
- n->setLocation(locator->lineNumber(), locator->columnNumber());
- node->appendChild(n.data());
- n.take();
-
- return true;
-}
-
-bool QDomHandler::processingInstruction(const QString& target, const QString& data)
-{
- QDomNodePrivate *n;
- n = doc->createProcessingInstruction(target, data);
- if (n) {
- n->setLocation(locator->lineNumber(), locator->columnNumber());
- node->appendChild(n);
- return true;
- }
- else
- return false;
-}
-
-bool QDomHandler::skippedEntity(const QString& name)
-{
- // we can only handle inserting entity references into content
- if (reader && !reader->d_ptr->skipped_entity_in_content)
- return true;
-
- QDomNodePrivate *n = doc->createEntityReference(name);
- n->setLocation(locator->lineNumber(), locator->columnNumber());
- node->appendChild(n);
- return true;
-}
-
-bool QDomHandler::fatalError(const QXmlParseException& exception)
-{
- errorMsg = exception.message();
- errorLine = exception.lineNumber();
- errorColumn = exception.columnNumber();
- return QXmlDefaultHandler::fatalError(exception);
-}
-
-bool QDomHandler::startCDATA()
-{
- cdata = true;
- return true;
-}
-
-bool QDomHandler::endCDATA()
-{
- cdata = false;
- return true;
-}
-
-bool QDomHandler::startEntity(const QString &name)
-{
- entityName = name;
- return true;
-}
-
-bool QDomHandler::endEntity(const QString &)
-{
- entityName.clear();
- return true;
-}
-
-bool QDomHandler::comment(const QString& ch)
-{
- QDomNodePrivate *n;
- n = doc->createComment(ch);
- n->setLocation(locator->lineNumber(), locator->columnNumber());
- node->appendChild(n);
- return true;
-}
-
-bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId, const QString &notationName)
-{
- QDomEntityPrivate* e = new QDomEntityPrivate(doc, nullptr, name,
- publicId, systemId, notationName);
- // keep the refcount balanced: appendChild() does a ref anyway.
- e->ref.deref();
- doc->doctype()->appendChild(e);
- return true;
-}
-
-bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId)
-{
- return unparsedEntityDecl(name, publicId, systemId, QString());
-}
-
-bool QDomHandler::notationDecl(const QString & name, const QString & publicId, const QString & systemId)
-{
- QDomNotationPrivate* n = new QDomNotationPrivate(doc, nullptr, name, publicId, systemId);
- // keep the refcount balanced: appendChild() does a ref anyway.
- n->ref.deref();
- doc->doctype()->appendChild(n);
- return true;
-}
-
-void QDomHandler::setDocumentLocator(QXmlLocator *locator)
-{
- this->locator = locator;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_DOM
diff --git a/src/xml/dom/qdom_p.h b/src/xml/dom/qdom_p.h
new file mode 100644
index 0000000000..06ed0d5f0e
--- /dev/null
+++ b/src/xml/dom/qdom_p.h
@@ -0,0 +1,533 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtXml 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 QDOM_P_H
+#define QDOM_P_H
+
+#include "qdom.h"
+
+#include <qglobal.h>
+#include <qhash.h>
+#include <qstring.h>
+#include <qlist.h>
+#include <qxml.h>
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience of
+// qxml.cpp and qdom.cpp. This header file may change from version to version without
+// notice, or even be removed.
+//
+// We mean it.
+//
+
+/**************************************************************
+ *
+ * Private class declerations
+ *
+ **************************************************************/
+
+class QDomImplementationPrivate
+{
+public:
+ inline QDomImplementationPrivate() {}
+
+ QDomImplementationPrivate *clone();
+ QAtomicInt ref;
+ static QDomImplementation::InvalidDataPolicy invalidDataPolicy;
+};
+
+class QDomNodePrivate
+{
+public:
+ QDomNodePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr);
+ QDomNodePrivate(QDomNodePrivate *n, bool deep);
+ virtual ~QDomNodePrivate();
+
+ QString nodeName() const { return name; }
+ QString nodeValue() const { return value; }
+ virtual void setNodeValue(const QString &v) { value = v; }
+
+ QDomDocumentPrivate *ownerDocument();
+ void setOwnerDocument(QDomDocumentPrivate *doc);
+
+ virtual QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild);
+ virtual QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild);
+ virtual QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild);
+ virtual QDomNodePrivate *removeChild(QDomNodePrivate *oldChild);
+ virtual QDomNodePrivate *appendChild(QDomNodePrivate *newChild);
+
+ QDomNodePrivate *namedItem(const QString &name);
+
+ virtual QDomNodePrivate *cloneNode(bool deep = true);
+ virtual void normalize();
+ virtual void clear();
+
+ inline QDomNodePrivate *parent() const { return hasParent ? ownerNode : nullptr; }
+ inline void setParent(QDomNodePrivate *p)
+ {
+ ownerNode = p;
+ hasParent = true;
+ }
+
+ void setNoParent()
+ {
+ ownerNode = hasParent ? (QDomNodePrivate *)ownerDocument() : nullptr;
+ hasParent = false;
+ }
+
+ // Dynamic cast
+ bool isAttr() const { return nodeType() == QDomNode::AttributeNode; }
+ bool isCDATASection() const { return nodeType() == QDomNode::CDATASectionNode; }
+ bool isDocumentFragment() const { return nodeType() == QDomNode::DocumentFragmentNode; }
+ bool isDocument() const { return nodeType() == QDomNode::DocumentNode; }
+ bool isDocumentType() const { return nodeType() == QDomNode::DocumentTypeNode; }
+ bool isElement() const { return nodeType() == QDomNode::ElementNode; }
+ bool isEntityReference() const { return nodeType() == QDomNode::EntityReferenceNode; }
+ bool isText() const
+ {
+ const QDomNode::NodeType nt = nodeType();
+ return (nt == QDomNode::TextNode) || (nt == QDomNode::CDATASectionNode);
+ }
+ bool isEntity() const { return nodeType() == QDomNode::EntityNode; }
+ bool isNotation() const { return nodeType() == QDomNode::NotationNode; }
+ bool isProcessingInstruction() const
+ {
+ return nodeType() == QDomNode::ProcessingInstructionNode;
+ }
+ bool isCharacterData() const
+ {
+ const QDomNode::NodeType nt = nodeType();
+ return (nt == QDomNode::CharacterDataNode) || (nt == QDomNode::TextNode)
+ || (nt == QDomNode::CommentNode);
+ }
+ bool isComment() const { return nodeType() == QDomNode::CommentNode; }
+
+ virtual QDomNode::NodeType nodeType() const { return QDomNode::BaseNode; }
+
+ virtual void save(QTextStream &, int, int) const;
+
+ void setLocation(int lineNumber, int columnNumber);
+
+ // Variables
+ QAtomicInt ref;
+ QDomNodePrivate *prev;
+ QDomNodePrivate *next;
+ QDomNodePrivate *ownerNode; // either the node's parent or the node's owner document
+ QDomNodePrivate *first;
+ QDomNodePrivate *last;
+
+ QString name; // this is the local name if prefix != null
+ QString value;
+ QString prefix; // set this only for ElementNode and AttributeNode
+ QString namespaceURI; // set this only for ElementNode and AttributeNode
+ bool createdWithDom1Interface : 1;
+ bool hasParent : 1;
+
+ int lineNumber;
+ int columnNumber;
+};
+
+class QDomNodeListPrivate
+{
+public:
+ QDomNodeListPrivate(QDomNodePrivate *);
+ QDomNodeListPrivate(QDomNodePrivate *, const QString &);
+ QDomNodeListPrivate(QDomNodePrivate *, const QString &, const QString &);
+ ~QDomNodeListPrivate();
+
+ bool operator==(const QDomNodeListPrivate &) const;
+ bool operator!=(const QDomNodeListPrivate &) const;
+
+ void createList();
+ QDomNodePrivate *item(int index);
+ int length() const;
+
+ QAtomicInt ref;
+ /*
+ This list contains the children of this node.
+ */
+ QDomNodePrivate *node_impl;
+ QString tagname;
+ QString nsURI;
+ QList<QDomNodePrivate *> list;
+ long timestamp;
+};
+
+class QDomNamedNodeMapPrivate
+{
+public:
+ QDomNamedNodeMapPrivate(QDomNodePrivate *);
+ ~QDomNamedNodeMapPrivate();
+
+ QDomNodePrivate *namedItem(const QString &name) const;
+ QDomNodePrivate *namedItemNS(const QString &nsURI, const QString &localName) const;
+ QDomNodePrivate *setNamedItem(QDomNodePrivate *arg);
+ QDomNodePrivate *setNamedItemNS(QDomNodePrivate *arg);
+ QDomNodePrivate *removeNamedItem(const QString &name);
+ QDomNodePrivate *item(int index) const;
+ int length() const;
+ bool contains(const QString &name) const;
+ bool containsNS(const QString &nsURI, const QString &localName) const;
+
+ /**
+ * Remove all children from the map.
+ */
+ void clearMap();
+ bool isReadOnly() { return readonly; }
+ void setReadOnly(bool r) { readonly = r; }
+ bool isAppendToParent() { return appendToParent; }
+ /**
+ * If true, then the node will redirect insert/remove calls
+ * to its parent by calling QDomNodePrivate::appendChild or removeChild.
+ * In addition the map won't increase or decrease the reference count
+ * of the nodes it contains.
+ *
+ * By default this value is false and the map will handle reference counting
+ * by itself.
+ */
+ void setAppendToParent(bool b) { appendToParent = b; }
+
+ /**
+ * Creates a copy of the map. It is a deep copy
+ * that means that all children are cloned.
+ */
+ QDomNamedNodeMapPrivate *clone(QDomNodePrivate *parent);
+
+ // Variables
+ QAtomicInt ref;
+ QHash<QString, QDomNodePrivate *> map;
+ QDomNodePrivate *parent;
+ bool readonly;
+ bool appendToParent;
+};
+
+class QDomDocumentTypePrivate : public QDomNodePrivate
+{
+public:
+ QDomDocumentTypePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr);
+ QDomDocumentTypePrivate(QDomDocumentTypePrivate *n, bool deep);
+ ~QDomDocumentTypePrivate();
+ void init();
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNodePrivate *insertBefore(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override;
+ QDomNodePrivate *insertAfter(QDomNodePrivate *newChild, QDomNodePrivate *refChild) override;
+ QDomNodePrivate *replaceChild(QDomNodePrivate *newChild, QDomNodePrivate *oldChild) override;
+ QDomNodePrivate *removeChild(QDomNodePrivate *oldChild) override;
+ QDomNodePrivate *appendChild(QDomNodePrivate *newChild) override;
+
+ QDomNode::NodeType nodeType() const override { return QDomNode::DocumentTypeNode; }
+
+ void save(QTextStream &s, int, int) const override;
+
+ // Variables
+ QDomNamedNodeMapPrivate *entities;
+ QDomNamedNodeMapPrivate *notations;
+ QString publicId;
+ QString systemId;
+ QString internalSubset;
+};
+
+class QDomDocumentFragmentPrivate : public QDomNodePrivate
+{
+public:
+ QDomDocumentFragmentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent = nullptr);
+ QDomDocumentFragmentPrivate(QDomNodePrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ virtual QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::DocumentFragmentNode; }
+};
+
+class QDomCharacterDataPrivate : public QDomNodePrivate
+{
+public:
+ QDomCharacterDataPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &data);
+ QDomCharacterDataPrivate(QDomCharacterDataPrivate *n, bool deep);
+
+ int dataLength() const;
+ QString substringData(unsigned long offset, unsigned long count) const;
+ void appendData(const QString &arg);
+ void insertData(unsigned long offset, const QString &arg);
+ void deleteData(unsigned long offset, unsigned long count);
+ void replaceData(unsigned long offset, unsigned long count, const QString &arg);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNode::NodeType nodeType() const override { return QDomNode::CharacterDataNode; }
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+};
+
+class QDomTextPrivate : public QDomCharacterDataPrivate
+{
+public:
+ QDomTextPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val);
+ QDomTextPrivate(QDomTextPrivate *n, bool deep);
+
+ QDomTextPrivate *splitText(int offset);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::TextNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+};
+
+class QDomAttrPrivate : public QDomNodePrivate
+{
+public:
+ QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &name);
+ QDomAttrPrivate(QDomDocumentPrivate *, QDomNodePrivate *, const QString &nsURI,
+ const QString &qName);
+ QDomAttrPrivate(QDomAttrPrivate *n, bool deep);
+
+ bool specified() const;
+
+ // Reimplemented from QDomNodePrivate
+ void setNodeValue(const QString &v) override;
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::AttributeNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+
+ // Variables
+ bool m_specified;
+};
+
+class QDomElementPrivate : public QDomNodePrivate
+{
+public:
+ QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name);
+ QDomElementPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &nsURI,
+ const QString &qName);
+ QDomElementPrivate(QDomElementPrivate *n, bool deep);
+ ~QDomElementPrivate();
+
+ QString attribute(const QString &name, const QString &defValue) const;
+ QString attributeNS(const QString &nsURI, const QString &localName,
+ const QString &defValue) const;
+ void setAttribute(const QString &name, const QString &value);
+ void setAttributeNS(const QString &nsURI, const QString &qName, const QString &newValue);
+ void removeAttribute(const QString &name);
+ QDomAttrPrivate *attributeNode(const QString &name);
+ QDomAttrPrivate *attributeNodeNS(const QString &nsURI, const QString &localName);
+ QDomAttrPrivate *setAttributeNode(QDomAttrPrivate *newAttr);
+ QDomAttrPrivate *setAttributeNodeNS(QDomAttrPrivate *newAttr);
+ QDomAttrPrivate *removeAttributeNode(QDomAttrPrivate *oldAttr);
+ bool hasAttribute(const QString &name);
+ bool hasAttributeNS(const QString &nsURI, const QString &localName);
+
+ QString text();
+
+ // Reimplemented from QDomNodePrivate
+ QDomNamedNodeMapPrivate *attributes() { return m_attr; }
+ bool hasAttributes() { return (m_attr->length() > 0); }
+ QDomNode::NodeType nodeType() const override { return QDomNode::ElementNode; }
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ virtual void save(QTextStream &s, int, int) const override;
+
+ // Variables
+ QDomNamedNodeMapPrivate *m_attr;
+};
+
+class QDomCommentPrivate : public QDomCharacterDataPrivate
+{
+public:
+ QDomCommentPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val);
+ QDomCommentPrivate(QDomCommentPrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::CommentNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+};
+
+class QDomCDATASectionPrivate : public QDomTextPrivate
+{
+public:
+ QDomCDATASectionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &val);
+ QDomCDATASectionPrivate(QDomCDATASectionPrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::CDATASectionNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+};
+
+class QDomNotationPrivate : public QDomNodePrivate
+{
+public:
+ QDomNotationPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name,
+ const QString &pub, const QString &sys);
+ QDomNotationPrivate(QDomNotationPrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::NotationNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+
+ // Variables
+ QString m_sys;
+ QString m_pub;
+};
+
+class QDomEntityPrivate : public QDomNodePrivate
+{
+public:
+ QDomEntityPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name,
+ const QString &pub, const QString &sys, const QString &notation);
+ QDomEntityPrivate(QDomEntityPrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::EntityNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+
+ // Variables
+ QString m_sys;
+ QString m_pub;
+ QString m_notationName;
+};
+
+class QDomEntityReferencePrivate : public QDomNodePrivate
+{
+public:
+ QDomEntityReferencePrivate(QDomDocumentPrivate *, QDomNodePrivate *parent, const QString &name);
+ QDomEntityReferencePrivate(QDomNodePrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::EntityReferenceNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+};
+
+class QDomProcessingInstructionPrivate : public QDomNodePrivate
+{
+public:
+ QDomProcessingInstructionPrivate(QDomDocumentPrivate *, QDomNodePrivate *parent,
+ const QString &target, const QString &data);
+ QDomProcessingInstructionPrivate(QDomProcessingInstructionPrivate *n, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::ProcessingInstructionNode; }
+ virtual void save(QTextStream &s, int, int) const override;
+};
+
+class QDomDocumentPrivate : public QDomNodePrivate
+{
+public:
+ QDomDocumentPrivate();
+ QDomDocumentPrivate(const QString &name);
+ QDomDocumentPrivate(QDomDocumentTypePrivate *dt);
+ QDomDocumentPrivate(QDomDocumentPrivate *n, bool deep);
+ ~QDomDocumentPrivate();
+
+ bool setContent(QXmlInputSource *source, bool namespaceProcessing, QString *errorMsg,
+ int *errorLine, int *errorColumn);
+ bool setContent(QXmlInputSource *source, QXmlReader *reader, QXmlSimpleReader *simpleReader,
+ QString *errorMsg, int *errorLine, int *errorColumn);
+
+ // Attributes
+ QDomDocumentTypePrivate *doctype() { return type.data(); }
+ QDomImplementationPrivate *implementation() { return impl.data(); }
+ QDomElementPrivate *documentElement();
+
+ // Factories
+ QDomElementPrivate *createElement(const QString &tagName);
+ QDomElementPrivate *createElementNS(const QString &nsURI, const QString &qName);
+ QDomDocumentFragmentPrivate *createDocumentFragment();
+ QDomTextPrivate *createTextNode(const QString &data);
+ QDomCommentPrivate *createComment(const QString &data);
+ QDomCDATASectionPrivate *createCDATASection(const QString &data);
+ QDomProcessingInstructionPrivate *createProcessingInstruction(const QString &target,
+ const QString &data);
+ QDomAttrPrivate *createAttribute(const QString &name);
+ QDomAttrPrivate *createAttributeNS(const QString &nsURI, const QString &qName);
+ QDomEntityReferencePrivate *createEntityReference(const QString &name);
+
+ QDomNodePrivate *importNode(QDomNodePrivate *importedNode, bool deep);
+
+ // Reimplemented from QDomNodePrivate
+ QDomNodePrivate *cloneNode(bool deep = true) override;
+ QDomNode::NodeType nodeType() const override { return QDomNode::DocumentNode; }
+ void clear() override;
+
+ // Variables
+ QExplicitlySharedDataPointer<QDomImplementationPrivate> impl;
+ QExplicitlySharedDataPointer<QDomDocumentTypePrivate> type;
+
+ void saveDocument(QTextStream &stream, const int indent,
+ QDomNode::EncodingPolicy encUsed) const;
+
+ /* \internal
+ Counter for the QDomNodeListPrivate timestamps.
+
+ This is a cache optimization, that might in some cases be effective. The
+ dilemma is that QDomNode::childNodes() returns a list, but the
+ implementation stores the children in a linked list. Hence, in order to
+ get the children out through childNodes(), a list must be populated each
+ time, which is O(N).
+
+ DOM has the requirement of node references being live, see DOM Core
+ Level 3, 1.1.1 The DOM Structure Model, which means that changes to the
+ underlying documents must be reflected in node lists.
+
+ This mechanism, nodeListTime, is a caching optimization that reduces the
+ amount of times the node list is rebuilt, by only doing so when the
+ document actually changes. However, a change to anywhere in any document
+ invalidate all lists, since no dependency tracking is done.
+
+ It functions by that all modifying functions(insertBefore() and so on)
+ increment the count; each QDomNodeListPrivate copies nodeListTime on
+ construction, and compares its own value to nodeListTime in order to
+ determine whether it needs to rebuild.
+
+ This is reentrant. The nodeListTime may overflow, but that's ok since we
+ check for equalness, not whether nodeListTime is smaller than the list's
+ stored timestamp.
+ */
+ long nodeListTime;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDOMHELPERS_P_H
diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp
new file mode 100644
index 0000000000..74d2c8c124
--- /dev/null
+++ b/src/xml/dom/qdomhelpers.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtXml 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 "qdomhelpers_p.h"
+#include "qdom_p.h"
+#include "private/qxml_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/**************************************************************
+ *
+ * QDomHandler
+ *
+ **************************************************************/
+
+QDomHandler::QDomHandler(QDomDocumentPrivate *adoc, QXmlSimpleReader *areader,
+ bool namespaceProcessing)
+ : errorLine(0),
+ errorColumn(0),
+ doc(adoc),
+ node(adoc),
+ cdata(false),
+ nsProcessing(namespaceProcessing),
+ locator(nullptr),
+ reader(areader)
+{
+}
+
+QDomHandler::~QDomHandler() {}
+
+bool QDomHandler::endDocument()
+{
+ // ### is this really necessary? (rms)
+ if (node != doc)
+ return false;
+ return true;
+}
+
+bool QDomHandler::startDTD(const QString &name, const QString &publicId, const QString &systemId)
+{
+ doc->doctype()->name = name;
+ doc->doctype()->publicId = publicId;
+ doc->doctype()->systemId = systemId;
+ return true;
+}
+
+bool QDomHandler::startElement(const QString &nsURI, const QString &, const QString &qName,
+ const QXmlAttributes &atts)
+{
+ // tag name
+ QDomNodePrivate *n;
+ if (nsProcessing) {
+ n = doc->createElementNS(nsURI, qName);
+ } else {
+ n = doc->createElement(qName);
+ }
+
+ if (!n)
+ return false;
+
+ n->setLocation(locator->lineNumber(), locator->columnNumber());
+
+ node->appendChild(n);
+ node = n;
+
+ // attributes
+ for (int i = 0; i < atts.length(); i++) {
+ if (nsProcessing) {
+ ((QDomElementPrivate *)node)->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i));
+ } else {
+ ((QDomElementPrivate *)node)->setAttribute(atts.qName(i), atts.value(i));
+ }
+ }
+
+ return true;
+}
+
+bool QDomHandler::endElement(const QString &, const QString &, const QString &)
+{
+ if (!node || node == doc)
+ return false;
+ node = node->parent();
+
+ return true;
+}
+
+bool QDomHandler::characters(const QString &ch)
+{
+ // No text as child of some document
+ if (node == doc)
+ return false;
+
+ QScopedPointer<QDomNodePrivate> n;
+ if (cdata) {
+ n.reset(doc->createCDATASection(ch));
+ } else if (!entityName.isEmpty()) {
+ QScopedPointer<QDomEntityPrivate> e(
+ new QDomEntityPrivate(doc, nullptr, entityName, QString(), QString(), QString()));
+ e->value = ch;
+ e->ref.deref();
+ doc->doctype()->appendChild(e.data());
+ e.take();
+ n.reset(doc->createEntityReference(entityName));
+ } else {
+ n.reset(doc->createTextNode(ch));
+ }
+ n->setLocation(locator->lineNumber(), locator->columnNumber());
+ node->appendChild(n.data());
+ n.take();
+
+ return true;
+}
+
+bool QDomHandler::processingInstruction(const QString &target, const QString &data)
+{
+ QDomNodePrivate *n;
+ n = doc->createProcessingInstruction(target, data);
+ if (n) {
+ n->setLocation(locator->lineNumber(), locator->columnNumber());
+ node->appendChild(n);
+ return true;
+ } else
+ return false;
+}
+
+bool QDomHandler::skippedEntity(const QString &name)
+{
+ // we can only handle inserting entity references into content
+ if (reader && !reader->d_ptr->skipped_entity_in_content)
+ return true;
+
+ QDomNodePrivate *n = doc->createEntityReference(name);
+ n->setLocation(locator->lineNumber(), locator->columnNumber());
+ node->appendChild(n);
+ return true;
+}
+
+bool QDomHandler::fatalError(const QXmlParseException &exception)
+{
+ errorMsg = exception.message();
+ errorLine = exception.lineNumber();
+ errorColumn = exception.columnNumber();
+ return QXmlDefaultHandler::fatalError(exception);
+}
+
+bool QDomHandler::startCDATA()
+{
+ cdata = true;
+ return true;
+}
+
+bool QDomHandler::endCDATA()
+{
+ cdata = false;
+ return true;
+}
+
+bool QDomHandler::startEntity(const QString &name)
+{
+ entityName = name;
+ return true;
+}
+
+bool QDomHandler::endEntity(const QString &)
+{
+ entityName.clear();
+ return true;
+}
+
+bool QDomHandler::comment(const QString &ch)
+{
+ QDomNodePrivate *n;
+ n = doc->createComment(ch);
+ n->setLocation(locator->lineNumber(), locator->columnNumber());
+ node->appendChild(n);
+ return true;
+}
+
+bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId,
+ const QString &systemId, const QString &notationName)
+{
+ QDomEntityPrivate *e =
+ new QDomEntityPrivate(doc, nullptr, name, publicId, systemId, notationName);
+ // keep the refcount balanced: appendChild() does a ref anyway.
+ e->ref.deref();
+ doc->doctype()->appendChild(e);
+ return true;
+}
+
+bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId,
+ const QString &systemId)
+{
+ return unparsedEntityDecl(name, publicId, systemId, QString());
+}
+
+bool QDomHandler::notationDecl(const QString &name, const QString &publicId,
+ const QString &systemId)
+{
+ QDomNotationPrivate *n = new QDomNotationPrivate(doc, nullptr, name, publicId, systemId);
+ // keep the refcount balanced: appendChild() does a ref anyway.
+ n->ref.deref();
+ doc->doctype()->appendChild(n);
+ return true;
+}
+
+void QDomHandler::setDocumentLocator(QXmlLocator *locator)
+{
+ this->locator = locator;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xml/dom/qdomhelpers_p.h b/src/xml/dom/qdomhelpers_p.h
new file mode 100644
index 0000000000..ee81f1f9ce
--- /dev/null
+++ b/src/xml/dom/qdomhelpers_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtXml 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 QDOMHELPERS_P_H
+#define QDOMHELPERS_P_H
+
+#include <qglobal.h>
+#include <qxml.h>
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience of
+// qxml.cpp and qdom.cpp. This header file may change from version to version without
+// notice, or even be removed.
+//
+// We mean it.
+//
+
+class QDomDocumentPrivate;
+class QDomNodePrivate;
+
+/**************************************************************
+ *
+ * QDomHandler
+ *
+ **************************************************************/
+
+class QDomHandler : public QXmlDefaultHandler
+{
+public:
+ QDomHandler(QDomDocumentPrivate *d, QXmlSimpleReader *reader, bool namespaceProcessing);
+ ~QDomHandler();
+
+ // content handler
+ bool endDocument() override;
+ bool startElement(const QString &nsURI, const QString &localName, const QString &qName,
+ const QXmlAttributes &atts) override;
+ bool endElement(const QString &nsURI, const QString &localName, const QString &qName) override;
+ bool characters(const QString &ch) override;
+ bool processingInstruction(const QString &target, const QString &data) override;
+ bool skippedEntity(const QString &name) override;
+
+ // error handler
+ bool fatalError(const QXmlParseException &exception) override;
+
+ // lexical handler
+ bool startCDATA() override;
+ bool endCDATA() override;
+ bool startEntity(const QString &) override;
+ bool endEntity(const QString &) override;
+ bool startDTD(const QString &name, const QString &publicId, const QString &systemId) override;
+ bool comment(const QString &ch) override;
+
+ // decl handler
+ bool externalEntityDecl(const QString &name, const QString &publicId,
+ const QString &systemId) override;
+
+ // DTD handler
+ bool notationDecl(const QString &name, const QString &publicId,
+ const QString &systemId) override;
+ bool unparsedEntityDecl(const QString &name, const QString &publicId, const QString &systemId,
+ const QString &notationName) override;
+
+ void setDocumentLocator(QXmlLocator *locator) override;
+
+ QString errorMsg;
+ int errorLine;
+ int errorColumn;
+
+private:
+ QDomDocumentPrivate *doc;
+ QDomNodePrivate *node;
+ QString entityName;
+ bool cdata;
+ bool nsProcessing;
+ QXmlLocator *locator;
+ QXmlSimpleReader *reader;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDOMHELPERS_P_H
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
index 768b227ecd..533d6b17b1 100644
--- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
+++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
@@ -1590,6 +1590,9 @@ void tst_QRhi::renderToWindowSimple()
QScopedPointer<QWindow> window(new QWindow);
switch (impl) {
case QRhi::OpenGLES2:
+#if QT_CONFIG(opengl)
+ window->setFormat(QRhiGles2InitParams::adjustedFormat());
+#endif
Q_FALLTHROUGH();
case QRhi::D3D11:
window->setSurfaceType(QSurface::OpenGLSurface);
diff --git a/tests/auto/network/ssl/qdtls/tst_qdtls.cpp b/tests/auto/network/ssl/qdtls/tst_qdtls.cpp
index e43546937e..3bbde484ce 100644
--- a/tests/auto/network/ssl/qdtls/tst_qdtls.cpp
+++ b/tests/auto/network/ssl/qdtls/tst_qdtls.cpp
@@ -836,10 +836,6 @@ void tst_QDtls::verifyServerCertificate()
void tst_QDtls::verifyClientCertificate_data()
{
-#if !QT_CONFIG(opensslv11)
- QSKIP("This test is not supposed to work with OpenSSL version below 1.1");
-#endif
-
QTest::addColumn<QSslSocket::PeerVerifyMode>("verifyMode");
QTest::addColumn<QList<QSslCertificate>>("clientCerts");
QTest::addColumn<QSslKey>("clientKey");
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 2fef31cdc2..98cb343ff8 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -77,7 +77,7 @@ typedef QSharedPointer<QSslSocket> QSslSocketPtr;
// Detect ALPN (Application-Layer Protocol Negotiation) support
#undef ALPN_SUPPORTED // Undef the variable first to be safe
-#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT)
+#if defined(OPENSSL_VERSION_NUMBER) && !defined(OPENSSL_NO_TLSEXT)
#define ALPN_SUPPORTED 1
#endif
@@ -94,11 +94,13 @@ typedef QSharedPointer<QSslSocket> QSslSocketPtr;
// Use this cipher to force PSK key sharing.
// Also, it's a cipher w/o auth, to check that we emit the signals warning
// about the identity of the peer.
+#ifndef QT_NO_OPENSSL
static const QString PSK_CIPHER_WITHOUT_AUTH = QStringLiteral("PSK-AES256-CBC-SHA");
static const quint16 PSK_SERVER_PORT = 4433;
static const QByteArray PSK_CLIENT_PRESHAREDKEY = QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f");
static const QByteArray PSK_SERVER_IDENTITY_HINT = QByteArrayLiteral("QtTestServerHint");
static const QByteArray PSK_CLIENT_IDENTITY = QByteArrayLiteral("Client_identity");
+#endif // !QT_NO_OPENSSL
class tst_QSslSocket : public QObject
{
@@ -1100,7 +1102,6 @@ void tst_QSslSocket::protocol()
QCOMPARE(socket->protocol(), QSsl::TlsV1_0);
socket->abort();
}
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
{
// qt-test-server probably doesn't allow TLSV1.1
socket->setProtocol(QSsl::TlsV1_1);
@@ -1137,7 +1138,7 @@ void tst_QSslSocket::protocol()
QCOMPARE(socket->protocol(), QSsl::TlsV1_2);
socket->abort();
}
-#endif
+
#ifdef TLS1_3_VERSION
{
// qt-test-server probably doesn't allow TLSV1.3
@@ -2642,7 +2643,6 @@ void tst_QSslSocket::ignoreSslErrorsList()
connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
-// this->socket = &socket;
QSslCertificate cert;
QFETCH(QList<QSslError>, expectedSslErrors);
@@ -4050,9 +4050,6 @@ void tst_QSslSocket::ephemeralServerKey_data()
QTest::addColumn<QString>("cipher");
QTest::addColumn<bool>("emptyKey");
-#if !QT_CONFIG(opensslv11) // 1.1 drops support for RC4-SHA
- QTest::newRow("NonForwardSecrecyCipher") << "RC4-SHA" << true;
-#endif // !opensslv11
QTest::newRow("ForwardSecrecyCipher") << "ECDHE-RSA-AES256-SHA" << (QSslSocket::sslLibraryVersionNumber() < 0x10002000L);
}
@@ -4177,9 +4174,6 @@ void tst_QSslSocket::signatureAlgorithm_data()
if (!QSslSocket::supportsSsl())
QSKIP("Signature algorithms cannot be tested without SSL support");
- if (QSslSocket::sslLibraryVersionNumber() < 0x10002000L)
- QSKIP("Signature algorithms cannot be tested with OpenSSL < 1.0.2");
-
if (QSslSocket::sslLibraryVersionNumber() >= 0x10101000L) {
// FIXME: investigate if this test makes any sense with TLS 1.3.
QSKIP("Test is not valid for TLS 1.3/OpenSSL 1.1.1");