这个问题与OpenSSL 1.1.0+有关。在代码示例中,我使用std::string_view,这意味着C++17。这不是必需的,C++11上的任何东西都可以,我只是太懒了,不想让const char* buf和std::size_t len作为单独的变量。
#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
发布于 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对象,那么您就应该没事。
下面是关于示例代码的其他一些想法:
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
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或之前只需要它)。
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, nullptr);考虑使用SSL_VERIFY_PEER,如果无法验证对等证书,这将中止握手。
https://stackoverflow.com/questions/58224138
复制相似问题