5#include <QtNetwork/private/qnativesocketengine_p_p.h>
11#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
12#include <QtNetwork/private/qsslcertificate_p.h>
13#include <QtNetwork/private/qssl_p.h>
15#include <QtNetwork/qudpsocket.h>
17#include <QtCore/qmessageauthenticationcode.h>
18#include <QtCore/qcryptographichash.h>
20#include <QtCore/qdebug.h>
27#define QT_DTLS_VERBOSE 0
31#define qDtlsWarning(arg) qWarning(arg)
32#define qDtlsDebug(arg) qDebug(arg)
36#define qDtlsWarning(arg)
37#define qDtlsDebug(arg)
51 qCWarning(lcTlsBackend,
"No BIO (dgram) found in SSL object");
57 qCWarning(lcTlsBackend,
"BIO_get_app_data returned invalid (nullptr) value");
61 const QHostAddress peerAddress(listener->remoteAddress);
62 const quint16 peerPort(listener->remotePort);
64 if (peerAddress.protocol() == QAbstractSocket::IPv6Protocol) {
65 const Q_IPV6ADDR sin6_addr(peerAddress.toIPv6Address());
66 peerData.resize(
int(
sizeof sin6_addr +
sizeof peerPort));
67 char *dst = peerData.data();
68 std::memcpy(dst, &peerPort,
sizeof peerPort);
69 dst +=
sizeof peerPort;
70 std::memcpy(dst, &sin6_addr,
sizeof sin6_addr);
71 }
else if (peerAddress.protocol() == QAbstractSocket::IPv4Protocol) {
72 const quint32 sin_addr(peerAddress.toIPv4Address());
73 peerData.resize(
int(
sizeof sin_addr +
sizeof peerPort));
74 char *dst = peerData.data();
75 std::memcpy(dst, &peerPort,
sizeof peerPort);
76 dst +=
sizeof peerPort;
77 std::memcpy(dst, &sin_addr,
sizeof sin_addr);
90 const int status = q_RAND_bytes(
reinterpret_cast<
unsigned char *>(key.data()),
104 return generator.key;
109 Q_ASSERT(tlsConnection);
110 timeval timeLeft = {};
111 q_DTLSv1_get_timeout(tlsConnection, &timeLeft);
112 return timeLeft.tv_sec * 1000;
127 q_BIO_ADDR_free(bio);
134 q_BIO_meth_free(method);
157 if (!ssl || !dst || !cookieLength) {
158 qCWarning(lcTlsBackend,
159 "Failed to generate cookie - invalid (nullptr) parameter(s)");
165 qCWarning(lcTlsBackend,
"SSL_get_ex_data returned nullptr, cannot generate cookie");
172 if (!dtls->secret.size())
176 if (!peerData.size())
179 QMessageAuthenticationCode hmac(dtls->hashAlgorithm, dtls->secret);
180 hmac.addData(peerData);
181 const QByteArrayView cookie = hmac.resultView();
182 Q_ASSERT(cookie.size() >= 0);
184 *cookieLength = qMin(DTLS1_COOKIE_LENGTH - 1, cookie.size());
185 std::memcpy(dst, cookie.constData(), *cookieLength);
192 if (!ssl || !cookie || !cookieLength) {
193 qCWarning(lcTlsBackend,
"Could not verify cookie, invalid (nullptr or zero) parameters");
197 unsigned char newCookie[DTLS1_COOKIE_LENGTH] = {};
198 unsigned newCookieLength = 0;
202 return newCookieLength == cookieLength
203 && !q_CRYPTO_memcmp(cookie, newCookie, size_t(cookieLength));
212 qCWarning(lcTlsBackend,
"X509_STORE_CTX_get_ex_data returned nullptr, handshake failure");
218 qCWarning(lcTlsBackend,
"SSL_get_ex_data returned nullptr, handshake failure");
233 unsigned max_identity_len,
unsigned char *psk,
unsigned max_psk_len)
245 unsigned max_psk_len)
263 if (!bio || !dst || bytesToRead <= 0) {
264 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
275 if (dtls->dgram.size()) {
276 bytesRead = qMin(dtls->dgram.size(), bytesToRead);
277 std::memcpy(dst, dtls->dgram.constData(), bytesRead);
280 dtls->dgram = dtls->dgram.mid(bytesRead);
293 if (!bio || !src || bytesToWrite <= 0) {
294 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
310 const QByteArray dgram(QByteArray::fromRawData(src, bytesToWrite));
311 qint64 bytesWritten = -1;
312 if (udpSocket->state() == QAbstractSocket::ConnectedState) {
313 bytesWritten = udpSocket->write(dgram);
315 bytesWritten = udpSocket->writeDatagram(dgram, dtls->remoteAddress,
319 if (bytesWritten <= 0)
322 Q_ASSERT(bytesWritten <= std::numeric_limits<
int>::max());
323 return int(bytesWritten);
329 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
333 return q_dgram_write(bio, src,
int(std::strlen(src)));
354 qCDebug(lcTlsBackend,
"invalid 'bio' parameter (nullptr)");
372 case BIO_C_FILE_SEEK:
373 case BIO_C_FILE_TELL:
374 qDtlsWarning(
"Unexpected cmd (BIO_C_FILE_SEEK/BIO_C_FILE_TELL)");
386 case BIO_CTRL_SET_CLOSE:
395 case BIO_CTRL_GET_CLOSE:
398 case BIO_CTRL_PENDING:
402 case BIO_CTRL_WPENDING:
413 case BIO_CTRL_SET_CALLBACK:
420 case BIO_CTRL_GET_CALLBACK:
424 *
static_cast<bio_info_cb **>(ptr) =
nullptr;
428 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_SET/BIO_CTRL_GET)");
435 case BIO_CTRL_DGRAM_CONNECT:
439 case BIO_CTRL_DGRAM_SET_CONNECTED:
440 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_CONNECTED)");
446 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
447 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_RECV_TIMEOUT)");
451 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
452 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_GET_RECV_TIMEOUT)");
456 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
457 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_SEND_TIMEOUT)");
460 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
461 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_GET_SEND_TIMEOUT)");
464 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
467 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
470 case BIO_CTRL_DGRAM_MTU_DISCOVER:
471 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_MTU_DISCOVER)");
476 case BIO_CTRL_DGRAM_QUERY_MTU:
477 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_QUERY_MTU)");
480 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
481 qDtlsWarning(
"Unexpected command *BIO_CTRL_DGRAM_GET_FALLBACK_MTU)");
486 case BIO_CTRL_DGRAM_GET_MTU:
487 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_GET_MTU)");
489 case BIO_CTRL_DGRAM_SET_MTU:
490 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_MTU)");
494 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
495 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_MTU_EXCEEDED)");
497 case BIO_CTRL_DGRAM_GET_PEER:
501 switch (dtls->remoteAddress.protocol()) {
502 case QAbstractSocket::IPv6Protocol:
503 return sizeof(sockaddr_in6);
504 case QAbstractSocket::IPv4Protocol:
505 return sizeof(sockaddr_in);
509 case BIO_CTRL_DGRAM_SET_PEER:
512 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
515 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
519 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
524 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
529 qWarning() <<
"Unexpected cmd (" << cmd <<
")";
560 const QHostAddress &remote, quint16 port,
561 const QByteArray &receivedMessage)
566 if (!tlsContext && !initTls(dtlsBase))
571 setLinkMtu(dtlsBase);
573 dgram = receivedMessage;
574 remoteAddress = remote;
578 BIO *bio = q_SSL_get_rbio(tlsConnection.data());
587 tlsConnection.reset();
591bool DtlsState::initTls(QDtlsBasePrivate *dtlsBase)
596 if (!QSslSocket::supportsSsl())
599 if (!initCtxAndConnection(dtlsBase))
602 if (!initBIO(dtlsBase)) {
603 tlsConnection.reset();
614 return QDtls::tr(
"%1 failed").arg(QLatin1StringView(function));
617bool DtlsState::initCtxAndConnection(QDtlsBasePrivate *dtlsBase)
620 Q_ASSERT(QSslSocket::supportsSsl());
622 if (dtlsBase->mode == QSslSocket::UnencryptedMode) {
623 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
624 QDtls::tr(
"Invalid SslMode, SslServerMode or SslClientMode expected"));
628 if (!QDtlsBasePrivate::isDtlsProtocol(dtlsBase->dtlsConfiguration.protocol())) {
629 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
630 QDtls::tr(
"Invalid protocol version, DTLS protocol expected"));
634 const bool rootsOnDemand = QTlsBackend::rootLoadingOnDemandAllowed(dtlsBase->dtlsConfiguration);
635 TlsContext newContext(QSslContext::sharedFromConfiguration(dtlsBase->mode, dtlsBase->dtlsConfiguration,
638 if (newContext->error() != QSslError::NoError) {
639 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError, newContext->errorString());
644 if (!newConnection.data()) {
645 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
646 msgFunctionFailed(
"SSL_new"));
650 const int set = q_SSL_set_ex_data(newConnection.data(),
654 if (set != 1 && dtlsBase->dtlsConfiguration.peerVerifyMode() != QSslSocket::VerifyNone) {
655 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
656 msgFunctionFailed(
"SSL_set_ex_data"));
660 if (dtlsBase->mode == QSslSocket::SslServerMode) {
661 if (dtlsBase->dtlsConfiguration.dtlsCookieVerificationEnabled())
662 q_SSL_set_options(newConnection.data(), SSL_OP_COOKIE_EXCHANGE);
668 tlsContext.swap(newContext);
669 tlsConnection.swap(newConnection);
674bool DtlsState::initBIO(QDtlsBasePrivate *dtlsBase)
677 Q_ASSERT(tlsContext && tlsConnection);
681 if (!customMethod.data()) {
682 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
683 msgFunctionFailed(
"BIO_meth_new"));
687 BIO_METHOD *biom = customMethod.data();
697 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
698 msgFunctionFailed(
"BIO_new"));
702 q_SSL_set_bio(tlsConnection.data(), bio, bio);
704 bioMethod.swap(customMethod);
709void DtlsState::setLinkMtu(QDtlsBasePrivate *dtlsBase)
713 Q_ASSERT(tlsConnection.data());
715 long mtu = dtlsBase->mtuHint;
719 bool optionFound =
false;
720 if (udpSocket->state() == QAbstractSocket::ConnectedState) {
721 const QVariant val(udpSocket->socketOption(QAbstractSocket::PathMtuSocketOption));
722 if (val.isValid() && val.canConvert<
int>())
723 mtu = val.toInt(&optionFound);
726 if (!optionFound || mtu <= 0) {
733 q_SSL_set_options(tlsConnection.data(), SSL_OP_NO_QUERY_MTU);
735 q_DTLS_set_link_mtu(tlsConnection.data(), mtu);
746 const QHostAddress &address, quint16 port)
749 Q_ASSERT(dgram.size());
750 Q_ASSERT(!address.isNull());
754 verifiedClientHello.clear();
756 if (!dtls.init(
this, socket, address, port, dgram))
759 dtls.secret = secret;
760 dtls.hashAlgorithm = hashAlgorithm;
762 Q_ASSERT(dtls.tlsConnection.data());
763 QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
765 setDtlsError(QDtlsError::TlsInitializationError,
766 QDtlsClientVerifier::tr(
"BIO_ADDR_new failed, ignoring client hello"));
770 const int ret = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
773 setDtlsError(QDtlsError::TlsFatalError, QTlsBackendOpenSSL::getErrorsFromOpenSsl());
778 verifiedClientHello = dgram;
787 return verifiedClientHello;
792 Q_ASSERT(!timer.isActive());
793 timer.start(hintMs > 0 ? hintMs : timeoutMs, Qt::PreciseTimer,
this);
798 if (timeoutMs * 2 < 60000)
812 Q_ASSERT(timer.isActive());
816 Q_ASSERT(dtlsConnection);
817 dtlsConnection->reportTimeout();
821 : QDtlsBasePrivate(side, dtlsutil::fallbackSecret()),
q(
qObject)
825 dtls.dtlsPrivate =
this;
835 remoteAddress = addr;
842 return remoteAddress;
872 return handshakeState;
877 return connectionEncrypted;
883 Q_ASSERT(handshakeState == QDtls::HandshakeNotStarted);
886 connectionEncrypted =
false;
888 if (!dtls.init(
this, socket, remoteAddress, remotePort, dgram))
891 if (mode == QSslSocket::SslServerMode && dtlsConfiguration.dtlsCookieVerificationEnabled()) {
892 dtls.secret = secret;
893 dtls.hashAlgorithm = hashAlgorithm;
898 QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
900 setDtlsError(QDtlsError::TlsInitializationError,
901 QDtls::tr(
"BIO_ADD_new failed, cannot start handshake"));
908 dtls.writeSuppressed =
true;
909 result = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
910 dtls.writeSuppressed =
false;
913 setDtlsError(QDtlsError::TlsFatalError,
914 QDtls::tr(
"Cannot start the handshake, verified client hello expected"));
920 handshakeState = QDtls::HandshakeInProgress;
921 opensslErrors.clear();
924 return continueHandshake(socket, dgram);
931 Q_ASSERT(handshakeState == QDtls::HandshakeInProgress);
935 if (timeoutHandler.data())
936 timeoutHandler->stop();
938 if (!dtls.init(
this, socket, remoteAddress, remotePort, dgram))
941 dtls.x509Errors.clear();
944 if (mode == QSslSocket::SslServerMode)
945 result = q_SSL_accept(dtls.tlsConnection.data());
947 result = q_SSL_connect(dtls.tlsConnection.data());
956 opensslErrors << dtls.x509Errors;
959 const auto code = q_SSL_get_error(dtls.tlsConnection.data(), result);
961 case SSL_ERROR_WANT_READ:
962 case SSL_ERROR_WANT_WRITE:
971 if (!timeoutHandler.data()) {
972 timeoutHandler.reset(
new TimeoutHandler);
973 timeoutHandler->dtlsConnection =
this;
976 timeoutHandler->resetTimeout();
979 timeoutHandler->start();
983 storePeerCertificates();
984 setDtlsError(QDtlsError::TlsFatalError,
985 QTlsBackendOpenSSL::msgErrorsDuringHandshake());
987 handshakeState = QDtls::HandshakeNotStarted;
992 storePeerCertificates();
993 fetchNegotiatedParameters();
995 const bool doVerifyPeer = dtlsConfiguration.peerVerifyMode() == QSslSocket::VerifyPeer
996 || (dtlsConfiguration.peerVerifyMode() == QSslSocket::AutoVerifyPeer
997 && mode == QSslSocket::SslClientMode);
999 if (!doVerifyPeer || verifyPeer() || tlsErrorsWereIgnored()) {
1000 connectionEncrypted =
true;
1001 handshakeState = QDtls::HandshakeComplete;
1005 setDtlsError(QDtlsError::PeerVerificationError, QDtls::tr(
"Peer verification failed"));
1006 handshakeState = QDtls::PeerVerificationFailed;
1015 Q_ASSERT(timeoutHandler.data());
1016 Q_ASSERT(dtls.tlsConnection.data());
1020 dtls.udpSocket = socket;
1022 if (q_DTLSv1_handle_timeout(dtls.tlsConnection.data()) > 0) {
1023 timeoutHandler->doubleTimeout();
1024 timeoutHandler->start();
1026 timeoutHandler->start(dtlsutil::next_timeoutMs(dtls.tlsConnection.data()));
1036 Q_ASSERT(handshakeState == QDtls::PeerVerificationFailed);
1040 if (tlsErrorsWereIgnored()) {
1041 handshakeState = QDtls::HandshakeComplete;
1042 connectionEncrypted =
true;
1044 tlsErrorsToIgnore.clear();
1054 Q_ASSERT(handshakeState == QDtls::PeerVerificationFailed
1055 || handshakeState == QDtls::HandshakeInProgress);
1059 if (handshakeState == QDtls::PeerVerificationFailed) {
1074 if (connectionEncrypted && !connectionWasShutdown) {
1075 dtls.udpSocket = socket;
1076 Q_ASSERT(dtls.tlsConnection.data());
1077 q_SSL_shutdown(dtls.tlsConnection.data());
1090 tlsErrorsToIgnore = errorsToIgnore;
1095 return sessionCipher;
1100 return sessionProtocol;
1104 const QByteArray &dgram)
1107 Q_ASSERT(dtls.tlsConnection.data());
1108 Q_ASSERT(connectionEncrypted);
1112 dtls.udpSocket = socket;
1113 const int written = q_SSL_write(dtls.tlsConnection.data(),
1114 dgram.constData(), dgram.size());
1119 if (!dgram.size() && errorCode == SSL_ERROR_NONE) {
1128 switch (errorCode) {
1129 case SSL_ERROR_WANT_WRITE:
1130 case SSL_ERROR_WANT_READ:
1134 case SSL_ERROR_ZERO_RETURN:
1135 connectionWasShutdown =
true;
1136 setDtlsError(QDtlsError::TlsFatalError, QDtls::tr(
"The DTLS connection has been closed"));
1137 handshakeState = QDtls::HandshakeNotStarted;
1140 case SSL_ERROR_SYSCALL:
1146 QString description(QTlsBackendOpenSSL::getErrorsFromOpenSsl());
1147 if (socket->error() != QAbstractSocket::UnknownSocketError && description.isEmpty()) {
1148 setDtlsError(QDtlsError::UnderlyingSocketError, socket->errorString());
1150 setDtlsError(QDtlsError::TlsFatalError,
1151 QDtls::tr(
"Error while writing: %1").arg(description));
1161 Q_ASSERT(tlsdgram.size());
1163 Q_ASSERT(dtls.tlsConnection.data());
1164 Q_ASSERT(connectionEncrypted);
1166 dtls.dgram = tlsdgram;
1167 dtls.udpSocket = socket;
1172 dgram.resize(tlsdgram.size());
1173 const int read = q_SSL_read(dtls.tlsConnection.data(), dgram.data(),
1183 if (errorCode == SSL_ERROR_NONE) {
1184 const int shutdown = q_SSL_get_shutdown(dtls.tlsConnection.data());
1185 if (shutdown & SSL_RECEIVED_SHUTDOWN)
1186 errorCode = SSL_ERROR_ZERO_RETURN;
1191 switch (errorCode) {
1192 case SSL_ERROR_WANT_READ:
1193 case SSL_ERROR_WANT_WRITE:
1195 case SSL_ERROR_ZERO_RETURN:
1198 connectionWasShutdown =
true;
1199 setDtlsError(QDtlsError::RemoteClosedConnectionError,
1200 QDtls::tr(
"The DTLS connection has been shutdown"));
1202 connectionEncrypted =
false;
1203 handshakeState = QDtls::HandshakeNotStarted;
1205 case SSL_ERROR_SYSCALL:
1210 setDtlsError(QDtlsError::TlsNonFatalError,
1211 QDtls::tr(
"Error while reading: %1")
1212 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1218 unsigned max_identity_len,
1220 unsigned max_psk_len)
1225 QSslPreSharedKeyAuthenticator authenticator;
1228 identityHint.clear();
1229 identityHint.append(hint);
1232 QTlsBackend::setupClientPskAuth(&authenticator, hint ? identityHint.constData() :
nullptr,
1233 hint ?
int(std::strlen(hint)) : 0, max_identity_len, max_psk_len);
1234 pskAuthenticator.swap(authenticator);
1238 emit q->pskRequired(&pskAuthenticator);
1241 if (pskAuthenticator.preSharedKey().isEmpty())
1245 const int identityLength = qMin(pskAuthenticator.identity().size(),
1246 pskAuthenticator.maximumIdentityLength());
1247 std::memcpy(identity, pskAuthenticator.identity().constData(), identityLength);
1248 identity[identityLength] = 0;
1250 const int pskLength = qMin(pskAuthenticator.preSharedKey().size(),
1251 pskAuthenticator.maximumPreSharedKeyLength());
1252 std::memcpy(psk, pskAuthenticator.preSharedKey().constData(), pskLength);
1258 unsigned max_psk_len)
1261 QSslPreSharedKeyAuthenticator authenticator;
1263 QTlsBackend::setupServerPskAuth(&authenticator, identity, dtlsConfiguration.preSharedKeyIdentityHint(),
1265 pskAuthenticator.swap(authenticator);
1269 emit q->pskRequired(&pskAuthenticator);
1272 if (pskAuthenticator.preSharedKey().isEmpty())
1276 const int pskLength = qMin(pskAuthenticator.preSharedKey().size(),
1277 pskAuthenticator.maximumPreSharedKeyLength());
1279 std::memcpy(psk, pskAuthenticator.preSharedKey().constData(), pskLength);
1286 QList<QSslError> errors;
1290 const auto &peerCertificateChain = dtlsConfiguration.peerCertificateChain();
1291 for (
const QSslCertificate &cert : peerCertificateChain) {
1292 if (QSslCertificatePrivate::isBlacklisted(cert))
1293 errors << QSslError(QSslError::CertificateBlacklisted, cert);
1296 const auto peerCertificate = dtlsConfiguration.peerCertificate();
1297 if (peerCertificate.isNull()) {
1298 errors << QSslError(QSslError::NoPeerCertificate);
1299 }
else if (mode == QSslSocket::SslClientMode) {
1308 QString name = peerVfyName;
1309 if (name.isEmpty()) {
1310 Q_ASSERT(dtls.udpSocket);
1311 name = dtls.udpSocket->peerName();
1314 if (!QTlsPrivate::TlsCryptograph::isMatchingHostname(peerCertificate, name))
1315 errors << QSslError(QSslError::HostNameMismatch, peerCertificate);
1319 using CertClass =
QTlsPrivate::X509CertificateOpenSSL;
1320 errors.reserve(errors.size() + opensslErrors.size());
1321 for (
const auto &error : std::as_const(opensslErrors)) {
1322 const auto value = peerCertificateChain.value(error.depth);
1323 errors << CertClass::openSSLErrorToQSslError(error.code, value);
1327 return tlsErrors.isEmpty();
1332 Q_ASSERT(dtls.tlsConnection.data());
1337 X509 *x509 = q_SSL_get_peer_certificate(dtls.tlsConnection.data());
1338 const auto peerCertificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1339 QTlsBackend::storePeerCertificate(dtlsConfiguration, peerCertificate);
1342 auto peerCertificateChain = dtlsConfiguration.peerCertificateChain();
1343 if (peerCertificateChain.isEmpty()) {
1344 auto stack = q_SSL_get_peer_cert_chain(dtls.tlsConnection.data());
1345 peerCertificateChain = QTlsPrivate::X509CertificateOpenSSL::stackOfX509ToQSslCertificates(stack);
1346 if (!peerCertificate.isNull() && mode == QSslSocket::SslServerMode)
1347 peerCertificateChain.prepend(peerCertificate);
1348 QTlsBackend::storePeerCertificateChain(dtlsConfiguration, peerCertificateChain);
1357 for (
const QSslError &error : tlsErrors) {
1358 if (!tlsErrorsToIgnore.contains(error))
1362 return !tlsErrorsToIgnore.empty();
1367 Q_ASSERT(dtls.tlsConnection.data());
1369 if (
const SSL_CIPHER *cipher = q_SSL_get_current_cipher(dtls.tlsConnection.data()))
1370 sessionCipher = QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(cipher);
1377 switch (q_SSL_version(dtls.tlsConnection.data())) {
1379QT_WARNING_DISABLE_DEPRECATED
1381 sessionProtocol = QSsl::DtlsV1_0;
1384 case DTLS1_2_VERSION:
1385 sessionProtocol = QSsl::DtlsV1_2;
1388 qCWarning(lcTlsBackend,
"unknown protocol version");
1389 sessionProtocol = QSsl::UnknownProtocol;
1395 emit q->handshakeTimeout();
1401 connectionEncrypted =
false;
1403 tlsErrorsToIgnore.clear();
1404 QTlsBackend::clearPeerCertificates(dtlsConfiguration);
1405 connectionWasShutdown =
false;
1406 handshakeState = QDtls::HandshakeNotStarted;
1408 sessionProtocol = QSsl::UnknownProtocol;
QByteArray verifiedHello() const override
QDtlsClientVerifierOpenSSL()
bool verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port) override
void abortHandshake(QUdpSocket *socket) override
virtual QDtls::HandshakeState state() const override
QHostAddress peerAddress() const override
QSslSocket::SslMode cryptographMode() const override
void ignoreVerificationErrors(const QList< QSslError > &errorsToIgnore) override
QSslCipher dtlsSessionCipher() const override
bool startHandshake(QUdpSocket *socket, const QByteArray &datagram) override
QDtlsPrivateOpenSSL(QDtls *qObject, QSslSocket::SslMode mode)
bool resumeHandshake(QUdpSocket *socket) override
unsigned pskServerCallback(const char *identity, unsigned char *psk, unsigned max_psk_len)
bool handleTimeout(QUdpSocket *socket) override
virtual void setDtlsMtuHint(quint16 mtu) override
quint16 peerPort() const override
qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &datagram) override
void sendShutdownAlert(QUdpSocket *socket) override
unsigned pskClientCallback(const char *hint, char *identity, unsigned max_identity_len, unsigned char *psk, unsigned max_psk_len)
void setPeer(const QHostAddress &addr, quint16 port, const QString &name) override
QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &tlsdgram) override
QSsl::SslProtocol dtlsSessionProtocol() const override
virtual bool isConnectionEncrypted() const override
bool continueHandshake(QUdpSocket *socket, const QByteArray &datagram) override
QList< QSslError > peerVerificationErrors() const override
void setPeerVerificationName(const QString &name) override
virtual quint16 dtlsMtuHint() const override
QString peerVerificationName() const override
static int s_indexForSSLExtraData
static QSslErrorEntry errorEntryFromStoreContext(X509_STORE_CTX *ctx)
bool init(QDtlsBasePrivate *dtlsBase, QUdpSocket *socket, const QHostAddress &remote, quint16 port, const QByteArray &receivedMessage)
QDtlsPrivateOpenSSL * dtlsPrivate
Namespace containing onternal types that TLS backends implement.
int q_dgram_create(BIO *bio)
int q_dgram_read(BIO *bio, char *dst, int bytesToRead)
int q_dgram_write(BIO *bio, const char *src, int bytesToWrite)
int q_dgram_puts(BIO *bio, const char *src)
long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
int q_dgram_destroy(BIO *bio)
const char *const qdtlsMethodName
unsigned q_PSK_client_callback(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len, unsigned char *psk, unsigned max_psk_len)
unsigned q_PSK_server_callback(SSL *ssl, const char *identity, unsigned char *psk, unsigned max_psk_len)
int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx)
int q_generate_cookie_callback(SSL *ssl, unsigned char *dst, unsigned *cookieLength)
int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie, unsigned cookieLength)
static QString msgFunctionFailed(const char *function)
void delete_connection(SSL *ssl)
void delete_bio_method(BIO_METHOD *method)
QByteArray cookie_for_peer(SSL *ssl)
QByteArray fallbackSecret()
int next_timeoutMs(SSL *tlsConnection)
void delete_BIO_ADDR(BIO_ADDR *bio)
#define qDtlsWarning(arg)
int q_SSL_get_ex_data_X509_STORE_CTX_idx()
unsigned long q_ERR_get_error()
void * q_X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
#define q_BIO_get_app_data(s)
#define q_BIO_set_retry_read(b)
void q_BIO_set_init(BIO *a, int init)
BIO * q_BIO_new(const BIO_METHOD *a)
#define q_BIO_set_retry_write(b)
void * q_SSL_get_ex_data(const SSL *ssl, int idx)
#define q_BIO_set_app_data(s, arg)
BIO * q_SSL_get_rbio(const SSL *s)
void q_X509_free(X509 *a)
#define q_BIO_clear_retry_flags(b)