Непосредственно считывать / записывать данные подтверждения с помощью памяти BIO

Мне нужно создать соединение OpenSSL, где я могу напрямую читать / записывать данные подтверждения. Причина заключается в том, что данные установления связи будут передаваться в UDP-соединении (DTLS не является опцией, поскольку данные не находятся непосредственно в дейтаграмме, а внутри других пакетов протокола EAP, если вам интересно). До сих пор я создал соединение OpenSSL, но я даже не смог прочитать рукопожатие клиента для отправки на сервер.

В своем исследовании я обнаружил, что мне нужна память BIO для чтения / записи в соединение, но не могу понять, как извлечь данные для рукопожатия. Вот как я инициализирую клиентское соединение:

SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ctx = SSL_CTX_new(SSLv3_client_method()); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, rbio, wbio); SSL_set_connect_state(ssl); 

Я попробовал doint SSL_connect , чтобы инициировать рукопожатие:

 int ret = SSL_connect(ssl); 

Но возвращает -1 и делает SSL_get_error(ssl, res) Я получаю код ошибки 2 , затем я ERR_error_string с этим кодом и получаю:

 error:00000002:lib(0):func(0):system lib 

Кроме того, если я использую SSL_do_handshake вместо SSL_connect я получаю точно такую ​​же ошибку.

Я смог установить соединение OpenSSL через TCP, но никогда не делал этого с Memory BIO, поэтому любая помощь с этим была бы очень оценена. Благодаря!

Наконец, я заработал, я был в правильном направлении:

Функция SSL_set_connect_state(ssl) необходима, чтобы сообщить, что соединение будет подготовлено для инициализации рукопожатия. Затем мы вызываем SSL_do_handshake(ssl) чтобы начать рукопожатие. Эта функция вернет -1 потому что рукопожатие еще не закончено, но мы действительно можем читать из клиентского ssl-соединения BIO-записи и отправлять данные с использованием требуемого протокола (в моем случае, EAP RADIUS-пакеты через UDP).

клиент

 ctx = SSL_CTX_new(SSLv3_client_method()); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, rbio, wbio); SSL_set_connect_state(ssl); SSL_do_handshake(ssl); // This will return -1 (error) as the handshake is not finished, we can ignore it. char buf[4096]; BIO_read(wbio, buf, 4096); // Read from BIO, put data in buffer // Then use data in buffer to send to the server 

Сервер, с другой стороны, должен быть настроен с использованием учетных данных и закрытого ключа. Кроме того, вместо SSL_set_connect_state() мы должны использовать SSL_set_accept_state() как сервер будет ждать приветствия клиента. Затем мы просто пишем данные приветствия приветствия клиента на сервер BIO reader:

сервер

 ctx = SSL_CTX_new(SSLv3_server_method()); // This is the server! SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); ssl = SSL_new(ctx); rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); SSL_set_bio(ssl, rbio, wbio); SSL_set_accept_state(ssl); // The server uses SSL_set_accept_state // Here we get the data from the client suppose it's in the variable buf // and write it to the connection reader BIO. BIO_write(rbio, buf, strlen(buf)); if (!SSL_is_init_finished(ssl)) { SSL_do_handshake(ssl); } 

Мы можем использовать SSL_is_init_finished(ssl) чтобы проверить, выполнено ли рукопожатие, и пока это не сделано, мы вызываем SSL_do_handshake(ssl) , а затем снова читаем из BIO_writer для отправки данных клиенту.

Этот процесс между клиентом и сервером должен выполняться до тех пор, пока соединение не будет выполнено (т.е. SSL_is_init_finished(ssl) возвращает true ).

Затем, после того, как рукопожатие будет завершено, вы можете отправлять защищенные данные между клиентом / сервером, используя функции SSL_read и SSL_write . Надеюсь, это короткое объяснение полезно для кого-то!

Попробуйте сделать это

 // Connect the TCP socket (this is client side) int sock = tcp_connect(host, port); // Create BIO around the connected TCP socket BIO *sbio = BIO_new_socket(sock, BIO_NOCLOSE); SSL_set_bio(ssl,sbio,sbio); int ret = SSL_connect(ssl); 

Подумайте о BIO как обертывании сокета. Для клиентской стороны вы должны предоставить ему сокет, который подключен к требуемому хосту и порту, используя вызов connect (…). Для серверной стороны просто используйте сокет, который возвращается из вызова accept (…).

  • Регистрация нескольких хранилищ ключей в JVM
  • Heroku NodeJS http to https ssl принудительное redirect
  • Почему запросы Python игнорируют параметр проверки?
  • По умолчанию SecurityProtocol в .NET 4.5
  • curl: (60) SSL-сертификат: не удалось получить сертификат локального эмитента
  • javax.net.ssl.SSLHandshakeException: удаленное подключение к удаленному хосту во время рукопожатия во время веб-службы Communicaiton
  • Получение Chrome для принятия самоподписанного локального сертификата
  • SSL, Tomcat и Grails
  • Java-соединение и HTTPS-соединение без скачивания сертификата
  • javax.net.ssl.SSLException: Ошибка чтения: ssl = 0x9524b800: ошибка ввода-вывода во время системного вызова, сброс соединения с помощью одноранговой сети
  • веб-просмотр android с сертификатом клиента
  • Давайте будем гением компьютера.