From 32a60beadb1e49232b660e2ca48c124e902f18a3 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Tue, 10 Feb 2026 13:50:33 -0600 Subject: [PATCH] Fix rustls CryptoProvider panic by explicitly selecting ring Both ring and aws-lc-rs were enabled transitively (webpki-roots enables rustls default features), causing rustls to panic at runtime because it couldn't auto-detect which crypto provider to use. - Add rustls as direct dep with ring only, disable default features - Switch russh from aws-lc-rs (default) to ring crypto backend - Call ring::default_provider().install_default() at startup - Add macOS build fix: detect Homebrew OpenSSL path for netsnmp's libcrypto --- Cargo.lock | 14 ++++---------- Cargo.toml | 3 ++- build.rs | 16 ++++++++++++++++ src/main.rs | 7 +++++++ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15bdb81..7c7ce22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,7 +159,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" dependencies = [ "aws-lc-sys", - "untrusted 0.7.1", "zeroize", ] @@ -2224,7 +2223,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted 0.9.0", + "untrusted", "windows-sys 0.52.0", ] @@ -2254,7 +2253,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01fe22d10a0e39c1134a971d5b8db8a40357b48ef22d81fa8d6eac22202dd782" dependencies = [ "aes", - "aws-lc-rs", "bitflags", "block-padding", "byteorder", @@ -2293,6 +2291,7 @@ dependencies = [ "pkcs8 0.10.2", "rand 0.9.2", "rand_core 0.10.0-rc-3", + "ring", "rsa", "russh-cryptovec", "russh-util", @@ -2397,7 +2396,7 @@ dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] @@ -2963,6 +2962,7 @@ dependencies = [ "regex", "reqwest", "russh", + "rustls", "serde", "serde_json", "sha2 0.10.9", @@ -3089,12 +3089,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 2d7008c..c0e8a18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time" thiserror = "2" tokio-tungstenite = { version = "0.28", features = ["rustls-tls-webpki-roots"] } tokio-rustls = "0.26" +rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] } futures = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -18,7 +19,7 @@ prost = "0.14" prost-types = "0.14" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } -russh = "0.57" +russh = { version = "0.57", default-features = false, features = ["ring", "flate2", "rsa"] } async-trait = "0.1" home = "=0.5.12" zeroize = { version = "1", features = ["derive"] } diff --git a/build.rs b/build.rs index a059f8a..80a4e68 100644 --- a/build.rs +++ b/build.rs @@ -11,6 +11,22 @@ fn main() { // Link against netsnmp library println!("cargo:rustc-link-lib=netsnmp"); + // On macOS with Homebrew, net-snmp depends on OpenSSL which is keg-only + // (not linked into /usr/local/lib). Add the OpenSSL library path so the + // linker can find libcrypto. + #[cfg(target_os = "macos")] + { + if let Ok(output) = std::process::Command::new("brew") + .args(["--prefix", "openssl@3"]) + .output() + { + if output.status.success() { + let prefix = String::from_utf8_lossy(&output.stdout).trim().to_string(); + println!("cargo:rustc-link-search={}/lib", prefix); + } + } + } + // Inject compile timestamp as version // This allows tracking when a specific agent binary was built let version = get_version(); diff --git a/src/main.rs b/src/main.rs index 0db5c4b..71097b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -117,6 +117,13 @@ struct Args { } fn main() { + // Install ring as the default TLS crypto provider. Required because both + // ring and aws-lc-rs features are enabled transitively, so rustls can't + // auto-detect which one to use. + rustls::crypto::ring::default_provider() + .install_default() + .expect("Failed to install rustls CryptoProvider"); + // Build Tokio runtime with larger stack size for SNMPv3 crypto operations let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all()