如何从已有的SSL_CTX创建boost::asio::ssl::context对象
基于已有SSL_CTX创建boost::asio::ssl::context的方法
完全可以基于已有的原生OpenSSL SSL_CTX 直接创建boost::asio::ssl::context对象,不需要手动复制任何配置项,能完全避免手动同步配置带来的错误。
实现方案
boost::asio::ssl::context 提供了接收原生上下文句柄的重载构造函数,入参类型boost::asio::ssl::context::native_handle_type 本质就是OpenSSL的SSL_CTX*,使用方式分为两种场景:
场景1:将SSL_CTX所有权转让给asio管理
如果你不需要再单独使用原有的SSL_CTX指针,可以直接传入构造,asio会在自身析构时自动释放原生上下文:
// 你已有的原生SSL_CTX对象,已完成所有配置 SSL_CTX* existing_raw_ctx = /* 你的已有SSL_CTX实例 */; // 直接构造asio ssl上下文 boost::asio::ssl::context asio_ctx(existing_raw_ctx);
注意:该场景下禁止再手动调用
SSL_CTX_free释放existing_raw_ctx,否则会出现双重释放错误。
场景2:保留原有SSL_CTX的所有权
如果你其他逻辑还需要继续使用原有的SSL_CTX,可以先增加原生上下文的引用计数再交给asio管理,两者的生命周期完全独立:
// 你已有的原生SSL_CTX对象,已完成所有配置 SSL_CTX* existing_raw_ctx = /* 你的已有SSL_CTX实例 */; // 增加SSL_CTX的引用计数 SSL_CTX_up_ref(existing_raw_ctx); // 构造asio ssl上下文 boost::asio::ssl::context asio_ctx(existing_raw_ctx); // 后续你可以正常释放原有existing_raw_ctx,不会影响asio_ctx的使用 // SSL_CTX_free(existing_raw_ctx);
注意事项
- 传入的
SSL_CTX*必须是合法、未被释放的实例,否则会触发未定义行为 - Boost 1.66及之后的版本对原生句柄构造的支持完全稳定,低版本需要自行验证兼容性
- 程序运行时链接的OpenSSL版本,必须和Boost.Asio编译时使用的OpenSSL版本一致,避免结构体布局不兼容问题
- 如果使用OpenSSL 1.0.x版本,没有公开的
SSL_CTX_up_ref接口,可替换为CRYPTO_add(&existing_raw_ctx->references, 1, CRYPTO_LOCK_SSL_CTX)手动增加引用计数
内容的提问来源于stack exchange,提问作者Dorian
相关产品推荐
相关产品推荐

