OpenSSL SSL_read失败(错误:00000005:lib(0):func(0):DH lib)

时间:2017-10-30 20:26:20

标签: c++ windows ssl tcp openssl

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

以下是错误代码:

  

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

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

以下是我所拥有的日志中的一些错误

  

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

     

SSL错误 - 5:错误: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

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:5)

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

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

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

SSL_read(Windows上为-1)时,还有许多SSL_ERROR_SYSCALL返回SSL_get_errorerrno = 0 WSAGetLastError}的报告当底层连接收到EOF时,错误队列为空。有关详细讨论,请参阅https://github.com/openssl/openssl/issues/1903;特别是this comment解释了如何手动检查EOF。

有人声称这已在1.1.0d中修复,但在1.1.0f中还有其他报告存在此错误(例如https://redmine.lighttpd.net/issues/2784)。