Spec-Zone.ru › Qt 6.1

Класс QDtls

Этот класс обеспечивает шифрование для сокетов UDP. Подробнее...

Заголовок: #include <QDtls>
CMake: find_package(Qt6 COMPONENTS Network REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Network)
qmake: QT += network
С момента: Qt 5.12
Наследует: QObject
  • Список всех членов, включая наследуемые

Типы публичного доступа

GeneratorParameters
Перечисление HandshakeState { HandshakeNotStarted, HandshakeInProgress, PeerVerificationFailed, HandshakeComplete }

Функции публичного доступа

QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)
виртуальный ~QDtls()
bool abortHandshake(QUdpSocket *socket)
QDtls::GeneratorParameters cookieGeneratorParameters() const
QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
bool doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})
QSslConfiguration dtlsConfiguration() const
QDtlsError dtlsError() const
QString dtlsErrorString() const
bool handleTimeout(QUdpSocket *socket)
QDtls::HandshakeState handshakeState() const
void ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
bool isConnectionEncrypted() const
quint16 mtuHint() const
QHostAddress peerAddress() const
quint16 peerPort() const
QList<QSslError> peerVerificationErrors() const
QString peerVerificationName() const
bool resumeHandshake(QUdpSocket *socket)
QSslCipher sessionCipher() const
QSsl::SslProtocol sessionProtocol() const
bool setCookieGeneratorParameters(const QDtls::GeneratorParameters &params)
bool setDtlsConfiguration(const QSslConfiguration &configuration)
void setMtuHint(quint16 mtuHint)
bool setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})
bool setPeerVerificationName(const QString &name)
bool shutdown(QUdpSocket *socket)
QSslSocket::SslMode sslMode() const
qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)

Сигналы

void handshakeTimeout()
void pskRequired(QSslPreSharedKeyAuthenticator *authenticator)

Связанные нечлены

Перечисление QDtlsError { NoError, InvalidInputParameters, InvalidOperation, UnderlyingSocketError, RemoteClosedConnectionError, …, TlsNonFatalError }

Подробное описание

Класс QDtls может использоваться для установления защищенного соединения с сетевым узлом, используя протокол пользователя для датаграмм (UDP). Соединение DTLS по сути по протоколу UDP, означающее, что два узла должны сначала успешно завершить рукопожатие TLS, вызвав doHandshake(). После завершения рукопожатия, зашифрованные датаграммы могут быть отправлены узлу с помощью writeDatagramEncrypted(). Зашифрованные датаграммы, поступающие от узла, могут быть расшифрованы с помощью decryptDatagram().

END_OF_DOCUMENT_MARKER

QDtls предназначен для работы с QUdpSocket. Поскольку QUdpSocket может принимать дейтаграммы от разных узлов, приложение должно реализовать размножение, передавая дейтаграммы от разных узлов соответствующим экземплярам QDtls. Связь между сетевым узлом и его объектом QDtls может быть установлена с использованием адреса и номера порта узла. Перед началом рукопожатия приложение должно установить адрес и номер порта узла с помощью setPeer().

QDtls не считывает дейтаграммы из QUdpSocket, это должно выполняться приложением, например, в слоте, подключенном к сигналу QUdpSocket::readyRead(). Затем эти дейтаграммы должны быть обработаны QDtls.

Примечание: QDtls не берет на себя ответственность за объект QUdpSocket.

Обычно во время фазы рукопожатия оба узла должны принять и отправить несколько дейтаграмм. При чтении дейтаграмм сервер и клиент должны передавать эти дейтаграммы в doHandshake() до тех пор, пока не будет найдена ошибка или handshakeState() не вернёт HandshakeComplete:

// A client initiates a handshake:
QUdpSocket clientSocket;
QDtls clientDtls;
clientDtls.setPeer(address, port, peerName);
clientDtls.doHandshake(&clientSocket);

// A server accepting an incoming connection; address, port, clientHello are
// read by QUdpSocket::readDatagram():
QByteArray clientHello(serverSocket.pendingDatagramSize(), Qt::Uninitialized);
QHostAddress address;
quin16 port = {};
serverSocket.readDatagram(clientHello.data(), clientHello.size(), &address, &port);

QDtls serverDtls;
serverDtls.setPeer(address, port);
serverDtls.doHandshake(&serverSocket, clientHello);

// Handshake completion, both for server and client:
void DtlsConnection::continueHandshake(const QByteArray &datagram)
{
    if (dtls.doHandshake(&udpSocket, datagram)) {
        // Check handshake status:
        if (dtls.handshakeStatus() == QDlts::HandshakeComplete) {
            // Secure DTLS connection is now established.
        }
    } else {
        // Error handling.
    }
}

Для сервера первый вызов doHandshake() требует непустой дейтаграммы, содержащей сообщение ClientHello. Если сервер также использует QDtlsClientVerifier, ожидается, что первое сообщение ClientHello будет тем, которое проверено QDtlsClientVerifier.

В случае, если идентификатор узла не может быть проверен во время рукопожатия, приложение должно проверить ошибки, возвращаемые peerVerificationErrors(), а затем либо игнорировать ошибки, вызвав ignoreVerificationErrors(), либо прервать рукопожатие, вызвав abortHandshake(). Если ошибки были проигнорированы, рукопожатие можно возобновить, вызвав resumeHandshake().

После завершения рукопожатия дейтаграммы могут быть отправлены и получены от сетевого узла безопасно:

// Sending an encrypted datagram:
dtlsConnection.writeDatagramEncrypted(&clientSocket, "Hello DTLS server!");

// Decryption:
QByteArray encryptedMessage(dgramSize);
socket.readDatagram(encryptedMessage.data(), dgramSize);
const QByteArray plainText = dtlsConnection.decryptDatagram(&socket, encryptedMessage);

Соединение DTLS может быть закрыто с помощью shutdown().

DtlsClient::~DtlsClient()
{
    clientDtls.shutdown(&clientSocket);
}

Предупреждение: Рекомендуется вызывать shutdown() перед уничтожением объекта QDtls клиента, если вы планируете повторно использовать тот же номер порта для подключения к серверу позже. В противном случае сервер может отбрасывать входящие сообщения ClientHello, см. RFC 6347, раздел 4.2.8 для получения дополнительных сведений и советов по реализации.

Если сервер не использует QDtlsClientVerifier, он должен настроить свои объекты QDtls, чтобы отключить процедуру проверки cookie:

auto config = QSslConfiguration::defaultDtlsConfiguration();
config.setDtlsCookieVerificationEnabled(false);
// Some other customization ...
dtlsConnection.setDtlsConfiguration(config);

Сервер, использующий проверку cookie с параметрами генератора, отличными от стандартных, обязан установить те же параметры для своего объекта QDtls перед началом рукопожатия.

Примечание: Протокол DTLS делегирует обнаружение максимального размера транспортного блока пути (PMTU) приложению. Приложение может предоставить QDtls значение MTU с помощью setMtuHint(). Это значение влияет только на фазу рукопожатия, так как только сообщения рукопожатия могут быть фрагментированы и восстанавливаются DTLS. Все остальные сообщения, отправленные приложением, должны помещаться в один датаграмму.

Примечание: Специфичные для DTLS заголовки добавляют некоторую избыточность к данным приложения, что ещё больше уменьшает возможный размер сообщения.

Предупреждение: Сервер, настроенный на отправку ответа HelloVerifyRequest, отбросит все фрагментированные сообщения ClientHello, никогда не начав рукопожатия.

Примеры сервера DTLS и клиента DTLS демонстрируют, как использовать QDtls в приложениях.

См. также QUdpSocket, QDtlsClientVerifier, HandshakeState, QDtlsError и QSslConfiguration.

Документация по типам членов

[alias] QDtls::GeneratorParameters

[since 5.12] enum QDtls::HandshakeState

Описывает текущее состояние рукопожатия DTLS.

Этот перечисление описывает текущее состояние рукопожатия DTLS для соединения QDtls.

Константа Значение Описание
QDtls::HandshakeNotStarted 0 Ничего ещё не выполнено.
QDtls::HandshakeInProgress 1 Рукопожатие было инициировано, и до сих пор не обнаружено ошибок.
QDtls::PeerVerificationFailed 2 Идентификатор удалённого узла не может быть установлен.
QDtls::HandshakeComplete 3 Рукопожатие успешно завершено, и зашифрованное соединение установлено.

Это перечисление было добавлено или изменено в Qt 5.12.

См. также QDtls::doHandshake() и QDtls::handshakeState().

Документация по функциям членов

QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)

Создаёт объект QDtls, parent передаётся конструктору QObject. mode — QSslSocket::SslServerMode для соединения DTLS на стороне сервера или QSslSocket::SslClientMode для клиента.

См. также sslMode() и QSslSocket::SslMode.

[signal] void QDtls::handshakeTimeout()

Потеря пакетов может привести к таймаутам во время фазы рукопожатия. В этом случае QDtls излучает сигнал handshakeTimeout(). Вызовите handleTimeout(), чтобы повторно передать сообщения рукопожатия:

DtlsClient::DtlsClient()
{
    // Some initialization code here ...
    connect(&clientDtls, &QDtls::handshakeTimeout, this, &DtlsClient::handleTimeout);
}

void DtlsClient::handleTimeout()
{
    clientDtls.handleTimeout(&clientSocket);
}

См. также handleTimeout().

[signal] void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)

QDtls излучает этот сигнал, когда он переходит к шифрованию PSK, и поэтому необходима проверка подлинности PSK.

При использовании PSK клиент должен отправить серверу действительный идентификатор и действительный предварительно согласованный ключ, чтобы рукопожатие TLS продолжилось. Приложения могут предоставить эту информацию в слоте, подключённом к этому сигналу, заполнив переданный объект authenticator в соответствии со своими потребностями.

Примечание: Игнорирование этого сигнала или невозможность предоставить необходимые учетные данные приведёт к сбою рукопожатия и, следовательно, к прерыванию соединения.

Примечание: Объект authenticator принадлежит QDtls и не должен удаляться приложением.

См. также QSslPreSharedKeyAuthenticator.

[virtual] QDtls::~QDtls()

Удаляет объект QDtls.

bool QDtls::abortHandshake(QUdpSocket *socket)

Прерывает текущее рукопожатие. Возвращает true, если оно происходило на socket; в противном случае устанавливает соответствующую ошибку и возвращает false.

См. также doHandshake() и resumeHandshake().

QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const

Возвращает текущий алгоритм хеширования и секрет, либо стандартные, либо установленные ранее вызовом setCookieGeneratorParameters().

Стандартный алгоритм хеширования — QCryptographicHash::Sha256, если Qt был сконфигурирован для его поддержки, иначе QCryptographicHash::Sha1. Стандартный секрет получается из зависящего от реализации криптографически стойкого генератора псевдослучайных чисел.

См. также setCookieGeneratorParameters(), QDtlsClientVerifier и cookieGeneratorParameters().

QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)

Расшифровывает dgram и возвращает его содержимое как обычный текст. Рукопожатие должно быть завершено, прежде чем датаграммы могут быть расшифрованы. В зависимости от типа сообщения TLS соединение может записать данные в socket, который должен быть допустимым указателем.

bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})

Инициализирует или продолжает рукопожатие DTLS. socket должен быть допустимым указателем. При инициализации рукопожатия DTLS на стороне сервера dgram должно содержать начальное сообщение ClientHello, считанное из QUdpSocket. Эта функция возвращает true если не обнаружено ошибок. Состояние рукопожатия можно проверить с помощью handshakeState(). false возвращает значение означает возникновение ошибки, используйте dtlsError() для получения более подробной информации.

Примечание: Если идентификатор удалённого узла не может быть установлен, ошибка устанавливается в QDtlsError::PeerVerificationError. Если вы хотите пропустить ошибки проверки и продолжить подключение, вы должны вызвать ignoreVerificationErrors() и затем resumeHandshake(). Если ошибки нельзя пропустить, вы должны вызвать abortHandshake().

if (!dtls.doHandshake(&socket, dgram)) {
    if (dtls.dtlsError() == QDtlsError::PeerVerificationError)
        dtls.abortAfterError(&socket);
}

См. также handshakeState(), dtlsError(), ignoreVerificationErrors(), resumeHandshake(), и abortHandshake().

QSslConfiguration QDtls::dtlsConfiguration() const

Возвращает либо стандартную конфигурацию DTLS, либо конфигурацию, установленную ранее вызовом setDtlsConfiguration().

См. также setDtlsConfiguration() и QSslConfiguration::defaultDtlsConfiguration().

QDtlsError QDtls::dtlsError() const

Возвращает последнюю ошибку, возникшую при подключении, или QDtlsError::NoError.

См. также dtlsErrorString() и QDtlsError.

QString QDtls::dtlsErrorString() const

Возвращает текстовое описание последней ошибки, возникшей при подключении, или пустую строку.

См. также dtlsError().

bool QDtls::handleTimeout(QUdpSocket *socket)

Если при рукопожатии возникает таймаут, излучается сигнал handshakeTimeout(). Приложение должно вызвать handleTimeout(), чтобы повторно передать сообщения рукопожатия; handleTimeout() возвращает true если произошёл таймаут, false в противном случае. socket должен быть допустимым указателем.

См. также handshakeTimeout().

QDtls::HandshakeState QDtls::handshakeState() const

Возвращает текущее состояние рукопожатия для этого QDtls.

См. также doHandshake() и QDtls::HandshakeState.

void QDtls::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)

Этот метод сообщает QDtls игнорировать только указанные в errorsToIgnore ошибки.

Например, если вы хотите подключиться к серверу, использующему самозаверенный сертификат, рассмотрите следующий фрагмент:

QList<QSslCertificate> cert = QSslCertificate::fromPath(QLatin1String("server-certificate.pem"));
QSslError error(QSslError::SelfSignedCertificate, cert.at(0));
QList<QSslError> expectedSslErrors;
expectedSslErrors.append(error);

QDtls dtls;
dtls.ignoreVerificationErrors(expectedSslErrors);
dtls.doHandshake(udpSocket);

Вы также можете вызвать эту функцию после doHandshake(), если возникла ошибка QDtlsError::PeerVerificationError, и затем возобновить рукопожатие, вызвав resumeHandshake().

Позже вызовы этой функции заменят список ошибок, переданных в предыдущих вызовах. Вы можете очистить список ошибок, которые вы хотите проигнорировать, вызвав эту функцию со списком пустым.

См. также doHandshake(), resumeHandshake(), и QSslError.

bool QDtls::isConnectionEncrypted() const

Возвращает true, если рукопожатие DTLS завершилось успешно.

См. также doHandshake() и handshakeState().

quint16 QDtls::mtuHint() const

Возвращает значение, ранее заданное функцией setMtuHint(). Значение по умолчанию равно 0.

См. также setMtuHint().

QHostAddress QDtls::peerAddress() const

Возвращает адрес удалённой стороны, установленный функцией setPeer(), или QHostAddress::Null.

См. также setPeer().

quint16 QDtls::peerPort() const

Возвращает номер порта удалённой стороны, установленный функцией setPeer(), или 0.

См. также setPeer().

QList<QSslError> QDtls::peerVerificationErrors() const

Возвращает ошибки, обнаруженные при установлении личности удалённой стороны.

Если вы хотите продолжить подключение, несмотря на возникшие ошибки, необходимо вызвать ignoreVerificationErrors().

QString QDtls::peerVerificationName() const

Возвращает имя хоста, заданное функцией setPeer() или setPeerVerificationName(). Значение по умолчанию — пустая строка.

См. также setPeerVerificationName() и setPeer().

bool QDtls::resumeHandshake(QUdpSocket *socket)

Если ошибки проверки подлинности удалённой стороны были проигнорированы во время рукопожатия, resumeHandshake() возобновляет и завершает рукопожатие и возвращает true. socket должен быть допустимым указателем. Возвращает false, если рукопожатие не удалось возобновить.

См. также doHandshake(), abortHandshake(), peerVerificationErrors(), и ignoreVerificationErrors().

QSslCipher QDtls::sessionCipher() const

Возвращает криптографическое шифрование, используемое этим подключением, или пустое шифрование, если подключение не зашифровано. Шифр для сессии выбирается во время фазы рукопожатия. Шифр используется для шифрования и дешифрования данных.

QSslConfiguration предоставляет функции для задания упорядоченного списка шифров, из которых фаза рукопожатия в конечном итоге выберет сессионный шифр. Этот упорядоченный список должен быть установлен до начала фазы рукопожатия.

См. также QSslConfiguration, setDtlsConfiguration(), и dtlsConfiguration().

QSsl::SslProtocol QDtls::sessionProtocol() const

Возвращает используемую версию протокола DTLS этого подключения или UnknownProtocol, если подключение ещё не зашифровано. Протокол для подключения выбирается во время фазы рукопожатия.

setDtlsConfiguration() может задать предпочтительную версию до начала рукопожатия.

См. также setDtlsConfiguration(), QSslConfiguration, QSslConfiguration::defaultDtlsConfiguration(), и QSslConfiguration::setProtocol().

bool QDtls::setCookieGeneratorParameters(const QDtls::GeneratorParameters &params)

Устанавливает алгоритм криптографического хеширования и секрет из params. Эта функция необходима только для подключения QDtls на стороне сервера. Возвращает true при успехе.

Примечание: Эта функция должна быть вызвана до начала рукопожатия.

См. также cookieGeneratorParameters(), doHandshake(), QDtlsClientVerifier, и QDtlsClientVerifier::cookieGeneratorParameters().

bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)

Устанавливает конфигурацию TLS подключения из configuration и возвращает true при успехе.

Примечание: Эта функция должна быть вызвана до начала рукопожатия.

См. также dtlsConfiguration() и doHandshake().

void QDtls::setMtuHint(quint16 mtuHint)

mtuHint — максимальный размер блока передачи (MTU), обнаруженный или подсчитанный приложением. Приложение не обязано устанавливать это значение.

См. также mtuHint() и QAbstractSocket::PathMtuSocketOption.

bool QDtls::setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})

Устанавливает адрес, порт и имя хоста удалённой стороны и возвращает true при успехе. address не должен быть нулевым, многоадресным или широковещательным. verificationName — имя хоста, используемое для проверки сертификата.

См. также peerAddress(), peerPort(), и peerVerificationName().

bool QDtls::setPeerVerificationName(const QString &name)

Устанавливает имя хоста name, которое будет использоваться для проверки сертификата, и возвращает true при успехе.

Примечание: Эта функция должна быть вызвана до начала рукопожатия.

См. также peerVerificationName() и setPeer().

bool QDtls::shutdown(QUdpSocket *socket)

Отправляет зашифрованное сообщение об отключении и закрывает соединение DTLS. Состояние рукопожатия меняется на QDtls::HandshakeNotStarted. socket должен быть допустимым указателем. Эта функция возвращает true при успехе.

См. также doHandshake().

QSslSocket::SslMode QDtls::sslMode() const

Возвращает QSslSocket::SslServerMode для подключения на серверной стороне и QSslSocket::SslClientMode для клиента.

См. также QDtls() и QSslSocket::SslMode.

qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)

Шифрует dgram и записывает зашифрованные данные в socket. Возвращает количество записанных байтов или -1 в случае ошибки. Рукопожатие должно быть завершено перед записью зашифрованных данных. socket должен быть допустимым указателем.

См. также doHandshake(), handshakeState(), isConnectionEncrypted(), и dtlsError().

Связанные нечлены

[since 5.12] перечисление QDtlsError

Описывает ошибки, которые могут быть обнаружены QDtls и QDtlsClientVerifier.

Это перечисление описывает общие и специфичные для TLS ошибки, которые могут возникнуть у объектов классов QDtlsClientVerifier и QDtls.

Константа Значение Описание
QDtls::QDtlsError::NoError 0 Ошибка не произошла, последнее действие выполнено успешно.
QDtls::QDtlsError::InvalidInputParameters 1 Введённые вызывающим объектом параметры некорректны.
QDtls::QDtlsError::InvalidOperation 2 Попытка выполнить операцию в состоянии, которое её не допускает.
QDtls::QDtlsError::UnderlyingSocketError 3 QUdpSocket::writeDatagram() завершился неудачей, QUdpSocket::error() и QUdpSocket::errorString() могут предоставить более подробную информацию.
QDtls::QDtlsError::RemoteClosedConnectionError 4 Получено сообщение об отключении TLS.
QDtls::QDtlsError::PeerVerificationError 5 Идентичность удалённого узла не могла быть проверена во время рукопожатия TLS.
QDtls::QDtlsError::TlsInitializationError 6 Произошла ошибка при инициализации базового TLS-обработчика.
QDtls::QDtlsError::TlsFatalError 7 Произошла фатальная ошибка во время рукопожатия TLS, отличная от ошибки проверки подлинности удалённого узла или ошибки инициализации TLS.
QDtls::QDtlsError::TlsNonFatalError 8 Ошибка шифрования или дешифрования датаграммы, не фатальная, означающая, что QDtls может продолжить работу после этой ошибки.

Это перечисление было введено или изменено в Qt 5.12.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qdtls.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API