1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2014 BlackBerry Limited. All rights reserved.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5
6//#define QSSLSOCKET_DEBUG
7
8/*!
9 \class QSslSocket
10 \brief The QSslSocket class provides an SSL encrypted socket for both
11 clients and servers.
12 \since 4.3
13
14 \reentrant
15 \ingroup network
16 \ingroup ssl
17 \inmodule QtNetwork
18
19 QSslSocket establishes a secure, encrypted TCP connection you can
20 use for transmitting encrypted data. It can operate in both client
21 and server mode, and it supports modern TLS protocols, including
22 TLS 1.3. By default, QSslSocket uses only TLS protocols
23 which are considered to be secure (QSsl::SecureProtocols), but you can
24 change the TLS protocol by calling setProtocol() as long as you do
25 it before the handshake has started.
26
27 SSL encryption operates on top of the existing TCP stream after
28 the socket enters the ConnectedState. There are two simple ways to
29 establish a secure connection using QSslSocket: With an immediate
30 SSL handshake, or with a delayed SSL handshake occurring after the
31 connection has been established in unencrypted mode.
32
33 The most common way to use QSslSocket is to construct an object
34 and start a secure connection by calling connectToHostEncrypted().
35 This method starts an immediate SSL handshake once the connection
36 has been established.
37
38 \snippet code/src_network_ssl_qsslsocket.cpp 0
39
40 As with a plain QTcpSocket, QSslSocket enters the HostLookupState,
41 ConnectingState, and finally the ConnectedState, if the connection
42 is successful. The handshake then starts automatically, and if it
43 succeeds, the encrypted() signal is emitted to indicate the socket
44 has entered the encrypted state and is ready for use.
45
46 Note that data can be written to the socket immediately after the
47 return from connectToHostEncrypted() (i.e., before the encrypted()
48 signal is emitted). The data is queued in QSslSocket until after
49 the encrypted() signal is emitted.
50
51 An example of using the delayed SSL handshake to secure an
52 existing connection is the case where an SSL server secures an
53 incoming connection. Suppose you create an SSL server class as a
54 subclass of QTcpServer. You would override
55 QTcpServer::incomingConnection() with something like the example
56 below, which first constructs an instance of QSslSocket and then
57 calls setSocketDescriptor() to set the new socket's descriptor to
58 the existing one passed in. It then initiates the SSL handshake
59 by calling startServerEncryption().
60
61 \snippet code/src_network_ssl_qsslsocket.cpp 1
62
63 If an error occurs, QSslSocket emits the sslErrors() signal. In this
64 case, if no action is taken to ignore the error(s), the connection
65 is dropped. To continue, despite the occurrence of an error, you
66 can call ignoreSslErrors(), either from within this slot after the
67 error occurs, or any time after construction of the QSslSocket and
68 before the connection is attempted. This will allow QSslSocket to
69 ignore the errors it encounters when establishing the identity of
70 the peer. Ignoring errors during an SSL handshake should be used
71 with caution, since a fundamental characteristic of secure
72 connections is that they should be established with a successful
73 handshake.
74
75 Once encrypted, you use QSslSocket as a regular QTcpSocket. When
76 readyRead() is emitted, you can call read(), canReadLine() and
77 readLine(), or getChar() to read decrypted data from QSslSocket's
78 internal buffer, and you can call write() or putChar() to write
79 data back to the peer. QSslSocket will automatically encrypt the
80 written data for you, and emit encryptedBytesWritten() once
81 the data has been written to the peer.
82
83 As a convenience, QSslSocket supports QTcpSocket's blocking
84 functions waitForConnected(), waitForReadyRead(),
85 waitForBytesWritten(), and waitForDisconnected(). It also provides
86 waitForEncrypted(), which will block the calling thread until an
87 encrypted connection has been established.
88
89 \snippet code/src_network_ssl_qsslsocket.cpp 2
90
91 QSslSocket provides an extensive, easy-to-use API for handling
92 cryptographic ciphers, private keys, and local, peer, and
93 Certification Authority (CA) certificates. It also provides an API
94 for handling errors that occur during the handshake phase.
95
96 The following features can also be customized:
97
98 \list
99 \li The socket's cryptographic cipher suite can be customized before
100 the handshake phase with QSslConfiguration::setCiphers()
101 and QSslConfiguration::setDefaultCiphers().
102 \li The socket's local certificate and private key can be customized
103 before the handshake phase with setLocalCertificate() and
104 setPrivateKey().
105 \li The CA certificate database can be extended and customized with
106 QSslConfiguration::addCaCertificate(),
107 QSslConfiguration::addCaCertificates().
108 \endlist
109
110 To extend the list of \e default CA certificates used by the SSL sockets
111 during the SSL handshake you must update the default configuration, as
112 in the snippet below:
113
114 \code
115 QList<QSslCertificate> certificates = getCertificates();
116 QSslConfiguration configuration = QSslConfiguration::defaultConfiguration();
117 configuration.addCaCertificates(certificates);
118 QSslConfiguration::setDefaultConfiguration(configuration);
119 \endcode
120
121 \note If available, root certificates on Unix (excluding \macos) will be
122 loaded on demand from the standard certificate directories. If you do not
123 want to load root certificates on demand, you need to call either
124 QSslConfiguration::defaultConfiguration().setCaCertificates() before the first
125 SSL handshake is made in your application (for example, via passing
126 QSslSocket::systemCaCertificates() to it), or call
127 QSslConfiguration::defaultConfiguration()::setCaCertificates() on your QSslSocket instance
128 prior to the SSL handshake.
129
130 For more information about ciphers and certificates, refer to QSslCipher and
131 QSslCertificate.
132
133 This product includes software developed by the OpenSSL Project
134 for use in the OpenSSL Toolkit (\l{http://www.openssl.org/}).
135
136 \note Be aware of the difference between the bytesWritten() signal and
137 the encryptedBytesWritten() signal. For a QTcpSocket, bytesWritten()
138 will get emitted as soon as data has been written to the TCP socket.
139 For a QSslSocket, bytesWritten() will get emitted when the data
140 is being encrypted and encryptedBytesWritten()
141 will get emitted as soon as data has been written to the TCP socket.
142
143 \sa QSslCertificate, QSslCipher, QSslError
144*/
145
146/*!
147 \enum QSslSocket::SslMode
148
149 Describes the connection modes available for QSslSocket.
150
151 \value UnencryptedMode The socket is unencrypted. Its
152 behavior is identical to QTcpSocket.
153
154 \value SslClientMode The socket is a client-side SSL socket.
155 It is either already encrypted, or it is in the SSL handshake
156 phase (see QSslSocket::isEncrypted()).
157
158 \value SslServerMode The socket is a server-side SSL socket.
159 It is either already encrypted, or it is in the SSL handshake
160 phase (see QSslSocket::isEncrypted()).
161*/
162
163/*!
164 \enum QSslSocket::PeerVerifyMode
165 \since 4.4
166
167 Describes the peer verification modes for QSslSocket. The default mode is
168 AutoVerifyPeer, which selects an appropriate mode depending on the
169 socket's QSocket::SslMode.
170
171 \value VerifyNone QSslSocket will not request a certificate from the
172 peer. You can set this mode if you are not interested in the identity of
173 the other side of the connection. The connection will still be encrypted,
174 and your socket will still send its local certificate to the peer if it's
175 requested.
176
177 \value QueryPeer QSslSocket will request a certificate from the peer, but
178 does not require this certificate to be valid. This is useful when you
179 want to display peer certificate details to the user without affecting the
180 actual SSL handshake. This mode is the default for servers.
181 Note: In Schannel this value acts the same as VerifyNone.
182
183 \value VerifyPeer QSslSocket will request a certificate from the peer
184 during the SSL handshake phase, and requires that this certificate is
185 valid. On failure, QSslSocket will emit the QSslSocket::sslErrors()
186 signal. This mode is the default for clients.
187
188 \value AutoVerifyPeer QSslSocket will automatically use QueryPeer for
189 server sockets and VerifyPeer for client sockets.
190
191 \sa QSslSocket::peerVerifyMode()
192*/
193
194/*!
195 \fn void QSslSocket::encrypted()
196
197 This signal is emitted when QSslSocket enters encrypted mode. After this
198 signal has been emitted, QSslSocket::isEncrypted() will return true, and
199 all further transmissions on the socket will be encrypted.
200
201 \sa QSslSocket::connectToHostEncrypted(), QSslSocket::isEncrypted()
202*/
203
204/*!
205 \fn void QSslSocket::modeChanged(QSslSocket::SslMode mode)
206
207 This signal is emitted when QSslSocket changes from \l
208 QSslSocket::UnencryptedMode to either \l QSslSocket::SslClientMode or \l
209 QSslSocket::SslServerMode. \a mode is the new mode.
210
211 \sa QSslSocket::mode()
212*/
213
214/*!
215 \fn void QSslSocket::encryptedBytesWritten(qint64 written)
216 \since 4.4
217
218 This signal is emitted when QSslSocket writes its encrypted data to the
219 network. The \a written parameter contains the number of bytes that were
220 successfully written.
221
222 \sa QIODevice::bytesWritten()
223*/
224
225/*!
226 \fn void QSslSocket::peerVerifyError(const QSslError &error)
227 \since 4.4
228
229 QSslSocket can emit this signal several times during the SSL handshake,
230 before encryption has been established, to indicate that an error has
231 occurred while establishing the identity of the peer. The \a error is
232 usually an indication that QSslSocket is unable to securely identify the
233 peer.
234
235 This signal provides you with an early indication when something's wrong.
236 By connecting to this signal, you can manually choose to tear down the
237 connection from inside the connected slot before the handshake has
238 completed. If no action is taken, QSslSocket will proceed to emitting
239 QSslSocket::sslErrors().
240
241 \sa sslErrors()
242*/
243
244/*!
245 \fn void QSslSocket::sslErrors(const QList<QSslError> &errors);
246
247 QSslSocket emits this signal after the SSL handshake to indicate that one
248 or more errors have occurred while establishing the identity of the
249 peer. The errors are usually an indication that QSslSocket is unable to
250 securely identify the peer. Unless any action is taken, the connection
251 will be dropped after this signal has been emitted.
252
253 If you want to continue connecting despite the errors that have occurred,
254 you must call QSslSocket::ignoreSslErrors() from inside a slot connected to
255 this signal. If you need to access the error list at a later point, you
256 can call sslHandshakeErrors().
257
258 \a errors contains one or more errors that prevent QSslSocket from
259 verifying the identity of the peer.
260
261 \note You cannot use Qt::QueuedConnection when connecting to this signal,
262 or calling QSslSocket::ignoreSslErrors() will have no effect.
263
264 \sa peerVerifyError()
265*/
266
267/*!
268 \fn void QSslSocket::preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
269 \since 5.5
270
271 QSslSocket emits this signal when it negotiates a PSK ciphersuite, and
272 therefore a PSK authentication is then required.
273
274 When using PSK, the client must send to the server a valid identity and a
275 valid pre shared key, in order for the SSL handshake to continue.
276 Applications can provide this information in a slot connected to this
277 signal, by filling in the passed \a authenticator object according to their
278 needs.
279
280 \note Ignoring this signal, or failing to provide the required credentials,
281 will cause the handshake to fail, and therefore the connection to be aborted.
282
283 \note The \a authenticator object is owned by the socket and must not be
284 deleted by the application.
285
286 \sa QSslPreSharedKeyAuthenticator
287*/
288
289/*!
290 \fn void QSslSocket::alertSent(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description)
291
292 QSslSocket emits this signal if an alert message was sent to a peer. \a level
293 describes if it was a warning or a fatal error. \a type gives the code
294 of the alert message. When a textual description of the alert message is
295 available, it is supplied in \a description.
296
297 \note This signal is mostly informational and can be used for debugging
298 purposes, normally it does not require any actions from the application.
299 \note Not all backends support this functionality.
300
301 \sa alertReceived(), QSsl::AlertLevel, QSsl::AlertType
302*/
303
304/*!
305 \fn void QSslSocket::alertReceived(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description)
306
307 QSslSocket emits this signal if an alert message was received from a peer.
308 \a level tells if the alert was fatal or it was a warning. \a type is the
309 code explaining why the alert was sent. When a textual description of
310 the alert message is available, it is supplied in \a description.
311
312 \note The signal is mostly for informational and debugging purposes and does not
313 require any handling in the application. If the alert was fatal, underlying
314 backend will handle it and close the connection.
315 \note Not all backends support this functionality.
316
317 \sa alertSent(), QSsl::AlertLevel, QSsl::AlertType
318*/
319
320/*!
321 \fn void QSslSocket::handshakeInterruptedOnError(const QSslError &error)
322
323 QSslSocket emits this signal if a certificate verification error was
324 found and if early error reporting was enabled in QSslConfiguration.
325 An application is expected to inspect the \a error and decide if
326 it wants to continue the handshake, or abort it and send an alert message
327 to the peer. The signal-slot connection must be direct.
328
329 \sa continueInterruptedHandshake(), sslErrors(), QSslConfiguration::setHandshakeMustInterruptOnError()
330*/
331
332/*!
333 \fn void QSslSocket::newSessionTicketReceived()
334 \since 5.15
335
336 If TLS 1.3 protocol was negotiated during a handshake, QSslSocket
337 emits this signal after receiving NewSessionTicket message. Session
338 and session ticket's lifetime hint are updated in the socket's
339 configuration. The session can be used for session resumption (and
340 a shortened handshake) in future TLS connections.
341
342 \note This functionality enabled only with OpenSSL backend and requires
343 OpenSSL v 1.1.1 or above.
344
345 \sa QSslSocket::sslConfiguration(), QSslConfiguration::sessionTicket(), QSslConfiguration::sessionTicketLifeTimeHint()
346*/
347
348#include "qssl_p.h"
349#include "qsslsocket.h"
350#include "qsslcipher.h"
351#include "qocspresponse.h"
352#include "qtlsbackend_p.h"
353#include "qsslconfiguration_p.h"
354#include "qsslsocket_p.h"
355
356#include <QtCore/qdebug.h>
357#include <QtCore/qdir.h>
358#include <QtCore/qmutex.h>
359#include <QtCore/qurl.h>
360#include <QtCore/qelapsedtimer.h>
361#include <QtNetwork/qhostaddress.h>
362#include <QtNetwork/qhostinfo.h>
363
364QT_BEGIN_NAMESPACE
365
366using namespace Qt::StringLiterals;
367
368class QSslSocketGlobalData
369{
370public:
371 QSslSocketGlobalData()
372 : config(new QSslConfigurationPrivate),
373 dtlsConfig(new QSslConfigurationPrivate)
374 {
375#if QT_CONFIG(dtls)
376 dtlsConfig->protocol = QSsl::DtlsV1_2OrLater;
377#endif // dtls
378 }
379
380 QMutex mutex;
381 QList<QSslCipher> supportedCiphers;
382 QList<QSslEllipticCurve> supportedEllipticCurves;
383 QExplicitlySharedDataPointer<QSslConfigurationPrivate> config;
384 QExplicitlySharedDataPointer<QSslConfigurationPrivate> dtlsConfig;
385};
386Q_GLOBAL_STATIC(QSslSocketGlobalData, globalData)
387
388/*!
389 Constructs a QSslSocket object. \a parent is passed to QObject's
390 constructor. The new socket's \l {QSslCipher} {cipher} suite is
391 set to the one returned by the static method defaultCiphers().
392*/
393QSslSocket::QSslSocket(QObject *parent)
394 : QTcpSocket(*new QSslSocketPrivate, parent)
395{
396 Q_D(QSslSocket);
397#ifdef QSSLSOCKET_DEBUG
398 qCDebug(lcSsl) << "QSslSocket::QSslSocket(" << parent << "), this =" << (void *)this;
399#endif
400 d->q_ptr = this;
401 d->init();
402}
403
404/*!
405 Destroys the QSslSocket.
406*/
407QSslSocket::~QSslSocket()
408{
409 Q_D(QSslSocket);
410#ifdef QSSLSOCKET_DEBUG
411 qCDebug(lcSsl) << "QSslSocket::~QSslSocket(), this =" << (void *)this;
412#endif
413 delete d->plainSocket;
414 d->plainSocket = nullptr;
415}
416
417/*!
418 \reimp
419
420 \since 5.0
421
422 Continues data transfer on the socket after it has been paused. If
423 "setPauseMode(QAbstractSocket::PauseOnSslErrors);" has been called on
424 this socket and a sslErrors() signal is received, calling this method
425 is necessary for the socket to continue.
426
427 \sa QAbstractSocket::pauseMode(), QAbstractSocket::setPauseMode()
428*/
429void QSslSocket::resume()
430{
431 Q_D(QSslSocket);
432 if (!d->paused)
433 return;
434 // continuing might emit signals, rather do this through the event loop
435 QMetaObject::invokeMethod(obj: this, member: "_q_resumeImplementation", c: Qt::QueuedConnection);
436}
437
438/*!
439 Starts an encrypted connection to the device \a hostName on \a
440 port, using \a mode as the \l OpenMode. This is equivalent to
441 calling connectToHost() to establish the connection, followed by a
442 call to startClientEncryption(). The \a protocol parameter can be
443 used to specify which network protocol to use (eg. IPv4 or IPv6).
444
445 QSslSocket first enters the HostLookupState. Then, after entering
446 either the event loop or one of the waitFor...() functions, it
447 enters the ConnectingState, emits connected(), and then initiates
448 the SSL client handshake. At each state change, QSslSocket emits
449 signal stateChanged().
450
451 After initiating the SSL client handshake, if the identity of the
452 peer can't be established, signal sslErrors() is emitted. If you
453 want to ignore the errors and continue connecting, you must call
454 ignoreSslErrors(), either from inside a slot function connected to
455 the sslErrors() signal, or prior to entering encrypted mode. If
456 ignoreSslErrors() is not called, the connection is dropped, signal
457 disconnected() is emitted, and QSslSocket returns to the
458 UnconnectedState.
459
460 If the SSL handshake is successful, QSslSocket emits encrypted().
461
462 \snippet code/src_network_ssl_qsslsocket.cpp 3
463
464 \note The example above shows that text can be written to
465 the socket immediately after requesting the encrypted connection,
466 before the encrypted() signal has been emitted. In such cases, the
467 text is queued in the object and written to the socket \e after
468 the connection is established and the encrypted() signal has been
469 emitted.
470
471 The default for \a mode is \l ReadWrite.
472
473 If you want to create a QSslSocket on the server side of a connection, you
474 should instead call startServerEncryption() upon receiving the incoming
475 connection through QTcpServer.
476
477 \sa connectToHost(), startClientEncryption(), waitForConnected(), waitForEncrypted()
478*/
479void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode, NetworkLayerProtocol protocol)
480{
481 Q_D(QSslSocket);
482 if (d->state == ConnectedState || d->state == ConnectingState) {
483 qCWarning(lcSsl,
484 "QSslSocket::connectToHostEncrypted() called when already connecting/connected");
485 return;
486 }
487
488 if (!supportsSsl()) {
489 qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");
490 d->setErrorAndEmit(errorCode: QAbstractSocket::SslInternalError, errorString: tr(s: "TLS initialization failed"));
491 return;
492 }
493
494 if (!d->verifyProtocolSupported(where: "QSslSocket::connectToHostEncrypted:"))
495 return;
496
497 d->init();
498 d->autoStartHandshake = true;
499 d->initialized = true;
500
501 // Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs)
502 // establish the connection immediately (i.e., first attempt).
503 connectToHost(hostName, port, openMode: mode, protocol);
504}
505
506/*!
507 \since 4.6
508 \overload
509
510 In addition to the original behaviour of connectToHostEncrypted,
511 this overloaded method enables the usage of a different hostname
512 (\a sslPeerName) for the certificate validation instead of
513 the one used for the TCP connection (\a hostName).
514
515 \sa connectToHostEncrypted()
516*/
517void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,
518 const QString &sslPeerName, OpenMode mode,
519 NetworkLayerProtocol protocol)
520{
521 Q_D(QSslSocket);
522 if (d->state == ConnectedState || d->state == ConnectingState) {
523 qCWarning(lcSsl,
524 "QSslSocket::connectToHostEncrypted() called when already connecting/connected");
525 return;
526 }
527
528 if (!supportsSsl()) {
529 qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");
530 d->setErrorAndEmit(errorCode: QAbstractSocket::SslInternalError, errorString: tr(s: "TLS initialization failed"));
531 return;
532 }
533
534 d->init();
535 d->autoStartHandshake = true;
536 d->initialized = true;
537 d->verificationPeerName = sslPeerName;
538
539 // Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs)
540 // establish the connection immediately (i.e., first attempt).
541 connectToHost(hostName, port, openMode: mode, protocol);
542}
543
544/*!
545 Initializes QSslSocket with the native socket descriptor \a
546 socketDescriptor. Returns \c true if \a socketDescriptor is accepted
547 as a valid socket descriptor; otherwise returns \c false.
548 The socket is opened in the mode specified by \a openMode, and
549 enters the socket state specified by \a state.
550
551 \note It is not possible to initialize two sockets with the same
552 native socket descriptor.
553
554 \sa socketDescriptor()
555*/
556bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state, OpenMode openMode)
557{
558 Q_D(QSslSocket);
559#ifdef QSSLSOCKET_DEBUG
560 qCDebug(lcSsl) << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ','
561 << state << ',' << openMode << ')';
562#endif
563 if (!d->plainSocket)
564 d->createPlainSocket(openMode);
565 bool retVal = d->plainSocket->setSocketDescriptor(socketDescriptor, state, openMode);
566 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
567 d->setError(errorCode: d->plainSocket->error(), errorString: d->plainSocket->errorString());
568 setSocketState(state);
569 setOpenMode(openMode);
570 setLocalPort(d->plainSocket->localPort());
571 setLocalAddress(d->plainSocket->localAddress());
572 setPeerPort(d->plainSocket->peerPort());
573 setPeerAddress(d->plainSocket->peerAddress());
574 setPeerName(d->plainSocket->peerName());
575 d->readChannelCount = d->plainSocket->readChannelCount();
576 d->writeChannelCount = d->plainSocket->writeChannelCount();
577 return retVal;
578}
579
580/*!
581 \since 4.6
582 Sets the given \a option to the value described by \a value.
583
584 \sa socketOption()
585*/
586void QSslSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
587{
588 Q_D(QSslSocket);
589 if (d->plainSocket)
590 d->plainSocket->setSocketOption(option, value);
591}
592
593/*!
594 \since 4.6
595 Returns the value of the \a option option.
596
597 \sa setSocketOption()
598*/
599QVariant QSslSocket::socketOption(QAbstractSocket::SocketOption option)
600{
601 Q_D(QSslSocket);
602 if (d->plainSocket)
603 return d->plainSocket->socketOption(option);
604 else
605 return QVariant();
606}
607
608/*!
609 Returns the current mode for the socket; either UnencryptedMode, where
610 QSslSocket behaves identially to QTcpSocket, or one of SslClientMode or
611 SslServerMode, where the client is either negotiating or in encrypted
612 mode.
613
614 When the mode changes, QSslSocket emits modeChanged()
615
616 \sa SslMode
617*/
618QSslSocket::SslMode QSslSocket::mode() const
619{
620 Q_D(const QSslSocket);
621 return d->mode;
622}
623
624/*!
625 Returns \c true if the socket is encrypted; otherwise, false is returned.
626
627 An encrypted socket encrypts all data that is written by calling write()
628 or putChar() before the data is written to the network, and decrypts all
629 incoming data as the data is received from the network, before you call
630 read(), readLine() or getChar().
631
632 QSslSocket emits encrypted() when it enters encrypted mode.
633
634 You can call sessionCipher() to find which cryptographic cipher is used to
635 encrypt and decrypt your data.
636
637 \sa mode()
638*/
639bool QSslSocket::isEncrypted() const
640{
641 Q_D(const QSslSocket);
642 return d->connectionEncrypted;
643}
644
645/*!
646 Returns the socket's SSL protocol. By default, \l QSsl::SecureProtocols is used.
647
648 \sa setProtocol()
649*/
650QSsl::SslProtocol QSslSocket::protocol() const
651{
652 Q_D(const QSslSocket);
653 return d->configuration.protocol;
654}
655
656/*!
657 Sets the socket's SSL protocol to \a protocol. This will affect the next
658 initiated handshake; calling this function on an already-encrypted socket
659 will not affect the socket's protocol.
660*/
661void QSslSocket::setProtocol(QSsl::SslProtocol protocol)
662{
663 Q_D(QSslSocket);
664 d->configuration.protocol = protocol;
665}
666
667/*!
668 \since 4.4
669
670 Returns the socket's verify mode. This mode decides whether
671 QSslSocket should request a certificate from the peer (i.e., the client
672 requests a certificate from the server, or a server requesting a
673 certificate from the client), and whether it should require that this
674 certificate is valid.
675
676 The default mode is AutoVerifyPeer, which tells QSslSocket to use
677 VerifyPeer for clients and QueryPeer for servers.
678
679 \sa setPeerVerifyMode(), peerVerifyDepth(), mode()
680*/
681QSslSocket::PeerVerifyMode QSslSocket::peerVerifyMode() const
682{
683 Q_D(const QSslSocket);
684 return d->configuration.peerVerifyMode;
685}
686
687/*!
688 \since 4.4
689
690 Sets the socket's verify mode to \a mode. This mode decides whether
691 QSslSocket should request a certificate from the peer (i.e., the client
692 requests a certificate from the server, or a server requesting a
693 certificate from the client), and whether it should require that this
694 certificate is valid.
695
696 The default mode is AutoVerifyPeer, which tells QSslSocket to use
697 VerifyPeer for clients and QueryPeer for servers.
698
699 Setting this mode after encryption has started has no effect on the
700 current connection.
701
702 \sa peerVerifyMode(), setPeerVerifyDepth(), mode()
703*/
704void QSslSocket::setPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
705{
706 Q_D(QSslSocket);
707 d->configuration.peerVerifyMode = mode;
708}
709
710/*!
711 \since 4.4
712
713 Returns the maximum number of certificates in the peer's certificate chain
714 to be checked during the SSL handshake phase, or 0 (the default) if no
715 maximum depth has been set, indicating that the whole certificate chain
716 should be checked.
717
718 The certificates are checked in issuing order, starting with the peer's
719 own certificate, then its issuer's certificate, and so on.
720
721 \sa setPeerVerifyDepth(), peerVerifyMode()
722*/
723int QSslSocket::peerVerifyDepth() const
724{
725 Q_D(const QSslSocket);
726 return d->configuration.peerVerifyDepth;
727}
728
729/*!
730 \since 4.4
731
732 Sets the maximum number of certificates in the peer's certificate chain to
733 be checked during the SSL handshake phase, to \a depth. Setting a depth of
734 0 means that no maximum depth is set, indicating that the whole
735 certificate chain should be checked.
736
737 The certificates are checked in issuing order, starting with the peer's
738 own certificate, then its issuer's certificate, and so on.
739
740 \sa peerVerifyDepth(), setPeerVerifyMode()
741*/
742void QSslSocket::setPeerVerifyDepth(int depth)
743{
744 Q_D(QSslSocket);
745 if (depth < 0) {
746 qCWarning(lcSsl, "QSslSocket::setPeerVerifyDepth: cannot set negative depth of %d", depth);
747 return;
748 }
749 d->configuration.peerVerifyDepth = depth;
750}
751
752/*!
753 \since 4.8
754
755 Returns the different hostname for the certificate validation, as set by
756 setPeerVerifyName or by connectToHostEncrypted.
757
758 \sa setPeerVerifyName(), connectToHostEncrypted()
759*/
760QString QSslSocket::peerVerifyName() const
761{
762 Q_D(const QSslSocket);
763 return d->verificationPeerName;
764}
765
766/*!
767 \since 4.8
768
769 Sets a different host name, given by \a hostName, for the certificate
770 validation instead of the one used for the TCP connection.
771
772 \sa connectToHostEncrypted()
773*/
774void QSslSocket::setPeerVerifyName(const QString &hostName)
775{
776 Q_D(QSslSocket);
777 d->verificationPeerName = hostName;
778}
779
780/*!
781 \reimp
782
783 Returns the number of decrypted bytes that are immediately available for
784 reading.
785*/
786qint64 QSslSocket::bytesAvailable() const
787{
788 Q_D(const QSslSocket);
789 if (d->mode == UnencryptedMode)
790 return QAbstractSocket::bytesAvailable() + (d->plainSocket ? d->plainSocket->bytesAvailable() : 0);
791 return QAbstractSocket::bytesAvailable();
792}
793
794/*!
795 \reimp
796
797 Returns the number of unencrypted bytes that are waiting to be encrypted
798 and written to the network.
799*/
800qint64 QSslSocket::bytesToWrite() const
801{
802 Q_D(const QSslSocket);
803 if (d->mode == UnencryptedMode)
804 return d->plainSocket ? d->plainSocket->bytesToWrite() : 0;
805 return d->writeBuffer.size();
806}
807
808/*!
809 \since 4.4
810
811 Returns the number of encrypted bytes that are awaiting decryption.
812 Normally, this function will return 0 because QSslSocket decrypts its
813 incoming data as soon as it can.
814*/
815qint64 QSslSocket::encryptedBytesAvailable() const
816{
817 Q_D(const QSslSocket);
818 if (d->mode == UnencryptedMode)
819 return 0;
820 return d->plainSocket->bytesAvailable();
821}
822
823/*!
824 \since 4.4
825
826 Returns the number of encrypted bytes that are waiting to be written to
827 the network.
828*/
829qint64 QSslSocket::encryptedBytesToWrite() const
830{
831 Q_D(const QSslSocket);
832 if (d->mode == UnencryptedMode)
833 return 0;
834 return d->plainSocket->bytesToWrite();
835}
836
837/*!
838 \reimp
839
840 Returns \c true if you can read one while line (terminated by a single ASCII
841 '\\n' character) of decrypted characters; otherwise, false is returned.
842*/
843bool QSslSocket::canReadLine() const
844{
845 Q_D(const QSslSocket);
846 if (d->mode == UnencryptedMode)
847 return QAbstractSocket::canReadLine() || (d->plainSocket && d->plainSocket->canReadLine());
848 return QAbstractSocket::canReadLine();
849}
850
851/*!
852 \reimp
853*/
854void QSslSocket::close()
855{
856#ifdef QSSLSOCKET_DEBUG
857 qCDebug(lcSsl) << "QSslSocket::close()";
858#endif
859 Q_D(QSslSocket);
860
861 // On Windows, CertGetCertificateChain is probably still doing its
862 // job, if the socket is re-used, we want to ignore its reported
863 // root CA.
864 if (auto *backend = d->backend.get())
865 backend->cancelCAFetch();
866
867 if (!d->abortCalled && (encryptedBytesToWrite() || !d->writeBuffer.isEmpty()))
868 flush();
869 if (d->plainSocket) {
870 if (d->abortCalled)
871 d->plainSocket->abort();
872 else
873 d->plainSocket->close();
874 }
875 QTcpSocket::close();
876
877 // must be cleared, reading/writing not possible on closed socket:
878 d->buffer.clear();
879 d->writeBuffer.clear();
880}
881
882/*!
883 \reimp
884*/
885bool QSslSocket::atEnd() const
886{
887 Q_D(const QSslSocket);
888 if (d->mode == UnencryptedMode)
889 return QAbstractSocket::atEnd() && (!d->plainSocket || d->plainSocket->atEnd());
890 return QAbstractSocket::atEnd();
891}
892
893/*!
894 \since 4.4
895
896 Sets the size of QSslSocket's internal read buffer to be \a size bytes.
897*/
898void QSslSocket::setReadBufferSize(qint64 size)
899{
900 Q_D(QSslSocket);
901 d->readBufferMaxSize = size;
902
903 if (d->plainSocket)
904 d->plainSocket->setReadBufferSize(size);
905}
906
907/*!
908 \since 4.4
909
910 Returns the socket's SSL configuration state. The default SSL
911 configuration of a socket is to use the default ciphers,
912 default CA certificates, no local private key or certificate.
913
914 The SSL configuration also contains fields that can change with
915 time without notice.
916
917 \sa localCertificate(), peerCertificate(), peerCertificateChain(),
918 sessionCipher(), privateKey(), QSslConfiguration::ciphers(),
919 QSslConfiguration::caCertificates()
920*/
921QSslConfiguration QSslSocket::sslConfiguration() const
922{
923 Q_D(const QSslSocket);
924
925 // create a deep copy of our configuration
926 QSslConfigurationPrivate *copy = new QSslConfigurationPrivate(d->configuration);
927 copy->ref.storeRelaxed(newValue: 0); // the QSslConfiguration constructor refs up
928 copy->sessionCipher = d->sessionCipher();
929 copy->sessionProtocol = d->sessionProtocol();
930
931 return QSslConfiguration(copy);
932}
933
934/*!
935 \since 4.4
936
937 Sets the socket's SSL configuration to be the contents of \a configuration.
938 This function sets the local certificate, the ciphers, the private key and the CA
939 certificates to those stored in \a configuration.
940
941 It is not possible to set the SSL-state related fields.
942
943 \sa setLocalCertificate(), setPrivateKey(), QSslConfiguration::setCaCertificates(),
944 QSslConfiguration::setCiphers()
945*/
946void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
947{
948 Q_D(QSslSocket);
949 d->configuration.localCertificateChain = configuration.localCertificateChain();
950 d->configuration.privateKey = configuration.privateKey();
951 d->configuration.ciphers = configuration.ciphers();
952 d->configuration.ellipticCurves = configuration.ellipticCurves();
953 d->configuration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
954 d->configuration.dhParams = configuration.diffieHellmanParameters();
955 d->configuration.caCertificates = configuration.caCertificates();
956 d->configuration.peerVerifyDepth = configuration.peerVerifyDepth();
957 d->configuration.peerVerifyMode = configuration.peerVerifyMode();
958 d->configuration.protocol = configuration.protocol();
959 d->configuration.backendConfig = configuration.backendConfiguration();
960 d->configuration.sslOptions = configuration.d->sslOptions;
961 d->configuration.sslSession = configuration.sessionTicket();
962 d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
963 d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols();
964 d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
965 d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
966#if QT_CONFIG(ocsp)
967 d->configuration.ocspStaplingEnabled = configuration.ocspStaplingEnabled();
968#endif
969#if QT_CONFIG(openssl)
970 d->configuration.reportFromCallback = configuration.handshakeMustInterruptOnError();
971 d->configuration.missingCertIsFatal = configuration.missingCertificateIsFatal();
972#endif // openssl
973 // if the CA certificates were set explicitly (either via
974 // QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(),
975 // we cannot load the certificates on demand
976 if (!configuration.d->allowRootCertOnDemandLoading) {
977 d->allowRootCertOnDemandLoading = false;
978 d->configuration.allowRootCertOnDemandLoading = false;
979 }
980}
981
982/*!
983 Sets the certificate chain to be presented to the peer during the
984 SSL handshake to be \a localChain.
985
986 \sa QSslConfiguration::setLocalCertificateChain()
987 \since 5.1
988 */
989void QSslSocket::setLocalCertificateChain(const QList<QSslCertificate> &localChain)
990{
991 Q_D(QSslSocket);
992 d->configuration.localCertificateChain = localChain;
993}
994
995/*!
996 Returns the socket's local \l {QSslCertificate} {certificate} chain,
997 or an empty list if no local certificates have been assigned.
998
999 \sa setLocalCertificateChain()
1000 \since 5.1
1001*/
1002QList<QSslCertificate> QSslSocket::localCertificateChain() const
1003{
1004 Q_D(const QSslSocket);
1005 return d->configuration.localCertificateChain;
1006}
1007
1008/*!
1009 Sets the socket's local certificate to \a certificate. The local
1010 certificate is necessary if you need to confirm your identity to the
1011 peer. It is used together with the private key; if you set the local
1012 certificate, you must also set the private key.
1013
1014 The local certificate and private key are always necessary for server
1015 sockets, but are also rarely used by client sockets if the server requires
1016 the client to authenticate.
1017
1018 \note Secure Transport SSL backend on macOS may update the default keychain
1019 (the default is probably your login keychain) by importing your local certificates
1020 and keys. This can also result in system dialogs showing up and asking for
1021 permission when your application is using these private keys. If such behavior
1022 is undesired, set the QT_SSL_USE_TEMPORARY_KEYCHAIN environment variable to a
1023 non-zero value; this will prompt QSslSocket to use its own temporary keychain.
1024
1025 \sa localCertificate(), setPrivateKey()
1026*/
1027void QSslSocket::setLocalCertificate(const QSslCertificate &certificate)
1028{
1029 Q_D(QSslSocket);
1030 d->configuration.localCertificateChain = QList<QSslCertificate>();
1031 d->configuration.localCertificateChain += certificate;
1032}
1033
1034/*!
1035 \overload
1036
1037 Sets the socket's local \l {QSslCertificate} {certificate} to the
1038 first one found in file \a path, which is parsed according to the
1039 specified \a format.
1040*/
1041void QSslSocket::setLocalCertificate(const QString &path,
1042 QSsl::EncodingFormat format)
1043{
1044 QFile file(path);
1045 if (file.open(flags: QIODevice::ReadOnly | QIODevice::Text))
1046 setLocalCertificate(QSslCertificate(file.readAll(), format));
1047
1048}
1049
1050/*!
1051 Returns the socket's local \l {QSslCertificate} {certificate}, or
1052 an empty certificate if no local certificate has been assigned.
1053
1054 \sa setLocalCertificate(), privateKey()
1055*/
1056QSslCertificate QSslSocket::localCertificate() const
1057{
1058 Q_D(const QSslSocket);
1059 if (d->configuration.localCertificateChain.isEmpty())
1060 return QSslCertificate();
1061 return d->configuration.localCertificateChain[0];
1062}
1063
1064/*!
1065 Returns the peer's digital certificate (i.e., the immediate
1066 certificate of the host you are connected to), or a null
1067 certificate, if the peer has not assigned a certificate.
1068
1069 The peer certificate is checked automatically during the
1070 handshake phase, so this function is normally used to fetch
1071 the certificate for display or for connection diagnostic
1072 purposes. It contains information about the peer, including
1073 its host name, the certificate issuer, and the peer's public
1074 key.
1075
1076 Because the peer certificate is set during the handshake phase, it
1077 is safe to access the peer certificate from a slot connected to
1078 the sslErrors() signal or the encrypted() signal.
1079
1080 If a null certificate is returned, it can mean the SSL handshake
1081 failed, or it can mean the host you are connected to doesn't have
1082 a certificate, or it can mean there is no connection.
1083
1084 If you want to check the peer's complete chain of certificates,
1085 use peerCertificateChain() to get them all at once.
1086
1087 \sa peerCertificateChain()
1088*/
1089QSslCertificate QSslSocket::peerCertificate() const
1090{
1091 Q_D(const QSslSocket);
1092 return d->configuration.peerCertificate;
1093}
1094
1095/*!
1096 Returns the peer's chain of digital certificates, or an empty list
1097 of certificates.
1098
1099 Peer certificates are checked automatically during the handshake
1100 phase. This function is normally used to fetch certificates for
1101 display, or for performing connection diagnostics. Certificates
1102 contain information about the peer and the certificate issuers,
1103 including host name, issuer names, and issuer public keys.
1104
1105 The peer certificates are set in QSslSocket during the handshake
1106 phase, so it is safe to call this function from a slot connected
1107 to the sslErrors() signal or the encrypted() signal.
1108
1109 If an empty list is returned, it can mean the SSL handshake
1110 failed, or it can mean the host you are connected to doesn't have
1111 a certificate, or it can mean there is no connection.
1112
1113 If you want to get only the peer's immediate certificate, use
1114 peerCertificate().
1115
1116 \sa peerCertificate()
1117*/
1118QList<QSslCertificate> QSslSocket::peerCertificateChain() const
1119{
1120 Q_D(const QSslSocket);
1121 return d->configuration.peerCertificateChain;
1122}
1123
1124/*!
1125 Returns the socket's cryptographic \l {QSslCipher} {cipher}, or a
1126 null cipher if the connection isn't encrypted. The socket's cipher
1127 for the session is set during the handshake phase. The cipher is
1128 used to encrypt and decrypt data transmitted through the socket.
1129
1130 QSslSocket also provides functions for setting the ordered list of
1131 ciphers from which the handshake phase will eventually select the
1132 session cipher. This ordered list must be in place before the
1133 handshake phase begins.
1134
1135 \sa QSslConfiguration::ciphers(), QSslConfiguration::setCiphers(),
1136 QSslConfiguration::setCiphers(),
1137 QSslConfiguration::ciphers(),
1138 QSslConfiguration::supportedCiphers()
1139*/
1140QSslCipher QSslSocket::sessionCipher() const
1141{
1142 Q_D(const QSslSocket);
1143 return d->sessionCipher();
1144}
1145
1146/*!
1147 Returns the socket's SSL/TLS protocol or UnknownProtocol if the
1148 connection isn't encrypted. The socket's protocol for the session
1149 is set during the handshake phase.
1150
1151 \sa protocol(), setProtocol()
1152 \since 5.4
1153*/
1154QSsl::SslProtocol QSslSocket::sessionProtocol() const
1155{
1156 Q_D(const QSslSocket);
1157 return d->sessionProtocol();
1158}
1159
1160/*!
1161 \since 5.13
1162
1163 This function returns Online Certificate Status Protocol responses that
1164 a server may send during a TLS handshake using OCSP stapling. The list
1165 is empty if no definitive response or no response at all was received.
1166
1167 \sa QSslConfiguration::setOcspStaplingEnabled()
1168*/
1169QList<QOcspResponse> QSslSocket::ocspResponses() const
1170{
1171 Q_D(const QSslSocket);
1172 if (const auto *backend = d->backend.get())
1173 return backend->ocsps();
1174 return {};
1175}
1176
1177/*!
1178 Sets the socket's private \l {QSslKey} {key} to \a key. The
1179 private key and the local \l {QSslCertificate} {certificate} are
1180 used by clients and servers that must prove their identity to
1181 SSL peers.
1182
1183 Both the key and the local certificate are required if you are
1184 creating an SSL server socket. If you are creating an SSL client
1185 socket, the key and local certificate are required if your client
1186 must identify itself to an SSL server.
1187
1188 \sa privateKey(), setLocalCertificate()
1189*/
1190void QSslSocket::setPrivateKey(const QSslKey &key)
1191{
1192 Q_D(QSslSocket);
1193 d->configuration.privateKey = key;
1194}
1195
1196/*!
1197 \overload
1198
1199 Reads the string in file \a fileName and decodes it using
1200 a specified \a algorithm and encoding \a format to construct
1201 an \l {QSslKey} {SSL key}. If the encoded key is encrypted,
1202 \a passPhrase is used to decrypt it.
1203
1204 The socket's private key is set to the constructed key. The
1205 private key and the local \l {QSslCertificate} {certificate} are
1206 used by clients and servers that must prove their identity to SSL
1207 peers.
1208
1209 Both the key and the local certificate are required if you are
1210 creating an SSL server socket. If you are creating an SSL client
1211 socket, the key and local certificate are required if your client
1212 must identify itself to an SSL server.
1213
1214 \sa privateKey(), setLocalCertificate()
1215*/
1216void QSslSocket::setPrivateKey(const QString &fileName, QSsl::KeyAlgorithm algorithm,
1217 QSsl::EncodingFormat format, const QByteArray &passPhrase)
1218{
1219 QFile file(fileName);
1220 if (!file.open(flags: QIODevice::ReadOnly)) {
1221 qCWarning(lcSsl, "QSslSocket::setPrivateKey: Couldn't open file for reading");
1222 return;
1223 }
1224
1225 QSslKey key(file.readAll(), algorithm, format, QSsl::PrivateKey, passPhrase);
1226 if (key.isNull()) {
1227 qCWarning(lcSsl, "QSslSocket::setPrivateKey: "
1228 "The specified file does not contain a valid key");
1229 return;
1230 }
1231
1232 Q_D(QSslSocket);
1233 d->configuration.privateKey = key;
1234}
1235
1236/*!
1237 Returns this socket's private key.
1238
1239 \sa setPrivateKey(), localCertificate()
1240*/
1241QSslKey QSslSocket::privateKey() const
1242{
1243 Q_D(const QSslSocket);
1244 return d->configuration.privateKey;
1245}
1246
1247/*!
1248 Waits until the socket is connected, or \a msecs milliseconds,
1249 whichever happens first. If the connection has been established,
1250 this function returns \c true; otherwise it returns \c false.
1251
1252 \sa QAbstractSocket::waitForConnected()
1253*/
1254bool QSslSocket::waitForConnected(int msecs)
1255{
1256 Q_D(QSslSocket);
1257 if (!d->plainSocket)
1258 return false;
1259 bool retVal = d->plainSocket->waitForConnected(msecs);
1260 if (!retVal) {
1261 setSocketState(d->plainSocket->state());
1262 d->setError(errorCode: d->plainSocket->error(), errorString: d->plainSocket->errorString());
1263 }
1264 return retVal;
1265}
1266
1267/*!
1268 Waits until the socket has completed the SSL handshake and has
1269 emitted encrypted(), or \a msecs milliseconds, whichever comes
1270 first. If encrypted() has been emitted, this function returns
1271 true; otherwise (e.g., the socket is disconnected, or the SSL
1272 handshake fails), false is returned.
1273
1274 The following example waits up to one second for the socket to be
1275 encrypted:
1276
1277 \snippet code/src_network_ssl_qsslsocket.cpp 5
1278
1279 If msecs is -1, this function will not time out.
1280
1281 \sa startClientEncryption(), startServerEncryption(), encrypted(), isEncrypted()
1282*/
1283bool QSslSocket::waitForEncrypted(int msecs)
1284{
1285 Q_D(QSslSocket);
1286 if (!d->plainSocket || d->connectionEncrypted)
1287 return false;
1288 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1289 return false;
1290 if (!d->verifyProtocolSupported(where: "QSslSocket::waitForEncrypted:"))
1291 return false;
1292
1293 QElapsedTimer stopWatch;
1294 stopWatch.start();
1295
1296 if (d->plainSocket->state() != QAbstractSocket::ConnectedState) {
1297 // Wait until we've entered connected state.
1298 if (!d->plainSocket->waitForConnected(msecs))
1299 return false;
1300 }
1301
1302 while (!d->connectionEncrypted) {
1303 // Start the handshake, if this hasn't been started yet.
1304 if (d->mode == UnencryptedMode)
1305 startClientEncryption();
1306 // Loop, waiting until the connection has been encrypted or an error
1307 // occurs.
1308 if (!d->plainSocket->waitForReadyRead(msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed())))
1309 return false;
1310 }
1311 return d->connectionEncrypted;
1312}
1313
1314/*!
1315 \reimp
1316*/
1317bool QSslSocket::waitForReadyRead(int msecs)
1318{
1319 Q_D(QSslSocket);
1320 if (!d->plainSocket)
1321 return false;
1322 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1323 return d->plainSocket->waitForReadyRead(msecs);
1324
1325 // This function must return true if and only if readyRead() *was* emitted.
1326 // So we initialize "readyReadEmitted" to false and check if it was set to true.
1327 // waitForReadyRead() could be called recursively, so we can't use the same variable
1328 // (the inner waitForReadyRead() may fail, but the outer one still succeeded)
1329 bool readyReadEmitted = false;
1330 bool *previousReadyReadEmittedPointer = d->readyReadEmittedPointer;
1331 d->readyReadEmittedPointer = &readyReadEmitted;
1332
1333 QElapsedTimer stopWatch;
1334 stopWatch.start();
1335
1336 if (!d->connectionEncrypted) {
1337 // Wait until we've entered encrypted mode, or until a failure occurs.
1338 if (!waitForEncrypted(msecs)) {
1339 d->readyReadEmittedPointer = previousReadyReadEmittedPointer;
1340 return false;
1341 }
1342 }
1343
1344 if (!d->writeBuffer.isEmpty()) {
1345 // empty our cleartext write buffer first
1346 d->transmit();
1347 }
1348
1349 // test readyReadEmitted first because either operation above
1350 // (waitForEncrypted or transmit) may have set it
1351 while (!readyReadEmitted &&
1352 d->plainSocket->waitForReadyRead(msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()))) {
1353 }
1354
1355 d->readyReadEmittedPointer = previousReadyReadEmittedPointer;
1356 return readyReadEmitted;
1357}
1358
1359/*!
1360 \reimp
1361*/
1362bool QSslSocket::waitForBytesWritten(int msecs)
1363{
1364 Q_D(QSslSocket);
1365 if (!d->plainSocket)
1366 return false;
1367 if (d->mode == UnencryptedMode)
1368 return d->plainSocket->waitForBytesWritten(msecs);
1369
1370 QElapsedTimer stopWatch;
1371 stopWatch.start();
1372
1373 if (!d->connectionEncrypted) {
1374 // Wait until we've entered encrypted mode, or until a failure occurs.
1375 if (!waitForEncrypted(msecs))
1376 return false;
1377 }
1378 if (!d->writeBuffer.isEmpty()) {
1379 // empty our cleartext write buffer first
1380 d->transmit();
1381 }
1382
1383 return d->plainSocket->waitForBytesWritten(msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()));
1384}
1385
1386/*!
1387 Waits until the socket has disconnected or \a msecs milliseconds,
1388 whichever comes first. If the connection has been disconnected,
1389 this function returns \c true; otherwise it returns \c false.
1390
1391 \sa QAbstractSocket::waitForDisconnected()
1392*/
1393bool QSslSocket::waitForDisconnected(int msecs)
1394{
1395 Q_D(QSslSocket);
1396
1397 // require calling connectToHost() before waitForDisconnected()
1398 if (state() == UnconnectedState) {
1399 qCWarning(lcSsl, "QSslSocket::waitForDisconnected() is not allowed in UnconnectedState");
1400 return false;
1401 }
1402
1403 if (!d->plainSocket)
1404 return false;
1405 // Forward to the plain socket unless the connection is secure.
1406 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1407 return d->plainSocket->waitForDisconnected(msecs);
1408
1409 QElapsedTimer stopWatch;
1410 stopWatch.start();
1411
1412 if (!d->connectionEncrypted) {
1413 // Wait until we've entered encrypted mode, or until a failure occurs.
1414 if (!waitForEncrypted(msecs))
1415 return false;
1416 }
1417 // We are delaying the disconnect, if the write buffer is not empty.
1418 // So, start the transmission.
1419 if (!d->writeBuffer.isEmpty())
1420 d->transmit();
1421
1422 // At this point, the socket might be disconnected, if disconnectFromHost()
1423 // was called just after the connectToHostEncrypted() call. Also, we can
1424 // lose the connection as a result of the transmit() call.
1425 if (state() == UnconnectedState)
1426 return true;
1427
1428 bool retVal = d->plainSocket->waitForDisconnected(msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()));
1429 if (!retVal) {
1430 setSocketState(d->plainSocket->state());
1431 d->setError(errorCode: d->plainSocket->error(), errorString: d->plainSocket->errorString());
1432 }
1433 return retVal;
1434}
1435
1436/*!
1437 \since 5.15
1438
1439 Returns a list of the last SSL errors that occurred. This is the
1440 same list as QSslSocket passes via the sslErrors() signal. If the
1441 connection has been encrypted with no errors, this function will
1442 return an empty list.
1443
1444 \sa connectToHostEncrypted()
1445*/
1446QList<QSslError> QSslSocket::sslHandshakeErrors() const
1447{
1448 Q_D(const QSslSocket);
1449 if (const auto *backend = d->backend.get())
1450 return backend->tlsErrors();
1451 return {};
1452}
1453
1454/*!
1455 Returns \c true if this platform supports SSL; otherwise, returns
1456 false. If the platform doesn't support SSL, the socket will fail
1457 in the connection phase.
1458*/
1459bool QSslSocket::supportsSsl()
1460{
1461 return QSslSocketPrivate::supportsSsl();
1462}
1463
1464/*!
1465 \since 5.0
1466 Returns the version number of the SSL library in use. Note that
1467 this is the version of the library in use at run-time not compile
1468 time. If no SSL support is available then this will return -1.
1469*/
1470long QSslSocket::sslLibraryVersionNumber()
1471{
1472 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse())
1473 return tlsBackend->tlsLibraryVersionNumber();
1474
1475 return -1;
1476}
1477
1478/*!
1479 \since 5.0
1480 Returns the version string of the SSL library in use. Note that
1481 this is the version of the library in use at run-time not compile
1482 time. If no SSL support is available then this will return an empty value.
1483*/
1484QString QSslSocket::sslLibraryVersionString()
1485{
1486 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse())
1487 return tlsBackend->tlsLibraryVersionString();
1488 return {};
1489}
1490
1491/*!
1492 \since 5.4
1493 Returns the version number of the SSL library in use at compile
1494 time. If no SSL support is available then this will return -1.
1495
1496 \sa sslLibraryVersionNumber()
1497*/
1498long QSslSocket::sslLibraryBuildVersionNumber()
1499{
1500 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse())
1501 return tlsBackend->tlsLibraryBuildVersionNumber();
1502 return -1;
1503}
1504
1505/*!
1506 \since 5.4
1507 Returns the version string of the SSL library in use at compile
1508 time. If no SSL support is available then this will return an
1509 empty value.
1510
1511 \sa sslLibraryVersionString()
1512*/
1513QString QSslSocket::sslLibraryBuildVersionString()
1514{
1515 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse())
1516 return tlsBackend->tlsLibraryBuildVersionString();
1517
1518 return {};
1519}
1520
1521/*!
1522 \since 6.1
1523 Returns the names of the currently available backends. These names
1524 are in lower case, e.g. "openssl", "securetransport", "schannel"
1525 (similar to the already existing feature names for TLS backends in Qt).
1526
1527 \sa activeBackend()
1528*/
1529QList<QString> QSslSocket::availableBackends()
1530{
1531 return QTlsBackend::availableBackendNames();
1532}
1533
1534/*!
1535 \since 6.1
1536 Returns the name of the backend that QSslSocket and related classes
1537 use. If the active backend was not set explicitly, this function
1538 returns the name of a default backend that QSslSocket selects implicitly
1539 from the list of available backends.
1540
1541 \note When selecting a default backend implicitly, QSslSocket prefers
1542 the OpenSSL backend if available.
1543
1544 \sa setActiveBackend(), availableBackends()
1545*/
1546QString QSslSocket::activeBackend()
1547{
1548 const QMutexLocker locker(&QSslSocketPrivate::backendMutex);
1549
1550 if (!QSslSocketPrivate::activeBackendName.size())
1551 QSslSocketPrivate::activeBackendName = QTlsBackend::defaultBackendName();
1552
1553 return QSslSocketPrivate::activeBackendName;
1554}
1555
1556/*!
1557 \since 6.1
1558 Returns true if a backend with name \a backendName was set as
1559 active backend. \a backendName must be one of names returned
1560 by availableBackends().
1561
1562 \note An application cannot mix different backends simultaneously.
1563 This implies that a non-default backend must be selected prior
1564 to any use of QSslSocket or related classes, e.g. QSslCertificate
1565 or QSslKey.
1566
1567 \sa activeBackend(), availableBackends()
1568*/
1569bool QSslSocket::setActiveBackend(const QString &backendName)
1570{
1571 if (!backendName.size()) {
1572 qCWarning(lcSsl, "Invalid parameter (backend name cannot be an empty string)");
1573 return false;
1574 }
1575
1576 QMutexLocker locker(&QSslSocketPrivate::backendMutex);
1577 if (QSslSocketPrivate::tlsBackend) {
1578 qCWarning(lcSsl) << "Cannot set backend named" << backendName
1579 << "as active, another backend is already in use";
1580 locker.unlock();
1581 return activeBackend() == backendName;
1582 }
1583
1584 if (!QTlsBackend::availableBackendNames().contains(str: backendName)) {
1585 qCWarning(lcSsl) << "Cannot set unavailable backend named" << backendName
1586 << "as active";
1587 return false;
1588 }
1589
1590 QSslSocketPrivate::activeBackendName = backendName;
1591
1592 return true;
1593}
1594
1595/*!
1596 \since 6.1
1597 If a backend with name \a backendName is available, this function returns the
1598 list of TLS protocol versions supported by this backend. An empty \a backendName
1599 is understood as a query about the currently active backend. Otherwise, this
1600 function returns an empty list.
1601
1602 \sa availableBackends(), activeBackend(), isProtocolSupported()
1603*/
1604QList<QSsl::SslProtocol> QSslSocket::supportedProtocols(const QString &backendName)
1605{
1606 return QTlsBackend::supportedProtocols(backendName: backendName.size() ? backendName : activeBackend());
1607}
1608
1609/*!
1610 \since 6.1
1611 Returns true if \a protocol is supported by a backend named \a backendName. An empty
1612 \a backendName is understood as a query about the currently active backend.
1613
1614 \sa supportedProtocols()
1615*/
1616bool QSslSocket::isProtocolSupported(QSsl::SslProtocol protocol, const QString &backendName)
1617{
1618 const auto versions = supportedProtocols(backendName);
1619 return versions.contains(t: protocol);
1620}
1621
1622/*!
1623 \since 6.1
1624 This function returns backend-specific classes implemented by the backend named
1625 \a backendName. An empty \a backendName is understood as a query about the
1626 currently active backend.
1627
1628 \sa QSsl::ImplementedClass, activeBackend(), isClassImplemented()
1629*/
1630QList<QSsl::ImplementedClass> QSslSocket::implementedClasses(const QString &backendName)
1631{
1632 return QTlsBackend::implementedClasses(backendName: backendName.size() ? backendName : activeBackend());
1633}
1634
1635/*!
1636 \since 6.1
1637 Returns true if a class \a cl is implemented by the backend named \a backendName. An empty
1638 \a backendName is understood as a query about the currently active backend.
1639
1640 \sa implementedClasses()
1641*/
1642
1643bool QSslSocket::isClassImplemented(QSsl::ImplementedClass cl, const QString &backendName)
1644{
1645 return implementedClasses(backendName).contains(t: cl);
1646}
1647
1648/*!
1649 \since 6.1
1650 This function returns features supported by a backend named \a backendName.
1651 An empty \a backendName is understood as a query about the currently active backend.
1652
1653 \sa QSsl::SupportedFeature, activeBackend()
1654*/
1655QList<QSsl::SupportedFeature> QSslSocket::supportedFeatures(const QString &backendName)
1656{
1657 return QTlsBackend::supportedFeatures(backendName: backendName.size() ? backendName : activeBackend());
1658}
1659
1660/*!
1661 \since 6.1
1662 Returns true if a feature \a ft is supported by a backend named \a backendName. An empty
1663 \a backendName is understood as a query about the currently active backend.
1664
1665 \sa QSsl::SupportedFeature, supportedFeatures()
1666*/
1667bool QSslSocket::isFeatureSupported(QSsl::SupportedFeature ft, const QString &backendName)
1668{
1669 return supportedFeatures(backendName).contains(t: ft);
1670}
1671
1672/*!
1673 Starts a delayed SSL handshake for a client connection. This
1674 function can be called when the socket is in the \l ConnectedState
1675 but still in the \l UnencryptedMode. If it is not yet connected,
1676 or if it is already encrypted, this function has no effect.
1677
1678 Clients that implement STARTTLS functionality often make use of
1679 delayed SSL handshakes. Most other clients can avoid calling this
1680 function directly by using connectToHostEncrypted() instead, which
1681 automatically performs the handshake.
1682
1683 \sa connectToHostEncrypted(), startServerEncryption()
1684*/
1685void QSslSocket::startClientEncryption()
1686{
1687 Q_D(QSslSocket);
1688 if (d->mode != UnencryptedMode) {
1689 qCWarning(lcSsl,
1690 "QSslSocket::startClientEncryption: cannot start handshake on non-plain connection");
1691 return;
1692 }
1693 if (state() != ConnectedState) {
1694 qCWarning(lcSsl,
1695 "QSslSocket::startClientEncryption: cannot start handshake when not connected");
1696 return;
1697 }
1698
1699 if (!supportsSsl()) {
1700 qCWarning(lcSsl, "QSslSocket::startClientEncryption: TLS initialization failed");
1701 d->setErrorAndEmit(errorCode: QAbstractSocket::SslInternalError, errorString: tr(s: "TLS initialization failed"));
1702 return;
1703 }
1704
1705 if (!d->verifyProtocolSupported(where: "QSslSocket::startClientEncryption:"))
1706 return;
1707
1708#ifdef QSSLSOCKET_DEBUG
1709 qCDebug(lcSsl) << "QSslSocket::startClientEncryption()";
1710#endif
1711 d->mode = SslClientMode;
1712 emit modeChanged(newMode: d->mode);
1713 d->startClientEncryption();
1714}
1715
1716/*!
1717 Starts a delayed SSL handshake for a server connection. This
1718 function can be called when the socket is in the \l ConnectedState
1719 but still in \l UnencryptedMode. If it is not connected or it is
1720 already encrypted, the function has no effect.
1721
1722 For server sockets, calling this function is the only way to
1723 initiate the SSL handshake. Most servers will call this function
1724 immediately upon receiving a connection, or as a result of having
1725 received a protocol-specific command to enter SSL mode (e.g, the
1726 server may respond to receiving the string "STARTTLS\\r\\n" by
1727 calling this function).
1728
1729 The most common way to implement an SSL server is to create a
1730 subclass of QTcpServer and reimplement
1731 QTcpServer::incomingConnection(). The returned socket descriptor
1732 is then passed to QSslSocket::setSocketDescriptor().
1733
1734 \sa connectToHostEncrypted(), startClientEncryption()
1735*/
1736void QSslSocket::startServerEncryption()
1737{
1738 Q_D(QSslSocket);
1739 if (d->mode != UnencryptedMode) {
1740 qCWarning(lcSsl, "QSslSocket::startServerEncryption: cannot start handshake on non-plain connection");
1741 return;
1742 }
1743#ifdef QSSLSOCKET_DEBUG
1744 qCDebug(lcSsl) << "QSslSocket::startServerEncryption()";
1745#endif
1746 if (!supportsSsl()) {
1747 qCWarning(lcSsl, "QSslSocket::startServerEncryption: TLS initialization failed");
1748 d->setErrorAndEmit(errorCode: QAbstractSocket::SslInternalError, errorString: tr(s: "TLS initialization failed"));
1749 return;
1750 }
1751 if (!d->verifyProtocolSupported(where: "QSslSocket::startServerEncryption"))
1752 return;
1753
1754 d->mode = SslServerMode;
1755 emit modeChanged(newMode: d->mode);
1756 d->startServerEncryption();
1757}
1758
1759/*!
1760 This slot tells QSslSocket to ignore errors during QSslSocket's
1761 handshake phase and continue connecting. If you want to continue
1762 with the connection even if errors occur during the handshake
1763 phase, then you must call this slot, either from a slot connected
1764 to sslErrors(), or before the handshake phase. If you don't call
1765 this slot, either in response to errors or before the handshake,
1766 the connection will be dropped after the sslErrors() signal has
1767 been emitted.
1768
1769 If there are no errors during the SSL handshake phase (i.e., the
1770 identity of the peer is established with no problems), QSslSocket
1771 will not emit the sslErrors() signal, and it is unnecessary to
1772 call this function.
1773
1774 \warning Be sure to always let the user inspect the errors
1775 reported by the sslErrors() signal, and only call this method
1776 upon confirmation from the user that proceeding is ok.
1777 If there are unexpected errors, the connection should be aborted.
1778 Calling this method without inspecting the actual errors will
1779 most likely pose a security risk for your application. Use it
1780 with great care!
1781
1782 \sa sslErrors()
1783*/
1784void QSslSocket::ignoreSslErrors()
1785{
1786 Q_D(QSslSocket);
1787 d->ignoreAllSslErrors = true;
1788}
1789
1790/*!
1791 \overload
1792 \since 4.6
1793
1794 This method tells QSslSocket to ignore only the errors given in \a
1795 errors.
1796
1797 \note Because most SSL errors are associated with a certificate, for most
1798 of them you must set the expected certificate this SSL error is related to.
1799 If, for instance, you want to connect to a server that uses
1800 a self-signed certificate, consider the following snippet:
1801
1802 \snippet code/src_network_ssl_qsslsocket.cpp 6
1803
1804 Multiple calls to this function will replace the list of errors that
1805 were passed in previous calls.
1806 You can clear the list of errors you want to ignore by calling this
1807 function with an empty list.
1808
1809 \sa sslErrors(), sslHandshakeErrors()
1810*/
1811void QSslSocket::ignoreSslErrors(const QList<QSslError> &errors)
1812{
1813 Q_D(QSslSocket);
1814 d->ignoreErrorsList = errors;
1815}
1816
1817
1818/*!
1819 \since 6.0
1820
1821 If an application wants to conclude a handshake even after receiving
1822 handshakeInterruptedOnError() signal, it must call this function.
1823 This call must be done from a slot function attached to the signal.
1824 The signal-slot connection must be direct.
1825
1826 \sa handshakeInterruptedOnError(), QSslConfiguration::setHandshakeMustInterruptOnError()
1827*/
1828void QSslSocket::continueInterruptedHandshake()
1829{
1830 Q_D(QSslSocket);
1831 if (auto *backend = d->backend.get())
1832 backend->enableHandshakeContinuation();
1833}
1834
1835/*!
1836 \internal
1837*/
1838void QSslSocket::connectToHost(const QString &hostName, quint16 port, OpenMode openMode, NetworkLayerProtocol protocol)
1839{
1840 Q_D(QSslSocket);
1841 d->preferredNetworkLayerProtocol = protocol;
1842 if (!d->initialized)
1843 d->init();
1844 d->initialized = false;
1845
1846#ifdef QSSLSOCKET_DEBUG
1847 qCDebug(lcSsl) << "QSslSocket::connectToHost("
1848 << hostName << ',' << port << ',' << openMode << ')';
1849#endif
1850 if (!d->plainSocket) {
1851#ifdef QSSLSOCKET_DEBUG
1852 qCDebug(lcSsl) << "\tcreating internal plain socket";
1853#endif
1854 d->createPlainSocket(openMode);
1855 }
1856#ifndef QT_NO_NETWORKPROXY
1857 d->plainSocket->setProtocolTag(d->protocolTag);
1858 d->plainSocket->setProxy(proxy());
1859#endif
1860 QIODevice::open(mode: openMode);
1861 d->readChannelCount = d->writeChannelCount = 0;
1862 d->plainSocket->connectToHost(hostName, port, mode: openMode, protocol: d->preferredNetworkLayerProtocol);
1863 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
1864}
1865
1866/*!
1867 \internal
1868*/
1869void QSslSocket::disconnectFromHost()
1870{
1871 Q_D(QSslSocket);
1872#ifdef QSSLSOCKET_DEBUG
1873 qCDebug(lcSsl) << "QSslSocket::disconnectFromHost()";
1874#endif
1875 if (!d->plainSocket)
1876 return;
1877 if (d->state == UnconnectedState)
1878 return;
1879 if (d->mode == UnencryptedMode && !d->autoStartHandshake) {
1880 d->plainSocket->disconnectFromHost();
1881 return;
1882 }
1883 if (d->state <= ConnectingState) {
1884 d->pendingClose = true;
1885 return;
1886 }
1887 // Make sure we don't process any signal from the CA fetcher
1888 // (Windows):
1889 if (auto *backend = d->backend.get())
1890 backend->cancelCAFetch();
1891
1892 // Perhaps emit closing()
1893 if (d->state != ClosingState) {
1894 d->state = ClosingState;
1895 emit stateChanged(d->state);
1896 }
1897
1898 if (!d->writeBuffer.isEmpty()) {
1899 d->pendingClose = true;
1900 return;
1901 }
1902
1903 if (d->mode == UnencryptedMode) {
1904 d->plainSocket->disconnectFromHost();
1905 } else {
1906 d->disconnectFromHost();
1907 }
1908}
1909
1910/*!
1911 \reimp
1912*/
1913qint64 QSslSocket::readData(char *data, qint64 maxlen)
1914{
1915 Q_D(QSslSocket);
1916 qint64 readBytes = 0;
1917
1918 if (d->mode == UnencryptedMode && !d->autoStartHandshake) {
1919 readBytes = d->plainSocket->read(data, maxlen);
1920#ifdef QSSLSOCKET_DEBUG
1921 qCDebug(lcSsl) << "QSslSocket::readData(" << (void *)data << ',' << maxlen << ") =="
1922 << readBytes;
1923#endif
1924 } else {
1925 // possibly trigger another transmit() to decrypt more data from the socket
1926 if (d->plainSocket->bytesAvailable() || d->hasUndecryptedData())
1927 QMetaObject::invokeMethod(obj: this, member: "_q_flushReadBuffer", c: Qt::QueuedConnection);
1928 else if (d->state != QAbstractSocket::ConnectedState)
1929 return maxlen ? qint64(-1) : qint64(0);
1930 }
1931
1932 return readBytes;
1933}
1934
1935/*!
1936 \reimp
1937*/
1938qint64 QSslSocket::writeData(const char *data, qint64 len)
1939{
1940 Q_D(QSslSocket);
1941#ifdef QSSLSOCKET_DEBUG
1942 qCDebug(lcSsl) << "QSslSocket::writeData(" << (void *)data << ',' << len << ')';
1943#endif
1944 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1945 return d->plainSocket->write(data, len);
1946
1947 d->write(data, size: len);
1948
1949 // make sure we flush to the plain socket's buffer
1950 if (!d->flushTriggered) {
1951 d->flushTriggered = true;
1952 QMetaObject::invokeMethod(obj: this, member: "_q_flushWriteBuffer", c: Qt::QueuedConnection);
1953 }
1954
1955 return len;
1956}
1957
1958bool QSslSocketPrivate::s_loadRootCertsOnDemand = false;
1959
1960/*!
1961 \internal
1962*/
1963QSslSocketPrivate::QSslSocketPrivate()
1964 : initialized(false)
1965 , mode(QSslSocket::UnencryptedMode)
1966 , autoStartHandshake(false)
1967 , connectionEncrypted(false)
1968 , ignoreAllSslErrors(false)
1969 , readyReadEmittedPointer(nullptr)
1970 , allowRootCertOnDemandLoading(true)
1971 , plainSocket(nullptr)
1972 , paused(false)
1973 , flushTriggered(false)
1974{
1975 QSslConfigurationPrivate::deepCopyDefaultConfiguration(config: &configuration);
1976 // If the global configuration doesn't allow root certificates to be loaded
1977 // on demand then we have to disable it for this socket as well.
1978 if (!configuration.allowRootCertOnDemandLoading)
1979 allowRootCertOnDemandLoading = false;
1980
1981 const auto *tlsBackend = tlsBackendInUse();
1982 if (!tlsBackend) {
1983 qCWarning(lcSsl, "No TLS backend is available");
1984 return;
1985 }
1986 backend.reset(p: tlsBackend->createTlsCryptograph());
1987 if (!backend.get()) {
1988 qCWarning(lcSsl) << "The backend named" << tlsBackend->backendName()
1989 << "does not support TLS";
1990 }
1991}
1992
1993/*!
1994 \internal
1995*/
1996QSslSocketPrivate::~QSslSocketPrivate()
1997{
1998}
1999
2000/*!
2001 \internal
2002*/
2003bool QSslSocketPrivate::supportsSsl()
2004{
2005 if (const auto *tlsBackend = tlsBackendInUse())
2006 return tlsBackend->implementedClasses().contains(t: QSsl::ImplementedClass::Socket);
2007 return false;
2008}
2009
2010/*!
2011 \internal
2012
2013 Declared static in QSslSocketPrivate, makes sure the SSL libraries have
2014 been initialized.
2015*/
2016void QSslSocketPrivate::ensureInitialized()
2017{
2018 if (!supportsSsl())
2019 return;
2020
2021 const auto *tlsBackend = tlsBackendInUse();
2022 Q_ASSERT(tlsBackend);
2023 tlsBackend->ensureInitialized();
2024}
2025
2026/*!
2027 \internal
2028*/
2029void QSslSocketPrivate::init()
2030{
2031 // TLSTODO: delete those data members.
2032 mode = QSslSocket::UnencryptedMode;
2033 autoStartHandshake = false;
2034 connectionEncrypted = false;
2035 ignoreAllSslErrors = false;
2036 abortCalled = false;
2037 pendingClose = false;
2038 flushTriggered = false;
2039 // We don't want to clear the ignoreErrorsList, so
2040 // that it is possible setting it before connecting.
2041
2042 buffer.clear();
2043 writeBuffer.clear();
2044 configuration.peerCertificate.clear();
2045 configuration.peerCertificateChain.clear();
2046
2047 if (backend.get()) {
2048 Q_ASSERT(q_ptr);
2049 backend->init(q: static_cast<QSslSocket *>(q_ptr), d: this);
2050 }
2051}
2052
2053/*!
2054 \internal
2055*/
2056bool QSslSocketPrivate::verifyProtocolSupported(const char *where)
2057{
2058 auto protocolName = "DTLS"_L1;
2059 switch (configuration.protocol) {
2060 case QSsl::UnknownProtocol:
2061 // UnknownProtocol, according to our docs, is for cipher whose protocol is unknown.
2062 // Should not be used when configuring QSslSocket.
2063 protocolName = "UnknownProtocol"_L1;
2064 Q_FALLTHROUGH();
2065QT_WARNING_PUSH
2066QT_WARNING_DISABLE_DEPRECATED
2067 case QSsl::DtlsV1_0:
2068 case QSsl::DtlsV1_2:
2069 case QSsl::DtlsV1_0OrLater:
2070 case QSsl::DtlsV1_2OrLater:
2071 qCWarning(lcSsl) << where << "QSslConfiguration with unexpected protocol" << protocolName;
2072 setErrorAndEmit(errorCode: QAbstractSocket::SslInvalidUserDataError,
2073 errorString: QSslSocket::tr(s: "Attempted to use an unsupported protocol."));
2074 return false;
2075QT_WARNING_POP
2076 default:
2077 return true;
2078 }
2079}
2080
2081/*!
2082 \internal
2083*/
2084QList<QSslCipher> QSslSocketPrivate::defaultCiphers()
2085{
2086 QSslSocketPrivate::ensureInitialized();
2087 QMutexLocker locker(&globalData()->mutex);
2088 return globalData()->config->ciphers;
2089}
2090
2091/*!
2092 \internal
2093*/
2094QList<QSslCipher> QSslSocketPrivate::supportedCiphers()
2095{
2096 QSslSocketPrivate::ensureInitialized();
2097 QMutexLocker locker(&globalData()->mutex);
2098 return globalData()->supportedCiphers;
2099}
2100
2101/*!
2102 \internal
2103*/
2104void QSslSocketPrivate::setDefaultCiphers(const QList<QSslCipher> &ciphers)
2105{
2106 QMutexLocker locker(&globalData()->mutex);
2107 globalData()->config.detach();
2108 globalData()->config->ciphers = ciphers;
2109}
2110
2111/*!
2112 \internal
2113*/
2114void QSslSocketPrivate::setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers)
2115{
2116 QMutexLocker locker(&globalData()->mutex);
2117 globalData()->config.detach();
2118 globalData()->supportedCiphers = ciphers;
2119}
2120
2121/*!
2122 \internal
2123*/
2124void QSslSocketPrivate::resetDefaultEllipticCurves()
2125{
2126 const auto *tlsBackend = tlsBackendInUse();
2127 if (!tlsBackend)
2128 return;
2129
2130 auto ids = tlsBackend->ellipticCurvesIds();
2131 if (!ids.size())
2132 return;
2133
2134 QList<QSslEllipticCurve> curves;
2135 curves.reserve(size: ids.size());
2136 for (int id : ids) {
2137 QSslEllipticCurve curve;
2138 curve.id = id;
2139 curves.append(t: curve);
2140 }
2141
2142 // Set the list of supported ECs, but not the list
2143 // of *default* ECs. OpenSSL doesn't like forcing an EC for the wrong
2144 // ciphersuite, so don't try it -- leave the empty list to mean
2145 // "the implementation will choose the most suitable one".
2146 setDefaultSupportedEllipticCurves(curves);
2147}
2148
2149/*!
2150 \internal
2151*/
2152void QSslSocketPrivate::setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers)
2153{
2154 QMutexLocker locker(&globalData()->mutex);
2155 globalData()->dtlsConfig.detach();
2156 globalData()->dtlsConfig->ciphers = ciphers;
2157}
2158
2159/*!
2160 \internal
2161*/
2162QList<QSslCipher> QSslSocketPrivate::defaultDtlsCiphers()
2163{
2164 QSslSocketPrivate::ensureInitialized();
2165 QMutexLocker locker(&globalData()->mutex);
2166 return globalData()->dtlsConfig->ciphers;
2167}
2168
2169/*!
2170 \internal
2171*/
2172QList<QSslEllipticCurve> QSslSocketPrivate::supportedEllipticCurves()
2173{
2174 QSslSocketPrivate::ensureInitialized();
2175 const QMutexLocker locker(&globalData()->mutex);
2176 return globalData()->supportedEllipticCurves;
2177}
2178
2179/*!
2180 \internal
2181*/
2182void QSslSocketPrivate::setDefaultSupportedEllipticCurves(const QList<QSslEllipticCurve> &curves)
2183{
2184 const QMutexLocker locker(&globalData()->mutex);
2185 globalData()->config.detach();
2186 globalData()->dtlsConfig.detach();
2187 globalData()->supportedEllipticCurves = curves;
2188}
2189
2190/*!
2191 \internal
2192*/
2193QList<QSslCertificate> QSslSocketPrivate::defaultCaCertificates()
2194{
2195 QSslSocketPrivate::ensureInitialized();
2196 QMutexLocker locker(&globalData()->mutex);
2197 return globalData()->config->caCertificates;
2198}
2199
2200/*!
2201 \internal
2202*/
2203void QSslSocketPrivate::setDefaultCaCertificates(const QList<QSslCertificate> &certs)
2204{
2205 QSslSocketPrivate::ensureInitialized();
2206 QMutexLocker locker(&globalData()->mutex);
2207 globalData()->config.detach();
2208 globalData()->config->caCertificates = certs;
2209 globalData()->dtlsConfig.detach();
2210 globalData()->dtlsConfig->caCertificates = certs;
2211 // when the certificates are set explicitly, we do not want to
2212 // load the system certificates on demand
2213 s_loadRootCertsOnDemand = false;
2214}
2215
2216/*!
2217 \internal
2218*/
2219void QSslSocketPrivate::addDefaultCaCertificate(const QSslCertificate &cert)
2220{
2221 QSslSocketPrivate::ensureInitialized();
2222 QMutexLocker locker(&globalData()->mutex);
2223 if (globalData()->config->caCertificates.contains(t: cert))
2224 return;
2225 globalData()->config.detach();
2226 globalData()->config->caCertificates += cert;
2227 globalData()->dtlsConfig.detach();
2228 globalData()->dtlsConfig->caCertificates += cert;
2229}
2230
2231/*!
2232 \internal
2233*/
2234void QSslSocketPrivate::addDefaultCaCertificates(const QList<QSslCertificate> &certs)
2235{
2236 QSslSocketPrivate::ensureInitialized();
2237 QMutexLocker locker(&globalData()->mutex);
2238 globalData()->config.detach();
2239 globalData()->config->caCertificates += certs;
2240 globalData()->dtlsConfig.detach();
2241 globalData()->dtlsConfig->caCertificates += certs;
2242}
2243
2244/*!
2245 \internal
2246*/
2247QSslConfiguration QSslConfigurationPrivate::defaultConfiguration()
2248{
2249 QSslSocketPrivate::ensureInitialized();
2250 QMutexLocker locker(&globalData()->mutex);
2251 return QSslConfiguration(globalData()->config.data());
2252}
2253
2254/*!
2255 \internal
2256*/
2257void QSslConfigurationPrivate::setDefaultConfiguration(const QSslConfiguration &configuration)
2258{
2259 QSslSocketPrivate::ensureInitialized();
2260 QMutexLocker locker(&globalData()->mutex);
2261 if (globalData()->config == configuration.d)
2262 return; // nothing to do
2263
2264 globalData()->config = const_cast<QSslConfigurationPrivate*>(configuration.d.constData());
2265}
2266
2267/*!
2268 \internal
2269*/
2270void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPrivate *ptr)
2271{
2272 QSslSocketPrivate::ensureInitialized();
2273 QMutexLocker locker(&globalData()->mutex);
2274 const QSslConfigurationPrivate *global = globalData()->config.constData();
2275
2276 if (!global)
2277 return;
2278
2279 ptr->ref.storeRelaxed(newValue: 1);
2280 ptr->peerCertificate = global->peerCertificate;
2281 ptr->peerCertificateChain = global->peerCertificateChain;
2282 ptr->localCertificateChain = global->localCertificateChain;
2283 ptr->privateKey = global->privateKey;
2284 ptr->sessionCipher = global->sessionCipher;
2285 ptr->sessionProtocol = global->sessionProtocol;
2286 ptr->ciphers = global->ciphers;
2287 ptr->caCertificates = global->caCertificates;
2288 ptr->allowRootCertOnDemandLoading = global->allowRootCertOnDemandLoading;
2289 ptr->protocol = global->protocol;
2290 ptr->peerVerifyMode = global->peerVerifyMode;
2291 ptr->peerVerifyDepth = global->peerVerifyDepth;
2292 ptr->sslOptions = global->sslOptions;
2293 ptr->ellipticCurves = global->ellipticCurves;
2294 ptr->backendConfig = global->backendConfig;
2295#if QT_CONFIG(dtls)
2296 ptr->dtlsCookieEnabled = global->dtlsCookieEnabled;
2297#endif
2298#if QT_CONFIG(ocsp)
2299 ptr->ocspStaplingEnabled = global->ocspStaplingEnabled;
2300#endif
2301#if QT_CONFIG(openssl)
2302 ptr->reportFromCallback = global->reportFromCallback;
2303 ptr->missingCertIsFatal = global->missingCertIsFatal;
2304#endif
2305}
2306
2307/*!
2308 \internal
2309*/
2310QSslConfiguration QSslConfigurationPrivate::defaultDtlsConfiguration()
2311{
2312 QSslSocketPrivate::ensureInitialized();
2313 QMutexLocker locker(&globalData()->mutex);
2314
2315 return QSslConfiguration(globalData()->dtlsConfig.data());
2316}
2317
2318/*!
2319 \internal
2320*/
2321void QSslConfigurationPrivate::setDefaultDtlsConfiguration(const QSslConfiguration &configuration)
2322{
2323 QSslSocketPrivate::ensureInitialized();
2324 QMutexLocker locker(&globalData()->mutex);
2325 if (globalData()->dtlsConfig == configuration.d)
2326 return; // nothing to do
2327
2328 globalData()->dtlsConfig = const_cast<QSslConfigurationPrivate*>(configuration.d.constData());
2329}
2330
2331/*!
2332 \internal
2333*/
2334void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode)
2335{
2336 Q_Q(QSslSocket);
2337 q->setOpenMode(openMode); // <- from QIODevice
2338 q->setSocketState(QAbstractSocket::UnconnectedState);
2339 q->setSocketError(QAbstractSocket::UnknownSocketError);
2340 q->setLocalPort(0);
2341 q->setLocalAddress(QHostAddress());
2342 q->setPeerPort(0);
2343 q->setPeerAddress(QHostAddress());
2344 q->setPeerName(QString());
2345
2346 plainSocket = new QTcpSocket(q);
2347 q->connect(sender: plainSocket, SIGNAL(connected()),
2348 receiver: q, SLOT(_q_connectedSlot()),
2349 Qt::DirectConnection);
2350 q->connect(sender: plainSocket, SIGNAL(hostFound()),
2351 receiver: q, SLOT(_q_hostFoundSlot()),
2352 Qt::DirectConnection);
2353 q->connect(sender: plainSocket, SIGNAL(disconnected()),
2354 receiver: q, SLOT(_q_disconnectedSlot()),
2355 Qt::DirectConnection);
2356 q->connect(sender: plainSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
2357 receiver: q, SLOT(_q_stateChangedSlot(QAbstractSocket::SocketState)),
2358 Qt::DirectConnection);
2359 q->connect(sender: plainSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
2360 receiver: q, SLOT(_q_errorSlot(QAbstractSocket::SocketError)),
2361 Qt::DirectConnection);
2362 q->connect(sender: plainSocket, SIGNAL(readyRead()),
2363 receiver: q, SLOT(_q_readyReadSlot()),
2364 Qt::DirectConnection);
2365 q->connect(sender: plainSocket, SIGNAL(channelReadyRead(int)),
2366 receiver: q, SLOT(_q_channelReadyReadSlot(int)),
2367 Qt::DirectConnection);
2368 q->connect(sender: plainSocket, SIGNAL(bytesWritten(qint64)),
2369 receiver: q, SLOT(_q_bytesWrittenSlot(qint64)),
2370 Qt::DirectConnection);
2371 q->connect(sender: plainSocket, SIGNAL(channelBytesWritten(int,qint64)),
2372 receiver: q, SLOT(_q_channelBytesWrittenSlot(int,qint64)),
2373 Qt::DirectConnection);
2374 q->connect(sender: plainSocket, SIGNAL(readChannelFinished()),
2375 receiver: q, SLOT(_q_readChannelFinishedSlot()),
2376 Qt::DirectConnection);
2377#ifndef QT_NO_NETWORKPROXY
2378 q->connect(sender: plainSocket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
2379 receiver: q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
2380#endif
2381
2382 buffer.clear();
2383 writeBuffer.clear();
2384 connectionEncrypted = false;
2385 configuration.peerCertificate.clear();
2386 configuration.peerCertificateChain.clear();
2387 mode = QSslSocket::UnencryptedMode;
2388 q->setReadBufferSize(readBufferMaxSize);
2389}
2390
2391void QSslSocketPrivate::pauseSocketNotifiers(QSslSocket *socket)
2392{
2393 if (!socket->d_func()->plainSocket)
2394 return;
2395 QAbstractSocketPrivate::pauseSocketNotifiers(socket->d_func()->plainSocket);
2396}
2397
2398void QSslSocketPrivate::resumeSocketNotifiers(QSslSocket *socket)
2399{
2400 if (!socket->d_func()->plainSocket)
2401 return;
2402 QAbstractSocketPrivate::resumeSocketNotifiers(socket->d_func()->plainSocket);
2403}
2404
2405bool QSslSocketPrivate::isPaused() const
2406{
2407 return paused;
2408}
2409
2410void QSslSocketPrivate::setPaused(bool p)
2411{
2412 paused = p;
2413}
2414
2415bool QSslSocketPrivate::bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode)
2416{
2417 // this function is called from QAbstractSocket::bind
2418 if (!initialized)
2419 init();
2420 initialized = false;
2421
2422#ifdef QSSLSOCKET_DEBUG
2423 qCDebug(lcSsl) << "QSslSocket::bind(" << address << ',' << port << ',' << mode << ')';
2424#endif
2425 if (!plainSocket) {
2426#ifdef QSSLSOCKET_DEBUG
2427 qCDebug(lcSsl) << "\tcreating internal plain socket";
2428#endif
2429 createPlainSocket(openMode: QIODevice::ReadWrite);
2430 }
2431 bool ret = plainSocket->bind(address, port, mode);
2432 localPort = plainSocket->localPort();
2433 localAddress = plainSocket->localAddress();
2434 cachedSocketDescriptor = plainSocket->socketDescriptor();
2435 readChannelCount = writeChannelCount = 0;
2436 return ret;
2437}
2438
2439/*!
2440 \internal
2441*/
2442void QSslSocketPrivate::_q_connectedSlot()
2443{
2444 Q_Q(QSslSocket);
2445 q->setLocalPort(plainSocket->localPort());
2446 q->setLocalAddress(plainSocket->localAddress());
2447 q->setPeerPort(plainSocket->peerPort());
2448 q->setPeerAddress(plainSocket->peerAddress());
2449 q->setPeerName(plainSocket->peerName());
2450 cachedSocketDescriptor = plainSocket->socketDescriptor();
2451 readChannelCount = plainSocket->readChannelCount();
2452 writeChannelCount = plainSocket->writeChannelCount();
2453
2454#ifdef QSSLSOCKET_DEBUG
2455 qCDebug(lcSsl) << "QSslSocket::_q_connectedSlot()";
2456 qCDebug(lcSsl) << "\tstate =" << q->state();
2457 qCDebug(lcSsl) << "\tpeer =" << q->peerName() << q->peerAddress() << q->peerPort();
2458 qCDebug(lcSsl) << "\tlocal =" << QHostInfo::fromName(q->localAddress().toString()).hostName()
2459 << q->localAddress() << q->localPort();
2460#endif
2461
2462 if (autoStartHandshake)
2463 q->startClientEncryption();
2464
2465 emit q->connected();
2466
2467 if (pendingClose && !autoStartHandshake) {
2468 pendingClose = false;
2469 q->disconnectFromHost();
2470 }
2471}
2472
2473/*!
2474 \internal
2475*/
2476void QSslSocketPrivate::_q_hostFoundSlot()
2477{
2478 Q_Q(QSslSocket);
2479#ifdef QSSLSOCKET_DEBUG
2480 qCDebug(lcSsl) << "QSslSocket::_q_hostFoundSlot()";
2481 qCDebug(lcSsl) << "\tstate =" << q->state();
2482#endif
2483 emit q->hostFound();
2484}
2485
2486/*!
2487 \internal
2488*/
2489void QSslSocketPrivate::_q_disconnectedSlot()
2490{
2491 Q_Q(QSslSocket);
2492#ifdef QSSLSOCKET_DEBUG
2493 qCDebug(lcSsl) << "QSslSocket::_q_disconnectedSlot()";
2494 qCDebug(lcSsl) << "\tstate =" << q->state();
2495#endif
2496 disconnected();
2497 emit q->disconnected();
2498
2499 q->setLocalPort(0);
2500 q->setLocalAddress(QHostAddress());
2501 q->setPeerPort(0);
2502 q->setPeerAddress(QHostAddress());
2503 q->setPeerName(QString());
2504 cachedSocketDescriptor = -1;
2505}
2506
2507/*!
2508 \internal
2509*/
2510void QSslSocketPrivate::_q_stateChangedSlot(QAbstractSocket::SocketState state)
2511{
2512 Q_Q(QSslSocket);
2513#ifdef QSSLSOCKET_DEBUG
2514 qCDebug(lcSsl) << "QSslSocket::_q_stateChangedSlot(" << state << ')';
2515#endif
2516 q->setSocketState(state);
2517 emit q->stateChanged(state);
2518}
2519
2520/*!
2521 \internal
2522*/
2523void QSslSocketPrivate::_q_errorSlot(QAbstractSocket::SocketError error)
2524{
2525 Q_UNUSED(error);
2526#ifdef QSSLSOCKET_DEBUG
2527 Q_Q(QSslSocket);
2528 qCDebug(lcSsl) << "QSslSocket::_q_errorSlot(" << error << ')';
2529 qCDebug(lcSsl) << "\tstate =" << q->state();
2530 qCDebug(lcSsl) << "\terrorString =" << q->errorString();
2531#endif
2532 // this moves encrypted bytes from plain socket into our buffer
2533 if (plainSocket->bytesAvailable() && mode != QSslSocket::UnencryptedMode) {
2534 qint64 tmpReadBufferMaxSize = readBufferMaxSize;
2535 readBufferMaxSize = 0; // reset temporarily so the plain sockets completely drained drained
2536 transmit();
2537 readBufferMaxSize = tmpReadBufferMaxSize;
2538 }
2539
2540 setErrorAndEmit(errorCode: plainSocket->error(), errorString: plainSocket->errorString());
2541}
2542
2543/*!
2544 \internal
2545*/
2546void QSslSocketPrivate::_q_readyReadSlot()
2547{
2548 Q_Q(QSslSocket);
2549#ifdef QSSLSOCKET_DEBUG
2550 qCDebug(lcSsl) << "QSslSocket::_q_readyReadSlot() -" << plainSocket->bytesAvailable() << "bytes available";
2551#endif
2552 if (mode == QSslSocket::UnencryptedMode) {
2553 if (readyReadEmittedPointer)
2554 *readyReadEmittedPointer = true;
2555 emit q->readyRead();
2556 return;
2557 }
2558
2559 transmit();
2560}
2561
2562/*!
2563 \internal
2564*/
2565void QSslSocketPrivate::_q_channelReadyReadSlot(int channel)
2566{
2567 Q_Q(QSslSocket);
2568 if (mode == QSslSocket::UnencryptedMode)
2569 emit q->channelReadyRead(channel);
2570}
2571
2572/*!
2573 \internal
2574*/
2575void QSslSocketPrivate::_q_bytesWrittenSlot(qint64 written)
2576{
2577 Q_Q(QSslSocket);
2578#ifdef QSSLSOCKET_DEBUG
2579 qCDebug(lcSsl) << "QSslSocket::_q_bytesWrittenSlot(" << written << ')';
2580#endif
2581
2582 if (mode == QSslSocket::UnencryptedMode)
2583 emit q->bytesWritten(bytes: written);
2584 else
2585 emit q->encryptedBytesWritten(totalBytes: written);
2586 if (state == QAbstractSocket::ClosingState && writeBuffer.isEmpty())
2587 q->disconnectFromHost();
2588}
2589
2590/*!
2591 \internal
2592*/
2593void QSslSocketPrivate::_q_channelBytesWrittenSlot(int channel, qint64 written)
2594{
2595 Q_Q(QSslSocket);
2596 if (mode == QSslSocket::UnencryptedMode)
2597 emit q->channelBytesWritten(channel, bytes: written);
2598}
2599
2600/*!
2601 \internal
2602*/
2603void QSslSocketPrivate::_q_readChannelFinishedSlot()
2604{
2605 Q_Q(QSslSocket);
2606 emit q->readChannelFinished();
2607}
2608
2609/*!
2610 \internal
2611*/
2612void QSslSocketPrivate::_q_flushWriteBuffer()
2613{
2614 Q_Q(QSslSocket);
2615
2616 // need to notice if knock-on effects of this flush (e.g. a readReady() via transmit())
2617 // make another necessary, so clear flag before calling:
2618 flushTriggered = false;
2619 if (!writeBuffer.isEmpty())
2620 q->flush();
2621}
2622
2623/*!
2624 \internal
2625*/
2626void QSslSocketPrivate::_q_flushReadBuffer()
2627{
2628 // trigger a read from the plainSocket into SSL
2629 if (mode != QSslSocket::UnencryptedMode)
2630 transmit();
2631}
2632
2633/*!
2634 \internal
2635*/
2636void QSslSocketPrivate::_q_resumeImplementation()
2637{
2638 if (plainSocket)
2639 plainSocket->resume();
2640 paused = false;
2641 if (!connectionEncrypted) {
2642 if (verifyErrorsHaveBeenIgnored()) {
2643 continueHandshake();
2644 } else {
2645 const auto sslErrors = backend->tlsErrors();
2646 Q_ASSERT(!sslErrors.isEmpty());
2647 setErrorAndEmit(errorCode: QAbstractSocket::SslHandshakeFailedError, errorString: sslErrors.constFirst().errorString());
2648 plainSocket->disconnectFromHost();
2649 return;
2650 }
2651 }
2652 transmit();
2653}
2654
2655/*!
2656 \internal
2657*/
2658bool QSslSocketPrivate::verifyErrorsHaveBeenIgnored()
2659{
2660 Q_ASSERT(backend.get());
2661
2662 bool doEmitSslError;
2663 if (!ignoreErrorsList.empty()) {
2664 // check whether the errors we got are all in the list of expected errors
2665 // (applies only if the method QSslSocket::ignoreSslErrors(const QList<QSslError> &errors)
2666 // was called)
2667 const auto &sslErrors = backend->tlsErrors();
2668 doEmitSslError = false;
2669 for (int a = 0; a < sslErrors.size(); a++) {
2670 if (!ignoreErrorsList.contains(t: sslErrors.at(i: a))) {
2671 doEmitSslError = true;
2672 break;
2673 }
2674 }
2675 } else {
2676 // if QSslSocket::ignoreSslErrors(const QList<QSslError> &errors) was not called and
2677 // we get an SSL error, emit a signal unless we ignored all errors (by calling
2678 // QSslSocket::ignoreSslErrors() )
2679 doEmitSslError = !ignoreAllSslErrors;
2680 }
2681 return !doEmitSslError;
2682}
2683
2684/*!
2685 \internal
2686*/
2687bool QSslSocketPrivate::isAutoStartingHandshake() const
2688{
2689 return autoStartHandshake;
2690}
2691
2692/*!
2693 \internal
2694*/
2695bool QSslSocketPrivate::isPendingClose() const
2696{
2697 return pendingClose;
2698}
2699
2700/*!
2701 \internal
2702*/
2703void QSslSocketPrivate::setPendingClose(bool pc)
2704{
2705 pendingClose = pc;
2706}
2707
2708/*!
2709 \internal
2710*/
2711qint64 QSslSocketPrivate::maxReadBufferSize() const
2712{
2713 return readBufferMaxSize;
2714}
2715
2716/*!
2717 \internal
2718*/
2719void QSslSocketPrivate::setMaxReadBufferSize(qint64 maxSize)
2720{
2721 readBufferMaxSize = maxSize;
2722}
2723
2724/*!
2725 \internal
2726*/
2727void QSslSocketPrivate::setEncrypted(bool enc)
2728{
2729 connectionEncrypted = enc;
2730}
2731
2732/*!
2733 \internal
2734*/
2735QIODevicePrivate::QRingBufferRef &QSslSocketPrivate::tlsWriteBuffer()
2736{
2737 return writeBuffer;
2738}
2739
2740/*!
2741 \internal
2742*/
2743QIODevicePrivate::QRingBufferRef &QSslSocketPrivate::tlsBuffer()
2744{
2745 return buffer;
2746}
2747
2748/*!
2749 \internal
2750*/
2751bool &QSslSocketPrivate::tlsEmittedBytesWritten()
2752{
2753 return emittedBytesWritten;
2754}
2755
2756/*!
2757 \internal
2758*/
2759bool *QSslSocketPrivate::readyReadPointer()
2760{
2761 return readyReadEmittedPointer;
2762}
2763
2764bool QSslSocketPrivate::hasUndecryptedData() const
2765{
2766 return backend.get() && backend->hasUndecryptedData();
2767}
2768
2769/*!
2770 \internal
2771*/
2772qint64 QSslSocketPrivate::peek(char *data, qint64 maxSize)
2773{
2774 if (mode == QSslSocket::UnencryptedMode && !autoStartHandshake) {
2775 //unencrypted mode - do not use QIODevice::peek, as it reads ahead data from the plain socket
2776 //peek at data already in the QIODevice buffer (from a previous read)
2777 qint64 r = buffer.peek(data, maxLength: maxSize, pos: transactionPos);
2778 if (r == maxSize)
2779 return r;
2780 data += r;
2781 //peek at data in the plain socket
2782 if (plainSocket) {
2783 qint64 r2 = plainSocket->peek(data, maxlen: maxSize - r);
2784 if (r2 < 0)
2785 return (r > 0 ? r : r2);
2786 return r + r2;
2787 }
2788
2789 return -1;
2790 } else {
2791 //encrypted mode - the socket engine will read and decrypt data into the QIODevice buffer
2792 return QTcpSocketPrivate::peek(data, maxSize);
2793 }
2794}
2795
2796/*!
2797 \internal
2798*/
2799QByteArray QSslSocketPrivate::peek(qint64 maxSize)
2800{
2801 if (mode == QSslSocket::UnencryptedMode && !autoStartHandshake) {
2802 //unencrypted mode - do not use QIODevice::peek, as it reads ahead data from the plain socket
2803 //peek at data already in the QIODevice buffer (from a previous read)
2804 QByteArray ret;
2805 ret.reserve(asize: maxSize);
2806 ret.resize(size: buffer.peek(data: ret.data(), maxLength: maxSize, pos: transactionPos));
2807 if (ret.size() == maxSize)
2808 return ret;
2809 //peek at data in the plain socket
2810 if (plainSocket)
2811 return ret + plainSocket->peek(maxlen: maxSize - ret.size());
2812
2813 return QByteArray();
2814 } else {
2815 //encrypted mode - the socket engine will read and decrypt data into the QIODevice buffer
2816 return QTcpSocketPrivate::peek(maxSize);
2817 }
2818}
2819
2820/*!
2821 \reimp
2822*/
2823qint64 QSslSocket::skipData(qint64 maxSize)
2824{
2825 Q_D(QSslSocket);
2826
2827 if (d->mode == QSslSocket::UnencryptedMode && !d->autoStartHandshake)
2828 return d->plainSocket->skip(maxSize);
2829
2830 // In encrypted mode, the SSL backend writes decrypted data directly into the
2831 // QIODevice's read buffer. As this buffer is always emptied by the caller,
2832 // we need to wait for more incoming data.
2833 return (d->state == QAbstractSocket::ConnectedState) ? Q_INT64_C(0) : Q_INT64_C(-1);
2834}
2835
2836/*!
2837 \internal
2838*/
2839bool QSslSocketPrivate::flush()
2840{
2841#ifdef QSSLSOCKET_DEBUG
2842 qCDebug(lcSsl) << "QSslSocketPrivate::flush()";
2843#endif
2844 if (mode != QSslSocket::UnencryptedMode) {
2845 // encrypt any unencrypted bytes in our buffer
2846 transmit();
2847 }
2848
2849 return plainSocket && plainSocket->flush();
2850}
2851
2852/*!
2853 \internal
2854*/
2855void QSslSocketPrivate::startClientEncryption()
2856{
2857 if (backend.get())
2858 backend->startClientEncryption();
2859}
2860
2861/*!
2862 \internal
2863*/
2864void QSslSocketPrivate::startServerEncryption()
2865{
2866 if (backend.get())
2867 backend->startServerEncryption();
2868}
2869
2870/*!
2871 \internal
2872*/
2873void QSslSocketPrivate::transmit()
2874{
2875 if (backend.get())
2876 backend->transmit();
2877}
2878
2879/*!
2880 \internal
2881*/
2882void QSslSocketPrivate::disconnectFromHost()
2883{
2884 if (backend.get())
2885 backend->disconnectFromHost();
2886}
2887
2888/*!
2889 \internal
2890*/
2891void QSslSocketPrivate::disconnected()
2892{
2893 if (backend.get())
2894 backend->disconnected();
2895}
2896
2897/*!
2898 \internal
2899*/
2900QSslCipher QSslSocketPrivate::sessionCipher() const
2901{
2902 if (backend.get())
2903 return backend->sessionCipher();
2904
2905 return {};
2906}
2907
2908/*!
2909 \internal
2910*/
2911QSsl::SslProtocol QSslSocketPrivate::sessionProtocol() const
2912{
2913 if (backend.get())
2914 return backend->sessionProtocol();
2915
2916 return QSsl::UnknownProtocol;
2917}
2918
2919/*!
2920 \internal
2921*/
2922void QSslSocketPrivate::continueHandshake()
2923{
2924 if (backend.get())
2925 backend->continueHandshake();
2926}
2927
2928/*!
2929 \internal
2930*/
2931bool QSslSocketPrivate::rootCertOnDemandLoadingSupported()
2932{
2933 return s_loadRootCertsOnDemand;
2934}
2935
2936/*!
2937 \internal
2938*/
2939void QSslSocketPrivate::setRootCertOnDemandLoadingSupported(bool supported)
2940{
2941 s_loadRootCertsOnDemand = supported;
2942}
2943
2944/*!
2945 \internal
2946*/
2947QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
2948{
2949 const auto ba = [](const auto &cstr) constexpr {
2950 return QByteArray::fromRawData(data: std::begin(cstr), size: std::size(cstr) - 1);
2951 };
2952 static const QByteArray dirs[] = {
2953 ba("/etc/ssl/certs/"), // (K)ubuntu, OpenSUSE, Mandriva ...
2954 ba("/usr/lib/ssl/certs/"), // Gentoo, Mandrake
2955 ba("/usr/share/ssl/"), // Centos, Redhat, SuSE
2956 ba("/usr/local/ssl/"), // Normal OpenSSL Tarball
2957 ba("/var/ssl/certs/"), // AIX
2958 ba("/usr/local/ssl/certs/"), // Solaris
2959 ba("/etc/openssl/certs/"), // BlackBerry
2960 ba("/opt/openssl/certs/"), // HP-UX
2961 ba("/etc/ssl/"), // OpenBSD
2962 };
2963 return QList<QByteArray>::fromReadOnlyData(t: dirs);
2964}
2965
2966/*!
2967 \internal
2968*/
2969void QSslSocketPrivate::checkSettingSslContext(QSslSocket* socket, std::shared_ptr<QSslContext> tlsContext)
2970{
2971 if (!socket)
2972 return;
2973
2974 if (auto *backend = socket->d_func()->backend.get())
2975 backend->checkSettingSslContext(tlsContext);
2976}
2977
2978/*!
2979 \internal
2980*/
2981std::shared_ptr<QSslContext> QSslSocketPrivate::sslContext(QSslSocket *socket)
2982{
2983 if (!socket)
2984 return {};
2985
2986 if (const auto *backend = socket->d_func()->backend.get())
2987 return backend->sslContext();
2988
2989 return {};
2990}
2991
2992bool QSslSocketPrivate::isMatchingHostname(const QSslCertificate &cert, const QString &peerName)
2993{
2994 QHostAddress hostAddress(peerName);
2995 if (!hostAddress.isNull()) {
2996 const auto subjectAlternativeNames = cert.subjectAlternativeNames();
2997 const auto ipAddresses = subjectAlternativeNames.equal_range(akey: QSsl::AlternativeNameEntryType::IpAddressEntry);
2998
2999 for (auto it = ipAddresses.first; it != ipAddresses.second; it++) {
3000 if (QHostAddress(*it).isEqual(address: hostAddress, mode: QHostAddress::StrictConversion))
3001 return true;
3002 }
3003 }
3004
3005 const QString lowerPeerName = QString::fromLatin1(ba: QUrl::toAce(domain: peerName));
3006 const QStringList commonNames = cert.subjectInfo(info: QSslCertificate::CommonName);
3007
3008 for (const QString &commonName : commonNames) {
3009 if (isMatchingHostname(cn: commonName, hostname: lowerPeerName))
3010 return true;
3011 }
3012
3013 const auto subjectAlternativeNames = cert.subjectAlternativeNames();
3014 const auto altNames = subjectAlternativeNames.equal_range(akey: QSsl::DnsEntry);
3015 for (auto it = altNames.first; it != altNames.second; ++it) {
3016 if (isMatchingHostname(cn: *it, hostname: lowerPeerName))
3017 return true;
3018 }
3019
3020 return false;
3021}
3022
3023/*! \internal
3024 Checks if the certificate's name \a cn matches the \a hostname.
3025 \a hostname must be normalized in ASCII-Compatible Encoding, but \a cn is not normalized
3026 */
3027bool QSslSocketPrivate::isMatchingHostname(const QString &cn, const QString &hostname)
3028{
3029 qsizetype wildcard = cn.indexOf(c: u'*');
3030
3031 // Check this is a wildcard cert, if not then just compare the strings
3032 if (wildcard < 0)
3033 return QLatin1StringView(QUrl::toAce(domain: cn)) == hostname;
3034
3035 qsizetype firstCnDot = cn.indexOf(c: u'.');
3036 qsizetype secondCnDot = cn.indexOf(c: u'.', from: firstCnDot+1);
3037
3038 // Check at least 3 components
3039 if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.size()))
3040 return false;
3041
3042 // Check * is last character of 1st component (ie. there's a following .)
3043 if (wildcard+1 != firstCnDot)
3044 return false;
3045
3046 // Check only one star
3047 if (cn.lastIndexOf(c: u'*') != wildcard)
3048 return false;
3049
3050 // Reject wildcard character embedded within the A-labels or U-labels of an internationalized
3051 // domain name (RFC6125 section 7.2)
3052 if (cn.startsWith(s: "xn--"_L1, cs: Qt::CaseInsensitive))
3053 return false;
3054
3055 // Check characters preceding * (if any) match
3056 if (wildcard && QStringView{hostname}.left(n: wildcard).compare(other: QStringView{cn}.left(n: wildcard), cs: Qt::CaseInsensitive) != 0)
3057 return false;
3058
3059 // Check characters following first . match
3060 qsizetype hnDot = hostname.indexOf(c: u'.');
3061 if (QStringView{hostname}.mid(pos: hnDot + 1) != QStringView{cn}.mid(pos: firstCnDot + 1)
3062 && QStringView{hostname}.mid(pos: hnDot + 1) != QLatin1StringView(QUrl::toAce(domain: cn.mid(position: firstCnDot + 1)))) {
3063 return false;
3064 }
3065
3066 // Check if the hostname is an IP address, if so then wildcards are not allowed
3067 QHostAddress addr(hostname);
3068 if (!addr.isNull())
3069 return false;
3070
3071 // Ok, I guess this was a wildcard CN and the hostname matches.
3072 return true;
3073}
3074
3075/*!
3076 \internal
3077*/
3078QTlsBackend *QSslSocketPrivate::tlsBackendInUse()
3079{
3080 const QMutexLocker locker(&backendMutex);
3081 if (tlsBackend)
3082 return tlsBackend;
3083
3084 if (!activeBackendName.size())
3085 activeBackendName = QTlsBackend::defaultBackendName();
3086
3087 if (!activeBackendName.size()) {
3088 qCWarning(lcSsl, "No functional TLS backend was found");
3089 return nullptr;
3090 }
3091
3092 tlsBackend = QTlsBackend::findBackend(backendName: activeBackendName);
3093 if (tlsBackend) {
3094 QObject::connect(sender: tlsBackend, signal: &QObject::destroyed, slot: [] {
3095 const QMutexLocker locker(&backendMutex);
3096 tlsBackend = nullptr;
3097 });
3098 }
3099 return tlsBackend;
3100}
3101
3102/*!
3103 \internal
3104*/
3105QSslSocket::SslMode QSslSocketPrivate::tlsMode() const
3106{
3107 return mode;
3108}
3109
3110/*!
3111 \internal
3112*/
3113bool QSslSocketPrivate::isRootsOnDemandAllowed() const
3114{
3115 return allowRootCertOnDemandLoading;
3116}
3117
3118/*!
3119 \internal
3120*/
3121QString QSslSocketPrivate::verificationName() const
3122{
3123 return verificationPeerName;
3124}
3125
3126/*!
3127 \internal
3128*/
3129QString QSslSocketPrivate::tlsHostName() const
3130{
3131 return hostName;
3132}
3133
3134QTcpSocket *QSslSocketPrivate::plainTcpSocket() const
3135{
3136 return plainSocket;
3137}
3138
3139/*!
3140 \internal
3141*/
3142QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
3143{
3144 if (const auto *tlsBackend = tlsBackendInUse())
3145 return tlsBackend->systemCaCertificates();
3146 return {};
3147}
3148
3149QT_END_NAMESPACE
3150
3151#include "moc_qsslsocket.cpp"
3152

source code of qtbase/src/network/ssl/qsslsocket.cpp