Convert QDtls classes to the new plugin-based design
Essentially, the same code re-shuffled and placed behind the new interfaces. Fixes: QTBUG-91174 Task-number: QTBUG-65922 Change-Id: I8f14697f10713f9738c5c7805aed0150c084850c Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit 6c835796c8ea2590008900ffb5f4bf0d902ee73d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
fe9d7bf759
commit
7c1aa0c48c
@ -357,6 +357,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_securetransport AND QT_FE
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qdtls.cpp ssl/qdtls.h ssl/qdtls_p.h
|
||||
ssl/qdtls_base.cpp ssl/qdtls_base_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl
|
||||
|
@ -38,8 +38,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslconfiguration.h"
|
||||
#include "qdtls_openssl_p.h"
|
||||
#include "qsslsocket_p.h"
|
||||
#include "qudpsocket.h"
|
||||
#include "qsslcipher.h"
|
||||
#include "qdtls_p.h"
|
||||
#include "qssl_p.h"
|
||||
#include "qdtls.h"
|
||||
@ -337,72 +338,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QSslConfiguration QDtlsBasePrivate::configuration() const
|
||||
{
|
||||
auto copyPrivate = new QSslConfigurationPrivate(dtlsConfiguration);
|
||||
copyPrivate->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up
|
||||
QSslConfiguration copy(copyPrivate);
|
||||
copyPrivate->sessionCipher = sessionCipher;
|
||||
copyPrivate->sessionProtocol = sessionProtocol;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void QDtlsBasePrivate::setConfiguration(const QSslConfiguration &configuration)
|
||||
{
|
||||
dtlsConfiguration.localCertificateChain = configuration.localCertificateChain();
|
||||
dtlsConfiguration.privateKey = configuration.privateKey();
|
||||
dtlsConfiguration.ciphers = configuration.ciphers();
|
||||
dtlsConfiguration.ellipticCurves = configuration.ellipticCurves();
|
||||
dtlsConfiguration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
|
||||
dtlsConfiguration.dhParams = configuration.diffieHellmanParameters();
|
||||
dtlsConfiguration.caCertificates = configuration.caCertificates();
|
||||
dtlsConfiguration.peerVerifyDepth = configuration.peerVerifyDepth();
|
||||
dtlsConfiguration.peerVerifyMode = configuration.peerVerifyMode();
|
||||
dtlsConfiguration.protocol = configuration.protocol();
|
||||
dtlsConfiguration.sslOptions = configuration.d->sslOptions;
|
||||
dtlsConfiguration.sslSession = configuration.sessionTicket();
|
||||
dtlsConfiguration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
|
||||
dtlsConfiguration.nextAllowedProtocols = configuration.allowedNextProtocols();
|
||||
dtlsConfiguration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
|
||||
dtlsConfiguration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
|
||||
dtlsConfiguration.dtlsCookieEnabled = configuration.dtlsCookieVerificationEnabled();
|
||||
dtlsConfiguration.allowRootCertOnDemandLoading = configuration.d->allowRootCertOnDemandLoading;
|
||||
dtlsConfiguration.backendConfig = configuration.backendConfiguration();
|
||||
|
||||
clearDtlsError();
|
||||
}
|
||||
|
||||
bool QDtlsBasePrivate::setCookieGeneratorParameters(QCryptographicHash::Algorithm alg,
|
||||
const QByteArray &key)
|
||||
{
|
||||
if (!key.size()) {
|
||||
setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
QDtls::tr("Invalid (empty) secret"));
|
||||
return false;
|
||||
}
|
||||
|
||||
clearDtlsError();
|
||||
|
||||
hashAlgorithm = alg;
|
||||
secret = key;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDtlsBasePrivate::isDtlsProtocol(QSsl::SslProtocol protocol)
|
||||
{
|
||||
switch (protocol) {
|
||||
case QSsl::DtlsV1_0:
|
||||
case QSsl::DtlsV1_0OrLater:
|
||||
case QSsl::DtlsV1_2:
|
||||
case QSsl::DtlsV1_2OrLater:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static QString msgUnsupportedMulticastAddress()
|
||||
{
|
||||
return QDtls::tr("Multicast and broadcast addresses are not supported");
|
||||
@ -434,22 +369,37 @@ QDtlsClientVerifier::GeneratorParameters::GeneratorParameters(QCryptographicHash
|
||||
{
|
||||
}
|
||||
|
||||
QDtlsClientVerifierPrivate::QDtlsClientVerifierPrivate()
|
||||
{
|
||||
const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse();
|
||||
if (!tlsBackend) {
|
||||
qCWarning(lcSsl, "No TLS backend is available, cannot verify DTLS client");
|
||||
return;
|
||||
}
|
||||
backend.reset(tlsBackend->createDtlsCookieVerifier());
|
||||
if (!backend.get())
|
||||
qCWarning(lcSsl) << "The backend" << tlsBackend->backendName() << "does not support DTLS cookies";
|
||||
}
|
||||
|
||||
QDtlsClientVerifierPrivate::~QDtlsClientVerifierPrivate() = default;
|
||||
|
||||
/*!
|
||||
Constructs a QDtlsClientVerifier object, \a parent is passed to QObject's
|
||||
constructor.
|
||||
*/
|
||||
QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent)
|
||||
: QObject(*new QDtlsClientVerifierOpenSSL, parent)
|
||||
: QObject(*new QDtlsClientVerifierPrivate, parent)
|
||||
{
|
||||
Q_D(QDtlsClientVerifier);
|
||||
|
||||
d->mode = QSslSocket::SslServerMode;
|
||||
// The default configuration suffices: verifier never does a full
|
||||
// handshake and upon verifying a cookie in a client hello message,
|
||||
// it reports success.
|
||||
auto conf = QSslConfiguration::defaultDtlsConfiguration();
|
||||
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||
d->setConfiguration(conf);
|
||||
if (auto *backend = d->backend.get()) {
|
||||
// The default configuration suffices: verifier never does a full
|
||||
// handshake and upon verifying a cookie in a client hello message,
|
||||
// it reports success.
|
||||
auto conf = QSslConfiguration::defaultDtlsConfiguration();
|
||||
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||
backend->setConfiguration(conf);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -473,8 +423,10 @@ QDtlsClientVerifier::~QDtlsClientVerifier()
|
||||
bool QDtlsClientVerifier::setCookieGeneratorParameters(const GeneratorParameters ¶ms)
|
||||
{
|
||||
Q_D(QDtlsClientVerifier);
|
||||
if (auto *backend = d->backend.get())
|
||||
return backend->setCookieGeneratorParameters(params);
|
||||
|
||||
return d->setCookieGeneratorParameters(params.hash, params.secret);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -491,7 +443,10 @@ QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorPar
|
||||
{
|
||||
Q_D(const QDtlsClientVerifier);
|
||||
|
||||
return {d->hashAlgorithm, d->secret};
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->cookieGeneratorParameters();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -514,19 +469,23 @@ bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgr
|
||||
{
|
||||
Q_D(QDtlsClientVerifier);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket || address.isNull() || !dgram.size()) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("A valid UDP socket, non-empty datagram, valid address/port were expected"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("A valid UDP socket, non-empty datagram, and valid address/port were expected"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address.isBroadcast() || address.isMulticast()) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
msgUnsupportedMulticastAddress());
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
msgUnsupportedMulticastAddress());
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->verifyClient(socket, dgram, address, port);
|
||||
return backend->verifyClient(socket, dgram, address, port);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -539,7 +498,10 @@ QByteArray QDtlsClientVerifier::verifiedHello() const
|
||||
{
|
||||
Q_D(const QDtlsClientVerifier);
|
||||
|
||||
return d->verifiedClientHello;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->verifiedHello();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -551,7 +513,10 @@ QDtlsError QDtlsClientVerifier::dtlsError() const
|
||||
{
|
||||
Q_D(const QDtlsClientVerifier);
|
||||
|
||||
return d->errorCode;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->error();
|
||||
|
||||
return QDtlsError::TlsInitializationError;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -561,11 +526,17 @@ QDtlsError QDtlsClientVerifier::dtlsError() const
|
||||
*/
|
||||
QString QDtlsClientVerifier::dtlsErrorString() const
|
||||
{
|
||||
Q_D(const QDtlsBase);
|
||||
Q_D(const QDtlsClientVerifier);
|
||||
|
||||
return d->errorDescription;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->errorString();
|
||||
|
||||
return QStringLiteral("No TLS backend is available, no client verification");
|
||||
}
|
||||
|
||||
QDtlsPrivate::QDtlsPrivate() = default;
|
||||
QDtlsPrivate::~QDtlsPrivate() = default;
|
||||
|
||||
/*!
|
||||
Creates a QDtls object, \a parent is passed to the QObject constructor.
|
||||
\a mode is QSslSocket::SslServerMode for a server-side DTLS connection or
|
||||
@ -574,11 +545,19 @@ QString QDtlsClientVerifier::dtlsErrorString() const
|
||||
\sa sslMode(), QSslSocket::SslMode
|
||||
*/
|
||||
QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent)
|
||||
: QObject(*new QDtlsPrivateOpenSSL, parent)
|
||||
: QObject(*new QDtlsPrivate, parent)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
d->mode = mode;
|
||||
const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse();
|
||||
if (!tlsBackend) {
|
||||
qCWarning(lcSsl, "No TLS backend found, QDtls is unsupported");
|
||||
return;
|
||||
}
|
||||
d->backend.reset(tlsBackend->createDtlsCryptograph(this, mode));
|
||||
if (!d->backend.get()) {
|
||||
qCWarning(lcSsl) << "TLS backend" << tlsBackend->backendName()
|
||||
<< "does not support the protocol DTLS";
|
||||
}
|
||||
setDtlsConfiguration(QSslConfiguration::defaultDtlsConfiguration());
|
||||
}
|
||||
|
||||
@ -601,29 +580,30 @@ bool QDtls::setPeer(const QHostAddress &address, quint16 port,
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
if (d->handshakeState != HandshakeNotStarted) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot set peer after handshake started"));
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (backend->state() != HandshakeNotStarted) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot set peer after handshake started"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address.isNull()) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("Invalid address"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("Invalid address"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (address.isBroadcast() || address.isMulticast()) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
msgUnsupportedMulticastAddress());
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
msgUnsupportedMulticastAddress());
|
||||
return false;
|
||||
}
|
||||
|
||||
d->clearDtlsError();
|
||||
|
||||
d->remoteAddress = address;
|
||||
d->remotePort = port;
|
||||
d->peerVerificationName = verificationName;
|
||||
backend->clearDtlsError();
|
||||
backend->setPeer(address, port, verificationName);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -640,14 +620,18 @@ bool QDtls::setPeerVerificationName(const QString &name)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
if (d->handshakeState != HandshakeNotStarted) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (backend->state() != HandshakeNotStarted) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot set verification name after handshake started"));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->clearDtlsError();
|
||||
d->peerVerificationName = name;
|
||||
backend->clearDtlsError();
|
||||
backend->setPeerVerificationName(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -661,7 +645,10 @@ QHostAddress QDtls::peerAddress() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->remoteAddress;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->peerAddress();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -671,9 +658,12 @@ QHostAddress QDtls::peerAddress() const
|
||||
*/
|
||||
quint16 QDtls::peerPort() const
|
||||
{
|
||||
Q_D(const QDtlsBase);
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->remotePort;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->peerPort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -686,7 +676,10 @@ QString QDtls::peerVerificationName() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->peerVerificationName;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->peerVerificationName();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -699,7 +692,10 @@ QSslSocket::SslMode QDtls::sslMode() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->mode;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->cryptographMode();
|
||||
|
||||
return QSslSocket::UnencryptedMode;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -712,7 +708,8 @@ void QDtls::setMtuHint(quint16 mtuHint)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
d->mtuHint = mtuHint;
|
||||
if (auto *backend = d->backend.get())
|
||||
backend->setDtlsMtuHint(mtuHint);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -724,7 +721,10 @@ quint16 QDtls::mtuHint() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->mtuHint;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->dtlsMtuHint();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -741,7 +741,10 @@ bool QDtls::setCookieGeneratorParameters(const GeneratorParameters ¶ms)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
return d->setCookieGeneratorParameters(params.hash, params.secret);
|
||||
if (auto *backend = d->backend.get())
|
||||
backend->setCookieGeneratorParameters(params);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -759,7 +762,10 @@ QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return {d->hashAlgorithm, d->secret};
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->cookieGeneratorParameters();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -774,13 +780,17 @@ bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
if (d->handshakeState != HandshakeNotStarted) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot set configuration after handshake started"));
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (backend->state() != HandshakeNotStarted) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot set configuration after handshake started"));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->setConfiguration(configuration);
|
||||
backend->setConfiguration(configuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -793,8 +803,10 @@ bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)
|
||||
QSslConfiguration QDtls::dtlsConfiguration() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->configuration();
|
||||
|
||||
return d->configuration();
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -806,7 +818,10 @@ QDtls::HandshakeState QDtls::handshakeState()const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->handshakeState;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->state();
|
||||
|
||||
return QDtls::HandshakeNotStarted;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -832,13 +847,17 @@ bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
if (d->handshakeState == HandshakeNotStarted)
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (backend->state() == HandshakeNotStarted)
|
||||
return startHandshake(socket, dgram);
|
||||
else if (d->handshakeState == HandshakeInProgress)
|
||||
else if (backend->state() == HandshakeInProgress)
|
||||
return continueHandshake(socket, dgram);
|
||||
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot start/continue handshake, invalid handshake state"));
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot start/continue handshake, invalid handshake state"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -849,30 +868,34 @@ bool QDtls::startHandshake(QUdpSocket *socket, const QByteArray &datagram)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->remoteAddress.isNull()) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("To start a handshake you must set peer's address and port first"));
|
||||
if (backend->peerAddress().isNull()) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("To start a handshake you must set peer's address and port first"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sslMode() == QSslSocket::SslServerMode && !datagram.size()) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("To start a handshake, DTLS server requires non-empty datagram (client hello)"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("To start a handshake, DTLS server requires non-empty datagram (client hello)"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->handshakeState != HandshakeNotStarted) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot start handshake, already done/in progress"));
|
||||
if (backend->state() != HandshakeNotStarted) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot start handshake, already done/in progress"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->startHandshake(socket, datagram);
|
||||
return backend->startHandshake(socket, datagram);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -887,12 +910,16 @@ bool QDtls::handleTimeout(QUdpSocket *socket)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->handleTimeout(socket);
|
||||
return backend->handleTimeout(socket);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -902,19 +929,23 @@ bool QDtls::continueHandshake(QUdpSocket *socket, const QByteArray &datagram)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket || !datagram.size()) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("A valid QUdpSocket and non-empty datagram are needed to continue the handshake"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("A valid QUdpSocket and non-empty datagram are needed to continue the handshake"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->handshakeState != HandshakeInProgress) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot continue handshake, not in InProgress state"));
|
||||
if (backend->state() != HandshakeInProgress) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot continue handshake, not in InProgress state"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->continueHandshake(socket, datagram);
|
||||
return backend->continueHandshake(socket, datagram);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -929,18 +960,22 @@ bool QDtls::resumeHandshake(QUdpSocket *socket)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->handshakeState != PeerVerificationFailed) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot resume, not in VerificationError state"));
|
||||
if (backend->state() != PeerVerificationFailed) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot resume, not in VerificationError state"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->resumeHandshake(socket);
|
||||
return backend->resumeHandshake(socket);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -953,18 +988,22 @@ bool QDtls::abortHandshake(QUdpSocket *socket)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->handshakeState != PeerVerificationFailed && d->handshakeState != HandshakeInProgress) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("No handshake in progress, nothing to abort"));
|
||||
if (backend->state() != PeerVerificationFailed && backend->state() != HandshakeInProgress) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("No handshake in progress, nothing to abort"));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->abortHandshake(socket);
|
||||
backend->abortHandshake(socket);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -979,19 +1018,23 @@ bool QDtls::shutdown(QUdpSocket *socket)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return false;
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
tr("Invalid (nullptr) socket"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->connectionEncrypted) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot send shutdown alert, not encrypted"));
|
||||
if (!backend->isConnectionEncrypted()) {
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot send shutdown alert, not encrypted"));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->sendShutdownAlert(socket);
|
||||
backend->sendShutdownAlert(socket);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1004,7 +1047,11 @@ bool QDtls::isConnectionEncrypted() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->connectionEncrypted;
|
||||
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->isConnectionEncrypted();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1023,7 +1070,10 @@ QSslCipher QDtls::sessionCipher() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->sessionCipher;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->dtlsSessionCipher();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1040,7 +1090,10 @@ QSsl::SslProtocol QDtls::sessionProtocol() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->sessionProtocol;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->dtlsSessionProtocol();
|
||||
|
||||
return QSsl::UnknownProtocol;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1055,18 +1108,22 @@ qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return -1;
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!isConnectionEncrypted()) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot write a datagram, not in encrypted state"));
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot write a datagram, not in encrypted state"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return d->writeDatagramEncrypted(socket, dgram);
|
||||
return backend->writeDatagramEncrypted(socket, dgram);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1079,21 +1136,25 @@ QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
auto *backend = d->backend.get();
|
||||
if (!backend)
|
||||
return {};
|
||||
|
||||
if (!socket) {
|
||||
d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
backend->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!isConnectionEncrypted()) {
|
||||
d->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot read a datagram, not in encrypted state"));
|
||||
backend->setDtlsError(QDtlsError::InvalidOperation,
|
||||
tr("Cannot read a datagram, not in encrypted state"));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!dgram.size())
|
||||
return {};
|
||||
|
||||
return d->decryptDatagram(socket, dgram);
|
||||
return backend->decryptDatagram(socket, dgram);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1105,7 +1166,10 @@ QDtlsError QDtls::dtlsError() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->errorCode;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->error();
|
||||
|
||||
return QDtlsError::NoError;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1118,7 +1182,10 @@ QString QDtls::dtlsErrorString() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->errorDescription;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->errorString();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1131,7 +1198,11 @@ QList<QSslError> QDtls::peerVerificationErrors() const
|
||||
{
|
||||
Q_D(const QDtls);
|
||||
|
||||
return d->tlsErrors;
|
||||
if (const auto *backend = d->backend.get())
|
||||
return backend->peerVerificationErrors();
|
||||
|
||||
//return d->tlsErrors;
|
||||
return {};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1156,7 +1227,8 @@ void QDtls::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
|
||||
{
|
||||
Q_D(QDtls);
|
||||
|
||||
d->tlsErrorsToIgnore = errorsToIgnore;
|
||||
if (auto *backend = d->backend.get())
|
||||
backend->ignoreVerificationErrors(errorsToIgnore);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
137
src/network/ssl/qdtls_base.cpp
Normal file
137
src/network/ssl/qdtls_base.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdtls_base_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
void QDtlsBasePrivate::setDtlsError(QDtlsError code, const QString &description)
|
||||
{
|
||||
errorCode = code;
|
||||
errorDescription = description;
|
||||
}
|
||||
|
||||
QDtlsError QDtlsBasePrivate::error() const
|
||||
{
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
QString QDtlsBasePrivate::errorString() const
|
||||
{
|
||||
return errorDescription;
|
||||
}
|
||||
|
||||
void QDtlsBasePrivate::clearDtlsError()
|
||||
{
|
||||
errorCode = QDtlsError::NoError;
|
||||
errorDescription.clear();
|
||||
}
|
||||
|
||||
QSslConfiguration QDtlsBasePrivate::configuration() const
|
||||
{
|
||||
auto copyPrivate = new QSslConfigurationPrivate(dtlsConfiguration);
|
||||
copyPrivate->ref.storeRelaxed(0); // the QSslConfiguration constructor refs up
|
||||
QSslConfiguration copy(copyPrivate);
|
||||
copyPrivate->sessionCipher = sessionCipher;
|
||||
copyPrivate->sessionProtocol = sessionProtocol;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void QDtlsBasePrivate::setConfiguration(const QSslConfiguration &configuration)
|
||||
{
|
||||
dtlsConfiguration.localCertificateChain = configuration.localCertificateChain();
|
||||
dtlsConfiguration.privateKey = configuration.privateKey();
|
||||
dtlsConfiguration.ciphers = configuration.ciphers();
|
||||
dtlsConfiguration.ellipticCurves = configuration.ellipticCurves();
|
||||
dtlsConfiguration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
|
||||
dtlsConfiguration.dhParams = configuration.diffieHellmanParameters();
|
||||
dtlsConfiguration.caCertificates = configuration.caCertificates();
|
||||
dtlsConfiguration.peerVerifyDepth = configuration.peerVerifyDepth();
|
||||
dtlsConfiguration.peerVerifyMode = configuration.peerVerifyMode();
|
||||
dtlsConfiguration.protocol = configuration.protocol();
|
||||
dtlsConfiguration.sslOptions = configuration.d->sslOptions;
|
||||
dtlsConfiguration.sslSession = configuration.sessionTicket();
|
||||
dtlsConfiguration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
|
||||
dtlsConfiguration.nextAllowedProtocols = configuration.allowedNextProtocols();
|
||||
dtlsConfiguration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
|
||||
dtlsConfiguration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
|
||||
dtlsConfiguration.dtlsCookieEnabled = configuration.dtlsCookieVerificationEnabled();
|
||||
dtlsConfiguration.allowRootCertOnDemandLoading = configuration.d->allowRootCertOnDemandLoading;
|
||||
dtlsConfiguration.backendConfig = configuration.backendConfiguration();
|
||||
|
||||
clearDtlsError();
|
||||
}
|
||||
|
||||
bool QDtlsBasePrivate::setCookieGeneratorParameters(const GenParams ¶ms)
|
||||
{
|
||||
if (!params.secret.size()) {
|
||||
setDtlsError(QDtlsError::InvalidInputParameters,
|
||||
QDtls::tr("Invalid (empty) secret"));
|
||||
return false;
|
||||
}
|
||||
|
||||
clearDtlsError();
|
||||
|
||||
hashAlgorithm = params.hash;
|
||||
secret = params.secret;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QDtlsClientVerifier::GeneratorParameters
|
||||
QDtlsBasePrivate::cookieGeneratorParameters() const
|
||||
{
|
||||
return {hashAlgorithm, secret};
|
||||
}
|
||||
|
||||
bool QDtlsBasePrivate::isDtlsProtocol(QSsl::SslProtocol protocol)
|
||||
{
|
||||
switch (protocol) {
|
||||
case QSsl::DtlsV1_0:
|
||||
case QSsl::DtlsV1_0OrLater:
|
||||
case QSsl::DtlsV1_2:
|
||||
case QSsl::DtlsV1_2OrLater:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
115
src/network/ssl/qdtls_base_p.h
Normal file
115
src/network/ssl/qdtls_base_p.h
Normal file
@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QDTLS_BASE_P_H
|
||||
#define QDTLS_BASE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(dtls);
|
||||
|
||||
#include "qsslconfiguration_p.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
#include "qsslcipher.h"
|
||||
#include "qsslsocket.h"
|
||||
#include "qssl.h"
|
||||
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// This class exists to re-implement the shared error/cookie handling
|
||||
// for both QDtls and QDtlsClientVerifier classes. Use it if/when
|
||||
// you need it. Backend neutral.
|
||||
class QDtlsBasePrivate : virtual public QSsl::DtlsBase
|
||||
{
|
||||
public:
|
||||
QDtlsBasePrivate(QSslSocket::SslMode m, const QByteArray &s) : mode(m), secret(s) {}
|
||||
void setDtlsError(QDtlsError code, const QString &description) override;
|
||||
QDtlsError error() const override;
|
||||
QString errorString() const override;
|
||||
void clearDtlsError() override;
|
||||
|
||||
void setConfiguration(const QSslConfiguration &configuration) override;
|
||||
QSslConfiguration configuration() const override;
|
||||
|
||||
bool setCookieGeneratorParameters(const GenParams &) override;
|
||||
GenParams cookieGeneratorParameters() const override;
|
||||
|
||||
static bool isDtlsProtocol(QSsl::SslProtocol protocol);
|
||||
|
||||
QHostAddress remoteAddress;
|
||||
quint16 remotePort = 0;
|
||||
quint16 mtuHint = 0;
|
||||
|
||||
QDtlsError errorCode = QDtlsError::NoError;
|
||||
QString errorDescription;
|
||||
QSslConfigurationPrivate dtlsConfiguration;
|
||||
QSslSocket::SslMode mode = QSslSocket::SslClientMode;
|
||||
QSslCipher sessionCipher;
|
||||
QSsl::SslProtocol sessionProtocol = QSsl::UnknownProtocol;
|
||||
QString peerVfyName;
|
||||
QByteArray secret;
|
||||
|
||||
#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha1;
|
||||
#else
|
||||
QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDTLS_BASE_P_H
|
@ -783,8 +783,8 @@ void DtlsState::setLinkMtu(QDtlsBasePrivate *dtlsBase)
|
||||
} // namespace dtlsopenssl
|
||||
|
||||
QDtlsClientVerifierOpenSSL::QDtlsClientVerifierOpenSSL()
|
||||
: QDtlsBasePrivate(QSslSocket::SslServerMode, dtlsutil::fallbackSecret())
|
||||
{
|
||||
secret = dtlsutil::fallbackSecret();
|
||||
}
|
||||
|
||||
bool QDtlsClientVerifierOpenSSL::verifyClient(QUdpSocket *socket, const QByteArray &dgram,
|
||||
@ -827,6 +827,11 @@ bool QDtlsClientVerifierOpenSSL::verifyClient(QUdpSocket *socket, const QByteArr
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray QDtlsClientVerifierOpenSSL::verifiedHello() const
|
||||
{
|
||||
return verifiedClientHello;
|
||||
}
|
||||
|
||||
void QDtlsPrivateOpenSSL::TimeoutHandler::start(int hintMs)
|
||||
{
|
||||
Q_ASSERT(timerId == -1);
|
||||
@ -861,12 +866,66 @@ void QDtlsPrivateOpenSSL::TimeoutHandler::timerEvent(QTimerEvent *event)
|
||||
dtlsConnection->reportTimeout();
|
||||
}
|
||||
|
||||
QDtlsPrivateOpenSSL::QDtlsPrivateOpenSSL()
|
||||
QDtlsPrivateOpenSSL::QDtlsPrivateOpenSSL(QDtls *qObject, QSslSocket::SslMode side)
|
||||
: QDtlsBasePrivate(side, dtlsutil::fallbackSecret()), q(qObject)
|
||||
{
|
||||
secret = dtlsutil::fallbackSecret();
|
||||
Q_ASSERT(qObject);
|
||||
|
||||
dtls.dtlsPrivate = this;
|
||||
}
|
||||
|
||||
QSslSocket::SslMode QDtlsPrivateOpenSSL::cryptographMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void QDtlsPrivateOpenSSL::setPeer(const QHostAddress &addr, quint16 port, const QString &name)
|
||||
{
|
||||
remoteAddress = addr;
|
||||
remotePort = port;
|
||||
peerVfyName = name;
|
||||
}
|
||||
|
||||
QHostAddress QDtlsPrivateOpenSSL::peerAddress() const
|
||||
{
|
||||
return remoteAddress;
|
||||
}
|
||||
|
||||
quint16 QDtlsPrivateOpenSSL::peerPort() const
|
||||
{
|
||||
return remotePort;
|
||||
}
|
||||
|
||||
void QDtlsPrivateOpenSSL::setPeerVerificationName(const QString &name)
|
||||
{
|
||||
peerVfyName = name;
|
||||
}
|
||||
|
||||
QString QDtlsPrivateOpenSSL::peerVerificationName() const
|
||||
{
|
||||
return peerVfyName;
|
||||
}
|
||||
|
||||
void QDtlsPrivateOpenSSL::setDtlsMtuHint(quint16 mtu)
|
||||
{
|
||||
mtuHint = mtu;
|
||||
}
|
||||
|
||||
quint16 QDtlsPrivateOpenSSL::dtlsMtuHint() const
|
||||
{
|
||||
return mtuHint;
|
||||
}
|
||||
|
||||
QDtls::HandshakeState QDtlsPrivateOpenSSL::state() const
|
||||
{
|
||||
return handshakeState;
|
||||
}
|
||||
|
||||
bool QDtlsPrivateOpenSSL::isConnectionEncrypted() const
|
||||
{
|
||||
return connectionEncrypted;
|
||||
}
|
||||
|
||||
bool QDtlsPrivateOpenSSL::startHandshake(QUdpSocket *socket, const QByteArray &dgram)
|
||||
{
|
||||
Q_ASSERT(socket);
|
||||
@ -1070,6 +1129,26 @@ void QDtlsPrivateOpenSSL::sendShutdownAlert(QUdpSocket *socket)
|
||||
resetDtls();
|
||||
}
|
||||
|
||||
QList<QSslError> QDtlsPrivateOpenSSL::peerVerificationErrors() const
|
||||
{
|
||||
return tlsErrors;
|
||||
}
|
||||
|
||||
void QDtlsPrivateOpenSSL::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
|
||||
{
|
||||
tlsErrorsToIgnore = errorsToIgnore;
|
||||
}
|
||||
|
||||
QSslCipher QDtlsPrivateOpenSSL::dtlsSessionCipher() const
|
||||
{
|
||||
return sessionCipher;
|
||||
}
|
||||
|
||||
QSsl::SslProtocol QDtlsPrivateOpenSSL::dtlsSessionProtocol() const
|
||||
{
|
||||
return sessionProtocol;
|
||||
}
|
||||
|
||||
qint64 QDtlsPrivateOpenSSL::writeDatagramEncrypted(QUdpSocket *socket,
|
||||
const QByteArray &dgram)
|
||||
{
|
||||
@ -1191,9 +1270,6 @@ unsigned QDtlsPrivateOpenSSL::pskClientCallback(const char *hint, char *identity
|
||||
{
|
||||
// The code below is taken (with some modifications) from qsslsocket_openssl
|
||||
// - alas, we cannot simply re-use it, it's in QSslSocketPrivate.
|
||||
|
||||
Q_Q(QDtls);
|
||||
|
||||
{
|
||||
QSslPreSharedKeyAuthenticator authenticator;
|
||||
// Fill in some read-only fields (for client code)
|
||||
@ -1235,8 +1311,6 @@ unsigned QDtlsPrivateOpenSSL::pskClientCallback(const char *hint, char *identity
|
||||
unsigned QDtlsPrivateOpenSSL::pskServerCallback(const char *identity, unsigned char *psk,
|
||||
unsigned max_psk_len)
|
||||
{
|
||||
Q_Q(QDtls);
|
||||
|
||||
{
|
||||
QSslPreSharedKeyAuthenticator authenticator;
|
||||
// Fill in some read-only fields (for the user)
|
||||
@ -1287,7 +1361,7 @@ bool QDtlsPrivateOpenSSL::verifyPeer()
|
||||
// is empty, we call QAbstractSocket::peerName(), which returns
|
||||
// either peerName (can be set by setPeerName) or host name
|
||||
// (can be set as a result of connectToHost).
|
||||
QString name = peerVerificationName;
|
||||
QString name = peerVfyName;
|
||||
if (name.isEmpty()) {
|
||||
Q_ASSERT(dtls.udpSocket);
|
||||
name = dtls.udpSocket->peerName();
|
||||
@ -1366,8 +1440,6 @@ void QDtlsPrivateOpenSSL::fetchNegotiatedParameters()
|
||||
|
||||
void QDtlsPrivateOpenSSL::reportTimeout()
|
||||
{
|
||||
Q_Q(QDtls);
|
||||
|
||||
emit q->handshakeTimeout();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||
@ -46,6 +46,8 @@
|
||||
|
||||
#include <openssl/ossl_typ.h>
|
||||
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qdtls_base_p.h"
|
||||
#include "qdtls_p.h"
|
||||
|
||||
#include <private/qsslcontext_openssl_p.h>
|
||||
@ -55,7 +57,6 @@
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
|
||||
@ -76,6 +77,7 @@ QT_REQUIRE_CONFIG(dtls);
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDtlsPrivateOpenSSL;
|
||||
class QDtlsBasePrivate;
|
||||
class QUdpSocket;
|
||||
|
||||
namespace dtlsopenssl
|
||||
@ -131,23 +133,40 @@ private:
|
||||
|
||||
} // namespace dtlsopenssl
|
||||
|
||||
class QDtlsClientVerifierOpenSSL : public QDtlsClientVerifierPrivate
|
||||
class QDtlsClientVerifierOpenSSL : public QSsl::DtlsCookieVerifier, public QDtlsBasePrivate
|
||||
{
|
||||
public:
|
||||
|
||||
QDtlsClientVerifierOpenSSL();
|
||||
|
||||
bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
|
||||
const QHostAddress &address, quint16 port) override;
|
||||
QByteArray verifiedHello() const override;
|
||||
|
||||
private:
|
||||
dtlsopenssl::DtlsState dtls;
|
||||
QByteArray verifiedClientHello;
|
||||
};
|
||||
|
||||
class QDtlsPrivateOpenSSL : public QDtlsPrivate
|
||||
class QDtlsPrivateOpenSSL : public QSsl::DtlsCryptograph, public QDtlsBasePrivate
|
||||
{
|
||||
public:
|
||||
QDtlsPrivateOpenSSL();
|
||||
|
||||
QDtlsPrivateOpenSSL(QDtls *qObject, QSslSocket::SslMode mode);
|
||||
|
||||
private:
|
||||
|
||||
QSslSocket::SslMode cryptographMode() const override;
|
||||
void setPeer(const QHostAddress &addr, quint16 port, const QString &name) override;
|
||||
QHostAddress peerAddress() const override;
|
||||
quint16 peerPort() const override;
|
||||
void setPeerVerificationName(const QString &name) override;
|
||||
QString peerVerificationName() const override;
|
||||
|
||||
virtual void setDtlsMtuHint(quint16 mtu) override;
|
||||
virtual quint16 dtlsMtuHint() const override;
|
||||
|
||||
virtual QDtls::HandshakeState state() const override;
|
||||
virtual bool isConnectionEncrypted() const override;
|
||||
|
||||
bool startHandshake(QUdpSocket *socket, const QByteArray &datagram) override;
|
||||
bool continueHandshake(QUdpSocket *socket, const QByteArray &datagram) override;
|
||||
@ -156,9 +175,17 @@ public:
|
||||
bool handleTimeout(QUdpSocket *socket) override;
|
||||
void sendShutdownAlert(QUdpSocket *socket) override;
|
||||
|
||||
QList<QSslError> peerVerificationErrors() const override;
|
||||
void ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore) override;
|
||||
|
||||
QSslCipher dtlsSessionCipher() const override;
|
||||
QSsl::SslProtocol dtlsSessionProtocol() const override;
|
||||
|
||||
qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &datagram) override;
|
||||
QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &tlsdgram) override;
|
||||
|
||||
public:
|
||||
|
||||
unsigned pskClientCallback(const char *hint, char *identity, unsigned max_identity_len,
|
||||
unsigned char *psk, unsigned max_psk_len);
|
||||
unsigned pskServerCallback(const char *identity, unsigned char *psk,
|
||||
@ -195,14 +222,18 @@ private:
|
||||
QDtlsPrivateOpenSSL *dtlsConnection = nullptr;
|
||||
};
|
||||
|
||||
QDtls *q = nullptr;
|
||||
QDtls::HandshakeState handshakeState = QDtls::HandshakeNotStarted;
|
||||
|
||||
QList<QSslError> tlsErrors;
|
||||
QList<QSslError> tlsErrorsToIgnore;
|
||||
bool connectionEncrypted = false;
|
||||
// We will initialize it 'lazily', just in case somebody wants to move
|
||||
// QDtls to another thread.
|
||||
QScopedPointer<TimeoutHandler> timeoutHandler;
|
||||
bool connectionWasShutdown = false;
|
||||
QSslPreSharedKeyAuthenticator pskAuthenticator;
|
||||
QByteArray identityHint;
|
||||
|
||||
Q_DECLARE_PUBLIC(QDtls)
|
||||
};
|
||||
|
||||
|
||||
|
@ -42,21 +42,9 @@
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qdtls.h"
|
||||
|
||||
#include <private/qsslconfiguration_p.h>
|
||||
#include <private/qobject_p.h>
|
||||
|
||||
#include <QtNetwork/qabstractsocket.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
#include <QtNetwork/qsslcipher.h>
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include "qtlsbackend_p.h"
|
||||
|
||||
#include <QtCore/private/qobject_p.h>
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
@ -74,80 +62,20 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHostAddress;
|
||||
|
||||
class QDtlsBasePrivate : public QObjectPrivate
|
||||
class QDtlsClientVerifierPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
|
||||
void setDtlsError(QDtlsError code, const QString &description)
|
||||
{
|
||||
errorCode = code;
|
||||
errorDescription = description;
|
||||
}
|
||||
|
||||
void clearDtlsError()
|
||||
{
|
||||
errorCode = QDtlsError::NoError;
|
||||
errorDescription.clear();
|
||||
}
|
||||
|
||||
void setConfiguration(const QSslConfiguration &configuration);
|
||||
QSslConfiguration configuration() const;
|
||||
|
||||
bool setCookieGeneratorParameters(QCryptographicHash::Algorithm alg,
|
||||
const QByteArray &secret);
|
||||
|
||||
static bool isDtlsProtocol(QSsl::SslProtocol protocol);
|
||||
|
||||
QHostAddress remoteAddress;
|
||||
quint16 remotePort = 0;
|
||||
quint16 mtuHint = 0;
|
||||
|
||||
QDtlsError errorCode = QDtlsError::NoError;
|
||||
QString errorDescription;
|
||||
QSslConfigurationPrivate dtlsConfiguration;
|
||||
QSslSocket::SslMode mode = QSslSocket::SslClientMode;
|
||||
QSslCipher sessionCipher;
|
||||
QSsl::SslProtocol sessionProtocol = QSsl::UnknownProtocol;
|
||||
QString peerVerificationName;
|
||||
QByteArray secret;
|
||||
|
||||
#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha1;
|
||||
#else
|
||||
QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;
|
||||
#endif
|
||||
QDtlsClientVerifierPrivate();
|
||||
~QDtlsClientVerifierPrivate();
|
||||
std::unique_ptr<QSsl::DtlsCookieVerifier> backend;
|
||||
};
|
||||
|
||||
class QDtlsClientVerifierPrivate : public QDtlsBasePrivate
|
||||
class QDtlsPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
|
||||
QByteArray verifiedClientHello;
|
||||
|
||||
virtual bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
|
||||
const QHostAddress &address, quint16 port) = 0;
|
||||
};
|
||||
|
||||
class QDtlsPrivate : public QDtlsBasePrivate
|
||||
{
|
||||
public:
|
||||
|
||||
virtual bool startHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual bool handleTimeout(QUdpSocket *socket) = 0;
|
||||
virtual bool continueHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual bool resumeHandshake(QUdpSocket *socket) = 0;
|
||||
virtual void abortHandshake(QUdpSocket *socket) = 0;
|
||||
virtual void sendShutdownAlert(QUdpSocket *socket) = 0;
|
||||
|
||||
virtual qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
|
||||
QDtls::HandshakeState handshakeState = QDtls::HandshakeNotStarted;
|
||||
|
||||
QList<QSslError> tlsErrors;
|
||||
QList<QSslError> tlsErrorsToIgnore;
|
||||
|
||||
bool connectionEncrypted = false;
|
||||
QDtlsPrivate();
|
||||
~QDtlsPrivate();
|
||||
std::unique_ptr<QSsl::DtlsCryptograph> backend;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -199,6 +199,10 @@ TlsKey *X509Certificate::publicKey() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
DtlsBase::~DtlsBase() = default;
|
||||
#endif // QT_CONFIG(dtls)
|
||||
|
||||
} // namespace QSsl
|
||||
|
||||
const QString QTlsBackend::builtinBackendNames[] = {
|
||||
@ -250,8 +254,10 @@ QSsl::TlsCryptograph *QTlsBackend::createTlsCryptograph() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QSsl::DtlsCryptograph *QTlsBackend::createDtlsCryptograph() const
|
||||
QSsl::DtlsCryptograph *QTlsBackend::createDtlsCryptograph(QDtls *qObject, int mode) const
|
||||
{
|
||||
Q_UNUSED(qObject);
|
||||
Q_UNUSED(mode);
|
||||
REPORT_MISSING_SUPPORT("does not support QDtls");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -41,6 +41,10 @@
|
||||
#include "qtlskey_openssl_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
#include "qdtls_openssl_p.h"
|
||||
#endif // QT_CONFIG(dtls)
|
||||
|
||||
// TLSTODO: Later, this code (ensure initialised, etc.)
|
||||
// must move from the socket to backend.
|
||||
#include "qsslsocket_p.h"
|
||||
@ -163,6 +167,28 @@ QSsl::X509Certificate *QTlsBackendOpenSSL::createCertificate() const
|
||||
return new QSsl::X509CertificateOpenSSL;
|
||||
}
|
||||
|
||||
QSsl::DtlsCookieVerifier *QTlsBackendOpenSSL::createDtlsCookieVerifier() const
|
||||
{
|
||||
#if QT_CONFIG(dtls)
|
||||
return new QDtlsClientVerifierOpenSSL;
|
||||
#else
|
||||
qCWarning(lcTlsBackend, "Feature 'dtls' is disabled, cannot verify DTLS cookies");
|
||||
return nullptr;
|
||||
#endif // QT_CONFIG(dtls)
|
||||
}
|
||||
|
||||
QSsl::DtlsCryptograph *QTlsBackendOpenSSL::createDtlsCryptograph(QDtls *q, int mode) const
|
||||
{
|
||||
#if QT_CONFIG(dtls)
|
||||
return new QDtlsPrivateOpenSSL(q, QSslSocket::SslMode(mode));
|
||||
#else
|
||||
Q_UNUSED(q);
|
||||
Q_UNUSED(mode);
|
||||
qCWarning(lcTlsBackend, "Feature 'dtls' is disabled, cannot encrypt UDP datagrams");
|
||||
return nullptr;
|
||||
#endif // QT_CONFIG(dtls)
|
||||
}
|
||||
|
||||
QSsl::X509ChainVerifyPtr QTlsBackendOpenSSL::X509Verifier() const
|
||||
{
|
||||
return QSsl::X509CertificateOpenSSL::verify;
|
||||
|
@ -80,6 +80,10 @@ private:
|
||||
|
||||
// QSslCertificate:
|
||||
QSsl::X509Certificate *createCertificate() const override;
|
||||
|
||||
QSsl::DtlsCookieVerifier *createDtlsCookieVerifier() const override;
|
||||
QSsl::DtlsCryptograph *createDtlsCryptograph(QDtls *q, int mode) const override;
|
||||
|
||||
QSsl::X509ChainVerifyPtr X509Verifier() const override;
|
||||
QSsl::X509PemReaderPtr X509PemReader() const override;
|
||||
QSsl::X509DerReaderPtr X509DerReader() const override;
|
||||
|
@ -53,8 +53,14 @@
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qsslconfiguration.h"
|
||||
#include "qsslerror.h"
|
||||
#include "qssl_p.h"
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
#include "qdtls.h"
|
||||
#endif
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
#include <QtNetwork/qsslerror.h>
|
||||
#include <QtNetwork/qsslkey.h>
|
||||
@ -72,7 +78,10 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHostAddress;
|
||||
class QByteArray;
|
||||
class QSslCipher;
|
||||
class QUdpSocket;
|
||||
class QIODevice;
|
||||
class QSslKey;
|
||||
|
||||
@ -183,11 +192,81 @@ using X509Pkcs12ReaderPtr = bool (*)(QIODevice *device, QSslKey *key, QSslCertif
|
||||
// TLS over TCP. Handshake, encryption/decryption.
|
||||
class TlsCryptograph;
|
||||
|
||||
// TLS over UDP. Handshake, encryption/decryption.
|
||||
class DtlsCryptograph;
|
||||
#if QT_CONFIG(dtls)
|
||||
|
||||
class DtlsBase
|
||||
{
|
||||
public:
|
||||
virtual ~DtlsBase();
|
||||
|
||||
virtual void setDtlsError(QDtlsError code, const QString &description) = 0;
|
||||
|
||||
virtual QDtlsError error() const = 0;
|
||||
virtual QString errorString() const = 0;
|
||||
|
||||
virtual void clearDtlsError() = 0;
|
||||
|
||||
virtual void setConfiguration(const QSslConfiguration &configuration) = 0;
|
||||
virtual QSslConfiguration configuration() const = 0;
|
||||
|
||||
using GenParams = QDtlsClientVerifier::GeneratorParameters;
|
||||
virtual bool setCookieGeneratorParameters(const GenParams ¶ms) = 0;
|
||||
virtual GenParams cookieGeneratorParameters() const = 0;
|
||||
};
|
||||
|
||||
// DTLS cookie: generation and verification.
|
||||
class DtlsCookieVerifier : virtual public DtlsBase
|
||||
{
|
||||
public:
|
||||
virtual bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
|
||||
const QHostAddress &address, quint16 port) = 0;
|
||||
virtual QByteArray verifiedHello() const = 0;
|
||||
};
|
||||
|
||||
// TLS over UDP. Handshake, encryption/decryption.
|
||||
class DtlsCryptograph : virtual public DtlsBase
|
||||
{
|
||||
public:
|
||||
|
||||
virtual QSslSocket::SslMode cryptographMode() const = 0;
|
||||
virtual void setPeer(const QHostAddress &addr, quint16 port, const QString &name) = 0;
|
||||
virtual QHostAddress peerAddress() const = 0;
|
||||
virtual quint16 peerPort() const = 0;
|
||||
virtual void setPeerVerificationName(const QString &name) = 0;
|
||||
virtual QString peerVerificationName() const = 0;
|
||||
|
||||
virtual void setDtlsMtuHint(quint16 mtu) = 0;
|
||||
virtual quint16 dtlsMtuHint() const = 0;
|
||||
|
||||
virtual QDtls::HandshakeState state() const = 0;
|
||||
virtual bool isConnectionEncrypted() const = 0;
|
||||
|
||||
virtual bool startHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual bool handleTimeout(QUdpSocket *socket) = 0;
|
||||
virtual bool continueHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual bool resumeHandshake(QUdpSocket *socket) = 0;
|
||||
virtual void abortHandshake(QUdpSocket *socket) = 0;
|
||||
virtual void sendShutdownAlert(QUdpSocket *socket) = 0;
|
||||
|
||||
virtual QList<QSslError> peerVerificationErrors() const = 0;
|
||||
virtual void ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore) = 0;
|
||||
|
||||
virtual QSslCipher dtlsSessionCipher() const = 0;
|
||||
virtual QSsl::SslProtocol dtlsSessionProtocol() const = 0;
|
||||
|
||||
virtual qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
virtual QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram) = 0;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class DtlsCookieVerifier;
|
||||
class DtlsCryptograph;
|
||||
|
||||
#endif // QT_CONFIG(dtls)
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace QSsl
|
||||
|
||||
@ -213,7 +292,7 @@ public:
|
||||
|
||||
// TLS and DTLS:
|
||||
virtual QSsl::TlsCryptograph *createTlsCryptograph() const;
|
||||
virtual QSsl::DtlsCryptograph *createDtlsCryptograph() const;
|
||||
virtual QSsl::DtlsCryptograph *createDtlsCryptograph(class QDtls *qObject, int mode) const;
|
||||
virtual QSsl::DtlsCookieVerifier *createDtlsCookieVerifier() const;
|
||||
|
||||
// TLSTODO - get rid of these function pointers, make them virtuals in
|
||||
|
Loading…
x
Reference in New Issue
Block a user