ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

libcurl CURLINFO_SSL_ENGINES 详解:枚举 OpenSSL 加密引擎列表

libcurl CURLINFO_SSL_ENGINES 详解:枚举 OpenSSL 加密引擎列表 libcurl CURLINFO_SSL_ENGINES 详解枚举 OpenSSL 加密引擎列表【免费下载链接】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_SSL_ENGINES是 libcurl 提供的curl_easy_getinfo(3)查询项之一用于在运行时获取当前 OpenSSL 后端可用的加密引擎crypto engine名称链表。本文以其官方手册 CURLINFO_SSL_ENGINES.md 为骨架结合 lib/getinfo.c 与 lib/vtls/openssl.c 等源码讲清该接口的调用方式、内存所有权规则、底层实现机制以及它与CURLOPT_SSLENGINE配套完成“先枚举、再选型”的硬件加速/私钥卸载场景。基本信息速览项目说明函数curl_easy_getinfo(CURL *handle, CURLINFO_SSL_ENGINES, struct curl_slist **engine_list)引入版本7.12.3Added-in字段标注适用协议TLS所有基于 TLS 的传输如 HTTPS、FTPS、SMTPS 等TLS 后端仅 OpenSSL手册TLS-backend字段标注返回结构struct curl_slist *字符串单向链表配套选项CURLOPT_SSLENGINE用于设置/激活引擎原型与用法标准声明位于 include/curl/curl.h使用方式如下#include curl/curl.h CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_SSL_ENGINES, struct curl_slist **engine_list);调用时传入一个struct curl_slist *变量的地址调用成功后该指针指向一个新分配的链表链表中的每个字符串就是一个 OpenSSL 引擎的标识符engine id。之后通过遍历链表即可得到全部可用引擎名称。官方示例手册 CURLINFO_SSL_ENGINES.md 给出的完整示例int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; struct curl_slist *engines; result curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, engines); if((result CURLE_OK) engines) { /* we have a list, free it when done using it */ curl_slist_free_all(engines); } curl_easy_cleanup(curl); } }补充一个带遍历的实战版本便于实际输出引擎名称#include stdio.h #include curl/curl.h int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; struct curl_slist *engines; result curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, engines); if(result CURLE_OK) { struct curl_slist *node; for(node engines; node; node node-next) printf(engine: %s\n, node-data); curl_slist_free_all(engines); } curl_easy_cleanup(curl); } return 0; }内存所有权必须由调用者释放这是该接口最重要的使用约定。libcurl不会替你释放返回的链表调用者必须在使用完毕后调用curl_slist_free_all(3)释放整条链表否则会造成内存泄漏。官方手册 curl_slist_free_all.md 对该释放函数有完整说明。注意链表中的字符串同样由 libcurl 分配释放链表时其携带的字符串数据也会一并释放因此不要保留指向链表内data指针的引用并在释放后再使用。返回值与错误语义curl_easy_getinfo(3)返回CURLcodeCURLE_OK (0)调用成功engine_list指向有效链表可能为空链表见下文说明非零值出错错误码含义参见 libcurl-errors.md。值得注意从源码看即使成功返回engine_list也可能为空指针或空链表——例如在不支持引擎的后端下运行时因此示例中同时判断了result CURLE_OK与engines非空。底层实现从 getinfo 分发到 OpenSSL 后端1. 分发层lib/getinfo.c所有CURLINFO_*查询都在 lib/getinfo.c 中处理。CURLINFO_SSL_ENGINES属于 slist 类型查询走getinfo_slist()分支见 lib/getinfo.cstatic CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info, struct curl_slist **param_slistp) { ... switch(info) { case CURLINFO_SSL_ENGINES: *param_slistp Curl_ssl_engines_list(data); break; ...可见其核心动作就是调用Curl_ssl_engines_list()并把返回的链表指针写回调用者提供的指针变量。2. 抽象层lib/vtls/vtls.c 与 vtls.hlibcurl 将 TLS 后端抽象为一组函数指针Curl_ssl结构体定义于 lib/vtls/vtls_int.h其中包含engines_list回调。分发实现位于 lib/vtls/vtls.c/* Return list of OpenSSL crypto engine names. */ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data) { if(Curl_ssl-engines_list) return Curl_ssl-engines_list(data); return NULL; }声明见 lib/vtls/vtls.h。3. 各后端实现只有 OpenSSL 真正提供从源码各 TLS 后端的函数表可以确认只有 OpenSSL 后端实现了engines_listOpenSSLossl_engines_list见 lib/vtls/openssl.c注册于 lib/vtls/openssl.cGnuTLS、mbedTLS、wolfSSL、Schannel、rustls 等后端在各自的函数表中将engines_list置为NULL例如 lib/vtls/gtls.c、lib/vtls/mbedtls.c、lib/vtls/wolfssl.c、lib/vtls/schannel.c、lib/vtls/rustls.c。因此该查询仅在 OpenSSL 后端下有意义使用其他 TLS 后端时Curl_ssl_engines_list()返回NULL。4. OpenSSL 实现细节lib/vtls/openssl.cOpenSSL 后端的ossl_engines_list()完整实现/* Return list of OpenSSL crypto engine names. */ static struct curl_slist *ossl_engines_list(struct Curl_easy *data) { struct curl_slist *list NULL; #ifdef USE_OPENSSL_ENGINE struct curl_slist *beg; ENGINE *e; for(e ENGINE_get_first(); e; e ENGINE_get_next(e)) { beg curl_slist_append(list, ENGINE_get_id(e)); if(!beg) { curl_slist_free_all(list); return NULL; } list beg; } #endif (void)data; return list; }关键点使用 OpenSSL 引擎 APIENGINE_get_first()/ENGINE_get_next()遍历全局引擎注册表用ENGINE_get_id()取得每个引擎的标识符字符串每得到一个引擎就用curl_slist_append()追加到链表尾部追加失败内存不足时释放已构建的链表并返回NULL整体被#ifdef USE_OPENSSL_ENGINE包裹即 libcurl 编译时若未启用 OpenSSL 引擎支持则返回空链表手册明确提醒引擎通常以独立的动态库形式实现因此返回的引擎未必在运行时都可用——列表反映的是“已注册/受支持”的引擎真正能否加载还要看对应动态库是否存在、权限是否足够等。与 CURLOPT_SSLENGINE 的配套使用CURLINFO_SSL_ENGINES常用于先枚举可用引擎再用 CURLOPT_SSLENGINE.md 选择其中一个激活。OpenSSL 后端中对应的设置函数为ossl_set_engine()lib/vtls/openssl.cstatic CURLcode ossl_set_engine(struct Curl_easy *data, const char *name) { ... ENGINE *e ENGINE_by_id(name); ... }典型流程调用curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, engines)获取引擎 ID 列表遍历struct curl_slist匹配目标引擎如pkcs11、dynamic等通过curl_easy_setopt(curl, CURLOPT_SSLENGINE, engine_id)激活该引擎源码中ossl_set_engine在内部还会处理pkcs11等特殊引擎的加载见 lib/vtls/openssl.c 与 lib/vtls/openssl.c若希望该引擎成为所有 SSL 操作的默认引擎可配合CURLOPT_SSLENGINE_DEFAULT使用底层对应ossl_set_engine_default()lib/vtls/openssl.c内部调用ENGINE_set_default(e, ENGINE_METHOD_ALL)。该组合常用于硬件安全模块HSM、智能卡如 PKCS#11 设备等场景引擎负责持有私钥并提供加解密原语libcurl 只负责发起 TLS 握手并调用引擎完成签名/解密。使用注意事项小结仅 OpenSSL 后端有效GnuTLS/mbedTLS/wolfSSL/Schannel/rustls 后端的函数表将engines_list置为 NULL查询返回NULL必须释放链表调用curl_slist_free_all(engines)libcurl 不会替你释放列表可能为空编译时未启用USE_OPENSSL_ENGINE或运行时没有注册任何引擎时得到空链表引擎可用性不等价于可加载性引擎多在独立动态库中列表内引擎可能在当前环境无法加载无活动连接也可查询该查询只遍历 OpenSSL 全局引擎注册表不依赖某个已建立的 TLS 连接因此在curl_easy_init()之后即可调用如官方示例所示返回值判断务必同时检查CURLE_OK与链表非空再决定是否遍历。相关文档索引CURLINFO_SSL_ENGINES 手册原文curl_easy_getinfo 总览CURLOPT_SSLENGINE 选项curl_slist_free_all 释放函数libcurl 错误码源码入口lib/getinfo.c、lib/vtls/vtls.c、lib/vtls/openssl.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),仅供参考
返回列表