Move TLS to aws-lc-rs with post-quantum key exchange, drop ring via ureq 3, and fix the dependency defects behind it #192
Merged
enricobuehler
merged 6 commits from 2026-08-13 10:43:38 +00:00
worktree-aws-lc-rs-migration into main
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d0a7b262d2 |
chore(deps): regenerate notices + make audit.yml's header match what it now scans
windows-drivers / driver-build (pull_request) Successful in 1m57s
windows-drivers / probe-and-proto (pull_request) Successful in 35s
apple / swift (pull_request) Successful in 2m29s
apple / screenshots (pull_request) Skipped
ci / bun-nix (pull_request) Successful in 52s
ci / rust-arm64 (pull_request) Failing after 3m22s
ci / web (pull_request) Successful in 3m47s
ci / docs-site (pull_request) Successful in 5m10s
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 7m21s
windows / build (x86_64-pc-windows-msvc) (pull_request) Failing after 24s
ci / rust (pull_request) Failing after 11m30s
nix / flake (pull_request) Failing after 30m26s
android / android (pull_request) Successful in 13m2s
THIRD-PARTY-NOTICES regenerated after the dependency changes (582 crates). audit.yml's header claimed to cover "EVERY dependency tree the project ships"; it now actually does, so the note spells out that each Rust lockfile needs its own `--file` — a bare `cargo audit` reads only the root one, which is how the drivers lock stayed unscanned while already sitting in this job's `paths:` filter. Also corrected "BOTH Rust workspaces" for the licence gate, which covers the host + driver workspaces. Both cargo-about legs re-run after the dependency removals: RC=0. |
||
|
|
51a005dd43 |
fix(deps): close the audit gaps, drop unused declarations, declare what is used
Acting on the 2026-08-13 dependency sweep. Every claim below was re-verified against
the tree before acting on it (greps carry a positive control; the advisories were
re-checked with cargo audit 0.22.2).
SECURITY
- event-listener 5.4.1 -> 5.4.2 (RUSTSEC-2026-0221, unsound Send/Sync on StackSlot;
reaches the tray via zbus and the host via ashpd). This sat unnoticed because
`cargo audit` reports unsoundness as a WARNING and the job fails only on
vulnerabilities — audit.toml now says so out loud.
- spin 0.9.8 -> 0.9.9. 0.9.8 is YANKED and was genuinely compiled (flume via mdns-sd
and relm4, plus lazy_static).
- wayland-scanner 0.31.10 -> 0.31.11, which moves quick-xml 0.39 -> 0.41. That is the
exact trigger audit.toml documented for RUSTSEC-2026-0194/0195, so both ignores are
deleted rather than left as permanent exceptions. Only RUSTSEC-2023-0071 (rsa
Marvin, still unfixed upstream) remains.
- Corrected audit.toml's claim that `paste` arrives "via utoipa-axum": rav1d pulls it
too, so every client has it through the decode path and dropping utoipa-axum would
not have cleared it.
TWO CI GATES THAT SCANNED NOTHING
- `cargo audit` only ever reads the ROOT Cargo.lock. The drivers lock was already in
this job's `paths:` filter, so edits to it triggered a run that then ignored them.
All four secondary workspaces now get an explicit `--file` (verified: clean, bar the
known `paste` warning in drivers).
- packaging/windows/pf-vkhdr-layer had NO lockfile at all while shipping as a DLL in
the host installer, so every build resolved fresh and neither cargo-audit nor
cargo-about ever saw it. Lockfile generated and committed, and added to `paths:`.
UNUSED / DUPLICATE DECLARATIONS
- punktfunk-host: removed 13 dependencies it never references — the Wayland stack
(client, protocols{,-wlr,-misc}, scanner, backend), xkbcommon, reis, khronos-egl,
ash, usbip-sim, parking_lot, bytemuck. The code moved to pf-inject and pf-zerocopy
in the subsystem extraction and those crates declare them; only the manifest entries
and their now-false comments stayed. Also dropped four redundant re-declarations
(tokio/serde_json/futures-util in the Linux block, tower in dev-deps).
- Removed genuinely unused: bytes (punktfunk-core), anyhow (pf-win-display),
tracing (clients/cli), anyhow (clients/session), serde (clients/windows).
- Removed the high-level `wdk` crate from all five driver crates and the drivers
workspace: none of them ever referenced `wdk::` (62 `wdk_sys::` uses; pf-umdf-util
is a full WDF crate that never declared it). `tracing`/`tracing-subscriber` remain
in that lock afterwards but ONLY as wdk-sys build-dependencies, not in the DLLs.
- pf-win-display took punktfunk-core with `quic` for one type (`Mode`) that lives in
the ungated `config` module; now `default-features = false`, which keeps
quinn/tokio/rcgen/opus out of a leaf crate's declared closure.
- pf-encode declared the windows-rs feature `Wdk_Graphics_Direct3D` for a call that
lives in pf-frame and is resolved via GetProcAddress on gdi32.
LATENT BREAKAGE (compiled only by feature unification)
- pf-inject uses `tokio::select!` without declaring `macros` (borrowed from
punktfunk-core's quic feature); pf-capture uses `tokio::sync::oneshot` without
declaring `sync` (borrowed from ashpd->zbus); pf-client-core uses the `minwindef`
and `winnt` windows-rs headers without declaring them (borrowed from
clients/windows). Each now declares what it uses, so an unrelated crate changing its
features cannot break them.
- pf-console-ui took pf-client-core WITHOUT `default-features = false`, unlike every
other consumer. That default is `pyrowave`, which compiles the vendored PyroWave C++
— "fatal on Windows ARM64". Only safe today because the ARM64 leg passes
--no-default-features (which also drops `ui`).
CORRECTED A FALSE INVARIANT
- clients/windows claimed "the workspace builds ONE windows-rs". It does not: wasapi
pulls the crates.io windows 0.62.2 beside the git-rev copy. The invariant that DOES
hold is narrower (reactor and that crate share one rev, which is what makes the
IDXGISwapChain1 hand-off type-check). Comment rewritten, with a warning against
"fixing" it via a blanket [patch.crates-io] — this rev uses header-named features
while a dozen other manifests use the old Win32_* namespace ones.
Plus the safe in-compat `cargo update` sweep (no manifest edits).
Verified on macOS: punktfunk-core 385, pf-update-check 32, c_abi 1 (with
LIBRARY_PATH=/opt/homebrew/opt/opus/lib), cargo audit clean bar the two known
unmaintained warnings. Linux and Windows legs follow.
|
||
|
|
b84d37b5a0 |
test(host): make two socket stubs survive ureq 3 / Windows
Both failures found running the store + plugin-launch tests on the Windows runner after the ureq 3 port. Neither is a production defect — the request/response round trip and the 304 semantics both hold — but both tests were resting on assumptions that ureq 2 happened to tolerate. catalog::ureq_returns_304_as_ok: the stub answered without ever reading the request. Closing a socket that still holds unread received data makes Windows send an RST rather than a FIN, which discards the response already written, so the client saw a transport error (os error 10053) instead of the 304 the test exists to pin. The stub now drains the request first. The pinned behaviour is unchanged and still true: ureq 3 turns only `is_client_error() || is_server_error()` into Err, so 304 arrives as Ok exactly as before. plugin_launch::asks_the_registered_plugin_and_takes_its_answer: hardcoded a cwd of `/opt/emu`, which has no drive letter and is therefore NOT `Path::is_absolute` on Windows, so `validate_reply` refused the recipe. This test could never have passed on Windows, with either ureq version — its sibling `a_working_directory_must_be_absolute` already had the `cfg!(windows)` split and this one was simply missed. Confirmed by diagnostic before touching it: the body came back over ureq 3 byte-perfect, so everything up to validation was working. |
||
|
|
9ec8350fc3 |
chore(licenses): retire ring's licence exception now that ring is gone
`about.toml` carried `OpenSSL` in the global accepted list and a `[ring]` per-crate acceptance, both there solely because ring's licence is an AND that includes the OpenSSL terms. The ureq 2 -> 3 upgrade removed ring from every target we build, and aws-lc-sys 0.44's SPDX (ISC AND (Apache-2.0 OR ISC) AND Apache-2.0 AND MIT AND BSD-3-Clause AND ... MIT-0) carries no OpenSSL clause, so neither entry has anything left to permit. Note about.toml sets no `targets`, so cargo-about still walks quinn-proto's wasm-only ring edge — removing the exception is safe not because ring is invisible but because ring 0.17.14 declares `Apache-2.0 AND ISC`, and both are globally accepted already. Verified by running the gate itself, both legs of what audit.yml runs: cargo about generate about.hbs --fail -> 0 cargo about generate -m packaging/windows/drivers/Cargo.toml -c ... -> 0 and proved non-vacuous with a negative control: dropping "ISC" from the accepted list makes the first leg exit 1. THIRD-PARTY-NOTICES regenerated: 601 -> 580 crates (ureq 3 pulls a smaller tree than ureq 2 + ring), now listing ureq 3.4.0. |
||
|
|
3ccfd01699 |
feat(deps): upgrade ureq 2 -> 3, removing ring from the tree entirely
The aws-lc-rs move left `ring` compiled in for one reason: ureq 2 names `features = ["ring", ...]` inside its own `[dependencies.rustls]` block, and cargo features are additive, so no dependent could switch it off. ureq 3 declares rustls with `default-features = false` and selects no backend, which finally makes the choice ours. `cargo tree -i ring` is now empty for macOS, Windows and Linux. The one remaining hit under `--target all` is quinn-proto's wasm-only dependency (`cfg(all(target_family = "wasm", target_os = "unknown"))`), a target we never build. ⚠ The dependency must be spelled `features = ["rustls-no-provider", "rustls-webpki-roots"]`. ureq 3's convenience `rustls` feature expands to include `_ring` — the same shape of trap as rustls's own `features = ["ring"]`, and the reason punktfunk-webos still carries both backends today. Ported 9 files. The two pinning call sites (the desktop client's library fetch and the tray's status poll) needed a custom ureq Connector, because ureq 3's `TlsConfig` exposes roots/client-cert/off-switch but no hook for a custom ServerCertVerifier. That glue lives once in punktfunk-core behind a new off-by-default `ureq-tls` feature rather than being hand-rolled twice on a trust boundary; the Apple/Android cdylib embedders do not enable it and pull no HTTP stack. The connector is modelled on ureq's own crate-private RustlsConnector and is transport glue only. Two behaviour changes worth noting, both improvements: - Body caps are enforced by the reader, so an over-cap response is now an Err rather than ureq 2's silent truncation — which used to surface as a signature failure pointing at the wrong thing. - A pin mismatch matches ureq 3's typed `Error::Rustls(..)` instead of sniffing a substring out of a transport message, which could also fire on unrelated cert errors. Conditional requests are unchanged: 304 still arrives as Ok (only 4xx/5xx are Err), which the existing `ureq_returns_304_as_ok` socket test still pins. Also removed four now-dead `std::io::Read` imports. One of them (plugin_launch) is still needed by its test module, so it moved there rather than being deleted: host CI lints without `--all-targets`, so a top-level import used only under cfg(test) fails the shipping build. Verified on macOS: punktfunk-core (quic + ureq-tls) checks clean, pf-update-check 32/32, cargo fmt clean. |
||
|
|
79d755cd98 |
feat(crypto): move the rustls backend from ring to aws-lc-rs, with PQ key exchange
The workspace pinned `ring` everywhere because aws-lc-sys 0.41.0 failed to C-compile on the Windows CI runner. Re-tested on that runner (.133) with aws-lc-sys 0.44.0: the `params.c` cl.exe failure does not reproduce under MSVC 14.44, and rustls's `aws_lc_rs` feature turns on `aws-lc-rs/prebuilt-nasm`, so no NASM is needed on the box either. That unblocks post-quantum TLS: `prefer-post-quantum` offers X25519MLKEM768 first on every TLS 1.3 handshake (mgmt API, native control plane, QUIC), which ring cannot do — it has no ML-KEM. Classical curves stay in the list, so older clients still connect. rustls, quinn, rcgen and tokio-rustls each select a backend independently, so all four had to move together; a single dissenter pulls a second crypto stack in via feature unification. The direct `ring` users (ed25519 in pf-update-check, SHA-256 in the Windows updater) moved to aws-lc-rs, whose API is ring-compatible. `ring` does NOT leave the tree: ureq 2 names `features = ["ring"]` in its own rustls dependency line and cargo features are additive, so no dependent can switch it off. Two backends compiled in means rustls refuses to infer one, and anything built via `ClientConfig::builder()` panics instead of picking — which is what ureq's default agent does on its first HTTPS request. `tls::install_default_provider()` makes the choice explicit; it runs at each binary's entry point and defensively in pf-client-core, which several binaries link. Dropping ring entirely needs the ureq 2 -> 3 upgrade (36 call sites), deliberately left out of this change. Verified on macOS: pf-update-check 32, punktfunk-core 385, c_abi 1 (the last with LIBRARY_PATH=/opt/homebrew/opt/opus/lib) — aws-lc-sys links into the C ABI harness, so the Swift/Kotlin embedders keep working. cargo fmt --all --check clean. |