Запись байтов напрямую в OpenSSL Connection, без TCP

Я внедряю сервер RADIUS с поддержкой аутентификации EAP(PEAP). RADIUS использует UDP, и каждый пакет будет содержать сообщение EAP с данными аутентификации. Для упрощения каждое сообщение EAP(PEAP) содержит пакеты TLS, поэтому клиент сначала отправит пакет EAP, содержащий подтверждение клиента TLS, которое будет обрабатывать сервер, а затем вернет подтверждение подключения сервера TLS и т. Д. Со следующими пакетами.

Мне удалось реализовать простой TLS-сервер через TCP, но мне нужно написать TLS-байты непосредственно в SSL-соединении.

SSLConn_init_thread();
SSL_load_error_strings();
ERR_load_crypto_strings();
SSL_library_init();

SSL_CTX *ctx;
...
ctx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_use_PrivateKey(...);
SSL_CTX_use_certificate(...);

ssl = SSL_new(ctx); // I want to read/write TLS packets directly with this object

Я изучил документы OpenSSL, но они не очень хорошо документированы. В этом руководстве говорится, что можно сделать рукопожатие "вручную", используя SSL_set_accept_state() с SSL_read и SSL_write, но я точно не понимаю, как это сделать.

Любой совет с этим или об обработке соединений OpenSSL без использования TCP был бы очень признателен.

2 ответа

Решение

В итоге я прочитал книгу " Сетевая безопасность с OpenSSL" и обнаружил, что память BIO - это то, что мне нужно.

Сетевая безопасность с OpenSSL

Память BIO обрабатывает сегмент памяти так же, как файл или сокет, и может быть создан с использованием BIO_s_mem для получения объекта BIO_METHOD, подходящего для использования с BIO_new и BIO_set

BIO_s_mem ()

BIO_s_mem () возвращает функцию метода BIO памяти.

Память BIO - это источник / приемник BIO, который использует память для своих операций ввода-вывода. Данные, записанные в БИО памяти, хранятся в структуре BUF_MEM, которая расширяется в зависимости от необходимости для хранения хранимых данных.

Любые данные, записанные в память BIO, могут быть вызваны чтением из нее. Если только память BIO не будет прочитана, любые данные, прочитанные с нее, будут удалены из BIO.

По сути, вы можете читать / записывать зашифрованные данные непосредственно в соединение SSL, используя BIO памяти:

// setup SSL_context...
ssl = SSL_new(ctx);

// Create read/write BIOs 
rbio = BIO_new(BIO_s_mem());
wbio = BIO_new(BIO_s_mem());

SSL_set_bio(ssl, rbio, wbio);

if (/* Server */) {
  SSL_set_accept_state(ssl); 
} else {
  SSL_set_connect_state(ssl);
}

Чтобы писать / читать из БИО:

BIO_read(wbio, buffer, strlen(buffer));
BIO_write(wbio, buffer, strlen(buffer));

В терминах диаграммы ascii, вот как выглядит цикл байтов. SSL_read/SSL_write используются для передачи незашифрованных байтов в / из объекта SSL, а BIO_read/BIO_write используются для получения соответствующих зашифрованных байтов в / из объекта SSL. Затем вам нужно передать зашифрованные байты по сетевому соединению.

Git Hub пример неблокирующих сокетов / SSL

( https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca)

  +------+                                    +-----+
  |......|--> read(fd) --> BIO_write(rbio) -->|.....|--> SSL_read(ssl)  --> IN
  |......|                                    |.....|
  |.sock.|                                    |.SSL.|
  |......|                                    |.....|
  |......|<-- write(fd) <-- BIO_read(wbio) <--|.....|<-- SSL_write(ssl) <-- OUT
  +------+                                    +-----+
          |                                  |       |                     |
          |<-------------------------------->|       |<------------------->|
          |         encrypted bytes          |       |  unencrypted bytes  |
Другие вопросы по тегам