Rust in Everything
基于 rustls 0.23.46

证书校验

握手主线走到客户端的 ExpectCertificateVerify 时,手里有服务器发来的证书链和一个 CertificateVerify 签名。rustls 自己不解析 X.509,也不做路径构建:它把这两样交给配置里的 ServerCertVerifier,默认实现 WebPkiServerVerifier 再转给独立的 rustls-webpki crate。这一部分讲这条校验主线:从 verify_server_cert 进 rustls-webpki 的 EndEntityCert::verify_for_usage,在 verify_cert.rs 里从叶子往上找签发者,检查有效期、基本约束、扩展密钥用途和名字约束,受三个预算约束;回到 rustls 再比对名字、验 CertificateVerify 的签名;可选地查 CRL。反方向的客户端证书用同一套机器,最后是 dangerous() 下的自定义校验器到底能关掉什么。

代码分布(按 tag 统计 .rs 行数,含单元测试):rustls 的 rustls/src/webpki/ 1863 行(server_verifier.rs 448、client_verifier.rs 665、verify.rs 293、anchors.rs 143、mod.rs 314),两个 trait 在 verify.rs(383 行);rustls-webpki 0.103.16 的 src/verify_cert.rs 1523 行,名字匹配 src/subject_name/ 2237 行,CRL src/crl/ 1661 行,end_entity.rs 241 行。

  1. 服务器证书:ServerCertVerifier 的四个方法和它们返回的「标记类型」;WebPkiServerVerifier::verify_server_cert 的顺序(路径、OCSP 只记日志、名字);webpki 的错误怎么变成 rustls 的错误和告警;RootCertStore 存的是信任锚而不是证书,webpki-roots 的 118 个锚只占完整证书的四成;DNS、IP、通配符的匹配规则和 ServerName::try_from;CertificateVerify 签名用哪张算法表。
  2. 路径构建:rustls-webpki 的 build_chain_inner 怎么深度优先地找签发者,每一层查什么;签名 100 次、递归 200000 次、名字约束比较 250000 次三个预算和深度 6 的上限;用 rcgen 造的病态证书链实测每个预算在哪里触发、花多少时间;0.103.16 新加的不信任公钥表。
  3. 客户端证书与自定义校验:WebPkiClientVerifier、必选和可选的客户端认证、CertificateRequest 里的提示名单;CRL 吊销检查的四个开关和一个容易误读的报错;dangerous() 下的自定义校验器,以及 no-op 校验器连 CertificateVerify 签名一起跳过的后果。
flowchart TB
  ecv["ExpectCertificateVerify"] --> vsc["verify_server_cert"]
  vsc --> vfu["verify_for_usage"]
  vfu --> bc["build_chain_inner"]
  bc --> bud["Budget"]
  bc --> crl["CRL 可选"]
  vsc --> name["名字匹配"]
  ecv --> sig["verify_tls13_signature"]
  sig --> fin["ExpectFinished"]
  name --> fin

图里的 ExpectCertificateVerify 和它之后的 ExpectFinished 属于握手主线,见客户端 TLS 1.3;签名算法表来自 CryptoProvider,见 CryptoProvider。

💬 关联讨论

发起讨论
加载中...