Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,12 @@ jobs:
- run: pnpm exec vp fmt --check
- run: cargo autoinherit && git diff --exit-code
- run: cargo shear --deny-warnings
# Bans webpki-roots and webpki-root-certs for the platforms CI builds.
# The security workflow's cargo-deny uses that action's own config.
- uses: taiki-e/install-action@9e1e5806d4a4822de933115878265be9aaa786d9 # v2.82.2
with:
tool: cargo-deny@0.20.2
- run: cargo deny check bans
- run: cargo fmt --check
# --exclude fspy_benchmark: documenting it would build its musl artifact
# dependency, which needs a rust-std this job otherwise has no use for.
Expand Down
1 change: 1 addition & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EXCED = "EXCED"
[files]
extend-exclude = [
"crates/fspy_detours_sys/detours",
"third_party/rustls-platform-verifier",
"crates/fspy_detours_sys/src/generated_bindings.rs",
# Intentional typos for testing fuzzy matching and "did you mean" suggestions
"crates/vt_select/src/fuzzy.rs",
Expand Down
12 changes: 0 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,7 @@ panic = "abort" # Let it crash and force ourselves to write safe Rust.
# would compile them with the build-override profile (opt-level 0) even in
# release builds, in this workspace and in every downstream workspace. See
# https://github.com/rust-lang/cargo/issues/16719.

# Drops the wasm32 dependency on webpki-root-certs. See the vendored Cargo.toml.
[patch.crates-io]
rustls-platform-verifier = { path = "third_party/rustls-platform-verifier" }
4 changes: 4 additions & 0 deletions crates/vt_remote_cache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ rust-version.workspace = true
base64 = { workspace = true }
bytes = { workspace = true }
ciborium = { workspace = true }
# `rustls-no-provider` selects rustls with rustls-platform-verifier, which
# verifies certificates using the operating system's trust store. The crypto
# provider is installed in `Client::new`. The vendored verifier does not
# depend on `webpki-roots` or `webpki-root-certs`; deny.toml bans both.
reqwest = { workspace = true, features = [
"http2",
"multipart",
Expand Down
2 changes: 1 addition & 1 deletion crates/vt_remote_cache/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Client for the [remote cache server API](https://github.com/voidzero-dev/vite-ta

Only HTTP 200 counts as success for every operation, except that a fetch also accepts 404 as no match. Redirects aren't followed, so a redirect fails like any other status.

reqwest configures TLS. It uses the process's default rustls crypto provider, which the client installs as ring unless one is already installed, and verifies certificates with the operating system's verifier. HTTPS requests use HTTP/2 if the server accepts it during the TLS handshake and HTTP/1.1 otherwise. HTTP endpoints always use HTTP/1.1. Requests go through the proxy set in `HTTPS_PROXY`, `HTTP_PROXY`, or `ALL_PROXY`, except for hosts in `NO_PROXY`. Without those variables, the system proxy settings are used on macOS and Windows. Connections time out after 10 seconds. Reads time out after 60 seconds, and until the response headers arrive, that limit also covers sending the request.
reqwest configures TLS. It uses the process's default rustls crypto provider, which the client installs as ring unless one is already installed, and verifies certificates with the operating system's trust store. The vendored `rustls-platform-verifier` does not depend on `webpki-roots` or `webpki-root-certs`, so those crates are absent from `Cargo.lock`. `deny.toml` bans them, and CI runs `cargo deny check bans`. HTTPS requests use HTTP/2 if the server accepts it during the TLS handshake and HTTP/1.1 otherwise. HTTP endpoints always use HTTP/1.1. Requests go through the proxy set in `HTTPS_PROXY`, `HTTP_PROXY`, or `ALL_PROXY`, except for hosts in `NO_PROXY`. Without those variables, the system proxy settings are used on macOS and Windows. Connections time out after 10 seconds. Reads time out after 60 seconds, and until the response headers arrive, that limit also covers sending the request.

`Error` names the kind of failure: an invalid endpoint, a client that couldn't be created, a blob file that couldn't be read, credentials that couldn't be obtained, a network error (including timeouts and responses that end early), a status other than 200 (or 404, for a fetch), or a malformed fetch response. Its messages contain no OS-specific details, so they can be shown to users as is. The details are in the source: the underlying error, the parse error for an endpoint that isn't a URL, or the message in an error response's body. Network errors leave out the request URL, since the endpoint may contain credentials, such as a token in its query.
7 changes: 4 additions & 3 deletions crates/vt_remote_cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,10 @@ impl Client {
let fetch_url = route_url(&endpoint, "fetch")?;
let store_url = route_url(&endpoint, "store")?;
let blob_url = route_url(&endpoint, "blob")?;
// reqwest configures TLS with the process's default crypto provider.
// Installing fails if one is already installed; vite-plus installs
// ring too.
// reqwest configures TLS with the process's default crypto provider
// and verifies certificates with the operating system's trust store.
// Installing the provider fails if one is already installed; vite-plus
// installs ring too.
let _ = rustls::crypto::ring::default_provider().install_default();
// A redirect fails like any other status. Following one could turn a
// store into a GET of a login page that responds with 200. HTTPS
Expand Down
9 changes: 7 additions & 2 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ exceptions = [
# Each entry is the crate and version constraint, and its specific allow
# list
# { allow = ["Zlib"], name = "adler32", version = "*" },
# Mozilla's root certificates, used by rustls-platform-verifier on wasm32 only.
{ allow = ["CDLA-Permissive-2.0"], name = "webpki-root-certs" },
]

# Some crates don't have (easily) machine readable licensing information,
Expand Down Expand Up @@ -145,6 +143,13 @@ deny = [
# Wrapper crates can optionally be specified to allow the crate when it
# is a direct dependency of the otherwise banned crate
# { name = "ansi_term", version = "=0.11.0", wrappers = [] },
#
# Compiled-in Mozilla root certificates. HTTPS verification uses the
# operating system's trust store. The vendored rustls-platform-verifier
# does not depend on these crates, so they stay out of Cargo.lock. This
# ban fails if any target starts depending on an embedded trust store.
{ name = "webpki-roots" },
{ name = "webpki-root-certs" },
]

# List of features to allow/deny
Expand Down
64 changes: 64 additions & 0 deletions third_party/rustls-platform-verifier/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Vendored from crates.io rustls-platform-verifier 0.7.0 so the wasm32
# dependency on webpki-root-certs can be removed. Cargo.lock records every
# target-specific dependency, and that crate is Mozilla's compiled-in trust
# store. Certificate verification on the platforms vite-task ships still uses
# the operating system's trust store. Upstream tests and the update-certs
# example are omitted because they require webpki-root-certs.
# https://github.com/rustls/rustls-platform-verifier
[package]
name = "rustls-platform-verifier"
version = "0.7.0"
description = "rustls-platform-verifier supports verifying TLS certificates in rustls with the operating system verifier"
keywords = ["tls", "certificate", "verification", "os", "native"]
repository = "https://github.com/rustls/rustls-platform-verifier"
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.85"
publish = false

[lib]
name = "rustls_platform_verifier"

[features]
# Enables a C interface to use for testing where `cargo` can't be used.
# This feature is not stable, nor is the interface exported when it is enabled.
# Do not rely on this or use it in production.
ffi-testing = ["android_logger", "rustls/ring"]
# Enables APIs that expose lower-level verifier types for debugging purposes.
dbg = []
# Enables `log::debug` base64-encoded logging of all end-entity certificates processed
# by the platform's verifier.
cert-logging = ["base64"]
# Used for nicely documenting the Android-specific APIs. This feature is not stable.
docsrs = ["jni", "once_cell"]

[dependencies]
rustls = { version = "0.23.27", default-features = false, features = ["std"] }
log = { version = "0.4" }
base64 = { version = "0.22", optional = true } # Only used when the `cert-logging` feature is enabled.
jni = { version = "0.22.4", default-features = false, optional = true } # Only used during doc generation
once_cell = { version = "1.9", optional = true } # Only used during doc generation

[target.'cfg(all(unix, not(target_os = "android"), not(target_vendor = "apple"), not(target_arch = "wasm32")))'.dependencies]
rustls-native-certs = "0.8"
webpki = { package = "rustls-webpki", version = "0.103", default-features = false }

[target.'cfg(target_os = "android")'.dependencies]
once_cell = "1.9"
rustls-platform-verifier-android = "0.1.0"
jni = { version = "0.22", default-features = false }
webpki = { package = "rustls-webpki", version = "0.103", default-features = false }
android_logger = { version = "0.15", optional = true } # Only used during testing.

[target.'cfg(any(target_vendor = "apple"))'.dependencies]
core-foundation = "0.10"
core-foundation-sys = "0.8"
security-framework = "3.5.0"
security-framework-sys = "2.15"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = ">=0.52.0, <0.62.0", default-features = false, features = ["Win32_Foundation", "Win32_Security_Cryptography"] }

[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
features = ["dbg", "docsrs"]
Loading
Loading