如何管理 openssl 中的错误队列(SSL_get_error 和 ERR_get_error)

Posted

技术标签:

【中文标题】如何管理 openssl 中的错误队列(SSL_get_error 和 ERR_get_error)【英文标题】:How to manage the error queue in openssl (SSL_get_error and ERR_get_error) 【发布时间】:2013-08-13 07:12:41 【问题描述】:

在 OpenSSl 中,大多数 SSL_* 调用的手册页通过返回值

但是在这些调用以及其他 OpenSSL 库调用的手册页中,模糊地提到在 OpenSSL 中使用“错误队列” - SSL_get_error 的手册页中就是这种情况:

   The current thread's error queue must be empty before the TLS/SSL I/O
   operation is attempted, or  SSL_get_error() will not work reliably.

在同一个手册页中,SSL_ERROR_SSL 的描述是这样的:

   SSL_ERROR_SSL
       A failure in the SSL library occurred, usually a protocol error.
       The OpenSSL error queue contains more information on the error.

这种暗示表明错误队列中有一些值得一读的东西。并且未能读取它会使随后对 SSL_get_error 的调用不可靠。大概,拨打电话是ERR_get_error。

我计划在我的代码中使用非阻塞套接字。因此,重要的是我能够可靠地发现错误条件何时是 SSL_ERROR_WANT_READ 或 SSL_ERROR_WANT_WRITE,以便我可以将套接字置于正确的轮询模式。

所以我的问题是这样的:

SSL_get_error() 是否为我隐式调用 ERR_get_error()?还是我需要同时使用两者?

我应该在每次调用 OpenSSL 库之前调用 ERR_clear_error 吗?

OpenSSL 库调用完成后,队列中是否有可能出现多个错误?因此,是否存在队列中的第一个错误比最后一个错误更相关的情况?

【问题讨论】:

对于最后一个:是的,这可能发生。较低级别可能有错误,将消息添加到队列中,并且由于此错误,库中的较高级别添加了自己的消息。在某些情况下,我在堆栈上看到了 5 条甚至更多消息。 另请参阅codereview.stackexchange.com/questions/108600/… 这太疯狂了...就像...除非您在每次通话后都小心谨慎地清除它(并多次调用),否则您应该先清除它每次通话。因为你不能确定。哇... @rogerdpack 那不是errno 在 C 中无论如何都可以工作。我想它是模仿那种(糟糕的)行为。 【参考方案1】: SSL_get_error 不调用 ERR_get_error。因此,如果您只是调用 SSL_get_error,则错误会留在队列中。 您应该在任何 SSL 调用(SSL_read、SSL_write 等)之前调用 ERR_clear_error,然后再调用 SSL_get_error,否则您可能正在读取当前线程中先前发生的旧错误。

【讨论】:

@QuinnCarver 看看ERR_error_string。你会将ERR_get_error() 的结果传递给它。

以上是关于如何管理 openssl 中的错误队列(SSL_get_error 和 ERR_get_error)的主要内容,如果未能解决你的问题,请参考以下文章

管理区出现 gitlab 500 错误

如何通过OpenSSL与Shell中的IMAP服务器通信

Openssl:错误“证书链中的自签名证书”

python请求中的OpenSSL错误

如何使用 SQL 管理数据库中的 FIFO 队列?

Jenkins批量停止队列中卡主的jobs