Skip to content

feat(tls): honor a process-installed rustls CryptoProvider; harden the rustls backend - #446

Open
MattJackson wants to merge 2 commits into
stack/s6from
stack/s7
Open

feat(tls): honor a process-installed rustls CryptoProvider; harden the rustls backend#446
MattJackson wants to merge 2 commits into
stack/s6from
stack/s7

Conversation

@MattJackson

Copy link
Copy Markdown
Contributor

Part of the sync stack — slice s7, based on #444 (stack/s6).

What

  • Honor a process-installed rustls CryptoProvider. The rustls backend now uses CryptoProvider::get_default() when an application has installed one, falling back to aws-lc-rs otherwise (previously it always constructed aws-lc-rs). Raised by @SimSmith in review of fix(security): upgrade rustls stack to 0.23 — clear RUSTSEC-2026-0098/-0099/-0104 #439.
  • Full-file hardening pass on rustls_tls_stream.rs (boy-scout, while adding the above):
    • trust_cert_ca is now additive — a custom CA is added alongside the system roots instead of replacing them (previously a custom CA silently dropped all other trust anchors).
    • Extracted shared, testable helpers: resolve_crypto_provider, read_cert_chain, read_private_key, load_native_roots_into, build_ca_trust_store.
    • Added unit tests (crypto-provider resolution, cert/key readers, CA-store augmentation, server-name handling) — the module previously had none.

Validation

cargo fmt --check clean; cargo clippy green on both --features=all and the rustls feature set; unit tests pass (including the new rustls tests).

Please rebase-merge (not squash) to preserve commit attribution.

Use CryptoProvider::get_default() when the application has installed a
process-wide provider (via install_default), falling back to aws-lc-rs
otherwise. Lets callers choose their own backend (ring, a FIPS provider,
...) instead of being forced onto aws-lc-rs. Suggested by @SimSmith while
reviewing the rustls 0.23 migration (#439).
Review-driven follow-ups found while adding CryptoProvider support:

- fix(HIGH): trust_cert_ca now trusts the supplied CA *in addition to* the
  system trust store (best-effort), matching its documented contract and the
  native-tls backend. Previously the rustls path built RootCertStore::empty()
  with only the custom CA, so connections to public-CA servers failed. The
  native-root load is best-effort (an empty/unreadable OS store no longer
  breaks an explicit-CA-only deployment).
- fix: CA-cert read failures now preserve the underlying io::Error in the
  message (missing vs permission vs parse) instead of a generic string.
- refactor: extract read_cert_chain (shared by the CA and client-cert paths,
  removing duplicated pem/der extension parsing) and resolve_crypto_provider
  (pure, unit-testable; logs which provider was selected).
- docs: explain the TLS 1.2 pin (a macOS-CI workaround, tracked for removal in
  the macOS-parity follow-up), the NoCertVerifier scheme list, and the TrustAll
  placeholder SNI.
- test: add unit coverage for provider selection, get_server_name, cert-chain
  reading, the additive CA store, and client-auth loading (previously zero
  unit tests in this file).

No behavior change to TrustAll/Default paths. Gate: fmt + clippy --features=all
-D warnings + new unit tests all green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant