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");
61 const quint16 peerPort(listener->remotePort);
65 peerData.
resize(
int(
sizeof sin6_addr +
sizeof peerPort));
67 std::memcpy(
dst, &peerPort,
sizeof peerPort);
68 dst +=
sizeof peerPort;
69 std::memcpy(
dst, &sin6_addr,
sizeof sin6_addr);
72 peerData.
resize(
int(
sizeof sin_addr +
sizeof peerPort));
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()),
109 timeval timeLeft = {};
110 q_DTLSv1_get_timeout(tlsConnection, &timeLeft);
111 return timeLeft.tv_sec * 1000;
126 q_BIO_ADDR_free(bio);
155 unsigned *cookieLength)
157 if (!ssl || !
dst || !cookieLength) {
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())
184 *cookieLength =
qMin(DTLS1_COOKIE_LENGTH - 1, cookie.
size());
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
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)
243 return dtls->dtlsPrivate->pskClientCallback(
hint, identity, max_identity_len, psk, max_psk_len);
247 unsigned max_psk_len)
255 return dtls->dtlsPrivate->pskServerCallback(identity, psk, 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)");
304 if (
dtls->writeSuppressed) {
331 qCWarning(lcTlsBackend,
"invalid input parameter(s)");
356 qDebug(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()) {
505 return sizeof(sockaddr_in6);
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 <<
")";
568 if (!tlsContext && !initTls(dtlsBase))
573 setLinkMtu(dtlsBase);
575 dgram = receivedMessage;
576 remoteAddress = remote;
587void DtlsState::reset()
589 tlsConnection.reset();
601 if (!initCtxAndConnection(dtlsBase))
604 if (!initBIO(dtlsBase)) {
605 tlsConnection.reset();
626 QDtls::tr(
"Invalid SslMode, SslServerMode or SslClientMode expected"));
632 QDtls::tr(
"Invalid protocol version, DTLS protocol expected"));
636 const bool rootsOnDemand = QTlsBackend::rootLoadingOnDemandAllowed(dtlsBase->
dtlsConfiguration);
646 if (!newConnection.data()) {
670 tlsContext.swap(newContext);
671 tlsConnection.swap(newConnection);
679 Q_ASSERT(tlsContext && tlsConnection);
683 if (!customMethod.data()) {
689 BIO_METHOD *biom = customMethod.data();
706 bioMethod.swap(customMethod);
721 bool optionFound =
false;
724 if (
val.isValid() &&
val.canConvert<
int>())
725 mtu =
val.toInt(&optionFound);
728 if (!optionFound || mtu <= 0) {
737 q_DTLS_set_link_mtu(tlsConnection.data(), mtu);
756 verifiedClientHello.
clear();
768 QDtlsClientVerifier::tr(
"BIO_ADDR_new failed, ignoring client hello"));
780 verifiedClientHello = dgram;
789 return verifiedClientHello;
792void QDtlsPrivateOpenSSL::TimeoutHandler::start(
int hintMs)
795 timerId = startTimer(hintMs > 0 ? hintMs : timeoutMs,
Qt::PreciseTimer);
798void QDtlsPrivateOpenSSL::TimeoutHandler::doubleTimeout()
800 if (timeoutMs * 2 < 60000)
806void QDtlsPrivateOpenSSL::TimeoutHandler::stop()
823 dtlsConnection->reportTimeout();
878 return handshakeState;
883 return connectionEncrypted;
892 connectionEncrypted =
false;
907 QDtls::tr(
"BIO_ADD_new failed, cannot start handshake"));
920 QDtls::tr(
"Cannot start the handshake, verified client hello expected"));
927 opensslErrors.
clear();
941 if (timeoutHandler.
data())
942 timeoutHandler->stop();
967 case SSL_ERROR_WANT_READ:
968 case SSL_ERROR_WANT_WRITE:
977 if (!timeoutHandler.
data()) {
978 timeoutHandler.
reset(
new TimeoutHandler);
979 timeoutHandler->dtlsConnection =
this;
982 timeoutHandler->resetTimeout();
985 timeoutHandler->start();
989 storePeerCertificates();
998 storePeerCertificates();
999 fetchNegotiatedParameters();
1005 if (!doVerifyPeer || verifyPeer() || tlsErrorsWereIgnored()) {
1006 connectionEncrypted =
true;
1029 timeoutHandler->doubleTimeout();
1030 timeoutHandler->start();
1046 if (tlsErrorsWereIgnored()) {
1048 connectionEncrypted =
true;
1050 tlsErrorsToIgnore.
clear();
1080 if (connectionEncrypted && !connectionWasShutdown) {
1096 tlsErrorsToIgnore = errorsToIgnore;
1135 case SSL_ERROR_WANT_WRITE:
1136 case SSL_ERROR_WANT_READ:
1140 case SSL_ERROR_ZERO_RETURN:
1141 connectionWasShutdown =
true;
1146 case SSL_ERROR_SYSCALL:
1157 QDtls::tr(
"Error while writing: %1").
arg(description));
1172 dtls.
dgram = tlsdgram;
1191 if (shutdown & SSL_RECEIVED_SHUTDOWN)
1198 case SSL_ERROR_WANT_READ:
1199 case SSL_ERROR_WANT_WRITE:
1201 case SSL_ERROR_ZERO_RETURN:
1204 connectionWasShutdown =
true;
1206 QDtls::tr(
"The DTLS connection has been shutdown"));
1208 connectionEncrypted =
false;
1211 case SSL_ERROR_SYSCALL:
1217 QDtls::tr(
"Error while reading: %1")
1224 unsigned max_identity_len,
1226 unsigned max_psk_len)
1234 identityHint.
clear();
1239 hint ? int(std::strlen(
hint)) : 0, max_identity_len, max_psk_len);
1240 pskAuthenticator.
swap(authenticator);
1244 emit q->pskRequired(&pskAuthenticator);
1254 identity[identityLength] = 0;
1264 unsigned max_psk_len)
1271 pskAuthenticator.
swap(authenticator);
1275 emit q->pskRequired(&pskAuthenticator);
1290bool QDtlsPrivateOpenSSL::verifyPeer()
1303 if (peerCertificate.isNull()) {
1315 if (
name.isEmpty()) {
1320 if (!QTlsPrivate::TlsCryptograph::isMatchingHostname(peerCertificate,
name))
1327 for (
const auto &
error :
std::as_const(opensslErrors)) {
1328 const auto value = peerCertificateChain.value(
error.depth);
1329 errors << CertClass::openSSLErrorToQSslError(
error.code,
value);
1336void QDtlsPrivateOpenSSL::storePeerCertificates()
1349 if (peerCertificateChain.isEmpty()) {
1353 peerCertificateChain.prepend(peerCertificate);
1354 QTlsBackend::storePeerCertificateChain(
dtlsConfiguration, peerCertificateChain);
1358bool QDtlsPrivateOpenSSL::tlsErrorsWereIgnored()
const
1368 return !tlsErrorsToIgnore.
empty();
1371void QDtlsPrivateOpenSSL::fetchNegotiatedParameters()
1390 case DTLS1_2_VERSION:
1394 qCWarning(lcTlsBackend,
"unknown protocol version");
1399void QDtlsPrivateOpenSSL::reportTimeout()
1401 emit q->handshakeTimeout();
1404void QDtlsPrivateOpenSSL::resetDtls()
1407 connectionEncrypted =
false;
1409 tlsErrorsToIgnore.
clear();
1411 connectionWasShutdown =
false;
static constexpr auto IPv4Protocol
QString peerName() const
Returns the name of the peer as specified by connectToHost(), or an empty QString if connectToHost() ...
SocketState state() const
Returns the state of the socket.
static constexpr auto IPv6Protocol
SocketError error() const
Returns the type of error that last occurred.
constexpr qsizetype size() const noexcept
constexpr const_pointer constData() const noexcept
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
void clear()
Clears the contents of the byte array and makes it null.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
QSsl::SslProtocol sessionProtocol
QHostAddress remoteAddress
QCryptographicHash::Algorithm hashAlgorithm
QDtlsError error() const override
void clearDtlsError() override
void setDtlsError(QDtlsError code, const QString &description) override
QSslConfiguration dtlsConfiguration
static bool isDtlsProtocol(QSsl::SslProtocol protocol)
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
This class provides encryption for UDP sockets.
The QHostAddress class provides an IP address.
quint32 toIPv4Address(bool *ok=nullptr) const
Returns the IPv4 address as a number.
Q_IPV6ADDR toIPv6Address() const
Returns the IPv6 address as a Q_IPV6ADDR structure.
NetworkLayerProtocol protocol() const
Returns the network layer protocol of the host address.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
QString errorString() const
Returns a human-readable description of the last device error that occurred.
qsizetype size() const noexcept
bool isEmpty() const noexcept
bool empty() const noexcept
void reserve(qsizetype size)
QByteArrayView resultView() const noexcept
void addData(const char *data, qsizetype length)
This is an overloaded member function, provided for convenience. It differs from the above function o...
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
static Q_NETWORK_PRIVATE_EXPORT bool isBlacklisted(const QSslCertificate &certificate)
The QSslCertificate class provides a convenient API for an X509 certificate.
The QSslCipher class represents an SSL cryptographic cipher.
QSslSocket::PeerVerifyMode peerVerifyMode() const
Returns the verify mode.
QSsl::SslProtocol protocol() const
Returns the protocol setting for this SSL configuration.
QByteArray preSharedKeyIdentityHint() const
QList< QSslCertificate > peerCertificateChain() const
Returns the peer's chain of digital certificates, starting with the peer's immediate certificate and ...
QSslCertificate peerCertificate() const
Returns the peer's digital certificate (i.e., the immediate certificate of the host you are connected...
static std::shared_ptr< QSslContext > sharedFromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
The QSslError class provides an SSL error.
The QSslPreSharedKeyAuthenticator class provides authentication data for pre shared keys (PSK) cipher...
void swap(QSslPreSharedKeyAuthenticator &other) noexcept
Swaps the QSslPreSharedKeyAuthenticator object authenticator with this object.
Q_NETWORK_EXPORT QByteArray preSharedKey() const
Returns the pre shared key.
Q_NETWORK_EXPORT int maximumIdentityLength() const
Returns the maximum length, in bytes, of the PSK client identity.
Q_NETWORK_EXPORT QByteArray identity() const
Returns the PSK client identity.
Q_NETWORK_EXPORT int maximumPreSharedKeyLength() const
Returns the maximum length, in bytes, of the pre shared key.
The QSslSocket class provides an SSL encrypted socket for both clients and servers.
SslMode
Describes the connection modes available for QSslSocket.
static bool supportsSsl()
Returns true if this platform supports SSL; otherwise, returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QSslCipher qt_OpenSSL_cipher_to_QSslCipher(const SSL_CIPHER *cipher)
static QString msgErrorsDuringHandshake()
static int s_indexForSSLExtraData
static QString getErrorsFromOpenSsl()
static void setupClientPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *hint, int hintLength, unsigned maxIdentityLen, unsigned maxPskLen)
static void setupServerPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *identity, const QByteArray &identityHint, unsigned maxPskLen)
static QSslErrorEntry errorEntryFromStoreContext(X509_STORE_CTX *ctx)
static QSslCertificate certificateFromX509(X509 *x)
static QList< QSslCertificate > stackOfX509ToQSslCertificates(STACK_OF(X509) *x509)
qint64 writeDatagram(const QNetworkDatagram &datagram)
bool init(QDtlsBasePrivate *dtlsBase, QUdpSocket *socket, const QHostAddress &remote, quint16 port, const QByteArray &receivedMessage)
QCryptographicHash::Algorithm hashAlgorithm
QDtlsPrivateOpenSSL * dtlsPrivate
TlsConnection tlsConnection
QList< QSslErrorEntry > x509Errors
SslProtocol
Describes the protocol of the cipher.
Combined button and popup list for selecting options.
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)
const char *const qdtlsMethodName
long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
int q_dgram_destroy(BIO *bio)
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 QT_WARNING_DISABLE_DEPRECATED
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
@ RemoteClosedConnectionError
#define qDtlsWarning(arg)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCWarning(category,...)
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMin(const T &a, const T &b)
GLenum GLsizei GLuint GLint * bytesWritten
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
const SSL_CIPHER * q_SSL_get_current_cipher(SSL *a)
int q_SSL_get_ex_data_X509_STORE_CTX_idx()
unsigned long q_ERR_get_error()
int q_SSL_get_error(SSL *a, int b)
X509 * q_SSL_get_peer_certificate(SSL *a)
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)
unsigned long q_SSL_set_options(SSL *s, unsigned long op)
int q_SSL_get_shutdown(const SSL *ssl)
int q_SSL_shutdown(SSL *a)
void q_BIO_set_init(BIO *a, int init)
BIO * q_BIO_new(const BIO_METHOD *a)
int q_SSL_write(SSL *a, const void *b, int c)
#define q_BIO_set_retry_write(b)
void * q_SSL_get_ex_data(const SSL *ssl, int idx)
int q_SSL_read(SSL *a, void *b, int c)
int q_CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
#define q_BIO_set_app_data(s, arg)
BIO * q_SSL_get_rbio(const SSL *s)
int q_SSL_version(const SSL *a)
int q_RAND_bytes(unsigned char *b, int n)
void q_SSL_set_bio(SSL *a, BIO *b, BIO *c)
void q_X509_free(X509 *a)
int q_SSL_connect(SSL *a)
void q_SSL_set_psk_server_callback(SSL *ssl, q_psk_server_callback_t callback)
#define q_BIO_clear_retry_flags(b)
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)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
ReturnedValue read(const char *data)
QFuture< QSet< QChar > > set
[10]
QRandomGenerator generator(sseq)
QList< QSslCertificate > cert
[0]
bool contains(const AT &t) const noexcept