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