Coverage Report

Created: 2026-08-17 07:50

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