4#include <QtNetwork/private/qnativesocketengine_p_p.h>
10#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
11#include <QtNetwork/private/qsslcertificate_p.h>
12#include <QtNetwork/private/qssl_p.h>
14#include <QtNetwork/qudpsocket.h>
16#include <QtCore/qmessageauthenticationcode.h>
17#include <QtCore/qcryptographichash.h>
19#include <QtCore/qdebug.h>
26#define QT_DTLS_VERBOSE 0
30#define qDtlsWarning(arg) qWarning(arg)
31#define qDtlsDebug(arg) qDebug(arg)
35#define qDtlsWarning(arg)
36#define qDtlsDebug(arg)
50 qCWarning(lcTlsBackend,
"No BIO (dgram) found in SSL object");
56 qCWarning(lcTlsBackend,
"BIO_get_app_data returned invalid (nullptr) value");
60 const QHostAddress peerAddress(listener->remoteAddress);
61 const quint16 peerPort(listener->remotePort);
63 if (peerAddress.protocol() == QAbstractSocket::IPv6Protocol) {
64 const Q_IPV6ADDR sin6_addr(peerAddress.toIPv6Address());
65 peerData.resize(
int(
sizeof sin6_addr +
sizeof peerPort));
66 char *dst = peerData.data();
67 std::memcpy(dst, &peerPort,
sizeof peerPort);
68 dst +=
sizeof peerPort;
69 std::memcpy(dst, &sin6_addr,
sizeof sin6_addr);
70 }
else if (peerAddress.protocol() == QAbstractSocket::IPv4Protocol) {
71 const quint32 sin_addr(peerAddress.toIPv4Address());
72 peerData.resize(
int(
sizeof sin_addr +
sizeof peerPort));
73 char *dst = peerData.data();
74 std::memcpy(dst, &peerPort,
sizeof peerPort);
75 dst +=
sizeof peerPort;
76 std::memcpy(dst, &sin_addr,
sizeof sin_addr);
89 const int status = q_RAND_bytes(
reinterpret_cast<
unsigned char *>(key.data()),
103 return generator.key;
108 Q_ASSERT(tlsConnection);
109 timeval timeLeft = {};
110 q_DTLSv1_get_timeout(tlsConnection, &timeLeft);
111 return timeLeft.tv_sec * 1000;
126 q_BIO_ADDR_free(bio);
133 q_BIO_meth_free(method);
155 unsigned *cookieLength)
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);
191 unsigned cookieLength)
193 if (!ssl || !cookie || !cookieLength) {
194 qCWarning(lcTlsBackend,
"Could not verify cookie, invalid (nullptr or zero) parameters");
198 unsigned char newCookie[DTLS1_COOKIE_LENGTH] = {};
199 unsigned newCookieLength = 0;
203 return newCookieLength == cookieLength
204 && !q_CRYPTO_memcmp(cookie, newCookie, size_t(cookieLength));
213 qCWarning(lcTlsBackend,
"X509_STORE_CTX_get_ex_data returned nullptr, handshake failure");
219 qCWarning(lcTlsBackend,
"SSL_get_ex_data returned nullptr, handshake failure");
234 unsigned max_identity_len,
unsigned char *psk,
235 unsigned max_psk_len)
247 unsigned max_psk_len)
265 if (!bio || !dst || bytesToRead <= 0) {
266 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
277 if (dtls->dgram.size()) {
278 bytesRead = qMin(dtls->dgram.size(), bytesToRead);
279 std::memcpy(dst, dtls->dgram.constData(), bytesRead);
282 dtls->dgram = dtls->dgram.mid(bytesRead);
295 if (!bio || !src || bytesToWrite <= 0) {
296 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
312 const QByteArray dgram(QByteArray::fromRawData(src, bytesToWrite));
313 qint64 bytesWritten = -1;
314 if (udpSocket->state() == QAbstractSocket::ConnectedState) {
315 bytesWritten = udpSocket->write(dgram);
317 bytesWritten = udpSocket->writeDatagram(dgram, dtls->remoteAddress,
321 if (bytesWritten <= 0)
324 Q_ASSERT(bytesWritten <= std::numeric_limits<
int>::max());
325 return int(bytesWritten);
331 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
335 return q_dgram_write(bio, src,
int(std::strlen(src)));
356 qCDebug(lcTlsBackend,
"invalid 'bio' parameter (nullptr)");
374 case BIO_C_FILE_SEEK:
375 case BIO_C_FILE_TELL:
376 qDtlsWarning(
"Unexpected cmd (BIO_C_FILE_SEEK/BIO_C_FILE_TELL)");
388 case BIO_CTRL_SET_CLOSE:
397 case BIO_CTRL_GET_CLOSE:
400 case BIO_CTRL_PENDING:
404 case BIO_CTRL_WPENDING:
415 case BIO_CTRL_SET_CALLBACK:
422 case BIO_CTRL_GET_CALLBACK:
426 *
static_cast<bio_info_cb **>(ptr) =
nullptr;
430 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_SET/BIO_CTRL_GET)");
437 case BIO_CTRL_DGRAM_CONNECT:
441 case BIO_CTRL_DGRAM_SET_CONNECTED:
442 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_CONNECTED)");
448 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
449 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_RECV_TIMEOUT)");
453 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
454 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_GET_RECV_TIMEOUT)");
458 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
459 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_SEND_TIMEOUT)");
462 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
463 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_GET_SEND_TIMEOUT)");
466 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
469 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
472 case BIO_CTRL_DGRAM_MTU_DISCOVER:
473 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_MTU_DISCOVER)");
478 case BIO_CTRL_DGRAM_QUERY_MTU:
479 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_QUERY_MTU)");
482 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
483 qDtlsWarning(
"Unexpected command *BIO_CTRL_DGRAM_GET_FALLBACK_MTU)");
488 case BIO_CTRL_DGRAM_GET_MTU:
489 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_GET_MTU)");
491 case BIO_CTRL_DGRAM_SET_MTU:
492 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_SET_MTU)");
496 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
497 qDtlsWarning(
"Unexpected cmd (BIO_CTRL_DGRAM_MTU_EXCEEDED)");
499 case BIO_CTRL_DGRAM_GET_PEER:
503 switch (dtls->remoteAddress.protocol()) {
504 case QAbstractSocket::IPv6Protocol:
505 return sizeof(sockaddr_in6);
506 case QAbstractSocket::IPv4Protocol:
507 return sizeof(sockaddr_in);
511 case BIO_CTRL_DGRAM_SET_PEER:
514 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
517 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
521 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
526 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
531 qWarning() <<
"Unexpected cmd (" << cmd <<
")";
562 const QHostAddress &remote, quint16 port,
563 const QByteArray &receivedMessage)
568 if (!tlsContext && !initTls(dtlsBase))
573 setLinkMtu(dtlsBase);
575 dgram = receivedMessage;
576 remoteAddress = remote;
580 BIO *bio = q_SSL_get_rbio(tlsConnection.data());
589 tlsConnection.reset();
593bool DtlsState::initTls(QDtlsBasePrivate *dtlsBase)
598 if (!QSslSocket::supportsSsl())
601 if (!initCtxAndConnection(dtlsBase))
604 if (!initBIO(dtlsBase)) {
605 tlsConnection.reset();
616 return QDtls::tr(
"%1 failed").arg(QLatin1StringView(function));
619bool DtlsState::initCtxAndConnection(QDtlsBasePrivate *dtlsBase)
622 Q_ASSERT(QSslSocket::supportsSsl());
624 if (dtlsBase->mode == QSslSocket::UnencryptedMode) {
625 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
626 QDtls::tr(
"Invalid SslMode, SslServerMode or SslClientMode expected"));
630 if (!QDtlsBasePrivate::isDtlsProtocol(dtlsBase->dtlsConfiguration.protocol())) {
631 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
632 QDtls::tr(
"Invalid protocol version, DTLS protocol expected"));
636 const bool rootsOnDemand = QTlsBackend::rootLoadingOnDemandAllowed(dtlsBase->dtlsConfiguration);
637 TlsContext newContext(QSslContext::sharedFromConfiguration(dtlsBase->mode, dtlsBase->dtlsConfiguration,
640 if (newContext->error() != QSslError::NoError) {
641 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError, newContext->errorString());
646 if (!newConnection.data()) {
647 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
648 msgFunctionFailed(
"SSL_new"));
652 const int set = q_SSL_set_ex_data(newConnection.data(),
656 if (set != 1 && dtlsBase->dtlsConfiguration.peerVerifyMode() != QSslSocket::VerifyNone) {
657 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
658 msgFunctionFailed(
"SSL_set_ex_data"));
662 if (dtlsBase->mode == QSslSocket::SslServerMode) {
663 if (dtlsBase->dtlsConfiguration.dtlsCookieVerificationEnabled())
664 q_SSL_set_options(newConnection.data(), SSL_OP_COOKIE_EXCHANGE);
670 tlsContext.swap(newContext);
671 tlsConnection.swap(newConnection);
676bool DtlsState::initBIO(QDtlsBasePrivate *dtlsBase)
679 Q_ASSERT(tlsContext && tlsConnection);
683 if (!customMethod.data()) {
684 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
685 msgFunctionFailed(
"BIO_meth_new"));
689 BIO_METHOD *biom = customMethod.data();
699 dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
700 msgFunctionFailed(
"BIO_new"));
704 q_SSL_set_bio(tlsConnection.data(), bio, bio);
706 bioMethod.swap(customMethod);
711void DtlsState::setLinkMtu(QDtlsBasePrivate *dtlsBase)
715 Q_ASSERT(tlsConnection.data());
717 long mtu = dtlsBase->mtuHint;
721 bool optionFound =
false;
722 if (udpSocket->state() == QAbstractSocket::ConnectedState) {
723 const QVariant val(udpSocket->socketOption(QAbstractSocket::PathMtuSocketOption));
724 if (val.isValid() && val.canConvert<
int>())
725 mtu = val.toInt(&optionFound);
728 if (!optionFound || mtu <= 0) {
735 q_SSL_set_options(tlsConnection.data(), SSL_OP_NO_QUERY_MTU);
737 q_DTLS_set_link_mtu(tlsConnection.data(), mtu);
748 const QHostAddress &address, quint16 port)
751 Q_ASSERT(dgram.size());
752 Q_ASSERT(!address.isNull());
756 verifiedClientHello.clear();
758 if (!dtls.init(
this, socket, address, port, dgram))
761 dtls.secret = secret;
762 dtls.hashAlgorithm = hashAlgorithm;
764 Q_ASSERT(dtls.tlsConnection.data());
765 QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
767 setDtlsError(QDtlsError::TlsInitializationError,
768 QDtlsClientVerifier::tr(
"BIO_ADDR_new failed, ignoring client hello"));
772 const int ret = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
775 setDtlsError(QDtlsError::TlsFatalError, QTlsBackendOpenSSL::getErrorsFromOpenSsl());
780 verifiedClientHello = dgram;
789 return verifiedClientHello;
794 Q_ASSERT(!timer.isActive());
795 timer.start(hintMs > 0 ? hintMs : timeoutMs, Qt::PreciseTimer,
this);
800 if (timeoutMs * 2 < 60000)
814 Q_ASSERT(timer.isActive());
818 Q_ASSERT(dtlsConnection);
819 dtlsConnection->reportTimeout();
823 : QDtlsBasePrivate(side, dtlsutil::fallbackSecret()),
q(
qObject)
827 dtls.dtlsPrivate =
this;
837 remoteAddress = addr;
844 return remoteAddress;
874 return handshakeState;
879 return connectionEncrypted;
885 Q_ASSERT(handshakeState == QDtls::HandshakeNotStarted);
888 connectionEncrypted =
false;
890 if (!dtls.init(
this, socket, remoteAddress, remotePort, dgram))
893 if (mode == QSslSocket::SslServerMode && dtlsConfiguration.dtlsCookieVerificationEnabled()) {
894 dtls.secret = secret;
895 dtls.hashAlgorithm = hashAlgorithm;
900 QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
902 setDtlsError(QDtlsError::TlsInitializationError,
903 QDtls::tr(
"BIO_ADD_new failed, cannot start handshake"));
910 dtls.writeSuppressed =
true;
911 result = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
912 dtls.writeSuppressed =
false;
915 setDtlsError(QDtlsError::TlsFatalError,
916 QDtls::tr(
"Cannot start the handshake, verified client hello expected"));
922 handshakeState = QDtls::HandshakeInProgress;
923 opensslErrors.clear();
926 return continueHandshake(socket, dgram);
933 Q_ASSERT(handshakeState == QDtls::HandshakeInProgress);
937 if (timeoutHandler.data())
938 timeoutHandler->stop();
940 if (!dtls.init(
this, socket, remoteAddress, remotePort, dgram))
943 dtls.x509Errors.clear();
946 if (mode == QSslSocket::SslServerMode)
947 result = q_SSL_accept(dtls.tlsConnection.data());
949 result = q_SSL_connect(dtls.tlsConnection.data());
958 opensslErrors << dtls.x509Errors;
961 const auto code = q_SSL_get_error(dtls.tlsConnection.data(), result);
963 case SSL_ERROR_WANT_READ:
964 case SSL_ERROR_WANT_WRITE:
973 if (!timeoutHandler.data()) {
974 timeoutHandler.reset(
new TimeoutHandler);
975 timeoutHandler->dtlsConnection =
this;
978 timeoutHandler->resetTimeout();
981 timeoutHandler->start();
985 storePeerCertificates();
986 setDtlsError(QDtlsError::TlsFatalError,
987 QTlsBackendOpenSSL::msgErrorsDuringHandshake());
989 handshakeState = QDtls::HandshakeNotStarted;
994 storePeerCertificates();
995 fetchNegotiatedParameters();
997 const bool doVerifyPeer = dtlsConfiguration.peerVerifyMode() == QSslSocket::VerifyPeer
998 || (dtlsConfiguration.peerVerifyMode() == QSslSocket::AutoVerifyPeer
999 && mode == QSslSocket::SslClientMode);
1001 if (!doVerifyPeer || verifyPeer() || tlsErrorsWereIgnored()) {
1002 connectionEncrypted =
true;
1003 handshakeState = QDtls::HandshakeComplete;
1007 setDtlsError(QDtlsError::PeerVerificationError, QDtls::tr(
"Peer verification failed"));
1008 handshakeState = QDtls::PeerVerificationFailed;
1017 Q_ASSERT(timeoutHandler.data());
1018 Q_ASSERT(dtls.tlsConnection.data());
1022 dtls.udpSocket = socket;
1024 if (q_DTLSv1_handle_timeout(dtls.tlsConnection.data()) > 0) {
1025 timeoutHandler->doubleTimeout();
1026 timeoutHandler->start();
1028 timeoutHandler->start(dtlsutil::next_timeoutMs(dtls.tlsConnection.data()));
1038 Q_ASSERT(handshakeState == QDtls::PeerVerificationFailed);
1042 if (tlsErrorsWereIgnored()) {
1043 handshakeState = QDtls::HandshakeComplete;
1044 connectionEncrypted =
true;
1046 tlsErrorsToIgnore.clear();
1056 Q_ASSERT(handshakeState == QDtls::PeerVerificationFailed
1057 || handshakeState == QDtls::HandshakeInProgress);
1061 if (handshakeState == QDtls::PeerVerificationFailed) {
1076 if (connectionEncrypted && !connectionWasShutdown) {
1077 dtls.udpSocket = socket;
1078 Q_ASSERT(dtls.tlsConnection.data());
1079 q_SSL_shutdown(dtls.tlsConnection.data());
1092 tlsErrorsToIgnore = errorsToIgnore;
1097 return sessionCipher;
1102 return sessionProtocol;
1106 const QByteArray &dgram)
1109 Q_ASSERT(dtls.tlsConnection.data());
1110 Q_ASSERT(connectionEncrypted);
1114 dtls.udpSocket = socket;
1115 const int written = q_SSL_write(dtls.tlsConnection.data(),
1116 dgram.constData(), dgram.size());
1121 if (!dgram.size() && errorCode == SSL_ERROR_NONE) {
1130 switch (errorCode) {
1131 case SSL_ERROR_WANT_WRITE:
1132 case SSL_ERROR_WANT_READ:
1136 case SSL_ERROR_ZERO_RETURN:
1137 connectionWasShutdown =
true;
1138 setDtlsError(QDtlsError::TlsFatalError, QDtls::tr(
"The DTLS connection has been closed"));
1139 handshakeState = QDtls::HandshakeNotStarted;
1142 case SSL_ERROR_SYSCALL:
1148 QString description(QTlsBackendOpenSSL::getErrorsFromOpenSsl());
1149 if (socket->error() != QAbstractSocket::UnknownSocketError && description.isEmpty()) {
1150 setDtlsError(QDtlsError::UnderlyingSocketError, socket->errorString());
1152 setDtlsError(QDtlsError::TlsFatalError,
1153 QDtls::tr(
"Error while writing: %1").arg(description));
1163 Q_ASSERT(tlsdgram.size());
1165 Q_ASSERT(dtls.tlsConnection.data());
1166 Q_ASSERT(connectionEncrypted);
1168 dtls.dgram = tlsdgram;
1169 dtls.udpSocket = socket;
1174 dgram.resize(tlsdgram.size());
1175 const int read = q_SSL_read(dtls.tlsConnection.data(), dgram.data(),
1185 if (errorCode == SSL_ERROR_NONE) {
1186 const int shutdown = q_SSL_get_shutdown(dtls.tlsConnection.data());
1187 if (shutdown & SSL_RECEIVED_SHUTDOWN)
1188 errorCode = SSL_ERROR_ZERO_RETURN;
1193 switch (errorCode) {
1194 case SSL_ERROR_WANT_READ:
1195 case SSL_ERROR_WANT_WRITE:
1197 case SSL_ERROR_ZERO_RETURN:
1200 connectionWasShutdown =
true;
1201 setDtlsError(QDtlsError::RemoteClosedConnectionError,
1202 QDtls::tr(
"The DTLS connection has been shutdown"));
1204 connectionEncrypted =
false;
1205 handshakeState = QDtls::HandshakeNotStarted;
1207 case SSL_ERROR_SYSCALL:
1212 setDtlsError(QDtlsError::TlsNonFatalError,
1213 QDtls::tr(
"Error while reading: %1")
1214 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1220 unsigned max_identity_len,
1222 unsigned max_psk_len)
1227 QSslPreSharedKeyAuthenticator authenticator;
1230 identityHint.clear();
1231 identityHint.append(hint);
1234 QTlsBackend::setupClientPskAuth(&authenticator, hint ? identityHint.constData() :
nullptr,
1235 hint ?
int(std::strlen(hint)) : 0, max_identity_len, max_psk_len);
1236 pskAuthenticator.swap(authenticator);
1240 emit q->pskRequired(&pskAuthenticator);
1243 if (pskAuthenticator.preSharedKey().isEmpty())
1247 const int identityLength = qMin(pskAuthenticator.identity().size(),
1248 pskAuthenticator.maximumIdentityLength());
1249 std::memcpy(identity, pskAuthenticator.identity().constData(), identityLength);
1250 identity[identityLength] = 0;
1252 const int pskLength = qMin(pskAuthenticator.preSharedKey().size(),
1253 pskAuthenticator.maximumPreSharedKeyLength());
1254 std::memcpy(psk, pskAuthenticator.preSharedKey().constData(), pskLength);
1260 unsigned max_psk_len)
1263 QSslPreSharedKeyAuthenticator authenticator;
1265 QTlsBackend::setupServerPskAuth(&authenticator, identity, dtlsConfiguration.preSharedKeyIdentityHint(),
1267 pskAuthenticator.swap(authenticator);
1271 emit q->pskRequired(&pskAuthenticator);
1274 if (pskAuthenticator.preSharedKey().isEmpty())
1278 const int pskLength = qMin(pskAuthenticator.preSharedKey().size(),
1279 pskAuthenticator.maximumPreSharedKeyLength());
1281 std::memcpy(psk, pskAuthenticator.preSharedKey().constData(), pskLength);
1288 QList<QSslError> errors;
1292 const auto &peerCertificateChain = dtlsConfiguration.peerCertificateChain();
1293 for (
const QSslCertificate &cert : peerCertificateChain) {
1294 if (QSslCertificatePrivate::isBlacklisted(cert))
1295 errors << QSslError(QSslError::CertificateBlacklisted, cert);
1298 const auto peerCertificate = dtlsConfiguration.peerCertificate();
1299 if (peerCertificate.isNull()) {
1300 errors << QSslError(QSslError::NoPeerCertificate);
1301 }
else if (mode == QSslSocket::SslClientMode) {
1310 QString name = peerVfyName;
1311 if (name.isEmpty()) {
1312 Q_ASSERT(dtls.udpSocket);
1313 name = dtls.udpSocket->peerName();
1316 if (!QTlsPrivate::TlsCryptograph::isMatchingHostname(peerCertificate, name))
1317 errors << QSslError(QSslError::HostNameMismatch, peerCertificate);
1321 using CertClass =
QTlsPrivate::X509CertificateOpenSSL;
1322 errors.reserve(errors.size() + opensslErrors.size());
1323 for (
const auto &error : std::as_const(opensslErrors)) {
1324 const auto value = peerCertificateChain.value(error.depth);
1325 errors << CertClass::openSSLErrorToQSslError(error.code, value);
1329 return tlsErrors.isEmpty();
1334 Q_ASSERT(dtls.tlsConnection.data());
1339 X509 *x509 = q_SSL_get_peer_certificate(dtls.tlsConnection.data());
1340 const auto peerCertificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1341 QTlsBackend::storePeerCertificate(dtlsConfiguration, peerCertificate);
1344 auto peerCertificateChain = dtlsConfiguration.peerCertificateChain();
1345 if (peerCertificateChain.isEmpty()) {
1346 auto stack = q_SSL_get_peer_cert_chain(dtls.tlsConnection.data());
1347 peerCertificateChain = QTlsPrivate::X509CertificateOpenSSL::stackOfX509ToQSslCertificates(stack);
1348 if (!peerCertificate.isNull() && mode == QSslSocket::SslServerMode)
1349 peerCertificateChain.prepend(peerCertificate);
1350 QTlsBackend::storePeerCertificateChain(dtlsConfiguration, peerCertificateChain);
1359 for (
const QSslError &error : tlsErrors) {
1360 if (!tlsErrorsToIgnore.contains(error))
1364 return !tlsErrorsToIgnore.empty();
1369 Q_ASSERT(dtls.tlsConnection.data());
1371 if (
const SSL_CIPHER *cipher = q_SSL_get_current_cipher(dtls.tlsConnection.data()))
1372 sessionCipher = QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(cipher);
1379 switch (q_SSL_version(dtls.tlsConnection.data())) {
1381QT_WARNING_DISABLE_DEPRECATED
1383 sessionProtocol = QSsl::DtlsV1_0;
1386 case DTLS1_2_VERSION:
1387 sessionProtocol = QSsl::DtlsV1_2;
1390 qCWarning(lcTlsBackend,
"unknown protocol version");
1391 sessionProtocol = QSsl::UnknownProtocol;
1397 emit q->handshakeTimeout();
1403 connectionEncrypted =
false;
1405 tlsErrorsToIgnore.clear();
1406 QTlsBackend::clearPeerCertificates(dtlsConfiguration);
1407 connectionWasShutdown =
false;
1408 handshakeState = QDtls::HandshakeNotStarted;
1410 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 QString getErrorsFromOpenSsl()
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)