libcurl中CURLOPT_CAPATH配置失效问题求助
问题:CURLOPT_CAPATH配置CA证书目录无效,仅CURLOPT_CAINFO指定文件有效
我使用CURLOPT_CAPATH设置CA证书存放目录:
curl_easy_setopt(curlobj->curl, CURLOPT_CAPATH, "/var/certs")
但该配置无效,无法正确选择证书,报错日志如下:
* About to connect() to xxxxxxxxxxxxx port 443 (#0) * Trying 10.x.x.x... * Adding handle: conn: 0xf49120d8 * Adding handle: send: 0 * Adding handle: recv: 0 * Curl_addHandleToPipeline: length: 1 * - Conn 0 (0xf49120d8) send_pipe: 1, recv_pipe: 0 * Connected to xxxxxxxxxxxxx (10.x.x.x) port 443 (#0) * successfully set certificate verify locations: * CAfile: none CApath: /var/certs * SSL certificate problem: unable to get local issuer certificate * Closing connection 0
若显式用CURLOPT_CAINFO指定证书文件则可正常工作:
curl_easy_setopt(curlobj->curl, CURLOPT_CAINFO, "/var/certs/ca-certificates.crt")
对应正常日志:
* About to connect() to xxxxxxxxxxxxx port 443 (#0) * Trying 10.x.x.x... * Adding handle: conn: 0xf501a4c8 * Adding handle: send: 0 * Adding handle: recv: 0 * Curl_addHandleToPipeline: length: 1 * - Conn 0 (0xf501a4c8) send_pipe: 1, recv_pipe: 0 * Connected to xxxxxxxxxxxxx (10.x.x.x) port 443 (#0) * successfully set certificate verify locations: * CAfile: /var/certs/ca-certificates.crt CApath: none * SSL connection using ECDHE-RSA-AES128-GCM-SHA256 * Server certificate:
根据curl手册说明:
如果libcurl基于OpenSSL编译,证书目录必须使用OpenSSL的
c_rehash工具预处理。
我已执行c_rehash处理证书目录,但问题仍未解决:
root@test:/# root@test:/# c_rehash /var/certs/ Doing /var/certs/ root@test:/# root@test:/# ls /var/certs/ ca-certificates.crt root@test:/#
补充信息:Curl版本7.33.0,SSL版本OpenSSL/1.0.1u
解决方案
核心原因
c_rehash需要为目录中的单个CA证书文件生成哈希符号链接,而你目录下的ca-certificates.crt是多个CA证书合并后的打包文件。OpenSSL无法通过哈希索引从合并文件中定位到对应的 issuer 证书,因此CURLOPT_CAPATH配置失效。
解决步骤
- 拆分合并的CA证书:将
ca-certificates.crt中的每个证书拆分到独立的.pem文件中,可通过以下脚本快速完成:awk 'BEGIN {c=0;} /BEGIN CERTIFICATE/ {c++} {print > "/var/certs/ca_" c ".pem"}' /var/certs/ca-certificates.crt - 重新执行
c_rehash:再次运行命令处理目录,此时工具会为每个拆分后的证书生成哈希链接:c_rehash /var/certs/ - 验证结果:执行
ls -l /var/certs/,应能看到类似8d690281.0 -> ca_1.pem的哈希符号链接文件。
额外说明
- 旧版本curl(如7.33.0)搭配OpenSSL 1.0.1u时,对CA目录的处理严格依赖单个证书的哈希链接,不支持直接从合并文件中查找 issuer。
- 若不想拆分证书,直接使用
CURLOPT_CAINFO指定合并文件是更简便的替代方案,这也是你当前验证有效的方式。
内容的提问来源于stack exchange,提问作者Karthick
相关产品推荐
相关产品推荐

