10#include "qwindowscarootfetcher_p.h"
13#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
14#include <QtNetwork/private/qsslcertificate_p.h>
15#include <QtNetwork/private/qocspresponse_p.h>
16#include <QtNetwork/private/qsslsocket_p.h>
18#include <QtNetwork/qsslpresharedkeyauthenticator.h>
19#include <QtNetwork/qsslkeyingmaterial.h>
21#include <QtCore/qscopedvaluerollback.h>
22#include <QtCore/qscopeguard.h>
29using namespace Qt::StringLiterals;
33QSsl::AlertLevel tlsAlertLevel(
int value)
35 using QSsl::AlertLevel;
40 switch (typeString[0]) {
42 return AlertLevel::Warning;
44 return AlertLevel::Fatal;
49 return AlertLevel::Unknown;
52QString tlsAlertDescription(
int value)
55 if (!description.size())
56 description =
"no description provided"_L1;
60QSsl::AlertType tlsAlertType(
int value)
66 return QSsl::AlertType(value & 0xff);
71QSslCertificate findCertificateToFetch(
const QList<QSslError> &tlsErrors,
bool checkAIA)
73 QSslCertificate certToFetch;
75 for (
const auto &tlsError : tlsErrors) {
76 switch (tlsError.error()) {
77 case QSslError::UnableToGetLocalIssuerCertificate:
78 case QSslError::SelfSignedCertificateInChain:
79 certToFetch = tlsError.certificate();
81 case QSslError::SelfSignedCertificate:
82 case QSslError::CertificateBlacklisted:
84 return QSslCertificate{};
86#ifdef QSSLSOCKET_DEBUG
87 qCDebug(lcTlsBackend) << tlsError.errorString();
95 const auto extensions = certToFetch.extensions();
96 for (
const auto &ext : extensions) {
97 if (ext.oid() == u"1.3.6.1.5.5.7.1.1")
104 return QSslCertificate{};
121 using ErrorListPtr = QList<QSslErrorEntry> *;
122 ErrorListPtr errors =
nullptr;
160 qCWarning(lcTlsBackend,
"Neither X509_STORE, nor SSL contains error list, handshake failure");
182 qCWarning(lcTlsBackend,
"Invalid store context (nullptr)");
194 qCWarning(lcTlsBackend,
"No external data (SSL) found in X509 store object");
202 qCWarning(lcTlsBackend,
"No external data (TlsCryptographOpenSSL) found in SSL object");
211#ifndef OPENSSL_NO_PSK
213 unsigned char *psk,
unsigned max_psk_len)
220 unsigned int max_psk_len)
228static unsigned q_ssl_psk_restore_client(SSL *ssl,
const char *hint,
char *identity,
unsigned max_identity_len,
229 unsigned char *psk,
unsigned max_psk_len)
233 Q_UNUSED(max_identity_len);
235 Q_UNUSED(max_psk_len);
238 auto tls =
static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
241 Q_ASSERT(tls->d->tlsMode() == QSslSocket::SslClientMode);
248 if (qEnvironmentVariableIsSet(
"QT_USE_TLS_1_3_PSK"))
256static int q_ssl_psk_use_session_callback(SSL *ssl,
const EVP_MD *md,
const unsigned char **id,
257 size_t *idlen, SSL_SESSION **sess)
265 auto *tls =
static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
268 Q_ASSERT(tls->d->tlsMode() == QSslSocket::SslClientMode);
277int q_ssl_sess_set_new_cb(SSL *ssl, SSL_SESSION *session)
280 qCWarning(lcTlsBackend,
"Invalid SSL (nullptr)");
284 qCWarning(lcTlsBackend,
"Invalid SSL_SESSION (nullptr)");
333#ifdef QSSLSOCKET_DEBUG
334 qCWarning(lcTlsBackend,
"Invalid 'connection' parameter (nullptr)");
344#ifdef QSSLSOCKET_DEBUG
345 qCWarning(lcTlsBackend,
"No external data (socket backend) found for parameter 'connection'");
350 if (!(from & SSL_CB_ALERT)) {
355 if (from & SSL_CB_WRITE)
484 ocspResponses.clear();
485 ocspResponseDer.clear();
487 systemOrSslErrorDetected =
false;
488 handshakeInterrupted =
false;
490 fetchAuthorityInformation =
false;
502 return sslContextPointer;
512 if (!initSslContext()) {
514 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
515 QSslSocket::tr(
"Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
527 if (!initSslContext()) {
529 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
530 QSslSocket::tr(
"Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
547 using ScopedBool = QScopedValueRollback<
bool>;
549 if (inSetAndEmitError)
552 const auto mode = d->tlsMode();
554 pendingFatalAlert =
false;
555 errorsReportedFromCallback =
false;
556 QList<QSslErrorEntry> lastErrors;
563 int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
570 if (!lastErrors.isEmpty() || errorsReportedFromCallback)
575 auto configuration = q->sslConfiguration();
576 if (!errorsReportedFromCallback) {
577 const auto &peerCertificateChain = configuration.peerCertificateChain();
578 for (
const auto ¤tError : std::as_const(lastErrors)) {
579 emit q->peerVerifyError(QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(currentError.code,
580 peerCertificateChain.value(currentError.depth)));
581 if (q->state() != QAbstractSocket::ConnectedState)
586 errorList << lastErrors;
589 if (q->state() != QAbstractSocket::ConnectedState)
595 case SSL_ERROR_WANT_READ:
596 case SSL_ERROR_WANT_WRITE:
600 QString errorString = QTlsBackendOpenSSL::msgErrorsDuringHandshake();
601#ifdef QSSLSOCKET_DEBUG
602 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::startHandshake: error!" << errorString;
605 const ScopedBool bg(inSetAndEmitError,
true);
606 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, errorString);
607 if (pendingFatalAlert) {
609 pendingFatalAlert =
false;
621 QList<QSslError> errors;
624 configuration = q->sslConfiguration();
626 const auto &peerCertificateChain = configuration.peerCertificateChain();
627 for (
const QSslCertificate &cert : peerCertificateChain) {
628 if (QSslCertificatePrivate::isBlacklisted(cert)) {
629 QSslError error(QSslError::CertificateBlacklisted, cert);
631 emit q->peerVerifyError(error);
632 if (q->state() != QAbstractSocket::ConnectedState)
637 const bool doVerifyPeer = configuration.peerVerifyMode() == QSslSocket::VerifyPeer
638 || (configuration.peerVerifyMode() == QSslSocket::AutoVerifyPeer
639 && mode == QSslSocket::SslClientMode);
644 if (!configuration.peerCertificate().isNull() && configuration.ocspStaplingEnabled() && doVerifyPeer) {
645 if (!checkOcspStatus()) {
646 if (ocspErrors.isEmpty()) {
648 const ScopedBool bg(inSetAndEmitError,
true);
649 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, ocspErrorDescription);
655 for (
const QSslError &error : ocspErrors) {
657 emit q->peerVerifyError(error);
658 if (q->state() != QAbstractSocket::ConnectedState)
668 if (!configuration.peerCertificate().isNull()) {
671 const auto verificationPeerName = d->verificationName();
672 if (mode == QSslSocket::SslClientMode) {
673 QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
675 if (!isMatchingHostname(configuration.peerCertificate(), peerName)) {
677 QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate());
679 emit q->peerVerifyError(error);
680 if (q->state() != QAbstractSocket::ConnectedState)
688 QSslError error(QSslError::NoPeerCertificate);
690 emit q->peerVerifyError(error);
691 if (q->state() != QAbstractSocket::ConnectedState)
697 errors.reserve(errors.size() + errorList.size());
698 for (
const auto &error : std::as_const(errorList))
699 errors << X509CertificateOpenSSL::openSSLErrorToQSslError(error.code, peerCertificateChain.value(error.depth));
701 if (!errors.isEmpty()) {
704 const bool fetchEnabled = QSslSocketPrivate::rootCertOnDemandLoadingSupported()
705 && d->isRootsOnDemandAllowed();
710 QSslCertificate certToFetch;
711 if (doVerifyPeer && !d->verifyErrorsHaveBeenIgnored())
712 certToFetch = findCertificateToFetch(sslErrors, !fetchEnabled);
715 if (!certToFetch.isNull()) {
716 fetchAuthorityInformation = !fetchEnabled;
723 fetchCaRootForCert(certToFetch);
732 if (q->state() != QAbstractSocket::ConnectedState)
744 handshakeInterrupted =
false;
749 fetchAuthorityInformation =
false;
755 auto sslCfg = q->sslConfiguration();
756 auto list = sslCfg.keyingMaterial();
758 for (
auto &entry : list) {
759 if (!entry.isValid()) {
760#ifdef QSSLSOCKET_DEBUG
761 qCDebug(lcTlsBackend) <<
"keying material request is invalid:" << entry;
767
768
769
770
771
772
773
774 const auto context = entry.context();
775 const auto label = entry.label();
776 if (QByteArray output(entry.keyingValueSize, Qt::Uninitialized);
777 q_SSL_export_keying_material(ssl,
778 reinterpret_cast<
unsigned char*>(output.data_ptr().data()),
779 entry.keyingValueSize,
782 reinterpret_cast<
const unsigned char*>(context.data()),
784 context.isNull() ? 0 : 1))
786 entry.keyingValue = std::move(output);
787#ifdef QSSLSOCKET_DEBUG
789 qCDebug(lcTlsBackend) <<
"cannot export keying material:" << entry;
794 sslCfg.setKeyingMaterial(list);
795 q->setSslConfiguration(sslCfg);
803 auto *plainSocket = d->plainTcpSocket();
804 Q_ASSERT(plainSocket);
806 const auto mode = d->tlsMode();
809 if (
const auto maxSize = d->maxReadBufferSize())
810 plainSocket->setReadBufferSize(maxSize);
812 if (q_SSL_session_reused(ssl))
813 QTlsBackend::setPeerSessionShared(d,
true);
815#ifdef QT_DECRYPT_SSL_TRAFFIC
816 if (q_SSL_get_session(ssl)) {
817 size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
nullptr, 0);
818 size_t client_random_len = q_SSL_get_client_random(ssl,
nullptr, 0);
819 QByteArray masterKey(
int(master_key_len), Qt::Uninitialized);
820 QByteArray clientRandom(
int(client_random_len), Qt::Uninitialized);
822 q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
823 reinterpret_cast<
unsigned char*>(masterKey.data()),
825 q_SSL_get_client_random(ssl,
reinterpret_cast<
unsigned char *>(clientRandom.data()),
826 clientRandom.size());
828 QByteArray debugLineClientRandom(
"CLIENT_RANDOM ");
829 debugLineClientRandom.append(clientRandom.toHex().toUpper());
830 debugLineClientRandom.append(
" ");
831 debugLineClientRandom.append(masterKey.toHex().toUpper());
832 debugLineClientRandom.append(
"\n");
834 QString sslKeyFile = QDir::tempPath() +
"/qt-ssl-keys"_L1;
835 QFile file(sslKeyFile);
836 if (!file.open(QIODevice::Append))
837 qCWarning(lcTlsBackend) <<
"could not open file" << sslKeyFile <<
"for appending";
838 if (!file.write(debugLineClientRandom))
839 qCWarning(lcTlsBackend) <<
"could not write to file" << sslKeyFile;
842 qCWarning(lcTlsBackend,
"could not decrypt SSL traffic");
846 const auto &configuration = q->sslConfiguration();
848 if (!(configuration.testSslOption(QSsl::SslOptionDisableSessionSharing))) {
849 if (!sslContextPointer->cacheSession(ssl)) {
850 sslContextPointer.reset();
853 if (!(configuration.testSslOption(QSsl::SslOptionDisableSessionPersistence))) {
854 if (!sslContextPointer->sessionASN1().isEmpty())
855 QTlsBackend::setSessionAsn1(d, sslContextPointer->sessionASN1());
856 QTlsBackend::setSessionLifetimeHint(d, sslContextPointer->sessionTicketLifeTimeHint());
861#if !defined(OPENSSL_NO_NEXTPROTONEG)
863 QTlsBackend::setAlpnStatus(d, sslContextPointer->npnContext().status);
864 if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
868 QTlsBackend::setNegotiatedProtocol(d, QByteArrayLiteral(
"http/1.1"));
870 const unsigned char *proto =
nullptr;
871 unsigned int proto_len = 0;
874 if (proto_len && mode == QSslSocket::SslClientMode) {
876 QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNegotiated);
884 QTlsBackend::setNegotiatedProtocol(d, QByteArray(
reinterpret_cast<
const char *>(proto), proto_len));
886 QTlsBackend::setNegotiatedProtocol(d,{});
890 if (mode == QSslSocket::SslClientMode) {
893 QTlsBackend::setEphemeralKey(d, QSslKey(key, QSsl::PublicKey));
898 d->setEncrypted(
true);
900 if (d->isAutoStartingHandshake() && d->isPendingClose()) {
901 d->setPendingClose(
false);
902 q->disconnectFromHost();
911 using ScopedBool = QScopedValueRollback<
bool>;
913 if (inSetAndEmitError)
920 auto &writeBuffer = d->tlsWriteBuffer();
921 auto &buffer = d->tlsBuffer();
922 auto *plainSocket = d->plainTcpSocket();
923 Q_ASSERT(plainSocket);
924 bool &emittedBytesWritten = d->tlsEmittedBytesWritten();
928 transmitting =
false;
932 if (q->isEncrypted() && !writeBuffer.isEmpty()) {
933 qint64 totalBytesWritten = 0;
934 int nextDataBlockSize;
935 while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
936 int writtenBytes = q_SSL_write(ssl, writeBuffer.readPointer(), nextDataBlockSize);
937 if (writtenBytes <= 0) {
940 if (error == SSL_ERROR_WANT_WRITE) {
943 }
else if (error == SSL_ERROR_WANT_READ) {
945 transmitting =
false;
949 const ScopedBool bg(inSetAndEmitError,
true);
950 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
951 QSslSocket::tr(
"Unable to write data: %1").arg(
952 QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
956#ifdef QSSLSOCKET_DEBUG
957 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: encrypted" << writtenBytes <<
"bytes";
959 writeBuffer.free(writtenBytes);
960 totalBytesWritten += writtenBytes;
962 if (writtenBytes < nextDataBlockSize) {
969 if (totalBytesWritten > 0) {
971 if (!emittedBytesWritten) {
972 emittedBytesWritten =
true;
973 emit q->bytesWritten(totalBytesWritten);
974 emittedBytesWritten =
false;
976 emit q->channelBytesWritten(0, totalBytesWritten);
981 QVarLengthArray<
char, 4096> data;
983 while (plainSocket->isValid() && (pendingBytes =
q_BIO_pending(writeBio)) > 0
984 && plainSocket->openMode() != QIODevice::NotOpen) {
986 data.resize(pendingBytes);
987 int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes);
990 qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead);
991#ifdef QSSLSOCKET_DEBUG
992 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: wrote" << encryptedBytesRead
993 <<
"encrypted bytes to the socket" << actualWritten <<
"actual.";
995 if (actualWritten < 0) {
997 const ScopedBool bg(inSetAndEmitError,
true);
998 setErrorAndEmit(d, plainSocket->error(), plainSocket->errorString());
1001 transmitting =
true;
1005 if (!q->isEncrypted() || !d->maxReadBufferSize() || buffer.size() < d->maxReadBufferSize())
1006 while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
1008 data.resize(pendingBytes);
1010 int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes);
1012#ifdef QSSLSOCKET_DEBUG
1013 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: read" << encryptedBytesRead <<
"encrypted bytes from the socket";
1016 int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead);
1019 if (writtenToBio > 0) {
1020 plainSocket->skip(writtenToBio);
1023 const ScopedBool bg(inSetAndEmitError,
true);
1024 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1025 QSslSocket::tr(
"Unable to decrypt data: %1")
1026 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1030 transmitting =
true;
1035 if (!q->isEncrypted()) {
1036#ifdef QSSLSOCKET_DEBUG
1037 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: testing encryption";
1040#ifdef QSSLSOCKET_DEBUG
1041 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: encryption established";
1043 d->setEncrypted(
true);
1044 transmitting =
true;
1045 }
else if (plainSocket->state() != QAbstractSocket::ConnectedState) {
1046#ifdef QSSLSOCKET_DEBUG
1047 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: connection lost";
1050 }
else if (d->isPaused()) {
1054#ifdef QSSLSOCKET_DEBUG
1055 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: encryption not done yet";
1070 const int bytesToRead = 4096;
1072 if (q->readChannelCount() == 0) {
1078 readBytes = q_SSL_read(ssl, buffer.reserve(bytesToRead), bytesToRead);
1081 renegotiated =
false;
1082 X509 *x509 = q_SSL_get_peer_certificate(ssl);
1083 const auto peerCertificate =
1084 QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1086 if (peerCertificate != q->peerCertificate()) {
1087 const ScopedBool bg(inSetAndEmitError,
true);
1089 d, QAbstractSocket::RemoteHostClosedError,
1091 "TLS certificate unexpectedly changed during renegotiation!"));
1096 if (readBytes > 0) {
1097#ifdef QSSLSOCKET_DEBUG
1098 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: decrypted" << readBytes <<
"bytes";
1100 buffer.chop(bytesToRead - readBytes);
1102 if (
bool *readyReadEmittedPointer = d->readyReadPointer())
1103 *readyReadEmittedPointer =
true;
1104 emit q->readyRead();
1105 emit q->channelReadyRead(0);
1106 transmitting =
true;
1109 buffer.chop(bytesToRead);
1113 case SSL_ERROR_WANT_READ:
1114 case SSL_ERROR_WANT_WRITE:
1117 case SSL_ERROR_ZERO_RETURN:
1119#ifdef QSSLSOCKET_DEBUG
1120 qCDebug(lcTlsBackend) <<
"TlsCryptographOpenSSL::transmit: remote disconnect";
1124 const ScopedBool bg(inSetAndEmitError,
true);
1125 setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
1126 QSslSocket::tr(
"The TLS/SSL connection has been closed"));
1129 case SSL_ERROR_SYSCALL:
1133 systemOrSslErrorDetected =
true;
1135 const ScopedBool bg(inSetAndEmitError,
true);
1136 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1137 QSslSocket::tr(
"Error while reading: %1")
1138 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1148 const ScopedBool bg(inSetAndEmitError,
true);
1149 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1150 QSslSocket::tr(
"Error while reading: %1")
1151 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1155 }
while (ssl && readBytes > 0);
1156 }
while (ssl && transmitting);
1172 auto *plainSocket = d->plainTcpSocket();
1173 Q_ASSERT(plainSocket);
1174 plainSocket->disconnectFromHost();
1180 auto *plainSocket = d->plainTcpSocket();
1181 Q_ASSERT(plainSocket);
1182 d->setEncrypted(
false);
1184 if (plainSocket->bytesAvailable() <= 0) {
1185 destroySslContext();
1188 const qint64 tmpReadBufferMaxSize = d->maxReadBufferSize();
1190 d->setMaxReadBufferSize(0);
1192 d->setMaxReadBufferSize(tmpReadBufferMaxSize);
1204 return sessionCipher ? QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(sessionCipher) : QSslCipher{};
1210 return QSsl::UnknownProtocol;
1215QT_WARNING_DISABLE_DEPRECATED
1217 return QSsl::TlsV1_0;
1219 return QSsl::TlsV1_1;
1222 return QSsl::TlsV1_2;
1224 return QSsl::TlsV1_3;
1227 return QSsl::UnknownProtocol;
1232 return ocspResponses;
1240 if (sslErrors.isEmpty())
1243 emit q->sslErrors(sslErrors);
1245 const auto vfyMode = q->peerVerifyMode();
1246 const auto mode = d->tlsMode();
1248 bool doVerifyPeer = vfyMode == QSslSocket::VerifyPeer || (vfyMode == QSslSocket::AutoVerifyPeer
1249 && mode == QSslSocket::SslClientMode);
1250 bool doEmitSslError = !d->verifyErrorsHaveBeenIgnored();
1252 if (doVerifyPeer && doEmitSslError) {
1253 if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) {
1254 QSslSocketPrivate::pauseSocketNotifiers(q);
1257 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString());
1258 auto *plainSocket = d->plainTcpSocket();
1259 Q_ASSERT(plainSocket);
1260 plainSocket->disconnectFromHost();
1272 Q_ASSERT(connection);
1277 if (q->sslConfiguration().testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
1283 if (!currentSession) {
1284 qCWarning(lcTlsBackend,
1285 "New session ticket callback, the session is invalid (nullptr)");
1294#ifdef TLS1_3_VERSION
1295 if (!q_SSL_SESSION_is_resumable(currentSession)) {
1296 qCDebug(lcTlsBackend,
"New session ticket, but the session is non-resumable");
1302 if (sessionSize <= 0) {
1303 qCWarning(lcTlsBackend,
"could not store persistent version of SSL session");
1308 QByteArray sessionTicket(sessionSize, 0);
1309 auto data =
reinterpret_cast<
unsigned char *>(sessionTicket.data());
1310 if (!q_i2d_SSL_SESSION(currentSession, &data)) {
1311 qCWarning(lcTlsBackend,
"could not store persistent version of SSL session");
1315 QTlsBackend::setSessionAsn1(d, sessionTicket);
1316 QTlsBackend::setSessionLifetimeHint(d, q_SSL_SESSION_get_ticket_lifetime_hint(currentSession));
1318 emit q->newSessionTicketReceived();
1327 const auto level = tlsAlertLevel(value);
1328 if (level == QSsl::AlertLevel::Fatal && !q->isEncrypted()) {
1330 pendingFatalAlert =
true;
1333 emit q->alertSent(level, tlsAlertType(value), tlsAlertDescription(value));
1341 emit q->alertReceived(tlsAlertLevel(value), tlsAlertType(value), tlsAlertDescription(value));
1351 using ScopedBool = QScopedValueRollback<
bool>;
1355 const ScopedBool bg(inSetAndEmitError,
true);
1359 qCWarning(lcTlsBackend,
"Could not obtain the certificate (that failed to verify)");
1363 const QSslCertificate certificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1365 const QSslError tlsError = QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(errorAndDepth.code, certificate);
1367 errorsReportedFromCallback =
true;
1368 handshakeInterrupted =
true;
1369 emit q->handshakeInterruptedOnError(tlsError);
1377 errorList->append(errorAndDepth);
1381 return !handshakeInterrupted;
1386 Q_ASSERT(pendingFatalAlert);
1389 auto *plainSocket = d->plainTcpSocket();
1391 pendingFatalAlert =
false;
1392 QVarLengthArray<
char, 4096> data;
1393 int pendingBytes = 0;
1394 while (plainSocket->isValid() && (pendingBytes =
q_BIO_pending(writeBio)) > 0
1395 && plainSocket->openMode() != QIODevice::NotOpen) {
1397 data.resize(pendingBytes);
1398 const int bioReadBytes = q_BIO_read(writeBio, data.data(), pendingBytes);
1401 qint64 actualWritten = plainSocket->write(data.constData(), bioReadBytes);
1402 if (actualWritten < 0)
1404 plainSocket->flush();
1415 const auto mode = d->tlsMode();
1416 const auto configuration = q->sslConfiguration();
1417 if (!sslContextPointer)
1418 sslContextPointer = QSslContext::sharedFromConfiguration(mode, configuration, d->isRootsOnDemandAllowed());
1420 if (sslContextPointer->error() != QSslError::NoError) {
1421 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError, sslContextPointer->errorString());
1422 sslContextPointer.reset();
1427 if (!(ssl = sslContextPointer->createSsl())) {
1428 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1429 QSslSocket::tr(
"Error creating SSL session, %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1433 if (configuration.protocol() != QSsl::UnknownProtocol && mode == QSslSocket::SslClientMode) {
1434 const auto verificationPeerName = d->verificationName();
1436 QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
1437 if (tlsHostName.isEmpty())
1438 tlsHostName = d->tlsHostName();
1439 QByteArray ace = QUrl::toAce(tlsHostName);
1442 && !QHostAddress().setAddress(tlsHostName)
1443 && !(configuration.testSslOption(QSsl::SslOptionDisableServerNameIndication))) {
1446 if (ace.endsWith(
'.'))
1448 if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data()))
1449 qCWarning(lcTlsBackend,
"could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
1459 if (!readBio || !writeBio) {
1460 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1461 QSslSocket::tr(
"Error creating SSL session: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1472 if (mode == QSslSocket::SslClientMode)
1479#ifndef OPENSSL_NO_PSK
1481 if (mode == QSslSocket::SslClientMode)
1483 else if (mode == QSslSocket::SslServerMode)
1486#if OPENSSL_VERSION_NUMBER
>= 0x10101006L
1488 if (mode == QSslSocket::SslClientMode
1489 && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
1490 q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback);
1497 if (configuration.ocspStaplingEnabled()) {
1498 if (mode == QSslSocket::SslServerMode) {
1499 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
1500 QSslSocket::tr(
"Server-side QSslSocket does not support OCSP stapling"));
1503 if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) {
1504 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1505 QSslSocket::tr(
"Failed to enable OCSP stapling"));
1510 ocspResponseDer.clear();
1511 const auto backendConfig = configuration.backendConfiguration();
1512 auto responsePos = backendConfig.find(
"Qt-OCSP-response");
1513 if (responsePos != backendConfig.end()) {
1517 const QVariant data(responsePos.value());
1518 if (data.canConvert<QByteArray>())
1519 ocspResponseDer = data.toByteArray();
1522 if (ocspResponseDer.size()) {
1523 if (mode != QSslSocket::SslServerMode) {
1524 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
1525 QSslSocket::tr(
"Client-side sockets do not send OCSP responses"));
1543 const auto errors = QTlsBackendOpenSSL::getErrorsFromOpenSsl();
1550 sslContextPointer.reset();
1561 X509 *x509 = q_SSL_get_peer_certificate(ssl);
1563 const auto peerCertificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1564 QTlsBackend::storePeerCertificate(d, peerCertificate);
1566 auto peerCertificateChain = q->peerCertificateChain();
1567 if (peerCertificateChain.isEmpty()) {
1568 peerCertificateChain = QTlsPrivate::X509CertificateOpenSSL::stackOfX509ToQSslCertificates(q_SSL_get_peer_cert_chain(ssl));
1569 if (!peerCertificate.isNull() && d->tlsMode() == QSslSocket::SslServerMode)
1570 peerCertificateChain.prepend(peerCertificate);
1571 QTlsBackend::storePeerCertificateChain(d, peerCertificateChain);
1757 unsigned max_identity_len,
1758 unsigned char *psk,
unsigned max_psk_len)
1762 QSslPreSharedKeyAuthenticator authenticator;
1764 const int hintLength = hint ?
int(std::strlen(hint)) : 0;
1765 QTlsBackend::setupClientPskAuth(&authenticator, hint, hintLength, max_identity_len, max_psk_len);
1767 emit q->preSharedKeyAuthenticationRequired(&authenticator);
1770 if (authenticator.preSharedKey().isEmpty())
1774 const int identityLength = qMin(authenticator.identity().size(), authenticator.maximumIdentityLength());
1775 std::memcpy(identity, authenticator.identity().constData(), identityLength);
1776 identity[identityLength] = 0;
1778 const int pskLength = qMin(authenticator.preSharedKey().size(), authenticator.maximumPreSharedKeyLength());
1779 std::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
1784 unsigned max_psk_len)
1788 QSslPreSharedKeyAuthenticator authenticator;
1791 QTlsBackend::setupServerPskAuth(&authenticator, identity, q->sslConfiguration().preSharedKeyIdentityHint(),
1793 emit q->preSharedKeyAuthenticationRequired(&authenticator);
1796 if (authenticator.preSharedKey().isEmpty())
1800 const int pskLength = qMin(authenticator.preSharedKey().size(), authenticator.maximumPreSharedKeyLength());
1801 std::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
1812 this->renegotiated = renegotiated;
static void clearErrorQueue()
static int s_indexForSSLExtraData
unsigned pskClientTlsCallback(const char *hint, char *identity, unsigned max_identity_len, unsigned char *psk, unsigned max_psk_len)
void enableHandshakeContinuation() override
void alertMessageReceived(int encoded)
std::shared_ptr< QSslContext > sslContext() const override
int handleNewSessionTicket(SSL *connection)
QList< QOcspResponse > ocsps() const override
int emitErrorFromCallback(X509_STORE_CTX *ctx)
void disconnectFromHost() override
void alertMessageSent(int encoded)
void continueHandshake() override
unsigned pskServerTlsCallback(const char *identity, unsigned char *psk, unsigned max_psk_len)
void startClientEncryption() override
QSsl::SslProtocol sessionProtocol() const override
void init(QSslSocket *qObj, QSslSocketPrivate *dObj) override
void disconnected() override
void storePeerCertificates()
void cancelCAFetch() override
QList< QSslError > tlsErrors() const override
void startServerEncryption() override
void setRenegotiated(bool renegotiated)
void exportKeyingMaterial()
QSslCipher sessionCipher() const override
static QSslErrorEntry errorEntryFromStoreContext(X509_STORE_CTX *ctx)
Namespace containing onternal types that TLS backends implement.
int q_X509Callback(int ok, X509_STORE_CTX *ctx)
static unsigned q_ssl_psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len, unsigned char *psk, unsigned max_psk_len)
void qt_AlertInfoCallback(const SSL *connection, int from, int value)
static unsigned int q_ssl_psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len)
int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx)
void q_SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len)
int q_SSL_in_init(const SSL *s)
const SSL_CIPHER * q_SSL_get_current_cipher(SSL *a)
void * q_X509_STORE_get_ex_data(X509_STORE *r, int idx)
int q_SSL_get_ex_data_X509_STORE_CTX_idx()
X509 * q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
void q_SSL_set_connect_state(SSL *a)
#define q_SSL_get_server_tmp_key(ssl, key)
int q_SSL_get_error(SSL *a, int b)
void * q_X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
void q_SSL_set_accept_state(SSL *a)
int q_SSL_shutdown(SSL *a)
BIO * q_BIO_new(const BIO_METHOD *a)
int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
const char * q_SSL_alert_desc_string_long(int value)
void * q_SSL_get_ex_data(const SSL *ssl, int idx)
SSL_SESSION * q_SSL_get_session(const SSL *ssl)
int q_SSL_version(const SSL *a)
const BIO_METHOD * q_BIO_s_mem()
const char * q_SSL_alert_type_string(int value)
void q_SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, unsigned *len)
void q_SSL_set_bio(SSL *a, BIO *b, BIO *c)
void q_X509_free(X509 *a)
void q_SSL_set_psk_server_callback(SSL *ssl, q_psk_server_callback_t callback)
void q_SSL_set_info_callback(SSL *ssl, void(*cb)(const SSL *ssl, int type, int val))
X509_STORE * q_X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
void q_SSL_set_psk_client_callback(SSL *ssl, q_psk_client_callback_t callback)
int q_SSL_set_ex_data(SSL *ssl, int idx, void *arg)