2017-01-30 2 views
1

Я использую OpenSSL 1.0.0-fips для Linux. Вопрос, который у меня возникает, заключается в том, что SSL_connect() возвращается -1, а SSL_get_error() возвращает SSL_ERROR_WANT_READ. Затем я помещаю дескриптор файла в select() с установкой timeval, установленной на 10 секунд, и select() просто отключается.Неблокирующий ввод-вывод с OpenSSL BIO

Я запустил Wireshark, и я вижу «Клиент Hello», и я вижу, что ServerHello возвращается к клиенту, но он никогда не «просыпается» в select(). Это просто время.

Мои вопросы:

  1. Должен ли я создать объект BIO с использованием BIO_new_socket() и затем назначьте объект BIO для моего объекта SSL с помощью SSL_set_bio()? В справочной странице для SSL_set_fd() указано, что она автоматически создаст объект BIO, чтобы, по-видимому, было указано, что SSL_set_bio() - это бесполезная функция, которую вам никогда не нужно звонить.

  2. Скажем, мы используем SSL_set_fd() и назначаем связанный файловый дескриптор TCP, который блокируется. Скажем, позже мы изменим этот файловый дескриптор на неблокирующий, используя fcntl(). Разве это вообще нарушает объект SSL (или базовый объект BIO)?

+0

Вероятно, вы должны указать некоторый код, включая настройку контекста. Асинхронный ввод-вывод и неблокирующие сокеты дают людям массу проблем, потому что библиотека не слишком удобна. Ознакомьтесь с исходным кодом для ['apps/ocsp.c'] (https://github.com/openssl/openssl/blob/master/apps/ocsp.c), чтобы узнать, как это работает OpenSSL. Кажется, я вспоминаю, что обычный контекст настроен в режиме блокировки, затем все переключается в неблокирующий режим с использованием основного сокета. Найдите код, который вызывает 'BIO_get_fd' и' select'. AFAIK, его единственный пример неблокирующего ввода-вывода в самодокументирующем коде :) – jww

+1

Я не публиковал код, потому что вся функция соединения для моего реализованного класса C++ SSL Socket довольно велика. Однако я нашел свою проблему. Я забыл добавить 1 к аргументу maxfd для выбора(). –

ответ

1

1) Должен ли я создать объект BIO с использованием BIO_new_socket(), а затем назначить объект BIO для моего объекта SSL с помощью SSL_set_bio()? Мужчина page для SSL_set_fd() говорит, что он автоматически создаст объект BIO , так что это означает, что SSL_set_bio() - это бесполезная функция , которую вам никогда не нужно звонить.

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

2) Допустим, мы используем SSL_set_fd() и назначить подключенный TCP файл дескриптор, который блокирует. Скажем, позднее мы изменим этот дескриптор файла на неблокирование с помощью fcntl(). Разве это вообще нарушает объект SSL (или базовый объект BIO)?

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

В частности, эта цитата из человека страницы:

БИО и, следовательно, SSL двигатель наследует поведение дескриптора.

...предположим, что вызовы настройки SSL будут проверять состояние вашего fd и устанавливать частные переменные в BIO и объекты SSL на основе блокирующего/неблокирующего состояния fd. Если вы затем «заходите за спину OpenSSL» и меняете поведение fd, подпрограммы OpenSSL не ожидают этого и, скорее всего, сделают неправильную вещь и не будут работать правильно.

+0

Итак, моя функция соединения, которую я написал в моем классе C++ SSL Socket, присваивает дескриптор файла объекту SSL с использованием SSL_set_fd(), а затем после этого устанавливает дескриптор файла в неблокирующий с помощью fnctl(), и он работает нормально. Я могу даже переключить его обратно на блокировку, и уровень SSL ведет себя так, как я ожидаю, что он будет себя вести. Таким образом, эта документация, похоже, вводит в заблуждение или просто может быть просто удачей, что она работает так, как я ее хочу. –

Смежные вопросы