SSL_shutdown上的openssl文档指出: 因此,如果双向关闭尚未完成(第一次调用的返回值为0),建议检查SSL_shutdown()的返回值并再次调用SSL_shutdown()。
https://www.openssl.org/docs/ssl/SSL_shutdown.html
我在下面有一个代码片段,我从SSL_shutdown检查返回值0并再次调用它,我一直在使用它。我的问题是,可以忽略第二次调用时SSL_shutdown的返回值,或者我们应该继续重试SSL_shutdown,直到返回1(双向关闭完成)。
int r = SSL_shutdown(ssl);
//error handling here if r < 0
if(!r)
{
shutdown(fd,1);
SSL_shutdown(ssl); //how should I handle return value and error handling here is it required??
}
SSL_free(ssl);
SSLMap.erase(fd);
shutdown(fd,2);
close(fd);
答案 0 :(得分:11)
openssl
是一种黑暗艺术。
首先,您引用的页面具有HTML-ified错误的返回值。这是man-page 实际上所说的内容:
RETURN VALUES
The following return values can occur:
0 The shutdown is not yet finished. Call SSL_shutdown() for a second
time, if a bidirectional shutdown shall be performed. The output
of SSL_get_error(3) may be misleading, as an erroneous
SSL_ERROR_SYSCALL may be flagged even though no error occurred.
1 The shutdown was successfully completed. The "close notify" alert
was sent and the peer's "close notify" alert was received.
-1 The shutdown was not successful because a fatal error occurred
either at the protocol level or a connection failure occurred. It
can also occur if action is need to continue the operation for non-
blocking BIOs. Call SSL_get_error(3) with the return value ret to
find out the reason.
如果您有阻止BIO,事情就相对简单了。如果您想要双向关机,则第一次呼叫时0表示您需要再次呼叫SSL_shutdown
。 1意味着你已经完成了。 A -1表示错误。在第二次调用时(只有在返回0时才会执行),然后启动双向关闭。逻辑规定你不能再回到0(因为它是一个阻塞的BIO并且将完成第一步)。 A -1表示错误,1表示完成。
如果你有非阻塞的BIO,同样适用,除了你需要经历整个SSL_ERROR_WANT_READ
和SSL_ERROR_WANT_WRITE
严格的事实,即:
If the underlying BIO is non-blocking, SSL_shutdown() will also return
when the underlying BIO could not satisfy the needs of SSL_shutdown()
to continue the handshake. In this case a call to SSL_get_error() with
the return value of SSL_shutdown() will yield SSL_ERROR_WANT_READ or
SSL_ERROR_WANT_WRITE. The calling process then must repeat the call
after taking appropriate action to satisfy the needs of SSL_shutdown().
The action depends on the underlying BIO. When using a non-blocking
socket, nothing is to be done, but select() can be used to check for
the required condition. When using a buffering BIO, like a BIO pair,
data must be written into or retrieved out of the BIO before being able
to continue.
所以你有两个重复级别。如果您以正常方式绕过SSL_shutdown
循环后获得SSL_ERROR_WANT_READ
或SSL_ERROR_WANT_WRITE
,则只需将select()
称为“第一次” SSL_shutdown
如果您收到非SSL_ERROR_WANT_
错误代码(在这种情况下失败了),或者您获得0
或1
返回,则表示已完成。如果你得到1
回复,你就完成了。如果您获得0
返回,并且您想要双向关机,那么您必须进行第二次通话,您需要再次检查SSL_ERROR_WANT_READ
或SSL_ERROR_WANT_WRITE
并重试选择;不应返回1
,但可能返回0或错误。
不简单。