资讯动态

libcurl CURLINFO_TLS_SESSION 详解:获取 TLS 会话内部指针与兼容性迁移指南

发布时间:2026/9/10 2:37:34 来源:尧图企业网站定制
libcurl CURLINFO_TLS_SESSION 详解获取 TLS 会话内部指针与兼容性迁移指南【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl导读CURLINFO_TLS_SESSION是 libcurl 提供的一类curl_easy_getinfo查询选项用于在 HTTPS 等 TLS 握手完成后取出底层 SSL 库如 OpenSSL、wolfSSL、GnuTLS内部会话结构体的指针从而让应用程序直接访问证书链、协议版本等底层信息。本文基于 CURLINFO_TLS_SESSION 官方文档结合 libcurl 源码实现、头文件定义 与仓库内的示例代码完整讲解该选项的用法、不同 SSL 后端下internals指针的具体类型差异、它在 7.48.0 版本被CURLINFO_TLS_SSL_PTR取代的历史背景以及新老接口的迁移要点。读完本文你将掌握如何调用该选项获取 TLS 会话信息、如何根据backend枚举值安全地类型转换底层指针、OpenSSL 与 wolfSSL 场景下新旧选项返回指针的差异以及新代码应如何使用推荐接口CURLINFO_TLS_SSL_PTR并规避已知限制。一、选项概览与基本用法1.1 功能定位CURLINFO_TLS_SESSION用于向curl_easy_getinfo查询当前 easy handle 上正在使用的 TLS 会话信息。查询结果是一个指向struct curl_tlssessioninfo的指针该结构体包含两个成员定义见 include/curl/curl.h#L2911-L2917struct curl_tlssessioninfo { curl_sslbackend backend; /* 标识握手所用的 SSL 库 */ void *internals; /* 指向该 SSL 库内部会话结构的指针 */ };backend一个枚举值标识 libcurl 实际编译链接的 SSL 后端。枚举的完整定义位于 include/curl/curl.h#L154-L178包括CURLSSLBACKEND_NONE未启用 TLS 支持时、CURLSSLBACKEND_OPENSSL、CURLSSLBACKEND_GNUTLS、CURLSSLBACKEND_WOLFSSL、CURLSSLBACKEND_SCHANNEL、CURLSSLBACKEND_SECURETRANSPORT、CURLSSLBACKEND_MBEDTLS等。其中 OpenSSL 的分支实现BoringSSL、LibreSSL、AWS-LC统一报告为CURLSSLBACKEND_OPENSSLwolfSSL 的前身 CyaSSL 则统一报告为CURLSSLBACKEND_WOLFSSL。internalsvoid 指针指向所使用 SSL 库的内部会话结构。它的具体类型随backend不同而变化直接强转前必须先检查backend。1.2 函数签名#include curl/curl.h CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_TLS_SESSION, struct curl_tlssessioninfo **session);handle执行过 TLS 握手的 easy handlesession输出参数调用后指向一个struct curl_tlssessioninfo *返回值CURLE_OK0表示成功非零表示出错具体错误码参见 libcurl-errors。1.3 官方示例GnuTLS 场景仓库中的官方示例 sessioninfo.c 展示了完整用法在写回调write_cb中调用curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, info)然后根据info-backend判断后端把info-internals当作gnutls_session_t使用并用 GnuTLS API 打印对端证书链static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *stream) { const struct curl_tlssessioninfo *info; CURLcode result; (void)stream; (void)ptr; result curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, info); if(result CURLE_OK) { unsigned int cert_list_size; const gnutls_datum_t *chainp; switch(info-backend) { case CURLSSLBACKEND_GNUTLS: /* info-internals 此时就是 gnutls_session_t */ chainp gnutls_certificate_get_peers(info-internals, cert_list_size); if(chainp cert_list_size) { /* 遍历证书链使用 gnutls_x509_crt_import / gnutls_x509_crt_print 打印 */ } break; case CURLSSLBACKEND_NONE: default: break; } } return size * nmemb; }该示例使用CURLOPT_WRITEFUNCTION在数据传输回调内查询会话信息这一模式能保证查询发生在 TLS 会话仍与 easy handle 关联的有效窗口期内详见下文指针的生命周期。注意示例文件头部注明当前该示例要求 libcurl 以 GnuTLS 编译USE_GNUTLS程序还需链接-lgnutls。二、不同 SSL 后端下 internals 指针的类型internals指向的是当前正在使用的那个 SSL 连接对象。由于 libcurl 可编译链接多种 TLS 库同一字段在不同后端下对应完全不同的底层类型必须依据backend成员进行区分。下表汇总了CURLINFO_TLS_SESSION即本文档与CURLINFO_TLS_SSL_PTR推荐接口在各后端下的类型对照SSL 后端CURLINFO_TLS_SESSION 的 internalsCURLINFO_TLS_SSL_PTR 的 internalsOpenSSL含 BoringSSL / LibreSSL / AWS-LCSSL_CTX *SSL *wolfSSL含 CyaSSLWOLFSSL_CTX *WOLFSSL *GnuTLSgnutls_session_tgnutls_session_tmbedTLSmbedtls_ssl_context *mbedtls_ssl_context *SchannelCtxtHandle *CtxtHandle *SecureTransportSecureTransport 内部会话句柄SecureTransport 内部会话句柄关键结论除 OpenSSL 与 wolfSSL 两个后端外CURLINFO_TLS_SESSION与CURLINFO_TLS_SSL_PTR返回的内容完全一致这一对照关系在两份文档中均有明确记载见 CURLINFO_TLS_SSL_PTR.md 的 DESCRIPTION 章节。2.1 OpenSSL 后端的差异SSL_CTX * vs SSL *当backend为CURLSSLBACKEND_OPENSSL时CURLINFO_TLS_SESSION返回的internals是SSL_CTX *SSL 上下文对象描述整个会话共用的配置CURLINFO_TLS_SSL_PTR返回的internals是SSL *具体的 SSL 连接对象描述当前这条连接。如需从SSL *反推SSL_CTX *可直接调用 OpenSSL 的函数SSL_get_SSL_CTX(3)。因此文档明确建议除非需要兼容旧版 libcurl否则一律使用CURLINFO_TLS_SSL_PTR因为SSL *是与具体连接绑定的对象能反映握手后的实际会话状态例如协商出的协议版本、会话票据等信息更贴近当前连接。2.2 wolfSSL 后端的差异WOLFSSL_CTX * vs WOLFSSL *wolfSSL原 CyaSSL场景下的情况与 OpenSSL 类似CURLINFO_TLS_SESSION返回WOLFSSL_CTX *CURLINFO_TLS_SSL_PTR返回WOLFSSL *。可通过 wolfSSL 的wolfSSL_get_SSL_CTX(3)从WOLFSSL *获取WOLFSSL_CTX *。同理新代码应优先使用CURLINFO_TLS_SSL_PTR。三、源码实现该选项在 libcurl 内部如何工作3.1 getinfo 分发逻辑在 lib/getinfo.c#L577-L593 中两个选项共用同一段分发代码唯一的区别是查询类型case CURLINFO_TLS_SESSION: case CURLINFO_TLS_SSL_PTR: { int query (info CURLINFO_TLS_SSL_PTR) ? CF_QUERY_SSL_INFO : CF_QUERY_SSL_CTX_INFO; struct curl_tlssessioninfo **tsip (struct curl_tlssessioninfo **) param_slistp; struct curl_tlssessioninfo *tsi data-tsi; /* we are exposing a pointer to internal memory with unknown * lifetime here. */ *tsip tsi; if(!Curl_conn_get_ssl_info(data,>#include curl/curl.h #include openssl/ssl.h static CURL *curl; static size_t wf(char *ptr, size_t size, size_t nmemb, void *stream) { const struct curl_tlssessioninfo *info NULL; CURLcode result curl_easy_getinfo(curl, CURLINFO_TLS_SSL_PTR, info); if(info !result) { if(CURLSSLBACKEND_OPENSSL info-backend) { printf(OpenSSL ver. %s\n, SSL_get_version((SSL*)info-internals)); } } return size * nmemb; } int main(int argc, char *argv[]) { CURLcode result CURLE_OK; curl curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, https://example.com); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wf); result curl_easy_perform(curl); curl_cleanup(curl); } return (int)result; }注意必须先判断info ! NULL且result CURLE_OK再比较info-backend最后才把internals强转为对应类型——因为internals的类型完全由backend决定跨后端强转属于未定义行为。6.2 官方测试用例佐证仓库的集成测试 tests/data/test1587关键词CURLINFO_TLS_SESSION在 OpenSSL HTTPS 环境下同时验证了CURLINFO_TLS_SESSION与CURLINFO_TLS_SSL_PTR两个选项测试客户端为 tests/libtest/lib1587.c测试要求 libcurl 具备SSL与OpenSSL特性。测试覆盖了两个选项在 OpenSSL 后端下返回指针的差异SSL_CTX *vsSSL *是理解本主题行为差异最直接的运行级证据。6.3 已知限制LIMITATIONS新接口CURLINFO_TLS_SSL_PTR继承并扩展了本文档相关的全部注意事项文档 CURLINFO_TLS_SSL_PTR.md 的 LIMITATIONS 章节 列出以下限制使用时应心中有数多会话场景只能取到第一个easy handle 可能同时存在多个进行中的 SSL 会话——典型场景是 FTP over SSL控制通道 数据通道均可能走 TLS。当前接口只能取到第一个 in-use 会话指针无法获取第二个会话。明文协议升级/降级场景未经充分测试FTP、SMTP、POP3、IMAP 配合CURLOPT_USE_SSL使用时从明文升级到 TLS 的过程中可能在你能取到 SSL 指针之前认证等敏感数据就已经在升级后的连接上发出。重协商renegotiation风险若底层 SSL 库允许不安全重协商或允许证书变更的重协商证书可能在重协商中发生变化而在你取到可能已变更的SSL 指针之前数据可能已按新证书继续收发。不要用它轮询证书变更文档给出的安全替代方案是使用CURLOPT_SSL_CTX_FUNCTION设置验证回调在支持的 TLS 后端下该方案更安全不承受上述任一问题。七、总结CURLINFO_TLS_SESSION是 libcurl 中接触底层 TLS 库内部对象的最早入口其核心价值在于通过struct curl_tlssessioninfo暴露握手所用的 SSL 后端与内部会话指针让开发者能够用 OpenSSL/GnuTLS/wolfSSL 等库的原生 API 做证书提取、协议版本查询、手动校验等深度操作。但受历史设计影响它在 OpenSSL 与 wolfSSL 后端返回的是SSL_CTX */WOLFSSL_CTX *这类上下文对象且自 7.48.0 起被CURLINFO_TLS_SSL_PTR取代。新项目应直接使用CURLINFO_TLS_SSL_PTR返回与具体连接绑定的SSL */WOLFSSL *在回调中查询、先核对backend再转换类型并规避多会话、升级连接与重协商场景下的已知限制。参考文件索引本文档docs/libcurl/opts/CURLINFO_TLS_SESSION.md推荐替代接口文档docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.md结构体与枚举定义include/curl/curl.h#L2911-L2917、include/curl/curl.h#L154-L178getinfo 实现lib/getinfo.c#L577-L593连接过滤链查询lib/vtls/vtls.c#L1238-L1246官方示例docs/examples/sessioninfo.c集成测试tests/data/test1587、tests/libtest/lib1587.c【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价