Запись байтов напрямую в 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 памяти.
Память 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 |