【问题标题】:SSL_connect and SSL_ERROR_SYSCALLSSL_connect 和 SSL_ERROR_SYSCALL
【发布时间】:2015-05-03 04:04:46
【问题描述】:

SSL_connect() 是否支持 ssl v3? 我问这个的原因是,在访问该网站时:

https://secure53.onlineaccess1.com

SSL_connect(ssl) 的返回值为 SSL_get_error() 的返回值为 5,ERR_get_error() 的返回值为 0。所以最终结果是我发现 SSL_get_error() 为 5,

SSL_ERROR_SYSCALL

发生了一些 I/O 错误。 OpenSSL 错误队列可能包含有关错误的更多信息。如果错误队列为空(即 ERR_get_error() 返回 0),ret 可用于查找有关 错误:如果 ret == 0,则观察到违反协议的 EOF。如果 ret == -1,底层 BIO 报告了一个 I/O 错误(对于 socket I/O on Unix系统,详情请咨询errno)。

由于ERR_get_error()返回0,it means an EOF was observed that violates the protocol.

但这是否意味着它不支持 sslv3?

我在命令行中使用 curl 尝试了 url,我不得不强制 v3 让它像这样工作:

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

有没有办法修复这个错误?

【问题讨论】:

  • 截至今天(2015 年 5 月),该站点仅支持 TLS 1.0 及更高版本。

标签: c++ ubuntu openssl


【解决方案1】:

我使用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_SYSCALLSSL_get_error()0ERR_get_error() 连接失败,我只需重置连接并使用SSLv3_method() 重新开始.我知道,这不是最好的方法。但它有效。

【讨论】:

    【解决方案2】:

    如手册页所示:

    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

    【讨论】:

      【解决方案3】:

      由于 ERR_get_error() 返回 0,这意味着观察到违反协议的 EOF。

      没有。它说在这种情况下你应该咨询ret(强调我的):

      SSL_ERROR_SYSCALL

      发生了一些 I/O 错误。 OpenSSL 错误队列可能包含有关错误的更多信息。 如果错误队列为空(即 ERR_get_error() 返回 0),则可以使用 ret 来查找有关错误的更多信息:如果 ret == 0,则观察到违反协议的 EOF。如果 ret == -1,则底层 BIO 报告 I/O 错误(对于 Unix 系统上的套接字 I/O,请参阅 errno 了解详细信息)。

      ret 已传递给 SSL_get_error(),因此 ret 是您原来的 SSL_connect() 调用的返回码。你说你从SSL_connect() 得到一个返回值errno 以了解发生了什么(强调我的):

      SSL_ERROR_SYSCALL

      发生了一些 I/O 错误。 OpenSSL 错误队列可能包含有关错误的更多信息。如果错误队列为空(即 ERR_get_error() 返回 0),则可以使用 ret 来查找有关错误的更多信息:如果 ret == 0,则观察到违反协议的 EOF。 如果 ret == -1,则底层 BIO 报告 I/O 错误(对于 Unix 系统上的套接字 I/O,请参阅 errno 了解详细信息)

      【讨论】:

      • 我在实现自定义 BIO 时遇到了完全相同的问题,并且 perror 报告“成功”这种方法的问题是,从 ssl 中生成错误的时间和地点到最终确定您需要的位置阅读errno,发生了很多事情,例如注销了许多行。
      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 2018-08-05
      • 2019-03-28
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 2019-01-12
      相关资源
      最近更新 更多