#path #x509 #path-finding #search #validation #validate #aia

x509-path-finder

X509 Path Finder 是一个用于 Rust 的深度优先搜索证书路径验证器。

9 个版本 (4 个重大更新)

0.7.1 2023 年 9 月 20 日
0.6.3 2023 年 9 月 7 日
0.5.2 2023 年 9 月 5 日
0.3.5 2023 年 8 月 31 日
0.2.1 2023 年 8 月 24 日

#8 in #path-finding

Download history 81/week @ 2024-04-23 4/week @ 2024-04-30

每月 55 次下载

Apache-2.0

215KB
1.5K SLoC

X509 Path Finder

X509 Path Finder 是一个 深度优先搜索 证书路径验证器。

CI Status

Depth-first search

概要

X509 Path Finder 受到 RFC 4158 的启发

现在许多 PKI 正在使用复杂的结构... 而不是简单的层次结构。此外,一些企业正在逐渐从包含许多信任锚点的信任列表转向一个具有一个信任锚点和许多交叉认证关系的基础设施...。本文档建议使用一种有效的一般方法来构建路径,该方法涉及深度优先树遍历。

X509 Path Finder 否认单一证书 "链" 的概念。相反,它搜索无限中的第一个匹配项。一旦找到可以验证的路径,搜索就会停止,并将路径返回给调用者。

路径搜索的复杂性受到三个因素的影响

  1. 预加载到其本地存储中的证书数量
  2. 它可以通过遵循 AIA URL 查找并下载的证书数量
  3. 任意时间限制

在评估路径候选以进行验证时,X509 Path Finder 是实现无关的。一旦找到已终止的路径,它就会将其呈现给后端权威机构进行验证。如果权威机构验证了路径,则搜索停止并将路径返回。如果路径被拒绝,则搜索继续。

X509 Path Finder 提供了两个 PathValidator 实现

  1. DefaultPathValidator - 使用 rustls-webpki 实现,默认可用。
  2. OpenSSLPathValidator - 使用 Rust OpenSSL 实现,可通过 openssl 功能标志获得

警告

实现 PathValidator 本身很简单,但安全的 X509 路径验证 并不是。鼓励工程师使用受信任的 X509 路径验证器作为其 PathValidator 实现的基础,并在其上堆叠业务逻辑。

用法

默认情况下,提供的 DefaultPathValidator 验证器可用。

[dependencies]
x509_path_finder = { version = "*"] }

启用 openssl 功能以访问提供的 OpenSSLPathValidator 验证器。

[dependencies]
x509_path_finder = { version = "*", features = ["openssl"] }

示例


    use webpki::{KeyUsage, TrustAnchor};
    use std::sync::Arc;
    use std::time::Duration;
    use x509_path_finder::provided::validator::default::DefaultPathValidator;
    use x509_path_finder::{X509PathFinder, X509PathFinderConfiguration};

    async fn test_find(
        root: Vec<u8>,
        ic: Vec<Arc<x509_path_finder::Certificate>>,
        ee: x509_path_finder::Certificate,
    ) -> Result<(), x509_path_finder::X509PathFinderError> {
        // instantiate default validator        
        let root = TrustAnchor::try_from_cert_der(root.as_slice()).unwrap();  
        let algorithms = &[&webpki::ECDSA_P256_SHA256];
        let validator = DefaultPathValidator::new(algorithms, vec![root], KeyUsage::client_auth(), &[]);

        // instantiate the finder
        let mut search = X509PathFinder::new(X509PathFinderConfiguration {
            limit: Duration::default(),
            aia: None,
            validator,
            certificates: ic,
        });

        // execute the search
        let found = search.find(ee).await?.found.unwrap();

        // path has two certificates
        assert_eq!(2, found.path.len());

        // Found is also an iterator over path
        assert_eq!(2, found.into_iter().count());
        
        Ok(())
    }

配置

使用 X509PathFinderConfiguration 结构配置 X509 路径构建器,该结构具有以下字段

资源管理

由于 X509 路径构建器可以从网络上消耗 AIA URL,对 X509PathFinder::find 的调用理论上可以无限期运行,或被强制下载大量数据。可以通过以下配置设置管理资源消耗

查找路径

调用 X509PathFinder::find 以查找路径。提供目标端实体 Certificate 以开始搜索。搜索将逆向工作到根证书。

返回的 Report 包含以下字段

  • found: 在路径查找成功时,包含 Found
  • duration: 路径搜索的持续时间
  • store: 未用于发现路径的缓存的 Certificate 集合
  • failures:由 PathValidator 实现报告的任何验证错误都保存在 ValidationFailure 中。

找到

Found 结构体包含以下字段

  • path - 发现的路径,一个 Certificate 的 vec。路径包括目标证书。根据 RFC 5246,路径是从目标开始,向信任锚方向排序的。
  • origin - 路径的 CertificateOrigin

Found 还是一个遍历 path 成员引用的迭代器。

CertificateOrigin

CertificateOrigin 是一个枚举,描述了每个证书的来源。可以是以下之一

  • Target:调用 X509PathFinder::find 时的初始证书。
  • Store:证书在存储中找到
  • Url:证书从 URL(AIA)下载

ValidateFailure

ValidationFailure 存储任何验证错误。即使在最终找到有效的证书路径的情况下,也可能发生验证错误。ValidateFailure 包含以下字段

ValidationFailure 还是一个遍历 path 成员引用的迭代器。

API

可以实现 X509 PathValidator API 以使用不同的后端权威机构验证证书路径并添加业务逻辑,特别是 策略 约束。

实现

TODO

按优先级排序

  • 更深入的集成测试
  • 基准测试
  • 在构建路径时缓存发行者 <-> 主题映射
  • 在摄入时忽略无效证书,而不是等待 PathValidator 拒绝整个路径候选者
  • 并行化 AIA 下载
  • 加权路径决策

依赖项

~12–26MB
~500K SLoC