onionwire/crates/onionwire-sdk/tests/provider_resolution.rs
Sirius DevOps 411194a8b2
test(sdk): reproduce rustls CryptoProvider panic from the device
RED. The APK builds, installs and opens, but the first rustls config built
from the process default panics one call deep inside Arti's rustls backend:

    Could not automatically determine the process-level CryptoProvider from
    Rustls crate features.
    Call CryptoProvider::install_default() before this point ...

rustls 0.23 picks its provider from its own 'ring' / 'aws-lc-rs' crate
features, not from which crypto crates happen to be linked. Arti reaches
rustls via tor-rtcompat with default-features = false, so neither provider
feature is on and rustls compiles with zero providers. 'ring' does appear in
cargo tree, pulled in by snow for Noise -- unrelated and irrelevant.

This commit adds rustls as an explicit dependency with no provider feature
(no behaviour change: it is already in the graph that way) so the test can
name the type, plus the regression test. On the host it reproduces the
device's panic verbatim.

The SDK lockfile is resynced with the root Cargo.toml on main (onionwire
0.2.1, rpassword, md-5, rtoolbox) in the same commit so the test build is
against a consistent lock.
2026-09-10 22:02:02 -04:00

45 lines
1.9 KiB
Rust

//! Regression test for the on-device failure: the APK built, installed and
//! opened, but pressing **Open** on the unlock screen died one call deep inside
//! Arti's rustls backend with
//!
//! ```text
//! Could not automatically determine the process-level CryptoProvider from
//! Rustls crate features.
//! Call CryptoProvider::install_default() before this point to select a
//! provider manually, or make sure exactly one of the 'aws-lc-rs' and 'ring'
//! features is enabled.
//! ```
//!
//! rustls 0.23 chooses its provider from its own `ring` / `aws-lc-rs` **crate
//! features**, not from which crypto crates happen to be linked. Arti reaches
//! rustls through `tor-rtcompat` with `default-features = false`, so neither
//! provider feature is on and rustls is compiled with *no* provider at all:
//! `ring` showing up in `cargo tree` (pulled in by `snow`, for Noise) proves
//! nothing. Everything compiles, the APK ships, and the process-default lookup
//! fails at runtime.
//!
//! This test is the invariant Arti relies on: the process default must be
//! resolvable **without** anyone calling `install_default()` first.
//!
//! Deliberately the only test in this file — a second test that installs a
//! provider would race with it inside the same test binary and could mask the
//! regression.
/// Building a `rustls` config the way Arti does, straight from the process
/// default, must not panic.
#[test]
fn rustls_default_provider_resolves_without_manual_install() {
assert!(
rustls::crypto::CryptoProvider::get_default().is_none(),
"this test must start with no provider installed"
);
// Pre-fix this panics with the device's exact message.
let _ = rustls::ClientConfig::builder();
assert!(
rustls::crypto::CryptoProvider::get_default().is_some(),
"rustls resolved no CryptoProvider — the crate feature that selects a \
provider is not enabled in this workspace"
);
}