485void QSslSocket::connectToHostEncrypted(
const QString &hostName, quint16 port, OpenMode mode, NetworkLayerProtocol protocol)
488 if (d->state == ConnectedState || d->state == ConnectingState) {
490 "QSslSocket::connectToHostEncrypted() called when already connecting/connected");
494 if (!supportsSsl()) {
495 qCWarning(lcSsl,
"QSslSocket::connectToHostEncrypted: TLS initialization failed");
496 d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr(
"TLS initialization failed"));
500 if (!d->verifyProtocolSupported(
"QSslSocket::connectToHostEncrypted:"))
504 d->autoStartHandshake =
true;
505 d->initialized =
true;
509 connectToHost(hostName, port, mode, protocol);
523void QSslSocket::connectToHostEncrypted(
const QString &hostName, quint16 port,
524 const QString &sslPeerName, OpenMode mode,
525 NetworkLayerProtocol protocol)
528 if (d->state == ConnectedState || d->state == ConnectingState) {
530 "QSslSocket::connectToHostEncrypted() called when already connecting/connected");
534 if (!supportsSsl()) {
535 qCWarning(lcSsl,
"QSslSocket::connectToHostEncrypted: TLS initialization failed");
536 d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr(
"TLS initialization failed"));
541 d->autoStartHandshake =
true;
542 d->initialized =
true;
543 d->verificationPeerName = sslPeerName;
547 connectToHost(hostName, port, mode, protocol);
562bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state, OpenMode openMode)
565#ifdef QSSLSOCKET_DEBUG
566 qCDebug(lcSsl) <<
"QSslSocket::setSocketDescriptor(" << socketDescriptor <<
','
567 << state <<
',' << openMode <<
')';
570 d->createPlainSocket(openMode);
571 bool retVal = d->plainSocket->setSocketDescriptor(socketDescriptor, state, openMode);
572 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
573 d->setError(d->plainSocket->error(), d->plainSocket->errorString());
574 setSocketState(state);
575 setOpenMode(openMode);
576 setLocalPort(d->plainSocket->localPort());
577 setLocalAddress(d->plainSocket->localAddress());
578 setPeerPort(d->plainSocket->peerPort());
579 setPeerAddress(d->plainSocket->peerAddress());
580 setPeerName(d->plainSocket->peerName());
581 d->readChannelCount = d->plainSocket->readChannelCount();
582 d->writeChannelCount = d->plainSocket->writeChannelCount();
959void QSslSocket::setSslConfiguration(
const QSslConfiguration &configuration)
962 d->configuration.localCertificateChain = configuration.localCertificateChain();
963 d->configuration.privateKey = configuration.privateKey();
964 d->configuration.ciphers = configuration.ciphers();
965 d->configuration.ellipticCurves = configuration.ellipticCurves();
966 d->configuration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
967 d->configuration.dhParams = configuration.diffieHellmanParameters();
968 d->configuration.caCertificates = configuration.caCertificates();
969 d->configuration.peerVerifyDepth = configuration.peerVerifyDepth();
970 d->configuration.peerVerifyMode = configuration.peerVerifyMode();
971 d->configuration.protocol = configuration.protocol();
972 d->configuration.backendConfig = configuration.backendConfiguration();
973 d->configuration.sslOptions = configuration.d->sslOptions;
974 d->configuration.sslSession = configuration.sessionTicket();
975 d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
976 d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols();
977 d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
978 d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
980 d->configuration.keyingMaterial = configuration.d->keyingMaterial;
982 d->configuration.ocspStaplingEnabled = configuration.ocspStaplingEnabled();
984#if QT_CONFIG(openssl)
985 d->configuration.reportFromCallback = configuration.handshakeMustInterruptOnError();
986 d->configuration.missingCertIsFatal = configuration.missingCertificateIsFatal();
991 if (!configuration.d->allowRootCertOnDemandLoading) {
992 d->allowRootCertOnDemandLoading =
false;
993 d->configuration.allowRootCertOnDemandLoading =
false;
1229void QSslSocket::setPrivateKey(
const QString &fileName, QSsl::KeyAlgorithm algorithm,
1230 QSsl::EncodingFormat format,
const QByteArray &passPhrase)
1232 QFile file(fileName);
1233 if (!file.open(QIODevice::ReadOnly)) {
1234 qCWarning(lcSsl,
"QSslSocket::setPrivateKey: Couldn't open file for reading");
1238 QSslKey key(file.readAll(), algorithm, format, QSsl::PrivateKey, passPhrase);
1240 qCWarning(lcSsl,
"QSslSocket::setPrivateKey: "
1241 "The specified file does not contain a valid key");
1246 d->configuration.privateKey = key;
1296bool QSslSocket::waitForEncrypted(
int msecs)
1299 if (!d->plainSocket || d->connectionEncrypted)
1301 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1303 if (!d->verifyProtocolSupported(
"QSslSocket::waitForEncrypted:"))
1306 QElapsedTimer stopWatch;
1309 if (d->plainSocket->state() != QAbstractSocket::ConnectedState) {
1311 if (!d->plainSocket->waitForConnected(msecs))
1315 while (!d->connectionEncrypted) {
1317 if (d->mode == UnencryptedMode)
1318 startClientEncryption();
1321 if (!d->plainSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed())))
1324 return d->connectionEncrypted;
1330bool QSslSocket::waitForReadyRead(
int msecs)
1333 if (!d->plainSocket)
1335 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1336 return d->plainSocket->waitForReadyRead(msecs);
1342 bool readyReadEmitted =
false;
1343 bool *previousReadyReadEmittedPointer = d->readyReadEmittedPointer;
1344 d->readyReadEmittedPointer = &readyReadEmitted;
1346 QElapsedTimer stopWatch;
1349 if (!d->connectionEncrypted) {
1351 if (!waitForEncrypted(msecs)) {
1352 d->readyReadEmittedPointer = previousReadyReadEmittedPointer;
1357 if (!d->writeBuffer.isEmpty()) {
1364 while (!readyReadEmitted &&
1365 d->plainSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
1368 d->readyReadEmittedPointer = previousReadyReadEmittedPointer;
1369 return readyReadEmitted;
1375bool QSslSocket::waitForBytesWritten(
int msecs)
1378 if (!d->plainSocket)
1380 if (d->mode == UnencryptedMode)
1381 return d->plainSocket->waitForBytesWritten(msecs);
1383 QElapsedTimer stopWatch;
1386 if (!d->connectionEncrypted) {
1388 if (!waitForEncrypted(msecs))
1391 if (!d->writeBuffer.isEmpty()) {
1396 return d->plainSocket->waitForBytesWritten(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
1406bool QSslSocket::waitForDisconnected(
int msecs)
1411 if (state() == UnconnectedState) {
1412 qCWarning(lcSsl,
"QSslSocket::waitForDisconnected() is not allowed in UnconnectedState");
1416 if (!d->plainSocket)
1419 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1420 return d->plainSocket->waitForDisconnected(msecs);
1422 QElapsedTimer stopWatch;
1425 if (!d->connectionEncrypted) {
1427 if (!waitForEncrypted(msecs))
1432 if (!d->writeBuffer.isEmpty())
1438 if (state() == UnconnectedState)
1441 bool retVal = d->plainSocket->waitForDisconnected(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
1443 setSocketState(d->plainSocket->state());
1444 d->setError(d->plainSocket->error(), d->plainSocket->errorString());
1703void QSslSocket::startClientEncryption()
1706 if (d->mode != UnencryptedMode) {
1708 "QSslSocket::startClientEncryption: cannot start handshake on non-plain connection");
1711 if (state() != ConnectedState) {
1713 "QSslSocket::startClientEncryption: cannot start handshake when not connected");
1717 if (!supportsSsl()) {
1718 qCWarning(lcSsl,
"QSslSocket::startClientEncryption: TLS initialization failed");
1719 d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr(
"TLS initialization failed"));
1723 if (!d->verifyProtocolSupported(
"QSslSocket::startClientEncryption:"))
1726#ifdef QSSLSOCKET_DEBUG
1727 qCDebug(lcSsl) <<
"QSslSocket::startClientEncryption()";
1729 d->mode = SslClientMode;
1730 emit modeChanged(d->mode);
1731 d->startClientEncryption();
1856void QSslSocket::connectToHost(
const QString &hostName, quint16 port, OpenMode openMode, NetworkLayerProtocol protocol)
1859 d->preferredNetworkLayerProtocol = protocol;
1860 if (!d->initialized)
1862 d->initialized =
false;
1864#ifdef QSSLSOCKET_DEBUG
1865 qCDebug(lcSsl) <<
"QSslSocket::connectToHost("
1866 << hostName <<
',' << port <<
',' << openMode <<
')';
1868 if (!d->plainSocket) {
1869#ifdef QSSLSOCKET_DEBUG
1870 qCDebug(lcSsl) <<
"\tcreating internal plain socket";
1872 d->createPlainSocket(openMode);
1874#ifndef QT_NO_NETWORKPROXY
1875 d->plainSocket->setProtocolTag(d->protocolTag);
1876 d->plainSocket->setProxy(proxy());
1878 QIODevice::open(openMode);
1879 d->readChannelCount = d->writeChannelCount = 0;
1880 d->plainSocket->connectToHost(hostName, port, openMode, d->preferredNetworkLayerProtocol);
1881 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
1887void QSslSocket::disconnectFromHost()
1890#ifdef QSSLSOCKET_DEBUG
1891 qCDebug(lcSsl) <<
"QSslSocket::disconnectFromHost()";
1893 if (!d->plainSocket)
1895 if (d->state == UnconnectedState)
1897 if (d->mode == UnencryptedMode && !d->autoStartHandshake) {
1898 d->plainSocket->disconnectFromHost();
1901 if (d->state <= ConnectingState) {
1902 d->pendingClose =
true;
1907 if (
auto *backend = d->backend.get())
1908 backend->cancelCAFetch();
1911 if (d->state != ClosingState) {
1912 d->state = ClosingState;
1913 emit stateChanged(d->state);
1916 if (!d->writeBuffer.isEmpty()) {
1917 d->pendingClose =
true;
1921 if (d->mode == UnencryptedMode) {
1922 d->plainSocket->disconnectFromHost();
1924 d->disconnectFromHost();
1931qint64 QSslSocket::readData(
char *data, qint64 maxlen)
1934 qint64 readBytes = 0;
1936 if (d->mode == UnencryptedMode && !d->autoStartHandshake) {
1937 readBytes = d->plainSocket->read(data, maxlen);
1938#ifdef QSSLSOCKET_DEBUG
1939 qCDebug(lcSsl) <<
"QSslSocket::readData(" << (
void *)data <<
',' << maxlen <<
") =="
1944 if (d->plainSocket->bytesAvailable() || d->hasUndecryptedData())
1945 QMetaObject::invokeMethod(
this,
"_q_flushReadBuffer", Qt::QueuedConnection);
1946 else if (d->state != QAbstractSocket::ConnectedState)
1947 return maxlen ? qint64(-1) : qint64(0);
1981QSslSocketPrivate::QSslSocketPrivate()
1982 : initialized(
false)
1983 , mode(QSslSocket::UnencryptedMode)
1984 , autoStartHandshake(
false)
1985 , connectionEncrypted(
false)
1986 , ignoreAllSslErrors(
false)
1987 , readyReadEmittedPointer(
nullptr)
1988 , allowRootCertOnDemandLoading(
true)
1989 , plainSocket(
nullptr)
1991 , flushTriggered(
false)
1993 QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration);
1996 if (!configuration.allowRootCertOnDemandLoading)
1997 allowRootCertOnDemandLoading =
false;
1999 const auto *tlsBackend = tlsBackendInUse();
2001 qCWarning(lcSsl,
"No TLS backend is available");
2004 backend.reset(tlsBackend->createTlsCryptograph());
2005 if (!backend.get()) {
2006 qCWarning(lcSsl) <<
"The backend named" << tlsBackend->backendName()
2007 <<
"does not support TLS";
2221void QSslSocketPrivate::setDefaultCaCertificates(
const QList<QSslCertificate> &certs)
2223 QSslSocketPrivate::ensureInitialized();
2224 QMutexLocker locker(&globalData()->mutex);
2225 globalData()->config.detach();
2226 globalData()->config->caCertificates = certs;
2227 globalData()->dtlsConfig.detach();
2228 globalData()->dtlsConfig->caCertificates = certs;
2231 s_loadRootCertsOnDemand =
false;
2237void QSslSocketPrivate::addDefaultCaCertificate(
const QSslCertificate &cert)
2239 QSslSocketPrivate::ensureInitialized();
2240 QMutexLocker locker(&globalData()->mutex);
2241 if (globalData()->config->caCertificates.contains(cert))
2243 globalData()->config.detach();
2244 globalData()->config->caCertificates += cert;
2245 globalData()->dtlsConfig.detach();
2246 globalData()->dtlsConfig->caCertificates += cert;
2252void QSslSocketPrivate::addDefaultCaCertificates(
const QList<QSslCertificate> &certs)
2254 QSslSocketPrivate::ensureInitialized();
2255 QMutexLocker locker(&globalData()->mutex);
2256 globalData()->config.detach();
2257 globalData()->config->caCertificates += certs;
2258 globalData()->dtlsConfig.detach();
2259 globalData()->dtlsConfig->caCertificates += certs;
2288void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPrivate *ptr)
2290 QSslSocketPrivate::ensureInitialized();
2291 QMutexLocker locker(&globalData()->mutex);
2292 const QSslConfigurationPrivate *global = globalData()->config.constData();
2297 ptr->ref.storeRelaxed(1);
2298 ptr->peerCertificate = global->peerCertificate;
2299 ptr->peerCertificateChain = global->peerCertificateChain;
2300 ptr->localCertificateChain = global->localCertificateChain;
2301 ptr->privateKey = global->privateKey;
2302 ptr->sessionCipher = global->sessionCipher;
2303 ptr->sessionProtocol = global->sessionProtocol;
2304 ptr->ciphers = global->ciphers;
2305 ptr->caCertificates = global->caCertificates;
2306 ptr->allowRootCertOnDemandLoading = global->allowRootCertOnDemandLoading;
2307 ptr->protocol = global->protocol;
2308 ptr->peerVerifyMode = global->peerVerifyMode;
2309 ptr->peerVerifyDepth = global->peerVerifyDepth;
2310 ptr->sslOptions = global->sslOptions;
2311 ptr->ellipticCurves = global->ellipticCurves;
2312 ptr->backendConfig = global->backendConfig;
2314 ptr->dtlsCookieEnabled = global->dtlsCookieEnabled;
2317 ptr->ocspStaplingEnabled = global->ocspStaplingEnabled;
2319#if QT_CONFIG(openssl)
2320 ptr->reportFromCallback = global->reportFromCallback;
2321 ptr->missingCertIsFatal = global->missingCertIsFatal;
2339void QSslConfigurationPrivate::setDefaultDtlsConfiguration(
const QSslConfiguration &configuration)
2341 QSslSocketPrivate::ensureInitialized();
2342 QMutexLocker locker(&globalData()->mutex);
2343 if (globalData()->dtlsConfig == configuration.d)
2346 globalData()->dtlsConfig =
const_cast<QSslConfigurationPrivate*>(configuration.d.constData());
2352void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode)
2355 q->setOpenMode(openMode);
2356 q->setSocketState(QAbstractSocket::UnconnectedState);
2357 q->setSocketError(QAbstractSocket::UnknownSocketError);
2359 q->setLocalAddress(QHostAddress());
2361 q->setPeerAddress(QHostAddress());
2362 q->setPeerName(QString());
2364 plainSocket =
new QTcpSocket(q);
2365 q->connect(plainSocket, SIGNAL(connected()),
2366 q, SLOT(_q_connectedSlot()),
2367 Qt::DirectConnection);
2368 q->connect(plainSocket, SIGNAL(hostFound()),
2369 q, SLOT(_q_hostFoundSlot()),
2370 Qt::DirectConnection);
2371 q->connect(plainSocket, SIGNAL(disconnected()),
2372 q, SLOT(_q_disconnectedSlot()),
2373 Qt::DirectConnection);
2374 q->connect(plainSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
2375 q, SLOT(_q_stateChangedSlot(QAbstractSocket::SocketState)),
2376 Qt::DirectConnection);
2377 q->connect(plainSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
2378 q, SLOT(_q_errorSlot(QAbstractSocket::SocketError)),
2379 Qt::DirectConnection);
2380 q->connect(plainSocket, SIGNAL(readyRead()),
2381 q, SLOT(_q_readyReadSlot()),
2382 Qt::DirectConnection);
2383 q->connect(plainSocket, SIGNAL(channelReadyRead(
int)),
2384 q, SLOT(_q_channelReadyReadSlot(
int)),
2385 Qt::DirectConnection);
2386 q->connect(plainSocket, SIGNAL(bytesWritten(qint64)),
2387 q, SLOT(_q_bytesWrittenSlot(qint64)),
2388 Qt::DirectConnection);
2389 q->connect(plainSocket, SIGNAL(channelBytesWritten(
int,qint64)),
2390 q, SLOT(_q_channelBytesWrittenSlot(
int,qint64)),
2391 Qt::DirectConnection);
2392 q->connect(plainSocket, SIGNAL(readChannelFinished()),
2393 q, SLOT(_q_readChannelFinishedSlot()),
2394 Qt::DirectConnection);
2395#ifndef QT_NO_NETWORKPROXY
2396 q->connect(plainSocket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
2397 q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
2401 writeBuffer.clear();
2402 connectionEncrypted =
false;
2403 configuration.peerCertificate.clear();
2404 configuration.peerCertificateChain.clear();
2405 mode = QSslSocket::UnencryptedMode;
2406 q->setReadBufferSize(readBufferMaxSize);
2433bool QSslSocketPrivate::bind(
const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode,
2434 const QNetworkInterface *iface)
2440 initialized =
false;
2442#ifdef QSSLSOCKET_DEBUG
2443 qCDebug(lcSsl) <<
"QSslSocket::bind(" << address <<
',' << port <<
',' << mode <<
')';
2446#ifdef QSSLSOCKET_DEBUG
2447 qCDebug(lcSsl) <<
"\tcreating internal plain socket";
2449 createPlainSocket(QIODevice::ReadWrite);
2451 bool ret = plainSocket->bind(address, port, mode);
2452 localPort = plainSocket->localPort();
2453 localAddress = plainSocket->localAddress();
2454 cachedSocketDescriptor = plainSocket->socketDescriptor();
2455 readChannelCount = writeChannelCount = 0;
2462void QSslSocketPrivate::_q_connectedSlot()
2465 q->setLocalPort(plainSocket->localPort());
2466 q->setLocalAddress(plainSocket->localAddress());
2467 q->setPeerPort(plainSocket->peerPort());
2468 q->setPeerAddress(plainSocket->peerAddress());
2469 q->setPeerName(plainSocket->peerName());
2470 cachedSocketDescriptor = plainSocket->socketDescriptor();
2471 readChannelCount = plainSocket->readChannelCount();
2472 writeChannelCount = plainSocket->writeChannelCount();
2474#ifdef QSSLSOCKET_DEBUG
2475 qCDebug(lcSsl) <<
"QSslSocket::_q_connectedSlot()";
2476 qCDebug(lcSsl) <<
"\tstate =" << q->state();
2477 qCDebug(lcSsl) <<
"\tpeer =" << q->peerName() << q->peerAddress() << q->peerPort();
2478 qCDebug(lcSsl) <<
"\tlocal =" << QHostInfo::fromName(q->localAddress().toString()).hostName()
2479 << q->localAddress() << q->localPort();
2482 if (autoStartHandshake)
2483 q->startClientEncryption();
2485 emit q->connected();
2487 if (pendingClose && !autoStartHandshake) {
2488 pendingClose =
false;
2489 q->disconnectFromHost();
3020bool QSslSocketPrivate::isMatchingHostname(
const QSslCertificate &cert,
const QString &peerName)
3022 QHostAddress hostAddress(peerName);
3023 if (!hostAddress.isNull()) {
3024 const auto subjectAlternativeNames = cert.subjectAlternativeNames();
3025 const auto ipAddresses = subjectAlternativeNames.equal_range(QSsl::AlternativeNameEntryType::IpAddressEntry);
3027 for (
auto it = ipAddresses.first; it != ipAddresses.second; it++) {
3028 if (QHostAddress(*it).isEqual(hostAddress, QHostAddress::StrictConversion))
3033 const QString lowerPeerName = QString::fromLatin1(QUrl::toAce(peerName));
3034 const QStringList commonNames = cert.subjectInfo(QSslCertificate::CommonName);
3036 for (
const QString &commonName : commonNames) {
3037 if (isMatchingHostname(commonName, lowerPeerName))
3041 const auto subjectAlternativeNames = cert.subjectAlternativeNames();
3042 const auto altNames = subjectAlternativeNames.equal_range(QSsl::DnsEntry);
3043 for (
auto it = altNames.first; it != altNames.second; ++it) {
3044 if (isMatchingHostname(*it, lowerPeerName))
3055bool QSslSocketPrivate::isMatchingHostname(
const QString &cn,
const QString &hostname)
3057 qsizetype wildcard = cn.indexOf(u'*');
3061 return QLatin1StringView(QUrl::toAce(cn)) == hostname;
3063 qsizetype firstCnDot = cn.indexOf(u'.');
3064 qsizetype secondCnDot = cn.indexOf(u'.', firstCnDot+1);
3067 if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.size()))
3071 if (wildcard+1 != firstCnDot)
3075 if (cn.lastIndexOf(u'*') != wildcard)
3080 if (cn.startsWith(
"xn--"_L1, Qt::CaseInsensitive))
3084 if (wildcard && QStringView{hostname}.left(wildcard).compare(QStringView{cn}.left(wildcard), Qt::CaseInsensitive) != 0)
3088 qsizetype hnDot = hostname.indexOf(u'.');
3089 if (QStringView{hostname}.mid(hnDot + 1) != QStringView{cn}.mid(firstCnDot + 1)
3090 && QStringView{hostname}.mid(hnDot + 1) != QLatin1StringView(QUrl::toAce(cn.mid(firstCnDot + 1)))) {
3095 QHostAddress addr(hostname);
3106QTlsBackend *QSslSocketPrivate::tlsBackendInUse()
3108 const QMutexLocker locker(&backendMutex);
3112 if (!activeBackendName.size())
3113 activeBackendName = QTlsBackend::defaultBackendName();
3115 if (!activeBackendName.size()) {
3116 qCWarning(lcSsl,
"No functional TLS backend was found");
3120 tlsBackend = QTlsBackend::findBackend(activeBackendName);
3122 QObject::connect(tlsBackend, &QObject::destroyed, tlsBackend, [] {
3123 const QMutexLocker locker(&backendMutex);
3124 tlsBackend =
nullptr;
3126 Qt::DirectConnection);