SSL_connect и SSL_ERROR_SYSCALL

SSL_connect() ли SSL_connect() поддержку ssl v3? Причина, по которой я прошу об этом, при доступе к сайту:

 https://secure53.onlineaccess1.com 

Я получаю возвращаемое значение для SSL_connect(ssl) как <0 и SSL_get_error() как 5 и ERR_get_error () как 0. Поэтому конечный результат я обнаружил, что, поскольку SSL_get_error() равен 5,

SSL_ERROR_SYSCALL

Произошла некоторая ошибка ввода-вывода. Очередь ошибок OpenSSL может содержать больше информации об ошибке. Если очередь ошибок пуста (т.е. ERR_get_error () возвращает 0), ret может использоваться, чтобы узнать больше об ошибке: Если ret == 0, наблюдался EOF, который нарушает протокол. Если ret == -1, базовый BIO сообщил о ошибке ввода-вывода (для ввода-вывода сокета в системах Unix, обратитесь за помощью к errno).

И поскольку ERR_get_error() возвращает 0, it means an EOF was observed that violates the protocol.

Но означает ли это, что он не поддерживает sslv3?

Я попробовал url в командной строке, используя curl, и мне пришлось заставить v3 заставить его работать следующим образом:

 curl -3 -v https://secure53.onlineaccess1.com 

И есть ли способ исправить эту ошибку?

Я использовал SSLv23_method() чтобы начать соединение. Но я думаю, что сервер не понимает sslv2. Поскольку этот метод will send out SSLv2 client hello messages and will indicate that it also understands SSLv3 and TLSv1 , сервер не понял, чего я хотел, и закрыл соединение с EOF .

Поэтому я попытался использовать SSLv3_method() для подключения к этому серверу, и он сработал. Так что теперь я пытаюсь подключиться к SSLv23_method() и если он не работает с SSL_ERROR_SYSCALL для SSL_get_error() и 0 для ERR_get_error() , я просто перезагружаю соединение и начинаю заново с помощью SSLv3_method() . Не лучший способ, я знаю. Но это работает.

Как показано на странице руководства:

 SSLv23_method(void), SSLv23_server_method(void), SSLv23_client_method(void) A TLS/SSL connection established with these methods will understand the SSLv2, SSLv3, and TLSv1 protocol. A client will send out SSLv2 client hello messages and will indicate that it also understands SSLv3 and TLSv1. A server will understand SSLv2, SSLv3, and TLSv1 client hello messages. This is the best choice when compatibility is a concern. 

Поэтому, в зависимости от используемой версии openSSL, при использовании SSLv23_client_method () клиент попытается согласовать самый высокий уровень протокола, который он может найти вместе с сервером.

Скорее всего, ваш сервер не поддерживает TLSv1.0 или выше. Я бы попробовал следующее:

 SSL_CTX *sslCTX = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_options(sslCTX, SSL_OP_ALL | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1); 

эффективно пытается договориться с SSLv3 и с возможным откатом на SSLv2

И поскольку ERR_get_error () возвращает 0, это означает, что наблюдался EOF, который нарушает протокол.

Нет. В этом случае вам следует посоветоваться с ret (акцент мой):

SSL_ERROR_SYSCALL

Произошла некоторая ошибка ввода-вывода. Очередь ошибок OpenSSL может содержать больше информации об ошибке. Если очередь ошибок пуста (т.е. ERR_get_error () возвращает 0), ret может использоваться, чтобы узнать больше об ошибке : Если ret == 0, наблюдался EOF, который нарушает протокол. Если ret == -1, базовый BIO сообщил о ошибке ввода-вывода (для ввода-вывода сокета в системах Unix, обратитесь за помощью к errno).

ret был передан в SSL_get_error() так что ret – это код возврата из вашего первоначального SSL_connect() . Вы заявили, что получили значение возврата <0 из SSL_connect() . Если он равен -1, и вы находитесь в системе unix, вам следует посоветоваться с errno чтобы узнать, что произошло (внимание мое):

SSL_ERROR_SYSCALL

Произошла некоторая ошибка ввода-вывода. Очередь ошибок OpenSSL может содержать больше информации об ошибке. Если очередь ошибок пуста (т.е. ERR_get_error () возвращает 0), ret может использоваться, чтобы узнать больше об ошибке: Если ret == 0, наблюдался EOF, который нарушает протокол. Если ret == -1, базовый BIO сообщил о ошибке ввода-вывода (для ввода-вывода сокета в системах Unix, обратитесь за помощью к errno) .