SSL_read因SSL_ERROR_SYSCALL错误而失败

时间:2012-12-03 15:29:30

标签: openssl ssl

我们已经使用openssl实现了tls。从服务器下载较大的数据时收到一些数据后出现SSL_ERROR_SYSCALL错误。对于较小的文件,我没有收到此错误,能够下载没有任何错误。对于较大的文件,ERR_get_error()显示为零。

我们正在使用linux和c ++框架。如何找到失败的原因?失败的原因是什么?请提供你的建议。

6 个答案:

答案 0 :(得分:8)

SSL_ERROR_SYSCALL表示底层I / O发生了一些问题(在这种情况下应该是TCP)。因此,您可以尝试使用errno进行检查。

OpenSSL帮助说:

  

SSL_ERROR_SYSCALL

     

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

答案 1 :(得分:4)

检查是否使用缓冲区大小为0调用SSL_read()。我使用SSL_pending()犯了以下错误:

int waitForReadFd = nBuf < bufSize;

if (waitForReadFd)
    FD_SET(fd, &rfds);

// ...
// select

int doReadFd = FD_ISSET(fd, &rfds) || SSL_pending(ssl);

if (doReadFd)
    n = SSL_read(ssl, buf, bufSize - nBuf);

如果调用nBuf == bufSize SSL_read(),缓冲区大小为0,则导致SSL_ERROR_SYSCALL与errno == 0。

更改doReadFd检查可以避免此问题:

int doReadFd = FD_ISSET(fd, &rfds) || nBuf < bufSize && SSL_pending(ssl);

答案 2 :(得分:3)

如果您查看SSL_get_error()的源代码,您会看到,只要它不确定究竟发生了什么,它就会返回SSL_ERROR_SYSCALL。它基本上是“未知”案例的默认返回码。

例如,在我的情况下(使用BIO执行非阻塞IO):

int buf;
const int n = SSL_read(ssl, &buf, 0);
const int err = SSL_get_error(ssl, n);
const int st = ERR_get_error();

n为0时,err仅为SSL_ERROR_SYSCALL因为。但是st仍然为0表示没有真正的错误。 SSL_read刚刚返回0,因为0个字节被写入buf

但是,请在通话后查看errno / WSAGetLastError()值,了解更多详情。

答案 3 :(得分:0)

问题是由网络连接被切断和服务器重新设置引起的。

在下载数据之前,请确保连接正常。

使用vagrant时可以看到类似的问题。

https://github.com/hashicorp/vagrant/issues/9612

答案 4 :(得分:0)

我发现问题出在我的公司防火墙阻止了请求。回家就可以了

答案 5 :(得分:0)

我们在Go应用程序中遇到了此错误。我们正在使用第三方库从Go连接到基础的openssl库。在读取数据时,第三方库正在将要读取的缓冲区/数据的长度转换为32位的C.int。对于大于等于2GB的大数据,这会导致溢出,并且会将负值传递给C.SSL_read函数。 在这种情况下,它会引发SSL_ERROR_SYSCALL错误。