Spec-Zone.ru › Qt 5.14

Класс QDtls

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

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

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

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

Публичные типы

typedef 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 может использоваться для установления защищенного соединения с сетевым узлом, используя протокол User Datagram Protocol (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 для отключения процедуры проверки 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.

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

typedef 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 для соединения DTLS на стороне клиента.

См. также 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 = {})

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

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

enum QDtlsError

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

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

Константа Значение Описание
QDtls::NoError 0 Ошибка не произошла, последняя операция выполнена успешно.
QDtls::InvalidInputParameters 1 Предоставленные вызывающей стороной входные параметры были неверны.
QDtls::InvalidOperation 2 Операция была предпринята в состоянии, которое не позволяло её выполнить.
QDtls::UnderlyingSocketError 3 QUdpSocket::writeDatagram() завершилась неудачно, QUdpSocket::error() и QUdpSocket::errorString() могут предоставить более подробную информацию.
QDtls::RemoteClosedConnectionError 4 Было получено сообщение TLS о завершении соединения.
QDtls::PeerVerificationError 5 Идентичность удалённой стороны не могла быть проверена во время рукопожатия TLS.
QDtls::TlsInitializationError 6 Произошла ошибка при инициализации базового TLS-бекенда.
QDtls::TlsFatalError 7 Произошла критическая ошибка во время рукопожатия TLS, кроме ошибки проверки идентичности удалённой стороны или ошибки инициализации TLS.
QDtls::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.14/qdtls.html

Spec-Zone.ru

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