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