资讯动态

curl `--cert-status` 全解析:借助 OCSP Stapling 严格校验服务器证书状态

发布时间:2026/9/10 3:01:32 来源:尧图企业网站定制
curl--cert-status全解析借助 OCSP Stapling 严格校验服务器证书状态【免费下载链接】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--cert-status是 curl 提供的 TLS 布尔开关选项它让 curl 在握手阶段通过 Certificate Status Request即 OCSP staplingTLS 扩展向服务器请求当前证书的在线状态证明并据此拒绝已吊销、状态未知或根本没有提供 OCSP 响应的服务器证书。本文以 docs/cmdline-opts/cert-status.md 为核心结合 curl 源码libcurl 选项处理、OpenSSL 与 GnuTLS 两个 TLS 后端的实现讲解该选项的用法、失败判定逻辑、适用后端限制及对应的 libcurl API帮助你把它正确用于证书吊销安全加固场景。--cert-status是什么一次握手就完成的证书状态核验TLS 证书本身在有效期内并不代表它当前仍然可信——证书可能已被吊销。传统上客户端需要额外去访问 CRL 或 OCSP 服务器查询吊销状态这既慢又不可靠。OCSP stapling 的思路是由服务器自己提前向 OCSP 响应者获取当前证书的状态证明staple并在 TLS 握手时把这份签名响应钉在 Certificate Status RequestRFC 6066status_request扩展中传给客户端客户端无需再发起额外的网络请求即可核验状态。curl 官方对该选项的定义cert-status.md 原文是Verify the status of the server certificate by using the Certificate Status Request (aka. OCSP stapling) TLS extension.即通过 Certificate Status Request又称 OCSP staplingTLS 扩展验证服务器证书的状态。文档元数据中记录的关键信息如下字段取值含义Longcert-status长选项名无前缀--ProtocolsTLS仅作用于 TLS 类协议HTTPS、FTPS、IMAPS、SMTPS 等Added7.41.0自 curl 7.41.0 起引入HelpVerify server cert status OCSP-staple--help输出中的简短说明Categorytls属于 TLS 类别选项Multiboolean布尔开关出现即启用不接收额外数值参数Example--cert-status $URL官方示例用法基本用法--cert-status不需要参数值在命令行中把它与 URL 一起给出即可启用curl --cert-status https://example.com/官方示例等价形式$URL可替换为任意目标地址curl --cert-status $URL启用后如果服务器不支持 OCSP stapling 扩展、未在握手中返回 stapled 响应curl 会把这次连接当作验证失败处理详见下文三种必失败的情形。因此该选项只适合连接到确实提供 OCSP staple 的服务器否则原本正常的 HTTPS 请求会直接报错中断。若想直观看到握手细节可叠加-v观察失败时还会出现带有 SSL certificate status 或 OCSP 相关字样的诊断输出curl -v --cert-status https://example.com/在脚本中组合使用也很常见例如与--failfail.md一起把证书状态验证失败变成非零退出码以驱动自动化流程curl --fail --cert-status https://example.com/ || echo 证书状态校验未通过三种必失败的情形原文档明确给出了启用该选项后判定失败的三类情况这也是该选项的安全语义所在服务器返回无效的响应例如响应已过期expired响应内容表明服务器证书已被吊销revoked完全收不到任何响应服务器不支持或未提供 OCSP stapling。只要触发以上任一情形curl 的证书状态验证即失败随后整个 TLS 连接建立被中止。在 libcurl 层面这种失败统一映射为错误码CURLE_SSL_INVALIDCERTSTATUS值为 91见 include/curl/curl.h对应的人类可读错误串为 SSL server certificate status verification FAILED见 lib/strerror.c。选项的前世今生CURLOPT_SSL_VERIFYSTATUS与--doh-cert-status--cert-status是 libcurl 选项CURLOPT_SSL_VERIFYSTATUS的命令行映射。该 API 选项在 include/curl/curl.h 中定义为CURLOPTTYPE_LONG编号 232自 7.41.0 起可用与命令行选项同一版本引入详细说明见 docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.md。库函数调用方式#include curl/curl.h CURL *curl curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, https://example.com/); /* 1 启用0 禁用默认 0*/ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L); CURLcode result curl_easy_perform(curl); curl_easy_cleanup(curl); }命令行到库选项的接线关系可以从工具源码中完整追出来选项解析注册在 src/tool_getparam.c{cert-status, ARG_BOOL|ARG_TLS, , C_CERT_STATUS}其中ARG_TLS表示仅与 TLS 场景相关ARG_BOOL表示布尔开关命中后在 src/tool_getparam.c 写入config-verifystatus toggle对应字段定义在 src/tool_cfgable.h真正下发到 libcurl 是在 src/config2setopts.cif(config-verifystatus) my_setopt_long(curl, CURLOPT_SSL_VERIFYSTATUS, 1);。与之配套的还有--doh-cert-statusdoh-cert-status.md它专门用于要求 DoHDNS over HTTPS服务器也提供 OCSP staple对应的 API 选项是CURLOPT_DOH_SSL_VERIFYSTATUS编号 308见 include/curl/curl.h详情见 docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.md。两条选项在 src/tool_getparam.c 中并列注册作用域一个针对普通连接、一个专门针对 DoH 服务器。后端支持矩阵仅 OpenSSL 与 GnuTLS原文档特别指出This support is currently only implemented in the OpenSSL and GnuTLS backends.即当前只在 OpenSSL 与 GnuTLS 两个 TLS 后端中实现了该能力。这一点在源码中有非常清晰的证据。libcurl 把 TLS 后端能力抽象成一个函数指针表struct Curl_ssl见 lib/vtls/vtls_int.h其中cert_status_request字段表示该后端是否支持证书状态请求统一通过 lib/vtls/vtls.c 的Curl_ssl_cert_status_request()暴露给上层。各后端的落实情况后端cert_status_request实现出处OpenSSL实现编译时受OPENSSL_NO_OCSP约束lib/vtls/openssl.cGnuTLS实现恒返回 TRUElib/vtls/gtls.cmbedTLSNULL不支持lib/vtls/mbedtls.cwolfSSLNULL不支持lib/vtls/wolfssl.cSchannelNULL不支持lib/vtls/schannel.crustlsNULL不支持lib/vtls/rustls.c对不支持的后端设置CURLOPT_SSL_VERIFYSTATUS会在 setopt 阶段直接被拦截并返回CURLE_NOT_BUILT_IN见 lib/setopt.c命令行工具则表现为该选项在当前构建不可用。因此使用前可用curl -V确认当前编译所绑定的 TLS 后端是否为 OpenSSL 或 GnuTLS。源码级原理从选项生效到握手校验的完整链路libcurl 选项存储在 lib/setopt.c 中CURLOPT_SSL_VERIFYSTATUS的取值先经Curl_ssl_cert_status_request()做能力探测再写入s-ssl.primary.verifystatus并通过Curl_ssl_conn_config_update()同步到当前连接。DoH 变体CURLOPT_DOH_SSL_VERIFYSTATUS写入s-doh_verifystatus逻辑相同lib/setopt.c。OpenSSL 后端的两段式实现第一段是发出请求。在ossl_init_ssl()创建SSL对象时lib/vtls/openssl.c如果当前连接配置的verifystatus为真就调用SSL_set_tlsext_status_type(octx-ssl, TLSEXT_STATUSTYPE_ocsp);这会让客户端在 ClientHello 中携带status_request扩展表明希望服务器回送 OCSP staple。第二段是握手后核验。证书链验证完成后lib/vtls/openssl.c若verifystatus开启、且不是 Session ID 复用reused session的连接——源码注释明确说明复用会话时不再重复校验——则调用verifystatus()lib/vtls/openssl.c执行真正的 OCSP 校验流程。该函数用 OpenSSL 的 OCSP API 依次完成通过SSL_get_tlsext_status_ocsp_resp()取出服务器 staple 的 OCSP 响应若为空则报 No OCSP response received用d2i_OCSP_RESPONSE()解析 DER 响应校验OCSP_response_status()是否为OCSP_RESPONSE_STATUS_SUCCESSFUL用OCSP_response_get1_basic()提取 BasicOCSPResponse并通过OCSP_basic_verify()结合证书链与信任库SSL_CTX_get_cert_store()验证响应签名者的可信度用OCSP_cert_to_id()哈希算法为 SHA-1代码注释说明该 ID 仅作为查找键、按 RFC 5019 设计计算服务器证书的 CertID再从响应中用OCSP_resp_find_status()找到对应条目用OCSP_check_validity()校验响应时间窗允许 300 秒时钟偏移thisupd/nextupd过期响应即失败最终检查证书状态V_OCSP_CERTSTATUS_GOOD通过V_OCSP_CERTSTATUS_REVOKED或V_OCSP_CERTSTATUS_UNKNOWN一律失败并附上OCSP_crl_reason_str()给出的吊销原因。任一步失败都以CURLE_SSL_INVALIDCERTSTATUS返回代码里对每一种失败都通过failf()写入了明确的诊断信息方便用-v排查。GnuTLS 后端实现GnuTLS 侧在握手启用阶段调用gnutls_ocsp_status_request_enable_client()发出扩展请求lib/vtls/gtls.c握手后调用gtls_verify_ocsp_status()lib/vtls/gtls.c。该校验函数lib/vtls/gtls.c的流程与 OpenSSL 版本对仗工整gnutls_ocsp_status_request_get()取响应无数据时按GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE报 No OCSP response received 并失败gnutls_ocsp_resp_import()解析响应gnutls_ocsp_resp_verify()借助 GnuTLS 凭据的信任列表验证响应签名gnutls_ocsp_resp_get_single()取出单条证书状态GNUTLS_OCSP_CERT_GOOD通过GNUTLS_OCSP_CERT_REVOKED会进一步把 CRL 原因码翻译成易读文本如 private key compromised、certificate is on hold后报 Server certificate was revokedGNUTLS_OCSP_CERT_UNKNOWN报 Server certificate status is unknown只要状态不是 GOOD最终统一返回CURLE_SSL_INVALIDCERTSTATUSlib/vtls/gtls.c。可以看到尽管两个后端使用的第三方密码库 API 完全不同但失败判据与原文档的三条规则严格一致这也说明该选项的语义与后端无关、是稳定契约。与其他校验类选项的分工--cert-status校验的是证书当前状态与另几个校验选项职责互补官方 See-also 中推荐了--pinnedpubkeypinnedpubkey.md选项校验对象--cert-status证书是否被吊销/状态未知依赖 OCSP staple--pinnedpubkey服务器公钥是否与本地钉死的公钥哈希一致--cacert/--capath证书链是否由信任的 CA 签发--cert-type/--cert客户端证书相关实践中常把--cert-status与--pinnedpubkey叠加使用前者保证证书当前未被吊销后者保证即使信任链被攻破也只能使用你预先钉死的那把公钥。注意事项与限制依赖服务器能力该选项要求服务器在 TLS 握手中真正提供 OCSP staple对不支持该扩展的服务器连接会被判定失败而非静默降级。这一点与CURLOPT_SSL_VERIFYSTATUS文档中的表述一致见 docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.md。仅限特定后端只有用 OpenSSL含 BoringSSL 等衍生构建且未被OPENSSL_NO_OCSP裁剪或 GnuTLS 编译的 curl 才支持其他后端下设置选项会得到CURLE_NOT_BUILT_IN。请以curl -V实际输出为准。会话复用时不重复校验从源码看lib/vtls/openssl.cSession ID/TLS 会话复用的握手不再重复执行 OCSP 校验如果同一连接后续复用了会话其证书状态校验收敛在首次完整握手时完成。错误码定位一旦失败传输层面返回CURLE_SSL_INVALIDCERTSTATUS91工具会以非零退出码结束配合-v可以读到具体是哪一步无响应、响应无效、响应过期、状态为 revoked 还是 unknown导致的失败。综上--cert-status是 curl 在证书链正确之外增加的一层吊销状态强校验。它把 OCSP 查询从客户端主动外连改造成握手内嵌验证既减少了额外网络往返又让证书被吊销这一安全事件在连接建立阶段就被及时拦截。对安全敏感的场景在 OpenSSL/GnuTLS 构建上启用它是一份低成本、高收益的防护选项。【免费下载链接】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 小时内与您沟通定制方案

免费获取报价