【问题标题】:OpenSSL SSL_read Failure (error:00000005:lib(0):func(0):DH lib)OpenSSL SSL_read 失败(错误:00000005:lib(0):func(0):DH lib)
【发布时间】:2018-04-11 22:15:00
【问题描述】:

我正在使用 OpenSSL 版本 1.1.0f 来加密我的客户端和我没有任何访问权限的中继服务器之间的连接。有时客户端的连接会因为客户端的 readLine 失败而突然终止。

这是错误代码:

readLine:readString 返回 -1,错误消息 - 错误:00000005:lib(0):func(0):DH lib

我确实搜索过这种错误代码的适当原因,每个人(例如this线程)都说在连接建立期间Diffie-Helman密钥交换似乎有问题。但是连接在几分钟内一直正常(有时甚至可能不会发生,并且在连接成功后 2 到 3 分钟后可能会非常频繁地发生一次),直到它突然终止。

以下是我的日志中的更多错误

SSL_read 失败,错误 - 5,接收到的字节数 -1,错误字符串 error:00000005:lib(0):func(0):DH lib, wsaError 0

SSL 错误 - 5:error:FFFFFFFF:lib(255):func(4095):reason(4095)

这是来自 SSL 客户端的套接字读取代码

if ((isSecureMode() == true) && (lpSSL != NULL))
{
    bytesReceived = SSL_read(lpSSL, receiveBuf, bufferSize) ;

    if ((bytesReceived <= 0))
    {
        int sslErrorCode = lpSSL ? SSL_get_error(lpSSL, bytesReceived) : -1;

        char sslErrorString[MAX_ERROR_MSG_LEN] = {'\0'};

        ERR_error_string(sslErrorCode, sslErrorString);
        setLastError(sslErrorCode, std::string(sslErrorString));

        int wsaError = WSAGetLastError();

        if(isShutdownInitiated == false)
        {
            if (Logger)
            {
                Logger->log(LOG_WARNING, "receiveString - SSL_read failed with error - %d, bytes received %d, error string %s, wsaError %d", sslErrorCode, bytesReceived, std::string(sslErrorString), wsaError);
            }
                                                    // Always return -1 incase of failure
            bytesReceived = -1;
        } 
        else
        {
            if (Logger)
            {
                Logger->log(LOG_WARNING, "receiveString - Socket was Shutdown, SSL_read failed with error - %d, bytes received %d, error string %s , wsaError %d", sslErrorCode, bytesReceived, std::string(sslErrorString), wsaError);
            }

            setLastError(ERROR_ALREADY_SHUTDOWN);
            bytesReceived = -1;
        }
    }
}

我不是 OpenSSL 方面的专家,我怀疑问题可能出在服务器上,但除了上述错误消息之外,没有任何错误消息可以证明这一点。

我确实分析了很多,并且花了数周时间没有任何改进。

更新: 在分析错误消息后,错误代码 SSL_ERROR_SYSCALL 和 wsa error_code 10054 表示连接已被远程方终止。服务器日志中写入了相同的错误消息。这导致怀疑连接是否由中间设备(可能是驻留在客户端和服务器之间的路由器)根据this 线程进行重置。我正在尝试进一步分析并解决问题。

更新 2: 我还发现该问题有时仅在某些网络上发生。它在少数网络上运行良好。上述线程也说明了这一点。

更新3:我已经弄清楚了连接终止的原因之一,错误10054实际上是由于防火墙和现在已经解决的网络。

调试 readline 失败并出现错误

SSL_read 失败,错误 - 5,接收到的字节数 -1,错误字符串 错误:00000005:lib(0):func(0):DH lib, wsaError 0

任何帮助将不胜感激。

【问题讨论】:

  • 您是否使用 SSL_CTX_check_private_key() 检查了您的私钥和证书的一致性?我怀疑你的上下文对象。还有你用于 SSL_CTX 的方法是什么?
  • 我正在为 SSL_CTX 使用 TLSv1_2_client_method。
  • 我没有做任何 SSL_CTX_check_private_key()。使用默认的证书存储证书,服务器的证书由受信任的机构签名。
  • 您使用的是哪个版本的openSSL?
  • 但连接正常运行了几分钟(有时甚至可能不会发生,并且在连接成功 2 到 3 分钟后可能会非常频繁地发生一次),直到它突然终止。 这听起来像是防火墙或 NAT 路由器等中间设备在超时间隔内没有任何流量的情况下超时连接。你如何建立你的 TCP 连接?如果启用 TCP keepalive,您可能会获得更好的结果。

标签: c++ windows ssl tcp openssl


【解决方案1】:

SSL_get_error 的返回值不应传递给ERR_error_stringsslErrorCode 中的值 5 可能是 SSL_ERROR_SYSCALL

您应该使用ERR_get_error 遍历本地线程错误队列以查找失败的原因,并且您还应该在调用SSL_read 之前清空错误队列。

(所有这些都包含在https://stackoverflow.com/a/37980911/1478356中)

也有很多关于SSL_read 返回-1SSL_ERROR_SYSCALLSSL_get_error)的报告,当errno = 0(Windows 上的WSAGetLastError)和错误队列为空时,当底层连接接收到一个EOF。请参阅https://github.com/openssl/openssl/issues/1903 进行长时间讨论;特别是 this comment 解释了如何手动检查 EOF。

有人声称此问题已在 1.1.0d 中得到修复,但在 1.1.0f 中也有其他报告包含此错误(例如 https://redmine.lighttpd.net/issues/2784)。

【讨论】:

  • SSL_ERROR_SYSCALL 是否有一般原因,以及推荐的解决方案?某些文档似乎不正确/过时并不是一个乐观的迹象......
  • 一般原因是“系统调用”的(未处理的)错误,即低级 POSIX(“libc”)函数。 errno / WSAGetLastError 应该会给你潜在的问题。
猜你喜欢
  • 2016-12-12
  • 2017-01-23
  • 1970-01-01
  • 2016-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 2012-03-15
相关资源
最近更新 更多