Spec-Zone.ru › Qt 5.12

Класс QDtlsClientVerifier

Этот класс реализует генерацию и проверку куки DTLS на стороне сервера. Подробнее...

Заголовок: #include <QDtlsClientVerifier>
qmake: QT += network
С момента: Qt 5.12
Наследует: QObject
  • Список всех членов, включая унаследованные
  • Устаревшие члены

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

класс GeneratorParameters

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

QDtlsClientVerifier(QObject *parent = nullptr)
virtual ~QDtlsClientVerifier()
QDtlsClientVerifier::GeneratorParameters cookieGeneratorParameters() const
QDtlsError dtlsError() const
QString dtlsErrorString() const
bool setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters &params)
QByteArray verifiedHello() const
bool verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)
  • 31 функции публичного доступа унаследованные от QObject

Статические члены публичного доступа

const QMetaObject staticMetaObject
  • 9 статических членов публичного доступа унаследованных от QObject

Дополнительные унаследованные члены

  • 1 свойство, унаследованное от QObject
  • 1 слот публичного доступа, унаследованный от QObject
  • 2 сигнала, унаследованные от QObject
  • 9 защищенных функций, унаследованных от QObject

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

Этот класс реализует генерацию и проверку куки DTLS на стороне сервера.

Класс QDtlsClientVerifier реализует генерацию и проверку куки DTLS на стороне сервера. Протоколы безопасности датаграмм очень уязвимы к различным атакам типа "отказ в обслуживании". Согласно RFC 6347, раздел 4.2.1, это два наиболее распространенных типа атак:

  • Злоумышленник отправляет серию запросов на инициацию рукопожатия, заставляя сервер выделять чрезмерные ресурсы и выполнять потенциально дорогостоящие криптографические операции.
  • Злоумышленник отправляет серию запросов на инициацию рукопожатия с поддельным источником жертвы, заставляя сервер действовать как усилитель. Обычно сервер отправлял бы жертве сообщение Certificate, которое может быть довольно большим, тем самым затапливая машину жертвы датаграммами.

В качестве меры противодействия этим атакам RFC 6347, раздел 4.2.1 предлагает использовать бессостоятельный механизм куки, который может использовать сервер:

  • В ответ на начальное сообщение ClientHello, сервер отправляет HelloVerifyRequest, содержащее куки. Эта куки представляет собой криптографический хэш и генерируется с использованием адреса клиента, номера порта и секрета сервера (который является криптографически стойкой псевдослучайной последовательностью байтов).
  • Достижимый клиент DTLS должен ответить новым сообщением ClientHello, содержащим эту куки.
  • Когда сервер получает сообщение ClientHello с куки, он генерирует новую куки, как описано выше. Эта новая куки сравнивается с куки, найденной в сообщении ClientHello.
  • Если куки совпадают, клиент считается реальным, и сервер может продолжить процедуру рукопожатия TLS.

Примечание: Сервер DTLS не обязан использовать куки DTLS.

QDtlsClientVerifier предназначен для работы с QUdpSocket, как показано в следующем фрагменте кода:

class DtlsServer : public QObject
{
public:
    bool listen(const QHostAddress &address, quint16 port);
    // ...

private:
    void readyRead();
    // ...

    QUdpSocket serverSocket;
    QDtlsClientVerifier verifier;
    // ...
};

bool DtlsServer::listen(const QHostAddress &serverAddress, quint16 serverPort)
{
    if (serverSocket.bind(serverAddress, serverPort))
        connect(&serverSocket, &QUdpSocket::readyRead, this, &DtlsServer::readyRead);
    return serverSocket.state() == QAbstractSocket::BoundState;
}

void DtlsServer::readyRead()
{
    QByteArray dgram(serverSocket.pendingDatagramSize(), Qt::Uninitialized);
    QHostAddress address;
    quint16 port = {};
    serverSocket.readDatagram(dgram.data(), dgram.size(), &address, &port);
    if (verifiedClients.contains({address, port}) {
        // This client was verified previously, we either continue the
        // handshake or decrypt the incoming message.
    } else if (verifier.verifyClient(&serverSocket, dgram, address, port)) {
        // Apparently we have a real DTLS client who wants to send us
        // encrypted datagrams. Remember this client as verified
        // and proceed with a handshake.
    } else {
        // No matching cookie was found in the incoming datagram,
        // verifyClient() has sent a ClientVerify message.
        // We'll hear from the client again soon, if they're real.
    }
}

QDtlsClientVerifier не накладывает никаких ограничений на то, как приложение использует QUdpSocket. Например, возможно иметь сервер с одним QUdpSocket в состоянии QAbstractSocket::BoundState, одновременно обрабатывающий несколько клиентов DTLS:

  • Проверка, являются ли новые клиенты реальными клиентами DTLS.
  • Завершение рукопожатий TLS с проверенными клиентами (см. QDtls).
  • Расшифровка датаграмм, поступающих от подключенных клиентов (см. QDtls).
  • Отправка зашифрованных датаграмм подключенным клиентам (см. QDtls).

Это означает, что QDtlsClientVerifier не читает непосредственно из сокета, вместо этого он ожидает, что приложение прочитает входящую датаграмму, извлечет адрес отправителя и порт, а затем передаст эти данные в verifyClient(). Чтобы отправить сообщение HelloVerifyRequest, verifyClient() может записывать в QUdpSocket.

Примечание: QDtlsClientVerifier не принимает на себя владение объектом QUdpSocket.

По умолчанию QDtlsClientVerifier получает свой секрет из криптографически стойкого генератора псевдослучайных чисел.

Примечание: По умолчанию секрет общий для всех объектов классов QDtlsClientVerifier и QDtls. Поскольку это может создавать риски безопасности, RFC 6347 рекомендует часто изменять секрет сервера. Обратитесь к RFC 6347, раздел 4.2.1 за подсказками по возможным реализациям серверов. Параметры генератора куки можно установить с помощью класса QDtlsClientVerifier::GeneratorParameters и setCookieGeneratorParameters():

void DtlsServer::updateServerSecret()
{
    const QByteArray newSecret(generateCryptoStrongSecret());
    if (newSecret.size()) {
        usedCookies.append(newSecret);
        verifier.setCookieGeneratorParameters({QCryptographicHash::Sha1, newSecret});
    }
}

Пример сервера DTLS иллюстрирует, как использовать QDtlsClientVerifier в приложении сервера.

См. также QUdpSocket, QAbstractSocket::BoundState, QDtls, verifyClient(), GeneratorParameters, setCookieGeneratorParameters(), cookieGeneratorParameters(), QDtls::setCookieGeneratorParameters(), QDtls::cookieGeneratorParameters(), QCryptographicHash::Algorithm, QDtlsError, dtlsError() и dtlsErrorString().

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

QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent = nullptr)

Конструирует объект QDtlsClientVerifier, parent передается в конструктор QObject.

[virtual] QDtlsClientVerifier::~QDtlsClientVerifier()

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

QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorParameters() const

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

См. также QCryptographicHash::Algorithm, QDtlsClientVerifier::GeneratorParameters и setCookieGeneratorParameters().

QDtlsError QDtlsClientVerifier::dtlsError() const

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

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

QString QDtlsClientVerifier::dtlsErrorString() const

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

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

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

Устанавливает секрет и алгоритм криптографического хеширования из params. Этот QDtlsClientVerifier будет использовать их для генерации куки. Если новый секрет имеет нулевой размер, эта функция возвращает false и не изменяет параметры генератора куки.

Примечание: Сегрет должен быть криптографически безопасной последовательностью байтов.

См. также QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters() и QCryptographicHash::Algorithm.

QByteArray QDtlsClientVerifier::verifiedHello() const

Функция для удобства. Возвращает последний успешно проверенный ClientHello-сообщение или пустой QByteArray, если проверка не была выполнена.

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

bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)

socket должен быть допустимым указателем, dgram — непустым датаграммой, address не может быть null, широковещательной или многоадресной. port — порт удалённого узла. Эта функция возвращает true если dgram содержит ClientHello-сообщение с валидной куки. Если соответствующая куки не найдена, verifyClient() отправит HelloVerifyRequest-сообщение с помощью socket и вернет false.

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

if (!verifier.verifyClient(&socket, message, address, port)) {
    switch (verifyClient.dtlsError()) {
    case QDtlsError::NoError:
        // Not verified yet, but no errors found and we have to wait for the next
        // message from this client.
        return;
    case QDtlsError::TlsInitializationError:
        // This error is fatal, nothing we can do about it.
        // Probably, quit the server after reporting the error.
        return;
    case QDtlsError::UnderlyingSocketError:
        // There is some problem in QUdpSocket, handle it (see QUdpSocket::error())
        return;
    case QDtlsError::InvalidInputParameters:
    default:
        Q_UNREACHABLE();
    }
}

См. также QHostAddress::isNull(), QHostAddress::isBroadcast(), QHostAddress::isMulticast(), setCookieGeneratorParameters() и cookieGeneratorParameters().

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

Spec-Zone.ru

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