484void QSslSocket::connectToHostEncrypted(
const QString &hostName, quint16 port, OpenMode mode, NetworkLayerProtocol protocol)
487 if (d->state == ConnectedState || d->state == ConnectingState) {
489 "QSslSocket::connectToHostEncrypted() called when already connecting/connected");
493 if (!supportsSsl()) {
494 qCWarning(lcSsl,
"QSslSocket::connectToHostEncrypted: TLS initialization failed");
495 d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr(
"TLS initialization failed"));
499 if (!d->verifyProtocolSupported(
"QSslSocket::connectToHostEncrypted:"))
503 d->autoStartHandshake =
true;
504 d->initialized =
true;
508 connectToHost(hostName, port, mode, protocol);
522void QSslSocket::connectToHostEncrypted(
const QString &hostName, quint16 port,
523 const QString &sslPeerName, OpenMode mode,
524 NetworkLayerProtocol protocol)
527 if (d->state == ConnectedState || d->state == ConnectingState) {
529 "QSslSocket::connectToHostEncrypted() called when already connecting/connected");
533 if (!supportsSsl()) {
534 qCWarning(lcSsl,
"QSslSocket::connectToHostEncrypted: TLS initialization failed");
535 d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr(
"TLS initialization failed"));
540 d->autoStartHandshake =
true;
541 d->initialized =
true;
542 d->verificationPeerName = sslPeerName;
546 connectToHost(hostName, port, mode, protocol);
561bool QSslSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState state, OpenMode openMode)
564#ifdef QSSLSOCKET_DEBUG
565 qCDebug(lcSsl) <<
"QSslSocket::setSocketDescriptor(" << socketDescriptor <<
','
566 << state <<
',' << openMode <<
')';
569 d->createPlainSocket(openMode);
570 bool retVal = d->plainSocket->setSocketDescriptor(socketDescriptor, state, openMode);
571 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
572 d->setError(d->plainSocket->error(), d->plainSocket->errorString());
573 setSocketState(state);
574 setOpenMode(openMode);
575 setLocalPort(d->plainSocket->localPort());
576 setLocalAddress(d->plainSocket->localAddress());
577 setPeerPort(d->plainSocket->peerPort());
578 setPeerAddress(d->plainSocket->peerAddress());
579 setPeerName(d->plainSocket->peerName());
580 d->readChannelCount = d->plainSocket->readChannelCount();
581 d->writeChannelCount = d->plainSocket->writeChannelCount();
951void QSslSocket::setSslConfiguration(
const QSslConfiguration &configuration)
954 d->configuration.localCertificateChain = configuration.localCertificateChain();
955 d->configuration.privateKey = configuration.privateKey();
956 d->configuration.ciphers = configuration.ciphers();
957 d->configuration.ellipticCurves = configuration.ellipticCurves();
958 d->configuration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
959 d->configuration.dhParams = configuration.diffieHellmanParameters();
960 d->configuration.caCertificates = configuration.caCertificates();
961 d->configuration.peerVerifyDepth = configuration.peerVerifyDepth();
962 d->configuration.peerVerifyMode = configuration.peerVerifyMode();
963 d->configuration.protocol = configuration.protocol();
964 d->configuration.backendConfig = configuration.backendConfiguration();
965 d->configuration.sslOptions = configuration.d->sslOptions;
966 d->configuration.sslSession = configuration.sessionTicket();
967 d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
968 d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols();
969 d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
970 d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
972 d->configuration.ocspStaplingEnabled = configuration.ocspStaplingEnabled();
974#if QT_CONFIG(openssl)
975 d->configuration.reportFromCallback = configuration.handshakeMustInterruptOnError();
976 d->configuration.missingCertIsFatal = configuration.missingCertificateIsFatal();
981 if (!configuration.d->allowRootCertOnDemandLoading) {
982 d->allowRootCertOnDemandLoading =
false;
983 d->configuration.allowRootCertOnDemandLoading =
false;
1221void QSslSocket::setPrivateKey(
const QString &fileName, QSsl::KeyAlgorithm algorithm,
1222 QSsl::EncodingFormat format,
const QByteArray &passPhrase)
1224 QFile file(fileName);
1225 if (!file.open(QIODevice::ReadOnly)) {
1226 qCWarning(lcSsl,
"QSslSocket::setPrivateKey: Couldn't open file for reading");
1230 QSslKey key(file.readAll(), algorithm, format, QSsl::PrivateKey, passPhrase);
1232 qCWarning(lcSsl,
"QSslSocket::setPrivateKey: "
1233 "The specified file does not contain a valid key");
1238 d->configuration.privateKey = key;
1288bool QSslSocket::waitForEncrypted(
int msecs)
1291 if (!d->plainSocket || d->connectionEncrypted)
1293 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1295 if (!d->verifyProtocolSupported(
"QSslSocket::waitForEncrypted:"))
1298 QElapsedTimer stopWatch;
1301 if (d->plainSocket->state() != QAbstractSocket::ConnectedState) {
1303 if (!d->plainSocket->waitForConnected(msecs))
1307 while (!d->connectionEncrypted) {
1309 if (d->mode == UnencryptedMode)
1310 startClientEncryption();
1313 if (!d->plainSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed())))
1316 return d->connectionEncrypted;
1322bool QSslSocket::waitForReadyRead(
int msecs)
1325 if (!d->plainSocket)
1327 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1328 return d->plainSocket->waitForReadyRead(msecs);
1334 bool readyReadEmitted =
false;
1335 bool *previousReadyReadEmittedPointer = d->readyReadEmittedPointer;
1336 d->readyReadEmittedPointer = &readyReadEmitted;
1338 QElapsedTimer stopWatch;
1341 if (!d->connectionEncrypted) {
1343 if (!waitForEncrypted(msecs)) {
1344 d->readyReadEmittedPointer = previousReadyReadEmittedPointer;
1349 if (!d->writeBuffer.isEmpty()) {
1356 while (!readyReadEmitted &&
1357 d->plainSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
1360 d->readyReadEmittedPointer = previousReadyReadEmittedPointer;
1361 return readyReadEmitted;
1367bool QSslSocket::waitForBytesWritten(
int msecs)
1370 if (!d->plainSocket)
1372 if (d->mode == UnencryptedMode)
1373 return d->plainSocket->waitForBytesWritten(msecs);
1375 QElapsedTimer stopWatch;
1378 if (!d->connectionEncrypted) {
1380 if (!waitForEncrypted(msecs))
1383 if (!d->writeBuffer.isEmpty()) {
1388 return d->plainSocket->waitForBytesWritten(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
1398bool QSslSocket::waitForDisconnected(
int msecs)
1403 if (state() == UnconnectedState) {
1404 qCWarning(lcSsl,
"QSslSocket::waitForDisconnected() is not allowed in UnconnectedState");
1408 if (!d->plainSocket)
1411 if (d->mode == UnencryptedMode && !d->autoStartHandshake)
1412 return d->plainSocket->waitForDisconnected(msecs);
1414 QElapsedTimer stopWatch;
1417 if (!d->connectionEncrypted) {
1419 if (!waitForEncrypted(msecs))
1424 if (!d->writeBuffer.isEmpty())
1430 if (state() == UnconnectedState)
1433 bool retVal = d->plainSocket->waitForDisconnected(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
1435 setSocketState(d->plainSocket->state());
1436 d->setError(d->plainSocket->error(), d->plainSocket->errorString());
1695void QSslSocket::startClientEncryption()
1698 if (d->mode != UnencryptedMode) {
1700 "QSslSocket::startClientEncryption: cannot start handshake on non-plain connection");
1703 if (state() != ConnectedState) {
1705 "QSslSocket::startClientEncryption: cannot start handshake when not connected");
1709 if (!supportsSsl()) {
1710 qCWarning(lcSsl,
"QSslSocket::startClientEncryption: TLS initialization failed");
1711 d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr(
"TLS initialization failed"));
1715 if (!d->verifyProtocolSupported(
"QSslSocket::startClientEncryption:"))
1718#ifdef QSSLSOCKET_DEBUG
1719 qCDebug(lcSsl) <<
"QSslSocket::startClientEncryption()";
1721 d->mode = SslClientMode;
1722 emit modeChanged(d->mode);
1723 d->startClientEncryption();
1848void QSslSocket::connectToHost(
const QString &hostName, quint16 port, OpenMode openMode, NetworkLayerProtocol protocol)
1851 d->preferredNetworkLayerProtocol = protocol;
1852 if (!d->initialized)
1854 d->initialized =
false;
1856#ifdef QSSLSOCKET_DEBUG
1857 qCDebug(lcSsl) <<
"QSslSocket::connectToHost("
1858 << hostName <<
',' << port <<
',' << openMode <<
')';
1860 if (!d->plainSocket) {
1861#ifdef QSSLSOCKET_DEBUG
1862 qCDebug(lcSsl) <<
"\tcreating internal plain socket";
1864 d->createPlainSocket(openMode);
1866#ifndef QT_NO_NETWORKPROXY
1867 d->plainSocket->setProtocolTag(d->protocolTag);
1868 d->plainSocket->setProxy(proxy());
1870 QIODevice::open(openMode);
1871 d->readChannelCount = d->writeChannelCount = 0;
1872 d->plainSocket->connectToHost(hostName, port, openMode, d->preferredNetworkLayerProtocol);
1873 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
1879void QSslSocket::disconnectFromHost()
1882#ifdef QSSLSOCKET_DEBUG
1883 qCDebug(lcSsl) <<
"QSslSocket::disconnectFromHost()";
1885 if (!d->plainSocket)
1887 if (d->state == UnconnectedState)
1889 if (d->mode == UnencryptedMode && !d->autoStartHandshake) {
1890 d->plainSocket->disconnectFromHost();
1893 if (d->state <= ConnectingState) {
1894 d->pendingClose =
true;
1899 if (
auto *backend = d->backend.get())
1900 backend->cancelCAFetch();
1903 if (d->state != ClosingState) {
1904 d->state = ClosingState;
1905 emit stateChanged(d->state);
1908 if (!d->writeBuffer.isEmpty()) {
1909 d->pendingClose =
true;
1913 if (d->mode == UnencryptedMode) {
1914 d->plainSocket->disconnectFromHost();
1916 d->disconnectFromHost();
1923qint64 QSslSocket::readData(
char *data, qint64 maxlen)
1926 qint64 readBytes = 0;
1928 if (d->mode == UnencryptedMode && !d->autoStartHandshake) {
1929 readBytes = d->plainSocket->read(data, maxlen);
1930#ifdef QSSLSOCKET_DEBUG
1931 qCDebug(lcSsl) <<
"QSslSocket::readData(" << (
void *)data <<
',' << maxlen <<
") =="
1936 if (d->plainSocket->bytesAvailable() || d->hasUndecryptedData())
1937 QMetaObject::invokeMethod(
this,
"_q_flushReadBuffer", Qt::QueuedConnection);
1938 else if (d->state != QAbstractSocket::ConnectedState)
1939 return maxlen ? qint64(-1) : qint64(0);
1973QSslSocketPrivate::QSslSocketPrivate()
1974 : initialized(
false)
1975 , mode(QSslSocket::UnencryptedMode)
1976 , autoStartHandshake(
false)
1977 , connectionEncrypted(
false)
1978 , ignoreAllSslErrors(
false)
1979 , readyReadEmittedPointer(
nullptr)
1980 , allowRootCertOnDemandLoading(
true)
1981 , plainSocket(
nullptr)
1983 , flushTriggered(
false)
1985 QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration);
1988 if (!configuration.allowRootCertOnDemandLoading)
1989 allowRootCertOnDemandLoading =
false;
1991 const auto *tlsBackend = tlsBackendInUse();
1993 qCWarning(lcSsl,
"No TLS backend is available");
1996 backend.reset(tlsBackend->createTlsCryptograph());
1997 if (!backend.get()) {
1998 qCWarning(lcSsl) <<
"The backend named" << tlsBackend->backendName()
1999 <<
"does not support TLS";
2213void QSslSocketPrivate::setDefaultCaCertificates(
const QList<QSslCertificate> &certs)
2215 QSslSocketPrivate::ensureInitialized();
2216 QMutexLocker locker(&globalData()->mutex);
2217 globalData()->config.detach();
2218 globalData()->config->caCertificates = certs;
2219 globalData()->dtlsConfig.detach();
2220 globalData()->dtlsConfig->caCertificates = certs;
2223 s_loadRootCertsOnDemand =
false;
2229void QSslSocketPrivate::addDefaultCaCertificate(
const QSslCertificate &cert)
2231 QSslSocketPrivate::ensureInitialized();
2232 QMutexLocker locker(&globalData()->mutex);
2233 if (globalData()->config->caCertificates.contains(cert))
2235 globalData()->config.detach();
2236 globalData()->config->caCertificates += cert;
2237 globalData()->dtlsConfig.detach();
2238 globalData()->dtlsConfig->caCertificates += cert;
2244void QSslSocketPrivate::addDefaultCaCertificates(
const QList<QSslCertificate> &certs)
2246 QSslSocketPrivate::ensureInitialized();
2247 QMutexLocker locker(&globalData()->mutex);
2248 globalData()->config.detach();
2249 globalData()->config->caCertificates += certs;
2250 globalData()->dtlsConfig.detach();
2251 globalData()->dtlsConfig->caCertificates += certs;
2280void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPrivate *ptr)
2282 QSslSocketPrivate::ensureInitialized();
2283 QMutexLocker locker(&globalData()->mutex);
2284 const QSslConfigurationPrivate *global = globalData()->config.constData();
2289 ptr->ref.storeRelaxed(1);
2290 ptr->peerCertificate = global->peerCertificate;
2291 ptr->peerCertificateChain = global->peerCertificateChain;
2292 ptr->localCertificateChain = global->localCertificateChain;
2293 ptr->privateKey = global->privateKey;
2294 ptr->sessionCipher = global->sessionCipher;
2295 ptr->sessionProtocol = global->sessionProtocol;
2296 ptr->ciphers = global->ciphers;
2297 ptr->caCertificates = global->caCertificates;
2298 ptr->allowRootCertOnDemandLoading = global->allowRootCertOnDemandLoading;
2299 ptr->protocol = global->protocol;
2300 ptr->peerVerifyMode = global->peerVerifyMode;
2301 ptr->peerVerifyDepth = global->peerVerifyDepth;
2302 ptr->sslOptions = global->sslOptions;
2303 ptr->ellipticCurves = global->ellipticCurves;
2304 ptr->backendConfig = global->backendConfig;
2306 ptr->dtlsCookieEnabled = global->dtlsCookieEnabled;
2309 ptr->ocspStaplingEnabled = global->ocspStaplingEnabled;
2311#if QT_CONFIG(openssl)
2312 ptr->reportFromCallback = global->reportFromCallback;
2313 ptr->missingCertIsFatal = global->missingCertIsFatal;
2331void QSslConfigurationPrivate::setDefaultDtlsConfiguration(
const QSslConfiguration &configuration)
2333 QSslSocketPrivate::ensureInitialized();
2334 QMutexLocker locker(&globalData()->mutex);
2335 if (globalData()->dtlsConfig == configuration.d)
2338 globalData()->dtlsConfig =
const_cast<QSslConfigurationPrivate*>(configuration.d.constData());
2344void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode)
2347 q->setOpenMode(openMode);
2348 q->setSocketState(QAbstractSocket::UnconnectedState);
2349 q->setSocketError(QAbstractSocket::UnknownSocketError);
2351 q->setLocalAddress(QHostAddress());
2353 q->setPeerAddress(QHostAddress());
2354 q->setPeerName(QString());
2356 plainSocket =
new QTcpSocket(q);
2357 q->connect(plainSocket, SIGNAL(connected()),
2358 q, SLOT(_q_connectedSlot()),
2359 Qt::DirectConnection);
2360 q->connect(plainSocket, SIGNAL(hostFound()),
2361 q, SLOT(_q_hostFoundSlot()),
2362 Qt::DirectConnection);
2363 q->connect(plainSocket, SIGNAL(disconnected()),
2364 q, SLOT(_q_disconnectedSlot()),
2365 Qt::DirectConnection);
2366 q->connect(plainSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
2367 q, SLOT(_q_stateChangedSlot(QAbstractSocket::SocketState)),
2368 Qt::DirectConnection);
2369 q->connect(plainSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
2370 q, SLOT(_q_errorSlot(QAbstractSocket::SocketError)),
2371 Qt::DirectConnection);
2372 q->connect(plainSocket, SIGNAL(readyRead()),
2373 q, SLOT(_q_readyReadSlot()),
2374 Qt::DirectConnection);
2375 q->connect(plainSocket, SIGNAL(channelReadyRead(
int)),
2376 q, SLOT(_q_channelReadyReadSlot(
int)),
2377 Qt::DirectConnection);
2378 q->connect(plainSocket, SIGNAL(bytesWritten(qint64)),
2379 q, SLOT(_q_bytesWrittenSlot(qint64)),
2380 Qt::DirectConnection);
2381 q->connect(plainSocket, SIGNAL(channelBytesWritten(
int,qint64)),
2382 q, SLOT(_q_channelBytesWrittenSlot(
int,qint64)),
2383 Qt::DirectConnection);
2384 q->connect(plainSocket, SIGNAL(readChannelFinished()),
2385 q, SLOT(_q_readChannelFinishedSlot()),
2386 Qt::DirectConnection);
2387#ifndef QT_NO_NETWORKPROXY
2388 q->connect(plainSocket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
2389 q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
2393 writeBuffer.clear();
2394 connectionEncrypted =
false;
2395 configuration.peerCertificate.clear();
2396 configuration.peerCertificateChain.clear();
2397 mode = QSslSocket::UnencryptedMode;
2398 q->setReadBufferSize(readBufferMaxSize);
2425bool QSslSocketPrivate::bind(
const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode)
2430 initialized =
false;
2432#ifdef QSSLSOCKET_DEBUG
2433 qCDebug(lcSsl) <<
"QSslSocket::bind(" << address <<
',' << port <<
',' << mode <<
')';
2436#ifdef QSSLSOCKET_DEBUG
2437 qCDebug(lcSsl) <<
"\tcreating internal plain socket";
2439 createPlainSocket(QIODevice::ReadWrite);
2441 bool ret = plainSocket->bind(address, port, mode);
2442 localPort = plainSocket->localPort();
2443 localAddress = plainSocket->localAddress();
2444 cachedSocketDescriptor = plainSocket->socketDescriptor();
2445 readChannelCount = writeChannelCount = 0;
2452void QSslSocketPrivate::_q_connectedSlot()
2455 q->setLocalPort(plainSocket->localPort());
2456 q->setLocalAddress(plainSocket->localAddress());
2457 q->setPeerPort(plainSocket->peerPort());
2458 q->setPeerAddress(plainSocket->peerAddress());
2459 q->setPeerName(plainSocket->peerName());
2460 cachedSocketDescriptor = plainSocket->socketDescriptor();
2461 readChannelCount = plainSocket->readChannelCount();
2462 writeChannelCount = plainSocket->writeChannelCount();
2464#ifdef QSSLSOCKET_DEBUG
2465 qCDebug(lcSsl) <<
"QSslSocket::_q_connectedSlot()";
2466 qCDebug(lcSsl) <<
"\tstate =" << q->state();
2467 qCDebug(lcSsl) <<
"\tpeer =" << q->peerName() << q->peerAddress() << q->peerPort();
2468 qCDebug(lcSsl) <<
"\tlocal =" << QHostInfo::fromName(q->localAddress().toString()).hostName()
2469 << q->localAddress() << q->localPort();
2472 if (autoStartHandshake)
2473 q->startClientEncryption();
2475 emit q->connected();
2477 if (pendingClose && !autoStartHandshake) {
2478 pendingClose =
false;
2479 q->disconnectFromHost();
3008bool QSslSocketPrivate::isMatchingHostname(
const QSslCertificate &cert,
const QString &peerName)
3010 QHostAddress hostAddress(peerName);
3011 if (!hostAddress.isNull()) {
3012 const auto subjectAlternativeNames = cert.subjectAlternativeNames();
3013 const auto ipAddresses = subjectAlternativeNames.equal_range(QSsl::AlternativeNameEntryType::IpAddressEntry);
3015 for (
auto it = ipAddresses.first; it != ipAddresses.second; it++) {
3016 if (QHostAddress(*it).isEqual(hostAddress, QHostAddress::StrictConversion))
3021 const QString lowerPeerName = QString::fromLatin1(QUrl::toAce(peerName));
3022 const QStringList commonNames = cert.subjectInfo(QSslCertificate::CommonName);
3024 for (
const QString &commonName : commonNames) {
3025 if (isMatchingHostname(commonName, lowerPeerName))
3029 const auto subjectAlternativeNames = cert.subjectAlternativeNames();
3030 const auto altNames = subjectAlternativeNames.equal_range(QSsl::DnsEntry);
3031 for (
auto it = altNames.first; it != altNames.second; ++it) {
3032 if (isMatchingHostname(*it, lowerPeerName))
3043bool QSslSocketPrivate::isMatchingHostname(
const QString &cn,
const QString &hostname)
3045 qsizetype wildcard = cn.indexOf(u'*');
3049 return QLatin1StringView(QUrl::toAce(cn)) == hostname;
3051 qsizetype firstCnDot = cn.indexOf(u'.');
3052 qsizetype secondCnDot = cn.indexOf(u'.', firstCnDot+1);
3055 if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.size()))
3059 if (wildcard+1 != firstCnDot)
3063 if (cn.lastIndexOf(u'*') != wildcard)
3068 if (cn.startsWith(
"xn--"_L1, Qt::CaseInsensitive))
3072 if (wildcard && QStringView{hostname}.left(wildcard).compare(QStringView{cn}.left(wildcard), Qt::CaseInsensitive) != 0)
3076 qsizetype hnDot = hostname.indexOf(u'.');
3077 if (QStringView{hostname}.mid(hnDot + 1) != QStringView{cn}.mid(firstCnDot + 1)
3078 && QStringView{hostname}.mid(hnDot + 1) != QLatin1StringView(QUrl::toAce(cn.mid(firstCnDot + 1)))) {
3083 QHostAddress addr(hostname);
3094QTlsBackend *QSslSocketPrivate::tlsBackendInUse()
3096 const QMutexLocker locker(&backendMutex);
3100 if (!activeBackendName.size())
3101 activeBackendName = QTlsBackend::defaultBackendName();
3103 if (!activeBackendName.size()) {
3104 qCWarning(lcSsl,
"No functional TLS backend was found");
3108 tlsBackend = QTlsBackend::findBackend(activeBackendName);
3110 QObject::connect(tlsBackend, &QObject::destroyed, tlsBackend, [] {
3111 const QMutexLocker locker(&backendMutex);
3112 tlsBackend =
nullptr;
3114 Qt::DirectConnection);