#tls-certificate #certificate #tls #operating-system #verification #native

rustls-platform-verifier

rustls-platform-verifier支持使用操作系统验证器在rustls中验证TLS证书

9个版本

新版本 0.3.4 2024年8月23日
0.3.3 2024年7月29日
0.3.2 2024年6月26日
0.3.1 2024年4月10日
0.1.1 2024年1月17日

#33 in 操作系统

Download history 27798/week @ 2024-05-03 25484/week @ 2024-05-10 35710/week @ 2024-05-17 34578/week @ 2024-05-24 41192/week @ 2024-05-31 34606/week @ 2024-06-07 40542/week @ 2024-06-14 58664/week @ 2024-06-21 66736/week @ 2024-06-28 73928/week @ 2024-07-05 81361/week @ 2024-07-12 82581/week @ 2024-07-19 95934/week @ 2024-07-26 85831/week @ 2024-08-02 97326/week @ 2024-08-09 91004/week @ 2024-08-16

386,917每月下载量
用于23个crate(其中13个直接使用)

MIT/Apache

135KB
2K SLoC

Rust 2K SLoC // 0.1% comments Go 231 SLoC // 0.2% comments

rustls-platform-verifier

crates.io version crate documentation MSRV crates.io downloads CI

一个基于操作系统的证书设施验证TLS证书有效性的Rust库。在那些没有这些功能的操作系统上,将使用webpki和/或rustls-native-certs

该crate相对于rustls-native-certs本身有几个优点

  • 提高正确性和安全性,因为将考虑操作系统的CA约束
  • 与操作系统证书存储和企业CA部署的更好集成。
  • 通过OCSP和CRLs验证有效性的吊销支持。
  • 更低的I/O和内存开销,因为不需要加载和解析所有平台CA。

该库支持以下平台和流程

操作系统 证书存储 验证方法 吊销支持
Windows Windows平台证书存储 Windows API证书验证
macOS (10.14+) macOS平台根和密钥链证书 macOS Security.framework
iOS iOS平台根和密钥链证书 iOS Security.framework
Android Android系统信任存储 Android信任管理器 有时[^1]
Linux 系统CA捆绑包或用户提供的证书[^3] webpki 否[^2]
WASM webpki根 webpki 否[^2]

[^1]: 在Android上,吊销检查需要API版本 >= 24(例如至少Android 7.0,2016年8月)。当可用时,仅对最终实体证书执行吊销检查。如果未提供最终实体证书的stapled OCSP响应,并且证书省略了OCSP响应者URL和CRL分发点以获取吊销信息,则吊销检查可能失败。

[^2]:为 Linux/WASM 配置的回退 webpki 验证器不支持为吊销检查提供 CRL。如果您需要在这些平台上进行吊销检查,请首选构建自己的 WebPkiServerVerifier,提供必要的 CRL。有关更多信息,请参阅 Rustls ServerCertVerifierBuilder 文档。

[^3]:在 Linux 上,使用 rustls-native-certsopenssl-probe 包尝试发现系统 CA 包。用户可能希望使用 webpki-roots 通过 Verifier::new_with_extra_roots 来增强这些证书,以防系统 CA 包不可用。

安装和设置

在大多数平台上,无需额外设置,只需通过 cargo 添加依赖项即可。

rustls-platform-verifier = "0.3"

要获取配置为使用平台验证器的 rustls ClientConfig,请使用以下方法

let config = rustls_platform_verifier::tls_config();

此包将使用 rustls 进程默认的 crypto 提供程序。要使用不同的 CryptoProvider 构建一个 ClientConfig,请使用以下方法

let arc_crypto_provider = std::sync::Arc::new(rustls::crypto::ring::default_provider());
let config = rustls_platform_verifier::tls_config_with_provider(arc_crypto_provider);

如果您想修改配置,可以像这样构建 ClientConfig

use std::sync::Arc;
use rustls::ClientConfig;
use rustls_platform_verifier::Verifier;

let mut config = ClientConfig::builder()
    .dangerous() // The `Verifier` we're using is actually safe
    .with_custom_certificate_verifier(Arc::new(Verifier::new()))
    .with_no_client_auth();

Android

要在 Android 上使用此包,需要在外部进行一些手动设置(除了 cargo 之外),以便在 Android 上使用证书验证器。为了使用 Android 的证书验证器,该包需要调用 JVM。必须在您的应用程序构建中包含一个小型 Kotlin 组件来支持 rustls-platform-verifier

Gradle 设置

rustls-platform-verifier 在包中捆绑了所需的本地组件,但项目必须设置为自动和正确地定位它们。以下步骤假设您正在使用 .gradle Groovy 文件,因为它们是最常见的,但所有内容 100% 适用于 Kotlin 脚本 (.gradle.kts) 配置,只需进行一些替换。

在您的项目的 build.gradle 文件中,添加以下代码和 Maven 仓库定义。如果适用,这应该是唯一一个“app”子项目,它将在运行时实际使用此包。如果多个项目同时运行此包,则您的 Gradle 配置性能可能会下降。

$PATH_TO_DEPENDENT_CRATE 是从 build.gradle 文件位置到任何依赖 rustls-platform-verifier 的包的 Cargo 清单文件 (Cargo.toml) 的相对路径。

import groovy.json.JsonSlurper

// ...Your own script code could be here...

repositories {
    // ... Your other repositories could be here...
    maven {
        url = findRustlsPlatformVerifierProject()
        metadataSources.artifact()
    }
}

String findRustlsPlatformVerifierProject() {
    def dependencyText = providers.exec {
        it.workingDir = new File("../")
        commandLine("cargo", "metadata", "--format-version", "1", "--manifest-path", "$PATH_TO_DEPENDENT_CRATE/Cargo.toml")
    }.standardOutput.asText.get()

    def dependencyJson = new JsonSlurper().parseText(dependencyText)
    def manifestPath = file(dependencyJson.packages.find { it.name == "rustls-platform-verifier-android" }.manifest_path)
    return new File(manifestPath.parentFile, "maven").path
}

然后,在您声明依赖项的地方,添加以下内容

implementation "rustls:rustls-platform-verifier:latest.release"

Cargo 会自动处理在您的项目中正确位置找到已下载的包。它还会处理在 rustls-platform-verifier 的新版本发布时更新版本。如果您只使用发布的版本,则不需要额外的维护。

这些脚本片段可以根据您的项目进行修改,但必须包含 cargo metadata 调用,以便在磁盘上定位 Android 实现部分。

Proguard

如果您的 Android 应用程序使用 Proguard 进行优化,请确保 Android 验证器组件没有被优化掉,因为它看起来像是死代码。Proguard 无法看到任何 JNI 使用,因此您必须手动将其包含在内。以下规则可以为您做到这一点

-keep, includedescriptorclasses class org.rustls.platformverifier.** { *; }

包初始化

为了让crate调用JVM,它需要来自Android的句柄。这些句柄由init_externalinit_hosted函数提供。这些函数为rustls-platform-verifier提供所需的资源,以便调用Android证书验证器。

例如,如果您的Rust Android组件在启动时被“本地”Android应用程序部分调用,并且具有初始化,如下所示

#[export_name = "Java_com_orgname_android_rust_init"]
extern "C" fn java_init(
    env: JNIEnv,
    _class: JClass,
    context: JObject,
) -> jboolean {
    // ... initialize your app's other parts here.
}

在最简单的情况下,您应该在任何网络运行之前在这里插入对rustls_platform_verifier::android::init_hosted()的调用,这只需要调用一次,验证器将有效于应用程序进程的生命周期。

extern "C" fn java_init(
    env: JNIEnv,
    _class: JClass,
    context: JObject,
) -> jboolean {
    // ... initialize your app's other parts here.

    // Then, initialize the certificate verifier for future use.
    rustls_platform_verifier::android::init_hosted(&env, context);
}

在更复杂的情况下,例如,如果您的代码已经存储了长生命周期的句柄到Android环境中,您可以使用init_external作为替代。这个函数接受对实现android::Runtime特质的对象的&'static引用,crate随后使用这个引用在需要时获取对JVM的访问。

致谢

由1Password和rustls团队用❤️制作。Android和Windows的实现部分是从Chromium之前的验证器实现中改编和引用的。

许可证

根据您的选择,在Apache License, Version 2.0MIT许可证下授权。
除非您明确说明,否则根据Apache-2.0许可证的定义,您提交的任何旨在包含在此crate中的贡献,将按照上述方式双重许可,不附加任何额外条款或条件。

依赖项

~7-16MB
~284K SLoC