From d399e65246a78b401e6c2ff6966b944f98aaeb8b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 15 Aug 2024 07:02:17 +0100 Subject: [PATCH] build(deps): bump tokio-tungstenite to 0.23 (#5509) With the upgrade to 0.23, `tokio-tungstenite` pulls in `rustls` 0.27 which supports multiple crypto providers. By default, this uses the `aws-lc-crypto` provider. The previous default was `ring`. This PR bumps the necessary versions and installs the `ring` crypto provider at the beginning of each application, before connlib starts. We try and do this as early as possible to make it obvious that it only needs to happen once per process. Resolves: #5380. --- rust/Cargo.lock | 103 ++++++++++++++---- rust/Cargo.toml | 3 +- rust/connlib/clients/android/Cargo.toml | 1 + rust/connlib/clients/android/src/lib.rs | 12 ++ rust/connlib/clients/apple/Cargo.toml | 1 + rust/connlib/clients/apple/src/lib.rs | 13 +++ rust/connlib/clients/shared/Cargo.toml | 10 +- rust/gateway/Cargo.toml | 2 +- rust/gateway/src/main.rs | 4 + rust/gui-client/src-tauri/Cargo.toml | 3 +- .../src-tauri/src/bin/firezone-client-ipc.rs | 4 + rust/gui-client/src-tauri/src/client.rs | 4 + rust/headless-client/Cargo.toml | 1 + rust/headless-client/src/main.rs | 4 + rust/relay/Cargo.toml | 1 + rust/relay/src/main.rs | 4 + 16 files changed, 138 insertions(+), 32 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 3fc4770a0..6fea7cc07 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1009,6 +1009,7 @@ dependencies = [ "libc", "log", "phoenix-channel", + "rustls", "secrecy", "serde_json", "socket-factory", @@ -1034,6 +1035,7 @@ dependencies = [ "libc", "oslog", "phoenix-channel", + "rustls", "secrecy", "serde_json", "socket-factory", @@ -1064,8 +1066,8 @@ dependencies = [ "serde_json", "socket-factory", "thiserror", + "time", "tokio", - "tokio-tungstenite", "tracing", "tun", "url", @@ -1848,6 +1850,7 @@ dependencies = [ "ip_network", "libc", "phoenix-channel", + "rustls", "secrecy", "serde", "serde_json", @@ -1855,7 +1858,6 @@ dependencies = [ "socket-factory", "static_assertions", "tokio", - "tokio-tungstenite", "tracing", "tracing-subscriber", "url", @@ -1887,6 +1889,7 @@ dependencies = [ "output_vt100", "rand 0.8.5", "reqwest", + "rustls", "sadness-generator", "secrecy", "semver", @@ -1938,6 +1941,7 @@ dependencies = [ "phoenix-channel", "resolv-conf", "rtnetlink", + "rustls", "sd-notify", "secrecy", "serde", @@ -1993,6 +1997,7 @@ dependencies = [ "phoenix-channel", "proptest", "rand 0.8.5", + "rustls", "secrecy", "serde", "sha2", @@ -2839,9 +2844,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.26.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", "http 1.1.0", @@ -2852,6 +2857,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots", ] [[package]] @@ -4700,6 +4706,53 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp 0.5.2", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quinn-udp" version = "0.5.4" @@ -4948,9 +5001,9 @@ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "base64 0.22.1", "bytes", @@ -4969,13 +5022,14 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", "rustls", "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.0", "tokio", "tokio-rustls", "tokio-util", @@ -5061,6 +5115,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -5085,11 +5145,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.4" +version = "0.23.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" dependencies = [ - "log", + "once_cell", "ring", "rustls-pki-types", "rustls-webpki", @@ -5109,15 +5169,15 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.4.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "ring", "rustls-pki-types", @@ -5587,7 +5647,7 @@ dependencies = [ name = "socket-factory" version = "0.1.0" dependencies = [ - "quinn-udp", + "quinn-udp 0.5.4", "socket2", "tokio", "tracing", @@ -6367,9 +6427,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls", "rustls-pki-types", @@ -6389,9 +6449,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.21.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd" dependencies = [ "futures-util", "log", @@ -6743,9 +6803,9 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.21.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" dependencies = [ "byteorder", "bytes", @@ -6758,7 +6818,6 @@ dependencies = [ "rustls-pki-types", "sha1", "thiserror", - "url", "utf-8", ] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e9332d28d..c89b8c66f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -37,9 +37,10 @@ str0m = { version = "0.6.2", default-features = false } futures-bounded = "0.2.1" domain = { version = "0.10", features = ["serde"] } dns-lookup = "2.0" -tokio-tungstenite = "0.21" +tokio-tungstenite = "0.23.1" rtnetlink = { version = "0.14.1", default-features = false, features = ["tokio_socket"] } tokio = "1.39" +rustls = { version = "0.23.10", default-features = false, features = ["ring"] } connlib-client-android = { path = "connlib/clients/android" } connlib-client-apple = { path = "connlib/clients/apple" } diff --git a/rust/connlib/clients/android/Cargo.toml b/rust/connlib/clients/android/Cargo.toml index b1d421b19..689cfd000 100644 --- a/rust/connlib/clients/android/Cargo.toml +++ b/rust/connlib/clients/android/Cargo.toml @@ -22,6 +22,7 @@ jni = { version = "0.21.1", features = ["invocation"] } libc = "0.2" log = "0.4" phoenix-channel = { workspace = true } +rustls = { workspace = true } secrecy = { workspace = true } serde_json = "1" socket-factory = { workspace = true } diff --git a/rust/connlib/clients/android/src/lib.rs b/rust/connlib/clients/android/src/lib.rs index ff18b1029..dda1e01b9 100644 --- a/rust/connlib/clients/android/src/lib.rs +++ b/rust/connlib/clients/android/src/lib.rs @@ -342,6 +342,8 @@ fn connect( let log_filter = string_from_jstring!(env, log_filter); let handle = init_logging(&PathBuf::from(log_dir), log_filter); + install_rustls_crypto_provider(); + let callbacks = CallbackHandler { vm: env.get_java_vm().map_err(ConnectError::GetJavaVmFailed)?, callback_handler, @@ -574,3 +576,13 @@ fn protected_udp_socket_factory(callbacks: CallbackHandler) -> impl SocketFactor Ok(socket) } } + +/// Installs the `ring` crypto provider for rustls. +fn install_rustls_crypto_provider() { + let existing = rustls::crypto::ring::default_provider().install_default(); + + if existing.is_err() { + // On Android, connlib gets loaded as shared library by the JVM and may remain loaded even if we disconnect the tunnel. + tracing::debug!("Skipping install of crypto provider because we already have one."); + } +} diff --git a/rust/connlib/clients/apple/Cargo.toml b/rust/connlib/clients/apple/Cargo.toml index cc81689f4..d4a7a22d2 100644 --- a/rust/connlib/clients/apple/Cargo.toml +++ b/rust/connlib/clients/apple/Cargo.toml @@ -19,6 +19,7 @@ firezone-logging = { workspace = true } ip_network = "0.4" libc = "0.2" phoenix-channel = { workspace = true } +rustls = { workspace = true } secrecy = { workspace = true } serde_json = "1" socket-factory = { workspace = true } diff --git a/rust/connlib/clients/apple/src/lib.rs b/rust/connlib/clients/apple/src/lib.rs index 080ce099b..f6c6193e0 100644 --- a/rust/connlib/clients/apple/src/lib.rs +++ b/rust/connlib/clients/apple/src/lib.rs @@ -183,6 +183,8 @@ impl WrappedSession { callback_handler: ffi::CallbackHandler, ) -> Result { let logger = init_logging(log_dir.into(), log_filter)?; + install_rustls_crypto_provider(); + let secret = SecretString::from(token); let (private_key, public_key) = keypair(); @@ -251,3 +253,14 @@ impl WrappedSession { fn err_to_string(result: Result) -> Result { result.map_err(|e| format!("{e:#}")) } + +/// Installs the `ring` crypto provider for rustls. +fn install_rustls_crypto_provider() { + let existing = rustls::crypto::ring::default_provider().install_default(); + + if existing.is_err() { + // On Apple platforms, network extensions get terminated on disconnect and thus all memory is free'd. + // Therefore, this should not never happen unless the above is somehow no longer true. + tracing::warn!("Skipping install of crypto provider because we already have one."); + } +} diff --git a/rust/connlib/clients/shared/Cargo.toml b/rust/connlib/clients/shared/Cargo.toml index 161b22d51..ee97b24a9 100644 --- a/rust/connlib/clients/shared/Cargo.toml +++ b/rust/connlib/clients/shared/Cargo.toml @@ -18,19 +18,15 @@ secrecy = { workspace = true } serde = { version = "1.0", default-features = false, features = ["std", "derive"] } socket-factory = { workspace = true } thiserror = "1.0.63" +time = { version = "0.3.36", features = ["formatting"] } tokio = { workspace = true, features = ["sync"] } -tokio-tungstenite = { version = "0.21", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] } -tracing = { workspace = true } -tun = { workspace = true } -url = { version = "2.5.2", features = ["serde"] } - -[target.'cfg(target_os = "android")'.dependencies] tracing = { workspace = true, features = ["std", "attributes"] } +tun = { workspace = true } +url = { version = "2.4.1", features = ["serde"] } [dev-dependencies] chrono = { workspace = true } serde_json = { version = "1.0", features = ["std"] } -tokio = { workspace = true, features = ["macros", "rt"] } [lints] workspace = true diff --git a/rust/gateway/Cargo.toml b/rust/gateway/Cargo.toml index 308b24a0e..3e10b652f 100644 --- a/rust/gateway/Cargo.toml +++ b/rust/gateway/Cargo.toml @@ -24,13 +24,13 @@ futures-bounded = { workspace = true } ip_network = { version = "0.4", default-features = false } libc = { version = "0.2", default-features = false, features = ["std", "const-extern-fn", "extra_traits"] } phoenix-channel = { workspace = true } +rustls = { workspace = true } secrecy = { workspace = true } serde = { version = "1.0", default-features = false, features = ["std", "derive"] } snownet = { workspace = true } socket-factory = { workspace = true } static_assertions = "1.1.0" tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread", "fs", "signal"] } -tokio-tungstenite = { version = "0.21", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] } tracing = { workspace = true } tracing-subscriber = "0.3.17" url = { version = "2.5.2", default-features = false } diff --git a/rust/gateway/src/main.rs b/rust/gateway/src/main.rs index 392e694c9..e9a93a182 100644 --- a/rust/gateway/src/main.rs +++ b/rust/gateway/src/main.rs @@ -31,6 +31,10 @@ const ID_PATH: &str = "/var/lib/firezone/gateway_id"; #[tokio::main] async fn main() { + rustls::crypto::ring::default_provider() + .install_default() + .expect("Calling `install_default` only once per process should always succeed"); + // Enforce errors only being printed on a single line using the technique recommended in the anyhow docs: // https://docs.rs/anyhow/latest/anyhow/struct.Error.html#display-representations // diff --git a/rust/gui-client/src-tauri/Cargo.toml b/rust/gui-client/src-tauri/Cargo.toml index 484c7b4bd..4ea93e436 100644 --- a/rust/gui-client/src-tauri/Cargo.toml +++ b/rust/gui-client/src-tauri/Cargo.toml @@ -29,7 +29,8 @@ minidumper = "0.8.2" native-dialog = "0.7.0" output_vt100 = "0.1" rand = "0.8.5" -reqwest = { version = "0.12.4", default-features = false, features = ["stream", "rustls-tls"] } +reqwest = { version = "0.12.5", default-features = false, features = ["stream", "rustls-tls"] } +rustls = { workspace = true } sadness-generator = "0.5.0" secrecy = { workspace = true } semver = { version = "1.0.22", features = ["serde"] } diff --git a/rust/gui-client/src-tauri/src/bin/firezone-client-ipc.rs b/rust/gui-client/src-tauri/src/bin/firezone-client-ipc.rs index b5fbcb570..97b797359 100644 --- a/rust/gui-client/src-tauri/src/bin/firezone-client-ipc.rs +++ b/rust/gui-client/src-tauri/src/bin/firezone-client-ipc.rs @@ -1,3 +1,7 @@ fn main() -> anyhow::Result<()> { + rustls::crypto::ring::default_provider() + .install_default() + .expect("Calling `install_default` only once per process should always succeed"); + firezone_headless_client::run_only_ipc_service() } diff --git a/rust/gui-client/src-tauri/src/client.rs b/rust/gui-client/src-tauri/src/client.rs index 1769bd6fe..e9d507928 100644 --- a/rust/gui-client/src-tauri/src/client.rs +++ b/rust/gui-client/src-tauri/src/client.rs @@ -32,6 +32,10 @@ pub(crate) fn run() -> Result<()> { std::panic::set_hook(Box::new(tracing_panic::panic_hook)); let cli = Cli::parse(); + rustls::crypto::ring::default_provider() + .install_default() + .expect("Calling `install_default` only once per process should always succeed"); + match cli.command { None => { if cli.no_deep_links { diff --git a/rust/headless-client/Cargo.toml b/rust/headless-client/Cargo.toml index 7ef36545b..9a0431bea 100644 --- a/rust/headless-client/Cargo.toml +++ b/rust/headless-client/Cargo.toml @@ -19,6 +19,7 @@ futures = "0.3.30" humantime = "2.1" ip_network = { version = "0.4", default-features = false } phoenix-channel = { workspace = true } +rustls = { workspace = true } secrecy = { workspace = true } serde = { version = "1.0.204", features = ["derive"] } serde_json = "1.0.117" diff --git a/rust/headless-client/src/main.rs b/rust/headless-client/src/main.rs index 78874fa8f..f23c3e492 100644 --- a/rust/headless-client/src/main.rs +++ b/rust/headless-client/src/main.rs @@ -101,6 +101,10 @@ enum Cmd { } fn main() -> Result<()> { + rustls::crypto::ring::default_provider() + .install_default() + .expect("Calling `install_default` only once per process should always succeed"); + let mut cli = Cli::try_parse()?; // Modifying the environment of a running process is unsafe. If any other diff --git a/rust/relay/Cargo.toml b/rust/relay/Cargo.toml index c59ccc12b..0e6812405 100644 --- a/rust/relay/Cargo.toml +++ b/rust/relay/Cargo.toml @@ -23,6 +23,7 @@ opentelemetry_sdk = { version = "0.24.1", features = ["rt-tokio"] } phoenix-channel = { path = "../phoenix-channel" } proptest = { version = "1", optional = true } rand = "0.8.5" +rustls = { workspace = true } secrecy = { workspace = true } serde = { version = "1.0.204", features = ["derive"] } sha2 = "0.10.8" diff --git a/rust/relay/src/main.rs b/rust/relay/src/main.rs index 20002722d..9b8860ef4 100644 --- a/rust/relay/src/main.rs +++ b/rust/relay/src/main.rs @@ -96,6 +96,10 @@ enum LogFormat { #[tokio::main(flavor = "current_thread")] async fn main() -> Result<()> { + rustls::crypto::ring::default_provider() + .install_default() + .expect("Calling `install_default` only once per process should always succeed"); + let args = Args::parse(); setup_tracing(&args)?;