首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为了OpenSSL 1.1.0+中的线程安全,我需要使用密码锁定函数吗?

为了OpenSSL 1.1.0+中的线程安全,我需要使用密码锁定函数吗?
EN

Stack Overflow用户
提问于 2019-10-03 17:26:37
回答 1查看 1.7K关注 0票数 6

这个问题与OpenSSL 1.1.0+有关。在代码示例中,我使用std::string_view,这意味着C++17。这不是必需的,C++11上的任何东西都可以,我只是太懒了,不想让const char* bufstd::size_t len作为单独的变量。

代码语言:javascript
复制
#include <string_view>

#include <openssl/err.h>
#include <openssl/ssl.h>

void startup()
{
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
    ERR_load_crypto_strings();
}

void shutdown()
{
    ERR_free_strings();
    EVP_cleanup();
}

void thread_shutdown()
{
    CRYPTO_cleanup_all_ex_data();
}

void run_per_thread()
{
    // intial non SSL stuff
    int sockfd = get_connected_socket();
    std::string_view hostname = get_hostname();
    std::string_view buffer = get_buffer();
    // SSL context setup
    auto ssl_ctx = SSL_CTX_new(TLS_client_method());
    auto ssl_ctx_options = SSL_OP_SINGLE_DH_USE || SSL_OP_NO_SSLv3;
    SSL_CTX_set_options(ssl_ctx, ssl_ctx_options);
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, nullptr);
    // SSL client setup
    auto ssl_client = SSL_new(ssl_ctx);
    SSL_set_tlsext_host_name(ssl_client, hostname.data());
    // connect and write
    auto ssl_err = SSL_connect(ssl_client);
    auto result = SSL_write(ssl_client, buf.data(), buf.size());
}

我有这四个函数(最后一个是伪函数)。startup在程序的开头运行,shutdown在程序的末尾运行(两者都只运行一次)。thread_shutdown在每个线程的末尾运行(包括主线程中的shutdown )。

run_per_thread函数是我如何在套接字中使用SSL的一个小例子。函数可以在多个线程中运行,但是局部变量从不会在线程之间函数的作用域之外共享。

我目前使用OpenSSL线程的方式安全吗?还是我需要用密码锁?(文件对我来说不够清楚)。如果我真的需要使用密码锁,你能给我举个小例子说明如何做吗?

我一直在使用这些链接作为参考指南编写以下内容:

How to properly uninitialize OpenSSL

https://curl.haxx.se/libcurl/c/threadsafe.html

https://www.openssl.org/docs/man1.1.0/man3/CRYPTO_THREAD_run_once.html#DESCRIPTION

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-03 22:41:55

您不需要在OpenSSL 1.1.0及更高版本中设置线程锁。OpenSSL常见问题是这样说的:

是OpenSSL线程安全吗?

是的,但有一些限制;例如,SSL连接不能由多个线程并发使用。对于大多数OpenSSL对象来说,这是正确的。

对于版本1.1.0及更高版本,没有什么需要做的了。

对于1.1.0以上的早期版本,应用程序必须设置线程回调函数。为此,应用程序必须调用CRYPTO_set_locking_callback(3)和CRYPTO_THREADID_set之一.请参阅OpenSSL线程手册中的详细信息和源代码发行版中安装文件中的“多线程注意事项”。

只要您不跨多个线程共享SSL对象,那么您就应该没事。

下面是关于示例代码的其他一些想法:

代码语言:javascript
复制
void startup()
{
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
    ERR_load_crypto_strings();
}

void shutdown()
{
    ERR_free_strings();
    EVP_cleanup();
}

void thread_shutdown()
{
    CRYPTO_cleanup_all_ex_data();
}

你不需要打任何上面的电话。这是您必须在OpenSSL 1.0.2中执行的神秘的启动和关闭代码。所有这些在OpenSSL 1.1.0中都不是必需的-它会自动启动和关闭。在某些情况下(但可能不需要),您可能需要在OPENSSL_thread_stop()函数中调用thread_shutdown()函数。请参见:

https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html

代码语言:javascript
复制
auto ssl_ctx_options = SSL_OP_SINGLE_DH_USE || SSL_OP_NO_SSLv3;

没有必要使用SSL_OP_SINGLE_DH_USE。它在OpenSSL 1.1.0中什么也不做( 1.0.2或之前只需要它)。

代码语言:javascript
复制
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, nullptr);

考虑使用SSL_VERIFY_PEER,如果无法验证对等证书,这将中止握手。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58224138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档