summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qabstractprotocolhandler.cpp2
-rw-r--r--src/network/access/qftp.cpp20
-rw-r--r--src/network/access/qhttpmultipart.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp16
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp20
-rw-r--r--src/network/access/qhttpnetworkreply.cpp10
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp2
-rw-r--r--src/network/access/qhttpprotocolhandler.cpp4
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp18
-rw-r--r--src/network/access/qnetworkaccessauthenticationmanager.cpp2
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp10
-rw-r--r--src/network/access/qnetworkaccesscache.cpp22
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp12
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp44
-rw-r--r--src/network/access/qnetworkaccessmanager.h3
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h2
-rw-r--r--src/network/access/qnetworkcookie.cpp2
-rw-r--r--src/network/access/qnetworkdiskcache.cpp22
-rw-r--r--src/network/access/qnetworkreplyfileimpl.cpp2
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp46
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h7
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp26
-rw-r--r--src/network/access/qnetworkrequest.cpp71
-rw-r--r--src/network/access/qnetworkrequest.h18
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp24
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp4
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp6
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp2
-rw-r--r--src/network/bearer/qnetworksession.cpp2
-rw-r--r--src/network/configure.json23
-rw-r--r--src/network/kernel/qauthenticator.cpp10
-rw-r--r--src/network/kernel/qdnslookup.cpp4
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp8
-rw-r--r--src/network/kernel/qhostaddress.cpp2
-rw-r--r--src/network/kernel/qhostinfo.cpp4
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp8
-rw-r--r--src/network/kernel/qnetworkinterface.cpp4
-rw-r--r--src/network/kernel/qnetworkinterface_p.h2
-rw-r--r--src/network/kernel/qnetworkinterface_unix_p.h2
-rw-r--r--src/network/kernel/qnetworkproxy.cpp12
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp7
-rw-r--r--src/network/kernel/qurlinfo.cpp10
-rw-r--r--src/network/socket/qabstractsocket.cpp14
-rw-r--r--src/network/socket/qabstractsocketengine.cpp6
-rw-r--r--src/network/socket/qhttpsocketengine.cpp16
-rw-r--r--src/network/socket/qlocalserver.cpp2
-rw-r--r--src/network/socket/qlocalserver_unix.cpp2
-rw-r--r--src/network/socket/qlocalsocket.cpp2
-rw-r--r--src/network/socket/qlocalsocket_unix.cpp13
-rw-r--r--src/network/socket/qnativesocketengine.cpp18
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp6
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp15
-rw-r--r--src/network/socket/qsocks5socketengine.cpp28
-rw-r--r--src/network/socket/qtcpserver.cpp6
-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/qssl.h10
-rw-r--r--src/network/ssl/qsslconfiguration.cpp78
-rw-r--r--src/network/ssl/qsslconfiguration.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.cpp47
-rw-r--r--src/network/ssl/qsslsocket.h16
-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_schannel.cpp131
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h1
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp5
-rw-r--r--src/network/ssl/ssl.pri12
82 files changed, 1531 insertions, 2861 deletions
diff --git a/src/network/access/qabstractprotocolhandler.cpp b/src/network/access/qabstractprotocolhandler.cpp
index f15dfe6899..6847816ba7 100644
--- a/src/network/access/qabstractprotocolhandler.cpp
+++ b/src/network/access/qabstractprotocolhandler.cpp
@@ -43,7 +43,7 @@
QT_BEGIN_NAMESPACE
QAbstractProtocolHandler::QAbstractProtocolHandler(QHttpNetworkConnectionChannel *channel)
- : m_channel(channel), m_reply(0), m_socket(m_channel->socket), m_connection(m_channel->connection)
+ : m_channel(channel), m_reply(nullptr), m_socket(m_channel->socket), m_connection(m_channel->connection)
{
Q_ASSERT(m_channel);
Q_ASSERT(m_socket);
diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp
index cc230a5411..62ae1adbd9 100644
--- a/src/network/access/qftp.cpp
+++ b/src/network/access/qftp.cpp
@@ -74,7 +74,7 @@ public:
CsConnectionRefused
};
- QFtpDTP(QFtpPI *p, QObject *parent = 0);
+ QFtpDTP(QFtpPI *p, QObject *parent = nullptr);
void setData(QByteArray *);
void setDevice(QIODevice *);
@@ -149,7 +149,7 @@ class QFtpPI : public QObject
Q_OBJECT
public:
- QFtpPI(QObject *parent = 0);
+ QFtpPI(QObject *parent = nullptr);
void connectToHost(const QString &host, quint16 port);
@@ -229,7 +229,7 @@ class QFtpCommand
{
public:
QFtpCommand(QFtp::Command cmd, const QStringList &raw, const QByteArray &ba);
- QFtpCommand(QFtp::Command cmd, const QStringList &raw, QIODevice *dev = 0);
+ QFtpCommand(QFtp::Command cmd, const QStringList &raw, QIODevice *dev = nullptr);
~QFtpCommand();
int id;
@@ -279,7 +279,7 @@ QFtpCommand::~QFtpCommand()
*********************************************************************/
QFtpDTP::QFtpDTP(QFtpPI *p, QObject *parent) :
QObject(parent),
- socket(0),
+ socket(nullptr),
listener(this),
pi(p),
callWriteData(false)
@@ -314,7 +314,7 @@ void QFtpDTP::connectToHost(const QString & host, quint16 port)
if (socket) {
delete socket;
- socket = 0;
+ socket = nullptr;
}
socket = new QTcpSocket(this);
#ifndef QT_NO_BEARERMANAGEMENT
@@ -427,7 +427,7 @@ void QFtpDTP::writeData()
}
// do we continue uploading?
- callWriteData = data.dev != 0;
+ callWriteData = data.dev != nullptr;
}
}
@@ -779,7 +779,7 @@ void QFtpDTP::setupSocket()
void QFtpDTP::clearData()
{
is_ba = false;
- data.dev = 0;
+ data.dev = nullptr;
}
/**********************************************************************
@@ -792,7 +792,7 @@ QFtpPI::QFtpPI(QObject *parent) :
rawCommand(false),
transferConnectionExtended(true),
dtp(this),
- commandSocket(0),
+ commandSocket(nullptr),
state(Begin), abortState(None),
currentCmd(QString()),
waitForDtpToConnect(false),
@@ -2173,10 +2173,10 @@ QFtp::Command QFtp::currentCommand() const
QIODevice* QFtp::currentDevice() const
{
if (d_func()->pending.isEmpty())
- return 0;
+ return nullptr;
QFtpCommand *c = d_func()->pending.first();
if (c->is_ba)
- return 0;
+ return nullptr;
return c->data.dev;
}
diff --git a/src/network/access/qhttpmultipart.cpp b/src/network/access/qhttpmultipart.cpp
index c59df9d8b8..d6fefc4314 100644
--- a/src/network/access/qhttpmultipart.cpp
+++ b/src/network/access/qhttpmultipart.cpp
@@ -111,7 +111,7 @@ QHttpPart::QHttpPart(const QHttpPart &other) : d(other.d)
*/
QHttpPart::~QHttpPart()
{
- d = 0;
+ d = nullptr;
}
/*!
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 21c6359807..b9a4c874c0 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -382,9 +382,9 @@ void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket,
// Clean the channel
channels[i].close();
- channels[i].reply = 0;
+ channels[i].reply = nullptr;
if (channels[i].protocolHandler)
- channels[i].protocolHandler->setReply(0);
+ channels[i].protocolHandler->setReply(nullptr);
channels[i].request = QHttpNetworkRequest();
if (socket)
channels[i].requeueCurrentlyPipelinedRequests();
@@ -408,7 +408,7 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica
}
// select another channel
- QAuthenticator* otherAuth = 0;
+ QAuthenticator* otherAuth = nullptr;
for (int i = 0; i < activeChannelCount; ++i) {
if (i == fromChannel)
continue;
@@ -441,7 +441,7 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
if (authMethod != QAuthenticatorPrivate::None) {
int i = indexOf(socket);
//Use a single authenticator for all domains. ### change later to use domain/realm
- QAuthenticator* auth = 0;
+ QAuthenticator* auth = nullptr;
if (isProxy) {
auth = &channels[i].proxyAuthenticator;
channels[i].proxyAuthMethod = authMethod;
@@ -496,7 +496,7 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
// we need to bail out if authentication is required.
if (priv->phase == QAuthenticatorPrivate::Done || !reply->request().withCredentials()) {
// Reset authenticator so the next request on that channel does not get messed up
- auth = 0;
+ auth = nullptr;
if (isProxy)
channels[i].proxyAuthenticator = QAuthenticator();
else
@@ -766,7 +766,7 @@ void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket)
int i = indexOf(socket);
// return fast if there was no reply right now processed
- if (channels[i].reply == 0)
+ if (channels[i].reply == nullptr)
return;
if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= defaultRePipelineLength)) {
@@ -937,9 +937,9 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
for (int i = 0; i < activeChannelCount; ++i) {
// is the reply associated the currently processing of this channel?
if (channels[i].reply == reply) {
- channels[i].reply = 0;
+ channels[i].reply = nullptr;
if (channels[i].protocolHandler)
- channels[i].protocolHandler->setReply(0);
+ channels[i].protocolHandler->setReply(nullptr);
channels[i].request = QHttpNetworkRequest();
channels[i].resendCurrent = false;
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 39f392a79b..47081b29d2 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -87,11 +87,11 @@ private:
static const int reconnectAttemptsDefault = 3;
QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
- : socket(0)
+ : socket(nullptr)
, ssl(false)
, isInitialized(false)
, state(IdleState)
- , reply(0)
+ , reply(nullptr)
, written(0)
, bytesTotal(0)
, resendCurrent(false)
@@ -102,13 +102,13 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
, proxyAuthMethod(QAuthenticatorPrivate::None)
, authenticationCredentialsSent(false)
, proxyCredentialsSent(false)
- , protocolHandler(0)
+ , protocolHandler(nullptr)
#ifndef QT_NO_SSL
, ignoreAllSslErrors(false)
#endif
, pipeliningSupported(PipeliningSupportUnknown)
, networkLayerPreference(QAbstractSocket::AnyIPProtocol)
- , connection(0)
+ , connection(nullptr)
{
// Inlining this function in the header leads to compiler error on
// release-armv5, on at least timebox 9.2 and 10.1.
@@ -295,9 +295,9 @@ void QHttpNetworkConnectionChannel::handleUnexpectedEOF()
close();
reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket);
emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString);
- reply = 0;
+ reply = nullptr;
if (protocolHandler)
- protocolHandler->setReply(0);
+ protocolHandler->setReply(nullptr);
request = QHttpNetworkRequest();
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
} else {
@@ -526,8 +526,8 @@ void QHttpNetworkConnectionChannel::allDone()
// problem.
if (!resendCurrent) {
request = QHttpNetworkRequest();
- reply = 0;
- protocolHandler->setReply(0);
+ reply = nullptr;
+ protocolHandler->setReply(nullptr);
}
// move next from pipeline to current request
@@ -1100,9 +1100,9 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (reply) {
reply->d_func()->errorString = errorString;
emit reply->finishedWithError(errorCode, errorString);
- reply = 0;
+ reply = nullptr;
if (protocolHandler)
- protocolHandler->setReply(0);
+ protocolHandler->setReply(nullptr);
}
} while (!connection->d_func()->highPriorityQueue.isEmpty()
|| !connection->d_func()->lowPriorityQueue.isEmpty());
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index a8b635c45a..af456c3607 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -330,12 +330,12 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
currentlyUploadedDataInWindow(0),
totallyUploadedData(0),
removedContentLength(-1),
- connection(0),
+ connection(nullptr),
autoDecompress(false), responseData(), requestIsPrepared(false)
,pipeliningUsed(false), spdyUsed(false), downstreamLimited(false)
- ,userProvidedDownloadBuffer(0)
+ ,userProvidedDownloadBuffer(nullptr)
#ifndef QT_NO_COMPRESS
- ,inflateStrm(0)
+ ,inflateStrm(nullptr)
#endif
{
@@ -375,8 +375,8 @@ void QHttpNetworkReplyPrivate::clearHttpLayerInformation()
// TODO: Isn't everything HTTP layer related? We don't need to set connection and connectionChannel to 0 at all
void QHttpNetworkReplyPrivate::clear()
{
- connection = 0;
- connectionChannel = 0;
+ connection = nullptr;
+ connectionChannel = nullptr;
autoDecompress = false;
clearHttpLayerInformation();
}
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index a3f71b8d2f..5fb8885bdf 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
- : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(0),
+ : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(nullptr),
autoDecompress(false), pipeliningAllowed(false), spdyAllowed(false), http2Allowed(false),
http2Direct(false), withCredentials(true), preConnect(false), redirectCount(0),
redirectPolicy(QNetworkRequest::ManualRedirectPolicy)
diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp
index edcbdcbe0e..d39589fb96 100644
--- a/src/network/access/qhttpprotocolhandler.cpp
+++ b/src/network/access/qhttpprotocolhandler.cpp
@@ -278,7 +278,7 @@ bool QHttpProtocolHandler::sendRequest()
m_reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
m_channel->allDone();
m_connection->preConnectFinished(); // will only decrease the counter
- m_reply = 0; // so we can reuse this channel
+ m_reply = nullptr; // so we can reuse this channel
return true; // we have a working connection and are done
}
@@ -373,7 +373,7 @@ bool QHttpProtocolHandler::sendRequest()
// premature eof happened
m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::UnknownNetworkError);
return false;
- } else if (readPointer == 0 || currentReadSize == 0) {
+ } else if (readPointer == nullptr || currentReadSize == 0) {
// nothing to read currently, break the loop
break;
} else {
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 63a3c4f204..f3125a3a95 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -189,7 +189,7 @@ public:
QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt,
QHttpNetworkConnection::ConnectionType connectionType,
QSharedPointer<QNetworkSession> networkSession)
- : QHttpNetworkConnection(hostName, port, encrypt, connectionType, /*parent=*/0,
+ : QHttpNetworkConnection(hostName, port, encrypt, connectionType, /*parent=*/nullptr,
std::move(networkSession))
#endif
{
@@ -241,9 +241,9 @@ QHttpThreadDelegate::QHttpThreadDelegate(QObject *parent) :
, removedContentLength(-1)
, incomingErrorCode(QNetworkReply::NoError)
, downloadBuffer()
- , httpConnection(0)
- , httpReply(0)
- , synchronousRequestLoop(0)
+ , httpConnection(nullptr)
+ , httpReply(nullptr)
+ , synchronousRequestLoop(nullptr)
{
}
@@ -439,7 +439,7 @@ void QHttpThreadDelegate::abortRequest()
if (httpReply) {
httpReply->abort();
delete httpReply;
- httpReply = 0;
+ httpReply = nullptr;
}
// Got aborted by the timeout timer
@@ -545,7 +545,7 @@ void QHttpThreadDelegate::finishedSlot()
QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
- httpReply = 0;
+ httpReply = nullptr;
}
void QHttpThreadDelegate::synchronousFinishedSlot()
@@ -568,7 +568,7 @@ void QHttpThreadDelegate::synchronousFinishedSlot()
QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection);
- httpReply = 0;
+ httpReply = nullptr;
}
void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail)
@@ -590,7 +590,7 @@ void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError erro
QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
- httpReply = 0;
+ httpReply = nullptr;
}
@@ -609,7 +609,7 @@ void QHttpThreadDelegate::synchronousFinishedWithErrorSlot(QNetworkReply::Networ
QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection);
- httpReply = 0;
+ httpReply = nullptr;
}
static void downloadBufferDeleter(char *ptr)
diff --git a/src/network/access/qnetworkaccessauthenticationmanager.cpp b/src/network/access/qnetworkaccessauthenticationmanager.cpp
index b661cc45b3..0df11684b1 100644
--- a/src/network/access/qnetworkaccessauthenticationmanager.cpp
+++ b/src/network/access/qnetworkaccessauthenticationmanager.cpp
@@ -71,7 +71,7 @@ public:
if (it == end() && !isEmpty())
--it;
if (it == end() || !domain.startsWith(it->domain))
- return 0;
+ return nullptr;
return &*it;
}
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 566e410051..8f42f3690b 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -105,7 +105,7 @@ QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessM
++it;
}
}
- return 0;
+ return nullptr;
}
QStringList QNetworkAccessManagerPrivate::backendSupportedSchemes() const
@@ -131,7 +131,7 @@ QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
else if (reply->outgoingData) {
uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingData);
} else {
- return 0;
+ return nullptr;
}
// We want signal emissions only for normal asynchronous uploads
@@ -151,8 +151,8 @@ void QNetworkAccessBackend::emitReplyUploadProgress(qint64 bytesSent, qint64 byt
}
QNetworkAccessBackend::QNetworkAccessBackend()
- : manager(0)
- , reply(0)
+ : manager(nullptr)
+ , reply(nullptr)
, synchronous(false)
{
}
@@ -223,7 +223,7 @@ QList<QNetworkProxy> QNetworkAccessBackend::proxyList() const
QAbstractNetworkCache *QNetworkAccessBackend::networkCache() const
{
if (!manager)
- return 0;
+ return nullptr;
return manager->networkCache;
}
diff --git a/src/network/access/qnetworkaccesscache.cpp b/src/network/access/qnetworkaccesscache.cpp
index b694a2c999..ba092f2618 100644
--- a/src/network/access/qnetworkaccesscache.cpp
+++ b/src/network/access/qnetworkaccesscache.cpp
@@ -73,7 +73,7 @@ struct QNetworkAccessCache::Node
int useCount;
Node()
- : older(0), newer(0), object(0), useCount(0)
+ : older(nullptr), newer(nullptr), object(nullptr), useCount(0)
{ }
};
@@ -103,7 +103,7 @@ void QNetworkAccessCache::CacheableObject::setShareable(bool enable)
}
QNetworkAccessCache::QNetworkAccessCache()
- : oldest(0), newest(0)
+ : oldest(nullptr), newest(nullptr)
{
}
@@ -130,7 +130,7 @@ void QNetworkAccessCache::clear()
timer.stop();
- oldest = newest = 0;
+ oldest = newest = nullptr;
}
/*!
@@ -145,11 +145,11 @@ void QNetworkAccessCache::linkEntry(const QByteArray &key)
Node *const node = &it.value();
Q_ASSERT(node != oldest && node != newest);
- Q_ASSERT(node->older == 0 && node->newer == 0);
+ Q_ASSERT(node->older == nullptr && node->newer == nullptr);
Q_ASSERT(node->useCount == 0);
if (newest) {
- Q_ASSERT(newest->newer == 0);
+ Q_ASSERT(newest->newer == nullptr);
newest->newer = node;
node->older = newest;
}
@@ -186,7 +186,7 @@ bool QNetworkAccessCache::unlinkEntry(const QByteArray &key)
if (node->newer)
node->newer->older = node->older;
- node->newer = node->older = 0;
+ node->newer = node->older = nullptr;
return wasOldest;
}
@@ -235,9 +235,9 @@ void QNetworkAccessCache::timerEvent(QTimerEvent *)
// fixup the list
if (oldest)
- oldest->older = 0;
+ oldest->older = nullptr;
else
- newest = 0;
+ newest = nullptr;
updateTimer();
}
@@ -277,7 +277,7 @@ bool QNetworkAccessCache::requestEntry(const QByteArray &key, QObject *target, c
if (node->useCount > 0 && !node->object->shareable) {
// object is not shareable and is in use
// queue for later use
- Q_ASSERT(node->older == 0 && node->newer == 0);
+ Q_ASSERT(node->older == nullptr && node->newer == nullptr);
node->receiverQueue.push_back({target, member});
// request queued
@@ -296,7 +296,7 @@ QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const
{
NodeHash::Iterator it = hash.find(key);
if (it == hash.end())
- return 0;
+ return nullptr;
if (it->useCount > 0) {
if (it->object->shareable) {
++it->useCount;
@@ -304,7 +304,7 @@ QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const
}
// object in use and not shareable
- return 0;
+ return nullptr;
}
// entry not in use, let the caller have it
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index 67a856506c..03ffc69628 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -70,13 +70,13 @@ QNetworkAccessDebugPipeBackendFactory::create(QNetworkAccessManager::Operation o
default:
// no, we can't handle this operation
- return 0;
+ return nullptr;
}
QUrl url = request.url();
if (url.scheme() == QLatin1String("debugpipe"))
return new QNetworkAccessDebugPipeBackend;
- return 0;
+ return nullptr;
}
QNetworkAccessDebugPipeBackend::QNetworkAccessDebugPipeBackend()
@@ -188,7 +188,7 @@ void QNetworkAccessDebugPipeBackend::pushFromUpstreamToSocket()
emitReplyUploadProgress(bytesUploaded, bytesUploaded);
possiblyFinish();
break;
- } else if (haveRead == 0 || readPointer == 0) {
+ } else if (haveRead == 0 || readPointer == nullptr) {
// nothing to read right now, we will be called again later
break;
} else {
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index 60353cb03e..507417f86c 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -73,7 +73,7 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
default:
// no, we can't handle this operation
- return 0;
+ return nullptr;
}
QUrl url = request.url();
@@ -95,7 +95,7 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
return new QNetworkAccessFileBackend;
}
- return 0;
+ return nullptr;
}
QNetworkAccessFileBackend::QNetworkAccessFileBackend()
@@ -198,7 +198,7 @@ void QNetworkAccessFileBackend::uploadReadyReadSlot()
file.close();
finished();
break;
- } else if (haveRead == 0 || readPointer == 0) {
+ } else if (haveRead == 0 || readPointer == nullptr) {
// nothing to read right now, we will be called again later
break;
} else {
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 51ed2f5a55..fb8cd79c12 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -75,13 +75,13 @@ QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
default:
// no, we can't handle this operation
- return 0;
+ return nullptr;
}
QUrl url = request.url();
if (url.scheme().compare(QLatin1String("ftp"), Qt::CaseInsensitive) == 0)
return new QNetworkAccessFtpBackend;
- return 0;
+ return nullptr;
}
class QNetworkAccessCachedFtpConnection: public QFtp, public QNetworkAccessCache::CacheableObject
@@ -104,7 +104,7 @@ public:
};
QNetworkAccessFtpBackend::QNetworkAccessFtpBackend()
- : ftp(0), uploadDevice(0), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1),
+ : ftp(nullptr), uploadDevice(nullptr), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1),
supportsSize(false), supportsMdtm(false), supportsPwd(false), state(Idle)
{
}
@@ -215,7 +215,7 @@ void QNetworkAccessFtpBackend::disconnectFromFtp(CacheCleanupMode mode)
state = Disconnecting;
if (ftp) {
- disconnect(ftp, 0, this, 0);
+ disconnect(ftp, nullptr, this, nullptr);
QByteArray key = makeCacheKey(url());
if (mode == RemoveCachedConnection) {
@@ -225,7 +225,7 @@ void QNetworkAccessFtpBackend::disconnectFromFtp(CacheCleanupMode mode)
QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key);
}
- ftp = 0;
+ ftp = nullptr;
}
}
@@ -362,7 +362,7 @@ void QNetworkAccessFtpBackend::ftpDone()
QFtp::TransferType type = QFtp::Binary;
if (operation() == QNetworkAccessManager::GetOperation) {
setCachingEnabled(true);
- ftp->get(url().path(), 0, type);
+ ftp->get(url().path(), nullptr, type);
} else {
ftp->put(uploadDevice, url().path(), type);
}
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 76b95b5823..ff916ff283 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1240,7 +1240,7 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin
// There is no way to enable SPDY/HTTP2 via a request, so we need to check
// the ssl configuration whether SPDY/HTTP2 is allowed here.
if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::ALPNProtocolHTTP2))
- request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
+ request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true);
else if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::NextProtocolSpdy3_0))
request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true);
@@ -1404,6 +1404,11 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, redirectPolicy());
}
+#if QT_CONFIG(http)
+ if (!req.transferTimeout())
+ req.setTransferTimeout(transferTimeout());
+#endif
+
if (autoDeleteReplies()
&& req.attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute).isNull()) {
req.setAttribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, true);
@@ -1713,6 +1718,41 @@ void QNetworkAccessManager::setAutoDeleteReplies(bool shouldAutoDelete)
d_func()->autoDeleteReplies = shouldAutoDelete;
}
+/*!
+ \since 5.15
+
+ Returns the timeout used for transfers, in milliseconds.
+
+ This timeout is zero if setTransferTimeout() hasn't been
+ called, which means that the timeout is not used.
+*/
+int QNetworkAccessManager::transferTimeout() const
+{
+ return d_func()->transferTimeout;
+}
+
+/*!
+ \since 5.15
+
+ Sets \a timeout as the transfer timeout in milliseconds.
+
+ Transfers are aborted if no bytes are transferred before
+ the timeout expires. Zero means no timer is set. If no
+ argument is provided, the timeout is
+ QNetworkRequest::TransferTimeoutPreset. If this function
+ is not called, the timeout is disabled and has the
+ value zero. The request-specific non-zero timeouts set for
+ the requests that are executed override this value. This means
+ that if QNetworkAccessManager has an enabled timeout, it needs
+ to be disabled to execute a request without a timeout.
+
+ \sa transferTimeout()
+*/
+void QNetworkAccessManager::setTransferTimeout(int timeout)
+{
+ d_func()->transferTimeout = timeout;
+}
+
void QNetworkAccessManagerPrivate::_q_replyFinished()
{
Q_Q(QNetworkAccessManager);
@@ -1941,7 +1981,7 @@ void QNetworkAccessManagerPrivate::destroyThread()
{
if (thread) {
thread->quit();
- thread->wait(5000);
+ thread->wait(QDeadlineTimer(5000));
if (thread->isFinished())
delete thread;
else
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 98498d07d2..aa4765a043 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -170,6 +170,9 @@ public:
bool autoDeleteReplies() const;
void setAutoDeleteReplies(bool autoDelete);
+ int transferTimeout() const;
+ void setTransferTimeout(int timeout = QNetworkRequest::TransferTimeoutPreset);
+
Q_SIGNALS:
#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 67ea2094b3..d558f61eed 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -229,6 +229,8 @@ public:
bool autoDeleteReplies = false;
+ int transferTimeout = 0;
+
#ifndef QT_NO_BEARERMANAGEMENT
Q_AUTOTEST_EXPORT static const QWeakPointer<const QNetworkSession> getNetworkSession(const QNetworkAccessManager *manager);
#endif
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index 903de322ff..47f6112b22 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -131,7 +131,7 @@ QNetworkCookie::QNetworkCookie(const QNetworkCookie &other)
QNetworkCookie::~QNetworkCookie()
{
// QSharedDataPointer auto deletes
- d = 0;
+ d = nullptr;
}
/*!
diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp
index df2e4902a4..b30d1c9664 100644
--- a/src/network/access/qnetworkdiskcache.cpp
+++ b/src/network/access/qnetworkdiskcache.cpp
@@ -180,11 +180,11 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData)
#endif
Q_D(QNetworkDiskCache);
if (!metaData.isValid() || !metaData.url().isValid() || !metaData.saveToDisk())
- return 0;
+ return nullptr;
if (d->cacheDirectory.isEmpty()) {
qWarning("QNetworkDiskCache::prepare() The cache directory is not set");
- return 0;
+ return nullptr;
}
const auto headers = metaData.rawHeaders();
@@ -192,14 +192,14 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData)
if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) {
const qint64 size = header.second.toLongLong();
if (size > (maximumCacheSize() * 3)/4)
- return 0;
+ return nullptr;
break;
}
}
QScopedPointer<QCacheItem> cacheItem(new QCacheItem);
cacheItem->metaData = metaData;
- QIODevice *device = 0;
+ QIODevice *device = nullptr;
if (cacheItem->canCompress()) {
cacheItem->data.open(QBuffer::ReadWrite);
device = &(cacheItem->data);
@@ -208,12 +208,12 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData)
QT_TRY {
cacheItem->file = new QTemporaryFile(templateName, &cacheItem->data);
} QT_CATCH(...) {
- cacheItem->file = 0;
+ cacheItem->file = nullptr;
}
if (!cacheItem->file || !cacheItem->file->open()) {
qWarning("QNetworkDiskCache::prepare() unable to open temporary file");
cacheItem.reset();
- return 0;
+ return nullptr;
}
cacheItem->writeHeader(cacheItem->file);
device = cacheItem->file;
@@ -397,19 +397,19 @@ QIODevice *QNetworkDiskCache::data(const QUrl &url)
Q_D(QNetworkDiskCache);
QScopedPointer<QBuffer> buffer;
if (!url.isValid())
- return 0;
+ return nullptr;
if (d->lastItem.metaData.url() == url && d->lastItem.data.isOpen()) {
buffer.reset(new QBuffer);
buffer->setData(d->lastItem.data.data());
} else {
QScopedPointer<QFile> file(new QFile(d->cacheFileName(url)));
if (!file->open(QFile::ReadOnly | QIODevice::Unbuffered))
- return 0;
+ return nullptr;
if (!d->lastItem.read(file.data(), true)) {
file->close();
remove(url);
- return 0;
+ return nullptr;
}
if (d->lastItem.data.isOpen()) {
// compressed
@@ -419,7 +419,7 @@ QIODevice *QNetworkDiskCache::data(const QUrl &url)
buffer.reset(new QBuffer);
// ### verify that QFile uses the fd size and not the file name
qint64 size = file->size() - file->pos();
- const uchar *p = 0;
+ const uchar *p = nullptr;
#if !defined(Q_OS_INTEGRITY)
p = file->map(file->pos(), size);
#endif
@@ -557,7 +557,7 @@ qint64 QNetworkDiskCache::expire()
for (QCacheItem *item : qAsConst(d->inserting)) {
if (item && item->file && item->file->fileName() == name) {
delete item->file;
- item->file = 0;
+ item->file = nullptr;
break;
}
}
diff --git a/src/network/access/qnetworkreplyfileimpl.cpp b/src/network/access/qnetworkreplyfileimpl.cpp
index ef319ebf0d..afab8ffd94 100644
--- a/src/network/access/qnetworkreplyfileimpl.cpp
+++ b/src/network/access/qnetworkreplyfileimpl.cpp
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
QNetworkReplyFileImplPrivate::QNetworkReplyFileImplPrivate()
- : QNetworkReplyPrivate(), managerPrivate(0), realFile(0)
+ : QNetworkReplyPrivate(), managerPrivate(nullptr), realFile(nullptr)
{
qRegisterMetaType<QNetworkRequest::KnownHeaders>();
qRegisterMetaType<QNetworkReply::NetworkError>();
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 8ac81d1780..ba9d0a76d5 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -461,6 +461,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate()
, preMigrationDownloaded(-1)
, bytesDownloaded(0)
, bytesBuffered(0)
+ , transferTimeout(nullptr)
, downloadBufferReadPosition(0)
, downloadBufferCurrentSize(0)
, downloadZerocopyBuffer(nullptr)
@@ -777,7 +778,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool())
httpRequest.setSPDYAllowed(true);
- if (request.attribute(QNetworkRequest::HTTP2AllowedAttribute).toBool())
+ if (request.attribute(QNetworkRequest::Http2AllowedAttribute).toBool())
httpRequest.setHTTP2Allowed(true);
if (request.attribute(QNetworkRequest::Http2DirectAttribute).toBool()) {
@@ -985,7 +986,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
}
thread->quit();
- thread->wait(5000);
+ thread->wait(QDeadlineTimer(5000));
if (thread->isFinished())
delete thread;
else
@@ -1067,6 +1068,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d)
if (!isHttpRedirectResponse()) {
buffer.append(d);
bytesDownloaded += d.size();
+ setupTransferTimeout();
}
bytesBuffered += d.size();
@@ -1280,15 +1282,15 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
}
q->setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, pu);
- const QVariant http2Allowed = request.attribute(QNetworkRequest::HTTP2AllowedAttribute);
+ const QVariant http2Allowed = request.attribute(QNetworkRequest::Http2AllowedAttribute);
const QVariant http2Direct = request.attribute(QNetworkRequest::Http2DirectAttribute);
if ((http2Allowed.isValid() && http2Allowed.toBool())
|| (http2Direct.isValid() && http2Direct.toBool())) {
- q->setAttribute(QNetworkRequest::HTTP2WasUsedAttribute, spdyWasUsed);
+ q->setAttribute(QNetworkRequest::Http2WasUsedAttribute, spdyWasUsed);
q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, false);
} else {
q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, spdyWasUsed);
- q->setAttribute(QNetworkRequest::HTTP2WasUsedAttribute, false);
+ q->setAttribute(QNetworkRequest::Http2WasUsedAttribute, false);
}
// reconstruct the HTTP header
@@ -1401,6 +1403,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadProgressSlot(qint64 bytesReceive
return;
bytesDownloaded = bytesReceived;
+ setupTransferTimeout();
downloadBufferCurrentSize = bytesReceived;
@@ -1857,7 +1860,6 @@ bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer<QNetworkSe
void QNetworkReplyHttpImplPrivate::_q_startOperation()
{
Q_Q(QNetworkReplyHttpImpl);
-
if (state == Working) // ensure this function is only being called once
return;
@@ -1897,6 +1899,7 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
}
#endif // QT_NO_BEARERMANAGEMENT
+ setupTransferTimeout();
if (synchronous) {
state = Finished;
q_func()->setFinished(true);
@@ -2033,6 +2036,31 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData()
}
}
+void QNetworkReplyHttpImplPrivate::_q_transferTimedOut()
+{
+ Q_Q(QNetworkReplyHttpImpl);
+ q->abort();
+}
+
+void QNetworkReplyHttpImplPrivate::setupTransferTimeout()
+{
+ Q_Q(QNetworkReplyHttpImpl);
+ if (!transferTimeout) {
+ transferTimeout = new QTimer(q);
+ QObject::connect(transferTimeout, SIGNAL(timeout()),
+ q, SLOT(_q_transferTimedOut()),
+ Qt::QueuedConnection);
+ }
+ transferTimeout->stop();
+ if (request.transferTimeout()) {
+ transferTimeout->setSingleShot(true);
+ transferTimeout->setInterval(request.transferTimeout());
+ QMetaObject::invokeMethod(transferTimeout, "start",
+ Qt::QueuedConnection);
+
+ }
+}
+
#ifndef QT_NO_BEARERMANAGEMENT
void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected()
{
@@ -2115,6 +2143,8 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin
if (isFinished)
return;
+ setupTransferTimeout();
+
if (!emitAllUploadProgressSignals) {
//choke signal emissions, except the first and last signals which are unconditional
if (uploadProgressSignalChoke.isValid()) {
@@ -2126,7 +2156,6 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin
uploadProgressSignalChoke.start();
}
}
-
emit q->uploadProgress(bytesSent, bytesTotal);
}
@@ -2159,7 +2188,8 @@ void QNetworkReplyHttpImplPrivate::_q_finished()
void QNetworkReplyHttpImplPrivate::finished()
{
Q_Q(QNetworkReplyHttpImpl);
-
+ if (transferTimeout)
+ transferTimeout->stop();
if (state == Finished || state == Aborted || state == WaitingForSession)
return;
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index ef69ce0653..dec0c4c589 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -59,6 +59,7 @@
#include "QtCore/qdatetime.h"
#include "QtCore/qsharedpointer.h"
#include "QtCore/qscopedpointer.h"
+#include "QtCore/qtimer.h"
#include "qatomic.h"
#include <QtNetwork/QNetworkCacheMetaData>
@@ -100,6 +101,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void _q_cacheLoadReadyRead())
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_transferTimedOut())
#ifndef QT_NO_BEARERMANAGEMENT
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected())
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed())
@@ -181,6 +183,9 @@ public:
void _q_cacheSaveDeviceAboutToClose();
+ void _q_transferTimedOut();
+ void setupTransferTimeout();
+
#ifndef QT_NO_BEARERMANAGEMENT
void _q_networkSessionConnected();
void _q_networkSessionFailed();
@@ -250,6 +255,8 @@ public:
qint64 bytesDownloaded;
qint64 bytesBuffered;
+ QTimer *transferTimeout;
+
// Only used when the "zero copy" style is used.
// Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
qint64 downloadBufferReadPosition;
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 6eab500e8c..a43a29a239 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -53,9 +53,9 @@
QT_BEGIN_NAMESPACE
inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
- : backend(0), outgoingData(0),
- copyDevice(0),
- cacheEnabled(false), cacheSaveDevice(0),
+ : backend(nullptr), outgoingData(nullptr),
+ copyDevice(nullptr),
+ cacheEnabled(false), cacheSaveDevice(nullptr),
notificationHandlingPaused(false),
bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), preMigrationDownloaded(-1),
httpStatusCode(0),
@@ -63,7 +63,7 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
, downloadBufferReadPosition(0)
, downloadBufferCurrentSize(0)
, downloadBufferMaximumSize(0)
- , downloadBuffer(0)
+ , downloadBuffer(nullptr)
{
if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool() == true)
emitAllUploadProgressSignals = true;
@@ -489,7 +489,7 @@ void QNetworkReplyImplPrivate::resumeNotificationHandling()
QAbstractNetworkCache *QNetworkReplyImplPrivate::networkCache() const
{
if (!backend)
- return 0;
+ return nullptr;
return backend->networkCache();
}
@@ -504,7 +504,7 @@ void QNetworkReplyImplPrivate::createCache()
bool QNetworkReplyImplPrivate::isCachingEnabled() const
{
- return (cacheEnabled && networkCache() != 0);
+ return (cacheEnabled && networkCache() != nullptr);
}
void QNetworkReplyImplPrivate::setCachingEnabled(bool enable)
@@ -529,7 +529,7 @@ void QNetworkReplyImplPrivate::setCachingEnabled(bool enable)
"backend %s probably needs to be fixed",
backend->metaObject()->className());
networkCache()->remove(url);
- cacheSaveDevice = 0;
+ cacheSaveDevice = nullptr;
cacheEnabled = false;
}
}
@@ -541,7 +541,7 @@ void QNetworkReplyImplPrivate::completeCacheSave()
} else if (cacheEnabled && cacheSaveDevice) {
networkCache()->insert(cacheSaveDevice);
}
- cacheSaveDevice = 0;
+ cacheSaveDevice = nullptr;
cacheEnabled = false;
}
@@ -610,7 +610,7 @@ void QNetworkReplyImplPrivate::initCacheSaveDevice()
networkCache()->metaObject()->className());
networkCache()->remove(url);
- cacheSaveDevice = 0;
+ cacheSaveDevice = nullptr;
cacheEnabled = false;
}
}
@@ -927,9 +927,9 @@ void QNetworkReplyImpl::abort()
// stop both upload and download
if (d->outgoingData)
- disconnect(d->outgoingData, 0, this, 0);
+ disconnect(d->outgoingData, nullptr, this, nullptr);
if (d->copyDevice)
- disconnect(d->copyDevice, 0, this, 0);
+ disconnect(d->copyDevice, nullptr, this, nullptr);
QNetworkReply::close();
@@ -943,7 +943,7 @@ void QNetworkReplyImpl::abort()
// finished may access the backend
if (d->backend) {
d->backend->deleteLater();
- d->backend = 0;
+ d->backend = nullptr;
}
}
@@ -958,7 +958,7 @@ void QNetworkReplyImpl::close()
if (d->backend)
d->backend->closeDownstreamChannel();
if (d->copyDevice)
- disconnect(d->copyDevice, 0, this, 0);
+ disconnect(d->copyDevice, nullptr, this, nullptr);
QNetworkReply::close();
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 118fb6b1fb..70b09dba22 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -277,23 +277,30 @@ QT_BEGIN_NAMESPACE
Indicates whether the QNetworkAccessManager code is
allowed to use SPDY with this request. This applies only
to SSL requests, and depends on the server supporting SPDY.
+ Obsolete, use Http2 instead of Spdy.
\value SpdyWasUsedAttribute
Replies only, type: QMetaType::Bool
Indicates whether SPDY was used for receiving
- this reply.
+ this reply. Obsolete, use Http2 instead of Spdy.
- \value HTTP2AllowedAttribute
+ \value Http2AllowedAttribute
Requests only, type: QMetaType::Bool (default: false)
Indicates whether the QNetworkAccessManager code is
allowed to use HTTP/2 with this request. This applies
to SSL requests or 'cleartext' HTTP/2.
- \value HTTP2WasUsedAttribute
+ \value Http2WasUsedAttribute
Replies only, type: QMetaType::Bool (default: false)
Indicates whether HTTP/2 was used for receiving this reply.
(This value was introduced in 5.9.)
+ \value HTTP2AllowedAttribute
+ Obsolete alias for Http2AllowedAttribute.
+
+ \value HTTP2WasUsedAttribute
+ Obsolete alias for Http2WasUsedAttribute.
+
\value EmitAllUploadProgressSignalsAttribute
Requests only, type: QMetaType::Bool (default: false)
Indicates whether all upload signals should be emitted.
@@ -329,7 +336,7 @@ QT_BEGIN_NAMESPACE
server supports HTTP/2. The attribute works with SSL or 'cleartext'
HTTP/2. If a server turns out to not support HTTP/2, when HTTP/2 direct
was specified, QNetworkAccessManager gives up, without attempting to
- fall back to HTTP/1.1. If both HTTP2AllowedAttribute and
+ fall back to HTTP/1.1. If both Http2AllowedAttribute and
Http2DirectAttribute are set, Http2DirectAttribute takes priority.
(This value was introduced in 5.11.)
@@ -418,6 +425,18 @@ QT_BEGIN_NAMESPACE
based on some app-specific configuration.
*/
+/*!
+ \enum QNetworkRequest::TransferTimeoutConstant
+ \since 5.15
+
+ A constant that can be used for enabling transfer
+ timeouts with a preset value.
+
+ \value TransferTimeoutPreset The transfer timeout in milliseconds.
+ Used if setTimeout() is called
+ without an argument.
+ */
+
class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate
{
public:
@@ -425,9 +444,10 @@ public:
inline QNetworkRequestPrivate()
: priority(QNetworkRequest::NormalPriority)
#ifndef QT_NO_SSL
- , sslConfiguration(0)
+ , sslConfiguration(nullptr)
#endif
, maxRedirectsAllowed(maxRedirectCount)
+ , transferTimeout(0)
{ qRegisterMetaType<QNetworkRequest>(); }
~QNetworkRequestPrivate()
{
@@ -444,7 +464,7 @@ public:
priority = other.priority;
maxRedirectsAllowed = other.maxRedirectsAllowed;
#ifndef QT_NO_SSL
- sslConfiguration = 0;
+ sslConfiguration = nullptr;
if (other.sslConfiguration)
sslConfiguration = new QSslConfiguration(*other.sslConfiguration);
#endif
@@ -452,6 +472,7 @@ public:
#if QT_CONFIG(http)
h2Configuration = other.h2Configuration;
#endif
+ transferTimeout = other.transferTimeout;
}
inline bool operator==(const QNetworkRequestPrivate &other) const
@@ -465,6 +486,7 @@ public:
#if QT_CONFIG(http)
&& h2Configuration == other.h2Configuration
#endif
+ && transferTimeout == other.transferTimeout
;
// don't compare cookedHeaders
}
@@ -479,6 +501,7 @@ public:
#if QT_CONFIG(http)
QHttp2Configuration h2Configuration;
#endif
+ int transferTimeout;
};
/*!
@@ -527,7 +550,7 @@ QNetworkRequest::QNetworkRequest(const QNetworkRequest &other)
QNetworkRequest::~QNetworkRequest()
{
// QSharedDataPointer auto deletes
- d = 0;
+ d = nullptr;
}
/*!
@@ -902,6 +925,40 @@ void QNetworkRequest::setHttp2Configuration(const QHttp2Configuration &configura
{
d->h2Configuration = configuration;
}
+
+/*!
+ \since 5.15
+
+ Returns the timeout used for transfers, in milliseconds.
+
+ This timeout is zero if setTransferTimeout hasn't been
+ called, which means that the timeout is not used.
+
+ \sa setTransferTimeout
+*/
+int QNetworkRequest::transferTimeout() const
+{
+ return d->transferTimeout;
+}
+
+/*!
+ \since 5.15
+
+ Sets \a timeout as the transfer timeout in milliseconds.
+
+ Transfers are aborted if no bytes are transferred before
+ the timeout expires. Zero means no timer is set. If no
+ argument is provided, the timeout is
+ QNetworkRequest::TransferTimeoutPreset. If this function
+ is not called, the timeout is disabled and has the
+ value zero.
+
+ \sa transferTimeout
+*/
+void QNetworkRequest::setTransferTimeout(int timeout)
+{
+ d->transferTimeout = timeout;
+}
#endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC)
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index e09ff8aaae..dcd2c6b61f 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -89,12 +89,18 @@ public:
DownloadBufferAttribute, // internal
SynchronousRequestAttribute, // internal
BackgroundRequestAttribute,
+#if QT_DEPRECATED_SINCE(5, 15)
SpdyAllowedAttribute,
SpdyWasUsedAttribute,
- EmitAllUploadProgressSignalsAttribute,
+#endif // QT_DEPRECATED_SINCE(5, 15)
+ EmitAllUploadProgressSignalsAttribute = BackgroundRequestAttribute + 3,
FollowRedirectsAttribute,
- HTTP2AllowedAttribute,
- HTTP2WasUsedAttribute,
+ Http2AllowedAttribute,
+ Http2WasUsedAttribute,
+#if QT_DEPRECATED_SINCE(5, 15)
+ HTTP2AllowedAttribute Q_DECL_ENUMERATOR_DEPRECATED_X("Use Http2AllowedAttribute") = Http2AllowedAttribute,
+ HTTP2WasUsedAttribute Q_DECL_ENUMERATOR_DEPRECATED_X("Use Http2WasUsedAttribute"),
+#endif // QT_DEPRECATED_SINCE(5, 15)
OriginalContentLengthAttribute,
RedirectPolicyAttribute,
Http2DirectAttribute,
@@ -128,6 +134,9 @@ public:
UserVerifiedRedirectPolicy
};
+ enum TransferTimeoutConstant {
+ TransferTimeoutPreset = 30000
+ };
QNetworkRequest();
explicit QNetworkRequest(const QUrl &url);
@@ -179,6 +188,9 @@ public:
#if QT_CONFIG(http) || defined(Q_CLANG_QDOC)
QHttp2Configuration http2Configuration() const;
void setHttp2Configuration(const QHttp2Configuration &configuration);
+
+ int transferTimeout() const;
+ void setTransferTimeout(int timeout = TransferTimeoutPreset);
#endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC)
private:
QSharedDataPointer<QNetworkRequestPrivate> d;
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index f845235bf7..eef8df288d 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -254,7 +254,7 @@ static const char spdyDictionary[] = {
//}
QSpdyProtocolHandler::QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel)
- : QObject(0), QAbstractProtocolHandler(channel),
+ : QObject(nullptr), QAbstractProtocolHandler(channel),
m_nextStreamID(-1),
m_maxConcurrentStreams(100), // 100 is recommended in the SPDY RFC
m_initialWindowSize(0),
@@ -613,7 +613,7 @@ void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair,
QHttpNetworkRequest request = messagePair.first;
QHttpNetworkReply *reply = messagePair.second;
- ControlFrameFlags flags = 0;
+ ControlFrameFlags flags;
if (!request.uploadByteDevice()) {
// no upload -> this is the last frame, send the FIN flag
@@ -675,14 +675,14 @@ void QSpdyProtocolHandler::sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_COD
char wireData[8];
appendIntToFourBytes(wireData, streamID);
appendIntToFourBytes(wireData + 4, statusCode);
- sendControlFrame(FrameType_RST_STREAM, /* flags = */ 0, wireData, /* length = */ 8);
+ sendControlFrame(FrameType_RST_STREAM, /* flags = */ { }, wireData, /* length = */ 8);
}
void QSpdyProtocolHandler::sendPING(quint32 pingID)
{
char rawData[4];
appendIntToFourBytes(rawData, pingID);
- sendControlFrame(FrameType_PING, /* flags = */ 0, rawData, /* length = */ 4);
+ sendControlFrame(FrameType_PING, /* flags = */ { }, rawData, /* length = */ 4);
}
bool QSpdyProtocolHandler::uploadData(qint32 streamID)
@@ -720,11 +720,11 @@ bool QSpdyProtocolHandler::uploadData(qint32 streamID)
m_connection->d_func()->emitReplyError(m_socket, reply,
QNetworkReply::UnknownNetworkError);
return false;
- } else if (readPointer == 0 || currentReadSize == 0) {
+ } else if (readPointer == nullptr || currentReadSize == 0) {
// nothing to read currently, break the loop
break;
} else {
- DataFrameFlags flags = 0;
+ DataFrameFlags flags;
// we will send the FIN flag later if appropriate
qint64 currentWriteSize = sendDataFrame(streamID, flags, currentReadSize, readPointer);
if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
@@ -746,7 +746,7 @@ bool QSpdyProtocolHandler::uploadData(qint32 streamID)
}
if (replyPrivate->totallyUploadedData == request.contentLength()) {
DataFrameFlags finFlag = DataFrame_FLAG_FIN;
- qint64 writeSize = sendDataFrame(streamID, finFlag, 0, 0);
+ qint64 writeSize = sendDataFrame(streamID, finFlag, 0, nullptr);
Q_ASSERT(writeSize == 0);
Q_UNUSED(writeSize); // silence -Wunused-variable
replyPrivate->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;
@@ -774,7 +774,7 @@ void QSpdyProtocolHandler::sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindo
appendIntToFourBytes(windowUpdateData, streamID);
appendIntToFourBytes(windowUpdateData + 4, deltaWindowSize);
- sendControlFrame(FrameType_WINDOW_UPDATE, /* flags = */ 0, windowUpdateData, /* length = */ 8);
+ sendControlFrame(FrameType_WINDOW_UPDATE, /* flags = */ { }, windowUpdateData, /* length = */ 8);
}
qint64 QSpdyProtocolHandler::sendDataFrame(qint32 streamID, DataFrameFlags flags,
@@ -892,7 +892,7 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
HttpMessagePair pair = it.value();
QHttpNetworkReply *httpReply = pair.second;
- Q_ASSERT(httpReply != 0);
+ Q_ASSERT(httpReply != nullptr);
if (httpReply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);
@@ -950,7 +950,7 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
if (flag_fin) {
if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
- sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
+ sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, nullptr);
replyFinished(httpReply, streamID);
}
}
@@ -1199,7 +1199,7 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)
HttpMessagePair pair = it.value();
QHttpNetworkRequest httpRequest = pair.first;
QHttpNetworkReply *httpReply = pair.second;
- Q_ASSERT(httpReply != 0);
+ Q_ASSERT(httpReply != nullptr);
QHttpNetworkReplyPrivate *replyPrivate = httpReply->d_func();
@@ -1261,7 +1261,7 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)
if (flag_fin) {
if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
- sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
+ sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, nullptr);
replyFinished(httpReply, streamID);
}
}
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index cd87c3669c..751735c8bd 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -68,7 +68,7 @@ static void connManager_cleanup()
int shutdown = appShutdown.fetchAndStoreAcquire(1);
Q_ASSERT(shutdown == 0);
Q_UNUSED(shutdown);
- QNetworkConfigurationManagerPrivate *cmp = connManager_ptr.fetchAndStoreAcquire(0);
+ QNetworkConfigurationManagerPrivate *cmp = connManager_ptr.fetchAndStoreAcquire(nullptr);
if (cmp)
cmp->cleanup();
}
@@ -355,7 +355,7 @@ QNetworkConfigurationManager::Capabilities QNetworkConfigurationManager::capabil
if (priv)
return priv->capabilities();
- return QNetworkConfigurationManager::Capabilities(0);
+ return {};
}
/*!
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index b432444669..f0aa452dd3 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
- : QObject(), pollTimer(0),
+ : QObject(), pollTimer(nullptr),
loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")),
forcedPolling(0), firstUpdate(true)
{
@@ -93,7 +93,7 @@ void QNetworkConfigurationManagerPrivate::cleanup()
{
QThread* thread = bearerThread;
deleteLater();
- if (thread->wait(5000))
+ if (thread->wait(QDeadlineTimer(5000)))
delete thread;
}
@@ -367,7 +367,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
bool envOK = false;
const int skipGeneric = qEnvironmentVariableIntValue("QT_EXCLUDE_GENERIC_BEARER", &envOK);
- QBearerEngine *generic = 0;
+ QBearerEngine *generic = nullptr;
QFactoryLoader *l = &loader;
const PluginKeyMap keyMap = l->keyMap();
const PluginKeyMapConstIterator cend = keyMap.constEnd();
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index 19bc44e02a..25c4ab711e 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -209,7 +209,7 @@ QT_BEGIN_NAMESPACE
\sa isValid()
*/
QNetworkConfiguration::QNetworkConfiguration()
- : d(0)
+ : d(nullptr)
{
}
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index 1636bcee97..324016d72a 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -250,7 +250,7 @@ QT_BEGIN_NAMESPACE
\sa QNetworkConfiguration
*/
QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent)
- : QObject(parent), d(0)
+ : QObject(parent), d(nullptr)
{
qRegisterMetaType<QNetworkSession::State>();
qRegisterMetaType<QNetworkSession::SessionError>();
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/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 33a30eb1cd..e9a8e2a9e5 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -158,7 +158,7 @@ static QByteArray qGssapiContinue(QAuthenticatorPrivate *ctx,
Constructs an empty authentication object.
*/
QAuthenticator::QAuthenticator()
- : d(0)
+ : d(nullptr)
{
}
@@ -175,7 +175,7 @@ QAuthenticator::~QAuthenticator()
Constructs a copy of \a other.
*/
QAuthenticator::QAuthenticator(const QAuthenticator &other)
- : d(0)
+ : d(nullptr)
{
if (other.d)
*this = other;
@@ -1227,7 +1227,7 @@ QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx,
QNtlmPhase3Block *phase3)
{
- Q_ASSERT(phase3 != 0);
+ Q_ASSERT(phase3 != nullptr);
// since v2 Hash is need for both NTLMv2 and LMv2 it is calculated
// only once and stored and reused
if(phase3->v2Hash.size() == 0) {
@@ -1284,7 +1284,7 @@ static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
const QNtlmPhase2Block& ch,
QNtlmPhase3Block *phase3)
{
- Q_ASSERT(phase3 != 0);
+ Q_ASSERT(phase3 != nullptr);
// return value stored in phase3
qCreatev2Hash(ctx, phase3);
@@ -1351,7 +1351,7 @@ static QByteArray qEncodeLmv2Response(const QAuthenticatorPrivate *ctx,
const QNtlmPhase2Block& ch,
QNtlmPhase3Block *phase3)
{
- Q_ASSERT(phase3 != 0);
+ Q_ASSERT(phase3 != nullptr);
// return value stored in phase3
qCreatev2Hash(ctx, phase3);
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index 1b66829070..ab1be02b6b 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -481,7 +481,7 @@ void QDnsLookup::abort()
{
Q_D(QDnsLookup);
if (d->runnable) {
- d->runnable = 0;
+ d->runnable = nullptr;
d->reply = QDnsLookupReply();
d->reply.error = QDnsLookup::OperationCancelledError;
d->reply.errorString = tr("Operation cancelled");
@@ -992,7 +992,7 @@ void QDnsLookupPrivate::_q_lookupFinished(const QDnsLookupReply &_reply)
qDebug("DNS reply for %s: %i (%s)", qPrintable(name), _reply.error, qPrintable(_reply.errorString));
#endif
reply = _reply;
- runnable = 0;
+ runnable = nullptr;
isFinished = true;
emit q->finished();
}
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index ee7484ab35..12b40fc35d 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -73,13 +73,13 @@ QT_BEGIN_NAMESPACE
typedef struct __res_state* res_state;
#endif
typedef int (*dn_expand_proto)(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
-static dn_expand_proto local_dn_expand = 0;
+static dn_expand_proto local_dn_expand = nullptr;
typedef void (*res_nclose_proto)(res_state);
-static res_nclose_proto local_res_nclose = 0;
+static res_nclose_proto local_res_nclose = nullptr;
typedef int (*res_ninit_proto)(res_state);
-static res_ninit_proto local_res_ninit = 0;
+static res_ninit_proto local_res_ninit = nullptr;
typedef int (*res_nquery_proto)(res_state, const char *, int, int, unsigned char *, int);
-static res_nquery_proto local_res_nquery = 0;
+static res_nquery_proto local_res_nquery = nullptr;
// Custom deleter to close resolver state.
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index b54fb349fb..ed1c23ed6e 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -144,7 +144,7 @@ static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr,
} else {
scopeId->clear();
}
- return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd()) == 0;
+ return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd()) == nullptr;
}
bool QHostAddressPrivate::parse(const QString &ipString)
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index f9335c3bb9..31671feece 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -410,7 +410,7 @@ QHostInfo QHostInfoAgent::reverseLookup(const QHostAddress &address)
// Reverse lookup
sockaddr_in sa4;
sockaddr_in6 sa6;
- sockaddr *sa = 0;
+ sockaddr *sa = nullptr;
QT_SOCKLEN_T saSize;
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
sa = reinterpret_cast<sockaddr *>(&sa4);
@@ -455,7 +455,7 @@ QHostInfo QHostInfoAgent::lookup(const QString &hostName)
return results;
}
- addrinfo *res = 0;
+ addrinfo *res = nullptr;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 78a05f8407..625fbabf31 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -80,12 +80,12 @@ enum LibResolvFeature {
typedef struct __res_state *res_state_ptr;
typedef int (*res_init_proto)(void);
-static res_init_proto local_res_init = 0;
+static res_init_proto local_res_init = nullptr;
typedef int (*res_ninit_proto)(res_state_ptr);
-static res_ninit_proto local_res_ninit = 0;
+static res_ninit_proto local_res_ninit = nullptr;
typedef void (*res_nclose_proto)(res_state_ptr);
-static res_nclose_proto local_res_nclose = 0;
-static res_state_ptr local_res = 0;
+static res_nclose_proto local_res_nclose = nullptr;
+static res_state_ptr local_res = nullptr;
#if QT_CONFIG(library) && !defined(Q_OS_QNX)
namespace {
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp
index d43dba3e0c..eed57f8a32 100644
--- a/src/network/kernel/qnetworkinterface.cpp
+++ b/src/network/kernel/qnetworkinterface.cpp
@@ -627,7 +627,7 @@ bool QNetworkAddressEntry::isPermanent() const
Constructs an empty network interface object.
*/
QNetworkInterface::QNetworkInterface()
- : d(0)
+ : d(nullptr)
{
}
@@ -746,7 +746,7 @@ QString QNetworkInterface::humanReadableName() const
*/
QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
{
- return d ? d->flags : InterfaceFlags(0);
+ return d ? d->flags : InterfaceFlags{};
}
/*!
diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h
index 44e27a7e34..b879a397f2 100644
--- a/src/network/kernel/qnetworkinterface_p.h
+++ b/src/network/kernel/qnetworkinterface_p.h
@@ -82,7 +82,7 @@ public:
class QNetworkInterfacePrivate: public QSharedData
{
public:
- QNetworkInterfacePrivate() : index(0), flags(nullptr)
+ QNetworkInterfacePrivate() : index(0)
{ }
~QNetworkInterfacePrivate()
{ }
diff --git a/src/network/kernel/qnetworkinterface_unix_p.h b/src/network/kernel/qnetworkinterface_unix_p.h
index 553af5a303..e5c8909eca 100644
--- a/src/network/kernel/qnetworkinterface_unix_p.h
+++ b/src/network/kernel/qnetworkinterface_unix_p.h
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
{
- QNetworkInterface::InterfaceFlags flags = nullptr;
+ QNetworkInterface::InterfaceFlags flags;
flags |= (rawFlags & IFF_UP) ? QNetworkInterface::IsUp : QNetworkInterface::InterfaceFlag(0);
flags |= (rawFlags & IFF_RUNNING) ? QNetworkInterface::IsRunning : QNetworkInterface::InterfaceFlag(0);
flags |= (rawFlags & IFF_BROADCAST) ? QNetworkInterface::CanBroadcast : QNetworkInterface::InterfaceFlag(0);
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index a2a89ed94b..90c8b75a86 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -254,13 +254,13 @@ class QGlobalNetworkProxy
{
public:
QGlobalNetworkProxy()
- : applicationLevelProxy(0)
- , applicationLevelProxyFactory(0)
+ : applicationLevelProxy(nullptr)
+ , applicationLevelProxyFactory(nullptr)
#if QT_CONFIG(socks5)
- , socks5SocketEngineHandler(0)
+ , socks5SocketEngineHandler(nullptr)
#endif
#if QT_CONFIG(http)
- , httpSocketEngineHandler(0)
+ , httpSocketEngineHandler(nullptr)
#endif
#ifdef QT_USE_SYSTEM_PROXIES
, useSystemProxies(true)
@@ -313,7 +313,7 @@ public:
applicationLevelProxy = new QNetworkProxy;
*applicationLevelProxy = proxy;
delete applicationLevelProxyFactory;
- applicationLevelProxyFactory = 0;
+ applicationLevelProxyFactory = nullptr;
useSystemProxies = false;
}
@@ -501,7 +501,7 @@ template<> void QSharedDataPointer<QNetworkProxyPrivate>::detach()
\sa setType(), setApplicationProxy()
*/
QNetworkProxy::QNetworkProxy()
- : d(0)
+ : d(nullptr)
{
// make sure we have QGlobalNetworkProxy singleton created, otherwise
// you don't have any socket engine handler created when directly setting
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index 92f91956b9..67fda24ea6 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -210,16 +210,14 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
QList<QNetworkProxy> result;
// obtain a dictionary to the proxy settings:
- CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
+ const QCFType<CFDictionaryRef> dict = SCDynamicStoreCopyProxies(NULL);
if (!dict) {
qWarning("QNetworkProxyFactory::systemProxyForQuery: SCDynamicStoreCopyProxies returned NULL");
return result; // failed
}
- if (isHostExcluded(dict, query.peerHostName())) {
- CFRelease(dict);
+ if (isHostExcluded(dict, query.peerHostName()))
return result; // no proxy for this host
- }
// is there a PAC enabled? If so, use it first.
CFNumberRef pacEnabled;
@@ -329,7 +327,6 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
result << https;
}
- CFRelease(dict);
return result;
}
diff --git a/src/network/kernel/qurlinfo.cpp b/src/network/kernel/qurlinfo.cpp
index 7ae6822fb4..e6f2e70ff4 100644
--- a/src/network/kernel/qurlinfo.cpp
+++ b/src/network/kernel/qurlinfo.cpp
@@ -126,7 +126,7 @@ public:
QUrlInfo::QUrlInfo()
{
- d = 0;
+ d = nullptr;
}
/*!
@@ -139,7 +139,7 @@ QUrlInfo::QUrlInfo(const QUrlInfo &ui)
d = new QUrlInfoPrivate;
*d = *ui.d;
} else {
- d = 0;
+ d = nullptr;
}
}
@@ -443,7 +443,7 @@ QUrlInfo &QUrlInfo::operator=(const QUrlInfo &ui)
*d = *ui.d;
} else {
delete d;
- d = 0;
+ d = nullptr;
}
return *this;
}
@@ -683,7 +683,7 @@ bool QUrlInfo::equal(const QUrlInfo &i1, const QUrlInfo &i2,
bool QUrlInfo::operator==(const QUrlInfo &other) const
{
if (!d)
- return other.d == 0;
+ return other.d == nullptr;
if (!other.d)
return false;
@@ -721,7 +721,7 @@ bool QUrlInfo::operator==(const QUrlInfo &other) const
*/
bool QUrlInfo::isValid() const
{
- return d != 0;
+ return d != nullptr;
}
QT_END_NAMESPACE
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index b1ea9a4133..cbc4114904 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -564,12 +564,12 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
port(0),
localPort(0),
peerPort(0),
- socketEngine(0),
+ socketEngine(nullptr),
cachedSocketDescriptor(-1),
readBufferMaxSize(0),
isBuffered(false),
hasPendingData(false),
- connectTimer(0),
+ connectTimer(nullptr),
hostLookupId(-1),
socketType(QAbstractSocket::UnknownSocketType),
state(QAbstractSocket::UnconnectedState),
@@ -603,7 +603,7 @@ void QAbstractSocketPrivate::resetSocketLayer()
socketEngine->close();
socketEngine->disconnect();
delete socketEngine;
- socketEngine = 0;
+ socketEngine = nullptr;
cachedSocketDescriptor = -1;
}
if (connectTimer)
@@ -659,7 +659,7 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc
configureCreatedSocket();
- if (threadData->hasEventDispatcher())
+ if (threadData.loadRelaxed()->hasEventDispatcher())
socketEngine->setReceiver(this);
#if defined (QABSTRACTSOCKET_DEBUG)
@@ -1138,7 +1138,7 @@ void QAbstractSocketPrivate::_q_connectToNextAddress()
}
// Start the connect timer.
- if (threadData->hasEventDispatcher()) {
+ if (threadData.loadRelaxed()->hasEventDispatcher()) {
if (!connectTimer) {
connectTimer = new QTimer(q);
QObject::connect(connectTimer, SIGNAL(timeout()),
@@ -1740,7 +1740,7 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
return;
#endif
} else {
- if (d->threadData->hasEventDispatcher()) {
+ if (d->threadData.loadRelaxed()->hasEventDispatcher()) {
// this internal API for QHostInfo either immediately gives us the desired
// QHostInfo from cache or later calls the _q_startConnecting slot.
bool immediateResultValid = false;
@@ -1953,7 +1953,7 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState
// Sync up with error string, which open() shall clear.
d->socketError = UnknownSocketError;
- if (d->threadData->hasEventDispatcher())
+ if (d->threadData.loadRelaxed()->hasEventDispatcher())
d->socketEngine->setReceiver(d);
QIODevice::open(openMode);
diff --git a/src/network/socket/qabstractsocketengine.cpp b/src/network/socket/qabstractsocketengine.cpp
index 3fffff6d5a..54c7452c66 100644
--- a/src/network/socket/qabstractsocketengine.cpp
+++ b/src/network/socket/qabstractsocketengine.cpp
@@ -85,7 +85,7 @@ QAbstractSocketEnginePrivate::QAbstractSocketEnginePrivate()
, peerPort(0)
, inboundStreamCount(0)
, outboundStreamCount(0)
- , receiver(0)
+ , receiver(nullptr)
{
}
@@ -104,7 +104,7 @@ QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(QAbstractSocket
#ifndef QT_NO_NETWORKPROXY
// proxy type must have been resolved by now
if (proxy.type() == QNetworkProxy::DefaultProxy)
- return 0;
+ return nullptr;
#endif
QMutexLocker locker(&socketHandlers()->mutex);
@@ -116,7 +116,7 @@ QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(QAbstractSocket
#ifndef QT_NO_NETWORKPROXY
// only NoProxy can have reached here
if (proxy.type() != QNetworkProxy::NoProxy)
- return 0;
+ return nullptr;
#endif
return new QNativeSocketEngine(parent);
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index c67b273937..76b3053224 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -216,7 +216,7 @@ void QHttpSocketEngine::close()
if (d->socket) {
d->socket->close();
delete d->socket;
- d->socket = 0;
+ d->socket = nullptr;
}
}
@@ -586,7 +586,7 @@ void QHttpSocketEngine::slotSocketReadNotification()
}
int statusCode = d->reply->statusCode();
- QAuthenticatorPrivate *priv = 0;
+ QAuthenticatorPrivate *priv = nullptr;
if (statusCode == 200) {
d->state = Connected;
setLocalAddress(d->socket->localAddress());
@@ -829,8 +829,8 @@ QHttpSocketEnginePrivate::QHttpSocketEnginePrivate()
, credentialsSent(false)
, pendingResponseData(0)
{
- socket = 0;
- reply = 0;
+ socket = nullptr;
+ reply = nullptr;
state = QHttpSocketEngine::None;
}
@@ -843,15 +843,15 @@ QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(QAbstractSoc
QObject *parent)
{
if (socketType != QAbstractSocket::TcpSocket)
- return 0;
+ return nullptr;
// proxy type must have been resolved by now
if (proxy.type() != QNetworkProxy::HttpProxy)
- return 0;
+ return nullptr;
// we only accept active sockets
if (!qobject_cast<QAbstractSocket *>(parent))
- return 0;
+ return nullptr;
QHttpSocketEngine *engine = new QHttpSocketEngine(parent);
engine->setProxy(proxy);
@@ -860,7 +860,7 @@ QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(QAbstractSoc
QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(qintptr, QObject *)
{
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp
index 3e36a7b229..5ca2db70b9 100644
--- a/src/network/socket/qlocalserver.cpp
+++ b/src/network/socket/qlocalserver.cpp
@@ -417,7 +417,7 @@ QLocalSocket *QLocalServer::nextPendingConnection()
{
Q_D(QLocalServer);
if (d->pendingConnections.isEmpty())
- return 0;
+ return nullptr;
QLocalSocket *nextSocket = d->pendingConnections.dequeue();
#ifndef QT_LOCALSOCKET_TCP
if (d->pendingConnections.size() <= d->maxPendingConnections)
diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp
index 9547ec5b88..88367d680d 100644
--- a/src/network/socket/qlocalserver_unix.cpp
+++ b/src/network/socket/qlocalserver_unix.cpp
@@ -243,7 +243,7 @@ void QLocalServerPrivate::closeServer()
if (socketNotifier) {
socketNotifier->setEnabled(false); // Otherwise, closed socket is checked before deleter runs
socketNotifier->deleteLater();
- socketNotifier = 0;
+ socketNotifier = nullptr;
}
if (-1 != listenSocket)
diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp
index af7cdb76d2..d35f838af5 100644
--- a/src/network/socket/qlocalsocket.cpp
+++ b/src/network/socket/qlocalsocket.cpp
@@ -372,7 +372,7 @@ QLocalSocket::~QLocalSocket()
QLocalSocket::close();
#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
Q_D(QLocalSocket);
- d->unixSocket.setParent(0);
+ d->unixSocket.setParent(nullptr);
#endif
}
diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp
index d1df26d9f1..7de9a7d4c7 100644
--- a/src/network/socket/qlocalsocket_unix.cpp
+++ b/src/network/socket/qlocalsocket_unix.cpp
@@ -61,10 +61,9 @@
QT_BEGIN_NAMESPACE
QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(),
- delayConnect(0),
- connectTimer(0),
+ delayConnect(nullptr),
+ connectTimer(nullptr),
connectingSocket(-1),
- connectingOpenMode(0),
state(QLocalSocket::UnconnectedState)
{
}
@@ -341,7 +340,7 @@ void QLocalSocketPrivate::_q_connectToSocket()
}
connectingSocket = -1;
connectingName.clear();
- connectingOpenMode = 0;
+ connectingOpenMode = { };
}
bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,
@@ -380,10 +379,10 @@ void QLocalSocketPrivate::cancelDelayedConnect()
if (delayConnect) {
delayConnect->setEnabled(false);
delete delayConnect;
- delayConnect = 0;
+ delayConnect = nullptr;
connectTimer->stop();
delete connectTimer;
- connectTimer = 0;
+ connectTimer = nullptr;
}
}
@@ -438,7 +437,7 @@ void QLocalSocket::close()
::close(d->connectingSocket);
d->connectingSocket = -1;
d->connectingName.clear();
- d->connectingOpenMode = 0;
+ d->connectingOpenMode = { };
d->serverName.clear();
d->fullServerName.clear();
QIODevice::close();
diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp
index 5126a5330f..31628846dc 100644
--- a/src/network/socket/qnativesocketengine.cpp
+++ b/src/network/socket/qnativesocketengine.cpp
@@ -191,9 +191,9 @@ QT_BEGIN_NAMESPACE
*/
QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() :
socketDescriptor(-1),
- readNotifier(0),
- writeNotifier(0),
- exceptNotifier(0)
+ readNotifier(nullptr),
+ writeNotifier(nullptr),
+ exceptNotifier(nullptr)
{
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QSysInfo::machineHostName(); // this initializes ws2_32.dll
@@ -985,15 +985,15 @@ void QNativeSocketEngine::close()
d->inboundStreamCount = d->outboundStreamCount = 0;
if (d->readNotifier) {
qDeleteInEventHandler(d->readNotifier);
- d->readNotifier = 0;
+ d->readNotifier = nullptr;
}
if (d->writeNotifier) {
qDeleteInEventHandler(d->writeNotifier);
- d->writeNotifier = 0;
+ d->writeNotifier = nullptr;
}
if (d->exceptNotifier) {
qDeleteInEventHandler(d->exceptNotifier);
- d->exceptNotifier = 0;
+ d->exceptNotifier = nullptr;
}
}
@@ -1341,7 +1341,7 @@ void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
Q_D(QNativeSocketEngine);
if (d->readNotifier) {
d->readNotifier->setEnabled(enable);
- } else if (enable && d->threadData->hasEventDispatcher()) {
+ } else if (enable && d->threadData.loadRelaxed()->hasEventDispatcher()) {
d->readNotifier = new QReadNotifier(d->socketDescriptor, this);
d->readNotifier->setEnabled(true);
}
@@ -1358,7 +1358,7 @@ void QNativeSocketEngine::setWriteNotificationEnabled(bool enable)
Q_D(QNativeSocketEngine);
if (d->writeNotifier) {
d->writeNotifier->setEnabled(enable);
- } else if (enable && d->threadData->hasEventDispatcher()) {
+ } else if (enable && d->threadData.loadRelaxed()->hasEventDispatcher()) {
d->writeNotifier = new QWriteNotifier(d->socketDescriptor, this);
d->writeNotifier->setEnabled(true);
}
@@ -1375,7 +1375,7 @@ void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable)
Q_D(QNativeSocketEngine);
if (d->exceptNotifier) {
d->exceptNotifier->setEnabled(enable);
- } else if (enable && d->threadData->hasEventDispatcher()) {
+ } else if (enable && d->threadData.loadRelaxed()->hasEventDispatcher()) {
d->exceptNotifier = new QExceptionNotifier(d->socketDescriptor, this);
d->exceptNotifier->setEnabled(true);
}
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 3ca586e247..e5b9fbbdb2 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -628,7 +628,7 @@ bool QNativeSocketEnginePrivate::nativeListen(int backlog)
int QNativeSocketEnginePrivate::nativeAccept()
{
- int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0);
+ int acceptedDescriptor = qt_safe_accept(socketDescriptor, nullptr, nullptr);
if (acceptedDescriptor == -1) {
switch (errno) {
case EBADF:
@@ -1002,7 +1002,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
struct cmsghdr *cmsgptr;
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wsign-compare")
- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
+ for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != nullptr;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
QT_WARNING_POP
if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO
@@ -1166,7 +1166,7 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
#endif
if (msg.msg_controllen == 0)
- msg.msg_control = 0;
+ msg.msg_control = nullptr;
ssize_t sentBytes = qt_safe_sendmsg(socketDescriptor, &msg, 0);
if (sentBytes < 0) {
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 9edabd7822..dd115c33dc 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -53,6 +53,8 @@
#include <qnetworkinterface.h>
#include <qoperatingsystemversion.h>
+#include <algorithm>
+
//#define QNATIVESOCKETENGINE_DEBUG
#if defined(QNATIVESOCKETENGINE_DEBUG)
# include <qstring.h>
@@ -1141,13 +1143,14 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
qint64 ret = -1;
int recvResult = 0;
DWORD flags;
- // We start at 1500 bytes (the MTU for Ethernet V2), which should catch
- // almost all uses (effective MTU for UDP under IPv4 is 1468), except
- // for localhost datagrams and those reassembled by the IP layer.
- char udpMessagePeekBuffer[1500];
- std::vector<WSABUF> buf;
+ // We increase the amount we peek by 2048 * 5 on each iteration
+ // Grabs most cases fast and early.
+ char udpMessagePeekBuffer[2048];
+ const int increments = 5;
+ QVarLengthArray<WSABUF, 10> buf;
for (;;) {
- buf.resize(buf.size() + 5, {sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
+ buf.reserve(buf.size() + increments);
+ std::fill_n(std::back_inserter(buf), increments, WSABUF{sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
flags = MSG_PEEK;
DWORD bytesRead = 0;
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index 8a030601dc..622d5df131 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -365,13 +365,13 @@ QSocks5BindData *QSocks5BindStore::retrieve(qintptr socketDescriptor)
QMutexLocker lock(&mutex);
const auto it = store.constFind(socketDescriptor);
if (it == store.cend())
- return 0;
+ return nullptr;
QSocks5BindData *bindData = it.value();
store.erase(it);
if (bindData) {
if (bindData->controlSocket->thread() != QThread::currentThread()) {
qWarning("Cannot access socks5 bind data from different thread");
- return 0;
+ return nullptr;
}
} else {
QSOCKS5_DEBUG << "__ERROR__ binddata == 0";
@@ -503,12 +503,12 @@ QSocks5SocketEnginePrivate::QSocks5SocketEnginePrivate()
, writeNotificationEnabled(false)
, exceptNotificationEnabled(false)
, socketDescriptor(-1)
- , data(0)
- , connectData(0)
+ , data(nullptr)
+ , connectData(nullptr)
#ifndef QT_NO_UDPSOCKET
- , udpData(0)
+ , udpData(nullptr)
#endif
- , bindData(0)
+ , bindData(nullptr)
, readNotificationActivated(false)
, writeNotificationActivated(false)
, readNotificationPending(false)
@@ -1038,11 +1038,11 @@ bool QSocks5SocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
d->data = d->connectData;
d->mode = QSocks5SocketEnginePrivate::ConnectMode;
d->data->controlSocket = bindData->controlSocket;
- bindData->controlSocket = 0;
+ bindData->controlSocket = nullptr;
d->data->controlSocket->setParent(this);
d->socketProtocol = d->data->controlSocket->localAddress().protocol();
d->data->authenticator = bindData->authenticator;
- bindData->authenticator = 0;
+ bindData->authenticator = nullptr;
d->localPort = bindData->localPort;
d->localAddress = bindData->localAddress;
d->peerPort = bindData->peerPort;
@@ -1367,7 +1367,7 @@ bool QSocks5SocketEngine::bind(const QHostAddress &addr, quint16 port)
QElapsedTimer stopWatch;
stopWatch.start();
d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port());
- if (!d->waitForConnected(msecs, 0) ||
+ if (!d->waitForConnected(msecs, nullptr) ||
d->data->controlSocket->state() == QAbstractSocket::UnconnectedState) {
// waitForConnected sets the error state and closes the socket
QSOCKS5_Q_DEBUG << "waitForConnected to proxy server" << d->data->controlSocket->errorString();
@@ -1428,13 +1428,13 @@ int QSocks5SocketEngine::accept()
case QSocks5SocketEnginePrivate::BindSuccess:
QSOCKS5_Q_DEBUG << "BindSuccess adding" << d->socketDescriptor << "to the bind store";
d->data->controlSocket->disconnect();
- d->data->controlSocket->setParent(0);
+ d->data->controlSocket->setParent(nullptr);
d->bindData->localAddress = d->localAddress;
d->bindData->localPort = d->localPort;
sd = d->socketDescriptor;
socks5BindStore()->add(sd, d->bindData);
- d->data = 0;
- d->bindData = 0;
+ d->data = nullptr;
+ d->bindData = nullptr;
d->socketDescriptor = 0;
//### do something about this socket layer ... set it closed and an error about why ...
// reset state and local port/address
@@ -1909,7 +1909,7 @@ QSocks5SocketEngineHandler::createSocketEngine(QAbstractSocket::SocketType socke
// proxy type must have been resolved by now
if (proxy.type() != QNetworkProxy::Socks5Proxy) {
QSOCKS5_DEBUG << "not proxying";
- return 0;
+ return nullptr;
}
QScopedPointer<QSocks5SocketEngine> engine(new QSocks5SocketEngine(parent));
engine->setProxy(proxy);
@@ -1923,7 +1923,7 @@ QAbstractSocketEngine *QSocks5SocketEngineHandler::createSocketEngine(qintptr so
QSOCKS5_DEBUG << "bind store contains" << socketDescriptor;
return new QSocks5SocketEngine(parent);
}
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp
index 98e58192a2..9916c75e65 100644
--- a/src/network/socket/qtcpserver.cpp
+++ b/src/network/socket/qtcpserver.cpp
@@ -121,7 +121,7 @@ QTcpServerPrivate::QTcpServerPrivate()
: port(0)
, socketType(QAbstractSocket::UnknownSocketType)
, state(QAbstractSocket::UnconnectedState)
- , socketEngine(0)
+ , socketEngine(nullptr)
, serverSocketError(QAbstractSocket::UnknownSocketError)
, maxConnections(30)
{
@@ -389,7 +389,7 @@ void QTcpServer::close()
// in out of memory situations, the socketEngine
// will be deleted in ~QTcpServer (it's a child-object of this)
}
- d->socketEngine = 0;
+ d->socketEngine = nullptr;
}
d->state = QAbstractSocket::UnconnectedState;
@@ -561,7 +561,7 @@ QTcpSocket *QTcpServer::nextPendingConnection()
{
Q_D(QTcpServer);
if (d->pendingConnections.isEmpty())
- return 0;
+ return nullptr;
if (!d->socketEngine) {
qWarning("QTcpServer::nextPendingConnection() called while not listening");
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/qssl.h b/src/network/ssl/qssl.h
index 42c7b5c56d..b28c2a87b9 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -77,17 +77,21 @@ namespace QSsl {
#endif
enum SslProtocol {
+#if QT_DEPRECATED_SINCE(5, 15)
SslV3,
SslV2,
- TlsV1_0,
+#endif
+ TlsV1_0 = 2,
#if QT_DEPRECATED_SINCE(5,0)
TlsV1 = TlsV1_0,
#endif
TlsV1_1,
TlsV1_2,
AnyProtocol,
+#if QT_DEPRECATED_SINCE(5, 15)
TlsV1SslV3,
- SecureProtocols,
+#endif
+ SecureProtocols = AnyProtocol + 2,
TlsV1_0OrLater,
TlsV1_1OrLater,
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 7e92d3a526..a2e694ec92 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -631,11 +631,10 @@ QList<QSslCipher> QSslConfiguration::supportedCiphers()
Returns this connection's CA certificate database. The CA certificate
database is used by the socket during the handshake phase to
validate the peer's certificate. It can be modified prior to the
- handshake with setCaCertificates(), or with \l{QSslSocket}'s
- \l{QSslSocket::}{addCaCertificate()} and
- \l{QSslSocket::}{addCaCertificates()}.
+ handshake with setCaCertificates(), or with addCaCertificate() and
+ addCaCertificates().
- \sa setCaCertificates()
+ \sa setCaCertificates(), addCaCertificate(), addCaCertificates()
*/
QList<QSslCertificate> QSslConfiguration::caCertificates() const
{
@@ -652,7 +651,7 @@ QList<QSslCertificate> QSslConfiguration::caCertificates() const
that is not available (as is commonly the case on iOS), the default database
is empty.
- \sa caCertificates()
+ \sa caCertificates(), addCaCertificates(), addCaCertificate()
*/
void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certificates)
{
@@ -661,6 +660,72 @@ void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certific
}
/*!
+ Searches all files in the \a path for certificates encoded in the
+ specified \a format and adds them to this socket's CA certificate
+ database. \a path must be a file or a pattern matching one or more
+ files, as specified by \a syntax. Returns \c true if one or more
+ certificates are added to the socket's CA certificate database;
+ otherwise returns \c false.
+
+ The CA certificate database is used by the socket during the
+ handshake phase to validate the peer's certificate.
+
+ For more precise control, use addCaCertificate().
+
+ \sa addCaCertificate(), QSslCertificate::fromPath()
+*/
+bool QSslConfiguration::addCaCertificates(const QString &path, QSsl::EncodingFormat format,
+ QRegExp::PatternSyntax syntax)
+{
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(path, format, syntax);
+ if (certs.isEmpty())
+ return false;
+
+ d->caCertificates += certs;
+ return true;
+}
+
+/*!
+ \since 5.15
+
+ Adds \a certificate to this configuration's CA certificate database.
+ The certificate database must be set prior to the SSL handshake.
+ The CA certificate database is used by the socket during the
+ handshake phase to validate the peer's certificate.
+
+ \note The default configuration uses the system CA certificate database. If
+ that is not available (as is commonly the case on iOS), the default database
+ is empty.
+
+ \sa caCertificates(), setCaCertificates(), addCaCertificates()
+*/
+void QSslConfiguration::addCaCertificate(const QSslCertificate &certificate)
+{
+ d->caCertificates += certificate;
+ d->allowRootCertOnDemandLoading = false;
+}
+
+/*!
+ \since 5.15
+
+ Adds \a certificates to this configuration's CA certificate database.
+ The certificate database must be set prior to the SSL handshake.
+ The CA certificate database is used by the socket during the
+ handshake phase to validate the peer's certificate.
+
+ \note The default configuration uses the system CA certificate database. If
+ that is not available (as is commonly the case on iOS), the default database
+ is empty.
+
+ \sa caCertificates(), setCaCertificates(), addCaCertificate()
+*/
+void QSslConfiguration::addCaCertificates(const QList<QSslCertificate> &certificates)
+{
+ d->caCertificates += certificates;
+ d->allowRootCertOnDemandLoading = false;
+}
+
+/*!
\since 5.5
This function provides the CA certificate database
@@ -668,7 +733,8 @@ void QSslConfiguration::setCaCertificates(const QList<QSslCertificate> &certific
returned by this function is used to initialize the database
returned by caCertificates() on the default QSslConfiguration.
- \sa caCertificates(), setCaCertificates(), defaultConfiguration()
+ \sa caCertificates(), setCaCertificates(), defaultConfiguration(),
+ addCaCertificate(), addCaCertificates()
*/
QList<QSslCertificate> QSslConfiguration::systemCaCertificates()
{
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index c25c2686de..247f3aecc9 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -131,6 +131,11 @@ public:
// Certificate Authority (CA) settings
QList<QSslCertificate> caCertificates() const;
void setCaCertificates(const QList<QSslCertificate> &certificates);
+ bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
+ QRegExp::PatternSyntax syntax = QRegExp::FixedString);
+ void addCaCertificate(const QSslCertificate &certificate);
+ void addCaCertificates(const QList<QSslCertificate> &certificates);
+
static QList<QSslCertificate> systemCaCertificates();
void setSslOption(QSsl::SslOption option, bool on);
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.cpp b/src/network/ssl/qsslsocket.cpp
index e302aa1761..690251727d 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -139,10 +139,21 @@
before the handshake phase with setLocalCertificate() and
setPrivateKey().
\li The CA certificate database can be extended and customized with
- addCaCertificate(), addCaCertificates(), addDefaultCaCertificate(),
- addDefaultCaCertificates(), and QSslConfiguration::defaultConfiguration().setCaCertificates().
+ QSslConfiguration::addCaCertificate(),
+ QSslConfiguration::addCaCertificates().
\endlist
+ To extend the list of \e default CA certificates used by the SSL sockets
+ during the SSL handshake you must update the default configuration, as
+ in the snippet below:
+
+ \code
+ QList<QSslCertificate> certificates = getCertificates();
+ QSslConfiguration configuration = QSslConfiguration::defaultConfiguration();
+ configuration.addCaCertificates(certificates);
+ QSslConfiguration::setDefaultConfiguration(configuration);
+ \endcode
+
\note If available, root certificates on Unix (excluding \macos) will be
loaded on demand from the standard certificate directories. If you do not
want to load root certificates on demand, you need to call either
@@ -1384,6 +1395,10 @@ QList<QSslCipher> QSslSocket::supportedCiphers()
#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() instead.
+
Searches all files in the \a path for certificates encoded in the
specified \a format and adds them to this socket's CA certificate
database. \a path must be a file or a pattern matching one or more
@@ -1411,6 +1426,10 @@ bool QSslSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat for
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificate() instead.
+
Adds the \a certificate to this socket's CA certificate database.
The CA certificate database is used by the socket during the
handshake phase to validate the peer's certificate.
@@ -1427,6 +1446,10 @@ void QSslSocket::addCaCertificate(const QSslCertificate &certificate)
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() instead.
+
Adds the \a certificates to this socket's CA certificate database.
The CA certificate database is used by the socket during the
handshake phase to validate the peer's certificate.
@@ -1489,6 +1512,10 @@ QList<QSslCertificate> QSslSocket::caCertificates() const
#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() on the default QSslConfiguration instead.
+
Searches all files in the \a path for certificates with the
specified \a encoding and adds them to the default CA certificate
database. \a path can be an explicit file, or it can contain
@@ -1498,8 +1525,8 @@ QList<QSslCertificate> QSslSocket::caCertificates() const
Each SSL socket's CA certificate database is initialized to the
default CA certificate database.
- \sa QSslConfiguration::caCertificates(), addCaCertificates(),
- addDefaultCaCertificate()
+ \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates(),
+ QSslConfiguration::addDefaultCaCertificate()
*/
bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat encoding,
QRegExp::PatternSyntax syntax)
@@ -1508,11 +1535,15 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificate() on the default QSslConfiguration instead.
+
Adds \a certificate to the default CA certificate database. Each
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::caCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
@@ -1520,11 +1551,15 @@ void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
}
/*!
+ \deprecated
+
+ Use QSslConfiguration::addCaCertificates() on the default QSslConfiguration instead.
+
Adds \a certificates to the default CA certificate database. Each
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::caCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certificates)
{
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 35943c7d7e..843e2d15f5 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -164,18 +164,22 @@ public:
#endif // QT_DEPRECATED_SINCE(5, 5)
// CA settings.
- bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificates()") bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
- void addCaCertificate(const QSslCertificate &certificate);
- void addCaCertificates(const QList<QSslCertificate> &certificates);
+ QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificate()") void addCaCertificate(const QSslCertificate &certificate);
+ QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificates()") void addCaCertificates(const QList<QSslCertificate> &certificates);
+#endif // QT_DEPRECATED_SINCE(5, 15)
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED_X("Use QSslConfiguration::setCaCertificates()") void setCaCertificates(const QList<QSslCertificate> &certificates);
QT_DEPRECATED_X("Use QSslConfiguration::caCertificates()") QList<QSslCertificate> caCertificates() const;
#endif // QT_DEPRECATED_SINCE(5, 5)
- static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem,
QRegExp::PatternSyntax syntax = QRegExp::FixedString);
- static void addDefaultCaCertificate(const QSslCertificate &certificate);
- static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates);
+ QT_DEPRECATED static void addDefaultCaCertificate(const QSslCertificate &certificate);
+ QT_DEPRECATED static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates);
+#endif // QT_DEPRECATED_SINCE(5, 15)
#if QT_DEPRECATED_SINCE(5, 5)
QT_DEPRECATED static void setDefaultCaCertificates(const QList<QSslCertificate> &certificates);
QT_DEPRECATED static QList<QSslCertificate> defaultCaCertificates();
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 51510f1c60..8fbbffcaca 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"
@@ -99,13 +98,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()
{
@@ -123,7 +121,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,
@@ -144,7 +142,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,
@@ -165,7 +162,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)
@@ -176,7 +172,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);
@@ -185,13 +180,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)
@@ -408,13 +402,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
@@ -477,17 +466,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;
@@ -591,15 +575,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
@@ -608,6 +590,9 @@ bool QSslSocketBackendPrivate::initSslContext()
}
#endif // openssl version >= 0x10101006L
+#endif // OPENSSL_NO_PSK
+
+
#if QT_CONFIG(ocsp)
if (configuration.ocspStaplingEnabled) {
if (mode == QSslSocket::SslServerMode) {
@@ -674,10 +659,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())
@@ -686,11 +704,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
@@ -707,11 +737,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()).
@@ -1738,6 +1764,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();
@@ -1790,19 +1984,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_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index c6e3e4d786..31b0db4818 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -431,6 +431,53 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
return alpnString;
}
#endif // SUPPORTS_ALPN
+
+qint64 readToBuffer(QByteArray &buffer, QTcpSocket *plainSocket)
+{
+ Q_ASSERT(plainSocket);
+ static const qint64 shrinkCutoff = 1024 * 12;
+ static const qint64 defaultRead = 1024 * 16;
+ qint64 bytesRead = 0;
+
+ const auto toRead = std::min(defaultRead, plainSocket->bytesAvailable());
+ if (toRead > 0) {
+ const auto bufferSize = buffer.size();
+ buffer.reserve(bufferSize + toRead); // avoid growth strategy kicking in
+ buffer.resize(bufferSize + toRead);
+ bytesRead = plainSocket->read(buffer.data() + bufferSize, toRead);
+ buffer.resize(bufferSize + bytesRead);
+ // In case of excessive memory usage we shrink:
+ if (buffer.size() < shrinkCutoff && buffer.capacity() > defaultRead)
+ buffer.shrink_to_fit();
+ }
+
+ return bytesRead;
+}
+
+void retainExtraData(QByteArray &buffer, const SecBuffer &secBuffer)
+{
+ Q_ASSERT(secBuffer.BufferType == SECBUFFER_EXTRA);
+ if (int(secBuffer.cbBuffer) >= buffer.size())
+ return;
+
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "We got SECBUFFER_EXTRA, will retain %lu bytes", secBuffer.cbBuffer);
+#endif
+ std::move(buffer.end() - secBuffer.cbBuffer, buffer.end(), buffer.begin());
+ buffer.resize(secBuffer.cbBuffer);
+}
+
+qint64 checkIncompleteData(const SecBuffer &secBuffer)
+{
+ if (secBuffer.BufferType == SECBUFFER_MISSING) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "Need %lu more bytes.", secBuffer.cbBuffer);
+#endif
+ return secBuffer.cbBuffer;
+}
+ return 0;
+}
+
} // anonymous namespace
bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
@@ -619,8 +666,8 @@ bool QSslSocketBackendPrivate::acquireCredentialsHandle()
nullptr);
if (!chainContext) {
const QString message = isClient
- ? QSslSocket::tr("The certificate provided cannot be used for a client.")
- : QSslSocket::tr("The certificate provided cannot be used for a server.");
+ ? QSslSocket::tr("The certificate provided cannot be used for a client.")
+ : QSslSocket::tr("The certificate provided cannot be used for a server.");
setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, message);
return false;
}
@@ -774,7 +821,11 @@ bool QSslSocketBackendPrivate::acceptContext()
Q_ASSERT(mode == QSslSocket::SslServerMode);
ULONG contextReq = getContextRequirements();
- intermediateBuffer += plainSocket->read(16384);
+ if (missingData > plainSocket->bytesAvailable())
+ return true;
+
+ missingData = 0;
+ readToBuffer(intermediateBuffer, plainSocket);
if (intermediateBuffer.isEmpty())
return true; // definitely need more data..
@@ -830,6 +881,7 @@ bool QSslSocketBackendPrivate::acceptContext()
if (status == SEC_E_INCOMPLETE_MESSAGE) {
// Need more data
+ missingData = checkIncompleteData(outBuffers[0]);
return true;
}
@@ -837,9 +889,9 @@ bool QSslSocketBackendPrivate::acceptContext()
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
// inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
// be stored.
- intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer));
+ retainExtraData(intermediateBuffer, inBuffers[1]);
} else { /* No 'extra' data, message not incomplete */
- intermediateBuffer.clear();
+ intermediateBuffer.resize(0);
}
if (status != SEC_I_CONTINUE_NEEDED) {
@@ -865,11 +917,15 @@ bool QSslSocketBackendPrivate::performHandshake()
Q_ASSERT(schannelState == SchannelState::PerformHandshake);
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "Bytes available from socket:" << plainSocket->bytesAvailable();
- qCDebug(lcSsl) << "intermediateBuffer size:" << intermediateBuffer.size();
+ qCDebug(lcSsl, "Bytes available from socket: %lld", plainSocket->bytesAvailable());
+ qCDebug(lcSsl, "intermediateBuffer size: %d", intermediateBuffer.size());
#endif
- intermediateBuffer += plainSocket->read(16384);
+ if (missingData > plainSocket->bytesAvailable())
+ return true;
+
+ missingData = 0;
+ readToBuffer(intermediateBuffer, plainSocket);
if (intermediateBuffer.isEmpty())
return true; // no data, will fail
@@ -918,11 +974,10 @@ bool QSslSocketBackendPrivate::performHandshake()
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
// inputBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
// be stored.
- intermediateBuffer = intermediateBuffer.right(int(inputBuffers[1].cbBuffer));
- } else {
+ retainExtraData(intermediateBuffer, inputBuffers[1]);
+ } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
// Clear the buffer if we weren't asked for more data
- if (status != SEC_E_INCOMPLETE_MESSAGE)
- intermediateBuffer.clear();
+ intermediateBuffer.resize(0);
}
switch (status) {
case SEC_E_OK:
@@ -955,6 +1010,7 @@ bool QSslSocketBackendPrivate::performHandshake()
return true;
case SEC_E_INCOMPLETE_MESSAGE:
// Simply incomplete, wait for more data
+ missingData = checkIncompleteData(outBuffers[0]);
return true;
case SEC_E_ALGORITHM_MISMATCH:
setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
@@ -1158,6 +1214,8 @@ void QSslSocketBackendPrivate::reset()
connectionEncrypted = false;
shutdown = false;
renegotiating = false;
+
+ missingData = 0;
}
void QSslSocketBackendPrivate::startClientEncryption()
@@ -1229,8 +1287,7 @@ void QSslSocketBackendPrivate::transmit()
fullMessage.resize(inputBuffers[0].cbBuffer + inputBuffers[1].cbBuffer + inputBuffers[2].cbBuffer);
const qint64 bytesWritten = plainSocket->write(fullMessage);
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "Wrote" << bytesWritten << "of total"
- << fullMessage.length() << "bytes";
+ qCDebug(lcSsl, "Wrote %lld of total %d bytes", bytesWritten, fullMessage.length());
#endif
if (bytesWritten >= 0) {
totalBytesWritten += bytesWritten;
@@ -1255,36 +1312,32 @@ void QSslSocketBackendPrivate::transmit()
int totalRead = 0;
bool hadIncompleteData = false;
while (!readBufferMaxSize || buffer.size() < readBufferMaxSize) {
- QByteArray ciphertext;
- if (intermediateBuffer.length()) {
+ if (missingData > plainSocket->bytesAvailable()) {
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "Restoring data from intermediateBuffer:"
- << intermediateBuffer.length() << "bytes";
+ qCDebug(lcSsl, "We're still missing %lld bytes, will check later.", missingData);
#endif
- ciphertext.swap(intermediateBuffer);
+ break;
}
- int initialLength = ciphertext.length();
- ciphertext += plainSocket->read(16384);
+
+ missingData = 0;
+ const qint64 bytesRead = readToBuffer(intermediateBuffer, plainSocket);
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "Read" << ciphertext.length() - initialLength
- << "encrypted bytes from the socket";
+ qCDebug(lcSsl, "Read %lld encrypted bytes from the socket", bytesRead);
#endif
- if (ciphertext.length() == 0 || (hadIncompleteData && initialLength == ciphertext.length())) {
+ if (intermediateBuffer.length() == 0 || (hadIncompleteData && bytesRead == 0)) {
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << (hadIncompleteData ? "No new data received, leaving loop!"
- : "Nothing to decrypt, leaving loop!");
+ qCDebug(lcSsl, (hadIncompleteData ? "No new data received, leaving loop!"
+ : "Nothing to decrypt, leaving loop!"));
#endif
- if (ciphertext.length()) // We have data, it came from intermediateBuffer, swap back
- intermediateBuffer.swap(ciphertext);
break;
}
hadIncompleteData = false;
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "Total amount of bytes to decrypt:" << ciphertext.length();
+ qCDebug(lcSsl, "Total amount of bytes to decrypt: %d", intermediateBuffer.length());
#endif
SecBuffer dataBuffer[4]{
- createSecBuffer(ciphertext, SECBUFFER_DATA),
+ createSecBuffer(intermediateBuffer, SECBUFFER_DATA),
createSecBuffer(nullptr, 0, SECBUFFER_EMPTY),
createSecBuffer(nullptr, 0, SECBUFFER_EMPTY),
createSecBuffer(nullptr, 0, SECBUFFER_EMPTY)
@@ -1300,34 +1353,30 @@ void QSslSocketBackendPrivate::transmit()
if (dataBuffer[1].cbBuffer > 0) {
// It is always decrypted in-place.
// But [0] is the STREAM_HEADER, [1] is the DATA and [2] is the STREAM_TRAILER.
- // The pointers in all of those still point into the 'ciphertext' byte array.
+ // The pointers in all of those still point into 'intermediateBuffer'.
buffer.append(static_cast<char *>(dataBuffer[1].pvBuffer),
dataBuffer[1].cbBuffer);
totalRead += dataBuffer[1].cbBuffer;
#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "Decrypted" << dataBuffer[1].cbBuffer
- << "bytes. New read buffer size:" << buffer.size();
+ qCDebug(lcSsl, "Decrypted %lu bytes. New read buffer size: %d",
+ dataBuffer[1].cbBuffer, buffer.size());
#endif
}
if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) {
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
// dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed,
// the rest need to be stored.
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:"
- << dataBuffer[3].cbBuffer << "bytes";
-#endif
- intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
+ retainExtraData(intermediateBuffer, dataBuffer[3]);
+ } else {
+ intermediateBuffer.resize(0);
}
}
if (status == SEC_E_INCOMPLETE_MESSAGE) {
- // Need more data before we can decrypt.. to the buffer it goes!
+ missingData = checkIncompleteData(dataBuffer[0]);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
#endif
- Q_ASSERT(intermediateBuffer.isEmpty());
- intermediateBuffer.swap(ciphertext);
// We try again, but if we don't get any more data then we leave
hadIncompleteData = true;
} else if (status == SEC_E_INVALID_HANDLE) {
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
index 6ab200e1f9..a184deef49 100644
--- a/src/network/ssl/qsslsocket_schannel_p.h
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -145,6 +145,7 @@ private:
const CERT_CONTEXT *localCertContext = nullptr;
ULONG contextAttributes = 0;
+ qint64 missingData = 0;
bool renegotiating = false;
};
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index 39c1ce55e3..f3ca3dc257 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