Метод проверки не срабатывает после второго ClientHello с BIO памяти OpenSSL

Я пишу собственный модуль DTLS для NodeJS, используя OpenSSL. Он использует BIO памяти, поэтому собственные сокеты узла могут использоваться для управления потоком данных. Кажется, что все работает, но я сталкиваюсь с некоторыми проблемами со смягчением DOS.

Согласно спецификации, исходное ClientHello, отправленное на сервер, должно быть отклонено, и сервер отправит HelloVerifyRequest, содержащий cookie, для повторной отправки обратно от клиента. Это все работает нормально, но когда клиент отправляет обратно второй ClientHello, по какой-то причине вызов DTLSv1_listen () вызывает мой метод генерации файлов cookie во второй раз вместо метода проверки файлов cookie. Как ни странно, если я отправлю обратно второй HelloVerifyRequest (точно такой же длины и содержания, что и первый), я получу ClientHello, который, кажется, вызывает метод проверки.

Вот небольшой тест, который я написал для иллюстрации того, что я делаю (не совсем, пропущены некоторые вещи, такие как импорт сертификата / ключа, проверка кода результата для чтения / записи после вызова рукопожатия, освобождение памяти и т. Д.).

TEST(New, Test) {
// Init context
auto ctx = SSL_CTX_new(DTLS_method());
SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, [](int ok, X509_STORE_CTX * context) { return 1; });
SSL_CTX_set_cookie_generate_cb(ctx, [](SSL * ssl, unsigned char * cookie, unsigned int * cookie_len) {
return 1;
});
SSL_CTX_set_cookie_verify_cb(ctx, [](SSL * ssl, const unsigned char * cookie, unsigned int cookie_len) {
return 1;
});

// Init connections
auto client = SSL_new(ctx);
auto client_rbio = BIO_new(BIO_s_mem());
auto client_wbio = BIO_new(BIO_s_mem());
SSL_set_bio(client, client_rbio, client_wbio);
SSL_set_connect_state(client);

auto server = SSL_new(ctx);
auto server_rbio = BIO_new(BIO_s_mem());
auto server_wbio = BIO_new(BIO_s_mem());
SSL_set_bio(server, server_rbio, server_wbio);
SSL_set_accept_state(server);

std::vector<unsigned char> data;

// Client Hello, no cookie
SSL_do_handshake(client);
auto data_len = BIO_ctrl_pending(client_wbio);
data.resize(data_len);
BIO_read(client_wbio, data.data(), data.size());

ASSERT_EQ(data[13], 1);

// Hello Verify Request
BIO_write(server_rbio, data.data(), data.size());
DTLSv1_listen(server, NULL);
data_len = BIO_ctrl_pending(server_wbio);
data.resize(data_len);
BIO_read(server_wbio, data.data(), data.size());

ASSERT_EQ(data[13], 3);

// Client Hello, with cookie
BIO_write(client_rbio, data.data(), data.size());
SSL_do_handshake(client);
data_len = BIO_ctrl_pending(client_wbio);
data.resize(data_len);
BIO_read(client_wbio, data.data(), data.size());

ASSERT_EQ(data[13], 1);

// Should be pass...?
BIO_write(server_rbio, data.data(), data.size());
ASSERT_EQ(DTLSv1_listen(server, NULL), 1);
}

Последнее утверждение не выполняется — в данном примере это -1, 0 в моем фактическом коде (и последующий BIO_read возвращает мне данные [13] = 3, иначе HelloVerifyRequest), но важно отметить, что если вы присоедините отладчик и поставите точка останова на проверке лямбда не будет ударить.

0

Решение

Вы можете попробовать использовать nodejs-DTLS

Пример использования можно найти в
IOTBroker. клиент облачного узла

Взгляните на протоколы CoAP и MQTT-SN

BR

Юлиан Ойфа

Mobius Software

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector