OpenSSL错误处理

Red*_*Red 6 c error-handling openssl

这是在OpenSSL中进行错误处理的正确方法吗?和之间有什么区别SSL_get_errorERR_get_error?在这方面,文件非常模糊.

int ssl_shutdown(SSL *ssl_connection)
{
    int rv, err;
    ERR_clear_error();
    rv = SSL_shutdown(ssl_connection);

    if (rv == 0)
        SSL_shutdown(ssl_connection);

    if (rv < 0)
    {
        err = SSL_get_error(ssl_connection, rv);

        if (err == SSL_ERROR_SSL)
            fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));

        fprintf(stderr, "%s\n", SSL_state_string(ssl_connection));

        return 1;
    }

    SSL_free(ssl_connection);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jez*_*zor 7

SSL_get_error :

SSL_get_error() 为在 ssl 上对 SSL_connect()、SSL_accept()、SSL_do_handshake()、SSL_read()、SSL_peek() 或 SSL_write() 的先前调用返回结果代码(适用于 C“switch”语句)。该 TLS/SSL I/O 函数返回的值必须在参数 ret 中传递给 SSL_get_error()。

ERR_get_error :

ERR_get_error() 从线程的错误队列中返回最早的错误代码并删除该条目。这个函数可以重复调用,直到没有更多的错误代码要返回。

所以后者用于更广泛的用途,不应一起使用,因为:

在尝试 TLS/SSL I/O 操作之前,当前线程的错误队列必须为空,否则 SSL_get_error() 将无法可靠地工作。

因此,您必须使用 ERR_get_error 读取所有错误并处理它们(或像在代码示例中那样通过删除忽略它们ERR_clear_error),然后执行 IO 操作。您的方法似乎是正确的,尽管我目前无法自己检查所有方面。

有关更多信息,请参阅此答案此帖子

编辑:根据教程,BIO_ 例程可能会产生错误并影响错误队列:

第三个字段是生成错误的包的名称,例如“BIO 例程”或“bignum 例程”。


jww*_*jww 7

SSL_get_error和ERR_get_error有什么区别?

OpenSSL有两个逻辑部分.首先是SSL库libssl.a(和libssl.so),它包括与通信相关的东西.第二个是加密库,libcrypto.a(和libcrypto.so),它包括大数字,配置,输入/输出等.

libssl.a依赖于它libcrypto.a,以及它为什么命令链接命令-lssl -lcrypto.

您可以使用SSL_get_error从SSL部分库中检索大多数错误,并使用它ERR_get_error来检索不在库的SSL部分中的错误.


这是在OpenSSL中进行错误处理的正确方法吗?

您展示的代码更接近"如何关闭SSL套接字".最终,回转控制两种情况.首先是半开连接,当客户端关闭而不发送关闭通知消息时.第二个是发送关闭通知消息时程序的行为.

很难回答"它是否正确",因为我们不知道你想要的行为.如果您不关心是否发送了关闭通知,那么我相信您只需要拨打SSL_shutdown一次,无论客户端做什么.