正确处理SSL_shutdown [英] Handling SSL_shutdown correctly
问题描述
在SSL_shutdown OpenSSL的文档指出:
因此建议,检查SSL_shutdown(返回值),并再次呼吁SSL_shutdown(),如果双向停机尚未完成(第一次调用的返回值为0)。
https://www.openssl.org/docs/ssl/SSL_shutdown.html
我有一个code段下面,我检查来自SSL_shutdown返回值为0,并再次调用它,这是我一直在使用。我的问题是,什么情况下可以忽略第二呼叫SSL_shutdown的返回值,或者我们应该继续重试SSL_shutdown直到1(双向停机完成)返回。
INT R = SSL_shutdown(SSL);
//错误处理这里如果为r 0
如果(!R)
{ 关闭(FD,1);
SSL_shutdown(SSL); //我应该怎么处理返回值和错误处理这里需要它?
}
SSL_free(SSL);
SSLMap.erase(FD);
关闭(FD,2);
关闭(FD);
的OpenSSL
是有点暗的艺术。
首先,你所引用的页面已经严重HTML的指明分数的返回值。下面是该名男子页的真正的说道:
返回值 可能会出现以下返回值: 0关机尚未完成。呼叫SSL_shutdown()如属第二
一次,如果应进行双向关闭。输出
SSL_get_error的(3)可以是误导,因为错误的
SSL_ERROR_SYSCALL可被标记,即使没有发生错误。 1关机已成功完成。 关闭通知警报
发送和接收对方的关闭通知警报。 -1关闭未成功,因为发生了致命错误
无论在协议级或连接故障的发生。它
如果动作是需要继续对非操作也可能发生
阻塞BIOS。呼叫SSL_get_error(3)与返回值ret到
找出原因。
如果你有阻止BIOS,事情就比较简单。在第一次调用A 0意味着你需要,如果你想有一个双向停机再打电话 SSL_shutdown
。 A 1意味着大功告成。 A -1意味着一个错误。在第二个电话(你只有当你得到了一个0回做),然后双向停机启动。从逻辑上讲,你不能得到一个0回来(因为它是一个阻塞BIO和将完成的第一步)。 A -1表示错误,和1表示完成。
如果您有无阻塞的BIOS,同样适用,节省您需要去通过全 SSL_ERROR_WANT_READ
和 SSL_ERROR_WANT_WRITE 事实code>繁琐程序,即:
如果底层的BIO是非阻塞,SSL_shutdown()也将返回
当底层BIO不能满足SSL_shutdown的需求()
继续握手。在这种情况下SSL_get_error()的调用与
SSL_shutdown()的返回值将产生SSL_ERROR_WANT_READ或
SSL_ERROR_WANT_WRITE。然后调用进程必须重复调用
采取适当的行动,以满足SSL_shutdown的需要()之后。
的操作取决于底层的BIO。当使用非阻挡
插座,没有什么是必须要做的,但选择()可以用来检查
所需要的条件。当使用一个缓冲BIO,就像一个BIO对,
数据必须写入或能够之前检索出的生物
接着说。
所以,你有重复的两个层次。你叫 SSL_shutdown
第一个时间,但如果你重复 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
以正常的方式围绕选择()
循环会后,只算第一个 SSL_shutdown
为已完成,如果你得到一个非 SSL_ERROR_WANT _
错误code(在这种情况下,它失败了),或者你收到了 0
或 1
的回报。如果你收到了 1
回报,你所做的一切。如果你收到了 0
回报,你想有一个双向停机,那么你必须做第二个电话,在其再次你将需要检查 SSL_ERROR_WANT_READ
或 SSL_ERROR_WANT_WRITE
并重新选择;这不应该返回 1
,但可能返回0或错误。
并不简单。
The openssl documentation on SSL_shutdown states that : It is therefore recommended, to check the return value of SSL_shutdown() and call SSL_shutdown() again, if the bidirectional shutdown is not yet complete (return value of the first call is 0).
https://www.openssl.org/docs/ssl/SSL_shutdown.html
I have a code snippet below where I check for return value 0 from SSL_shutdown and call it again, which I have been using. My question is, is it okay to disregard the return value of SSL_shutdown on the second call or we should keep retrying SSL_shutdown until a 1(bidirectional shutdown complete) is returned.
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);
openssl
is a bit of a dark art.
Firstly the page you referenced has HTML-ified the return values badly. Here's what the man-page actually says:
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.
If you have blocking BIOs, things are relatively simple. A 0 on the first call means you need to call SSL_shutdown
again if you want a bidirectional shutdown. A 1 means you're done. A -1 means an error. On the second call (which you only do if you got a 0 back), then a bidirectional shutdown is initiated. Logic dictates you can't get a 0 back again (because it's a blocking BIO and will have completed the first step). A -1 indicates an error, and a 1 indicates completion.
If you have non-blocking BIOs, the same applies, save for the fact you need to go through the whole SSL_ERROR_WANT_READ
and SSL_ERROR_WANT_WRITE
rigmarole, i.e.:
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.
So you have two levels of repetition. You call SSL_shutdown
the 'first' time but repeat if you get SSL_ERROR_WANT_READ
or SSL_ERROR_WANT_WRITE
after going around the select()
loop in the normal way, and only count the 'first' SSL_shutdown
as done if you get a non SSL_ERROR_WANT_
error code (in which case it failed), or you get a 0
or 1
return. If you get a 1
return, you've done. If you get a 0
return, and you want a bidirectional shutdown, then you have to do the second call, on which again you will need to check for SSL_ERROR_WANT_READ
or SSL_ERROR_WANT_WRITE
and retry select; that should not return 1
, but may return 0 or an error.
Not simple.
这篇关于正确处理SSL_shutdown的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!