Spec-Zone.ru › Qt 5.15

Класс QDtls

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

Заголовок: #include <QDtls>
qmake: QT += network
С момента: Qt 5.12
Наследуется от: QObject

Этот класс был представлен в Qt 5.12.

  • Список всех членов, включая унаследованные

Открытые типы

(псевдоним) 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 QVector<QSslError> &errorsToIgnore)
bool isConnectionEncrypted() const
quint16 mtuHint() const
QHostAddress peerAddress() const
quint16 peerPort() const
QVector<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().

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, чтобы отключить процедуру проверки куки:

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

Это псевдоним типа для QDtlsClientVerifier::GeneratorParameters.

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 QVector<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().

QVector<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 = {})

Устанавливает адрес, port и имя хоста удалённого узла и возвращает 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().

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

перечисление 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-5.15/qdtls.html

Spec-Zone.ru

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