正确处理ssl_shutdown

发布于 2025-01-31 04:55:57 字数 847 浏览 1 评论 0 原文

ssl_shutdown上的OpenSSL文档指出:

因此,建议您检查 ssl_shutdown()的返回值,并再次调用 ssl_shutdown() ,如果尚未完成双向关闭(尚未完成)第一个电话是0)。

htttps://www.openssl.org.org/docs/docs/ssl/ssl/ssl/ssl/ssl_shutdown.html

我在下面有一个代码段,其中我从 ssl_shutdown 中检查返回值0,然后再次调用它,我一直在使用。我的问题是,可以在第二个呼叫上忽略 ssl_shutdown 的返回值,否则我们应该继续重试 ssl_shutdown ,直到返回1(BiDirectional Shutdown完成)。

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);

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯狂的代价 2025-02-07 04:55:57

openssl 有点暗艺术。

首先,您引用的页面对html的返回值差。这是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.

如果您封锁了BIOS,情况相对简单。第一个呼叫上的0表示您需要再次调用 ssl_shutdown ,如果您想要完整的双向关闭。基本上,这意味着您发送了一个Close_notify Alert,但还没有退缩)。 1意味着您以前从其他同伴那里收到了Close_notify警报,并且您已经完成了。 A -1表示无法恢复的错误。在第二个通话中(仅当您获得0后才进行),然后启动双向关闭(即现在从另一侧等待他们向您发送他们的“ Close_notify”警报)。逻辑决定您无法再次获得0(因为这是一个阻止生物,并且将完成第一步)。 A -1表示错误,1表示完成成功。

如果您有非障碍BIOS,则相同的“可能为0,则1”返回值适用,除了需要遍历整个 ssl_err_err_want_read_read ssl_error_want_write rigmarole作为好吧,即:

   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> select> select(Select()以普通方式循环,仅计数“ first” ssl_shutdown ,如果您获得了非 ssl_error_want _ 错误代码>错误代码(在这种情况下),或者您获得了 0 1 返回。如果您获得 1 返回,则已经完成了。如果您获得 0 返回,并且需要双向关闭,则必须进行第二个调用,您将再次需要检查 ssl_error_want_read SSL_ERROR_WANT_WRITE 和重试选择;那不应返回 1 ,但可能会返回0或错误。

不简单。

并首次获得“ 0”,您可以选择然后调用 ssl_read ,而不是 ssl_shutdown (如果Peer仍在向您发送SSL上的任何数据插座),我想,“希望”他们最终从他们的身边向您发送了一个密切的信息,以冲洗管道。

另外,如果您打算在“无论如何”关闭完成后关闭套接字关闭插座,内核应照顾丢弃“现在忽略” CLOSS_NOTIFY警报,大概他们应该发送...

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 full bidirectional shutdown. Basically it means that you sent a close_notify alert but haven't one back yet). A 1 would mean you previously received a close_notify alert from the other peer, and you're totally done. A -1 means an unrecoverable error. On the second call (which you only do if you got a 0 back), then a bidirectional shutdown is initiated (i.e. now wait from the other side for them to send you their "close_notify" alert). 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 success.

If you have non-blocking BIOs, the same "possibly 0 then 1" return values apply, save for the fact you need to go through the whole SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE rigmarole as well, 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.

Couple more notes from the docs: after calling SSL_shutdown and getting a "0" back the first time, you could optionally then call SSL_read instead of SSL_shutdown (in case the peer is still sending you any data on that SSL socket), and, I guess, "hope" that they eventually send you a close message from their side, to flush the pipes.

Also if you're planning on closing the socket after shutdown completion "anyway" you could entirely skip the second call to SSL_shutdown (the "1" of the "0 then 1") and just go ahead and close the socket, the kernel should take care of discarding the "now ignored" close_notify alert that presumably they should be about to send...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文