diff --git a/Cargo.lock b/Cargo.lock index 30894eb174..a721982c57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8777,6 +8777,7 @@ dependencies = [ "spin-runtime-factors", "spin-telemetry", "spin-templates", + "spin-tls", "spin-trigger", "spin-trigger-http", "spin-trigger-redis", @@ -9747,6 +9748,13 @@ dependencies = [ "walkdir", ] +[[package]] +name = "spin-tls" +version = "4.1.0-pre0" +dependencies = [ + "rustls 0.23.37", +] + [[package]] name = "spin-trigger" version = "4.1.0-pre0" @@ -9770,6 +9778,7 @@ dependencies = [ "spin-factors", "spin-factors-executor", "spin-telemetry", + "spin-tls", "spin-world", "tempfile", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 1a2eb8b932..8c8bc05a98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,6 +74,7 @@ spin-telemetry = { path = "crates/telemetry", features = [ "tracing-log-compat", ] } spin-templates = { path = "crates/templates" } +spin-tls = { path = "crates/tls" } spin-trigger = { path = "crates/trigger" } spin-trigger-http = { path = "crates/trigger-http" } spin-trigger-redis = { path = "crates/trigger-redis" } diff --git a/crates/tls/Cargo.toml b/crates/tls/Cargo.toml new file mode 100644 index 0000000000..83e913d690 --- /dev/null +++ b/crates/tls/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "spin-tls" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +rust-version.workspace = true + +[dependencies] +rustls = { workspace = true } + +[lints] +workspace = true diff --git a/crates/tls/src/lib.rs b/crates/tls/src/lib.rs new file mode 100644 index 0000000000..b9b283ebba --- /dev/null +++ b/crates/tls/src/lib.rs @@ -0,0 +1,15 @@ +use std::sync::Once; + +static INSTALL_DEFAULT_CRYPTO_PROVIDER: Once = Once::new(); + +/// Install Spin's process-wide rustls crypto provider. +/// +/// This is idempotent for Spin's own duplicate calls from `main` and the trigger, +/// but fails loudly if something else installed a rustls provider first. +pub fn install_default_crypto_provider() { + INSTALL_DEFAULT_CRYPTO_PROVIDER.call_once(|| { + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls ring crypto provider"); + }); +} diff --git a/crates/trigger/Cargo.toml b/crates/trigger/Cargo.toml index 9b405b5e6d..7098bbc8d3 100644 --- a/crates/trigger/Cargo.toml +++ b/crates/trigger/Cargo.toml @@ -36,6 +36,7 @@ spin-factor-wasi = { path = "../factor-wasi" } spin-factors = { path = "../factors" } spin-factors-executor = { path = "../factors-executor" } spin-telemetry = { path = "../telemetry" } +spin-tls = { path = "../tls" } spin-world = { path = "../world" } tokio = { workspace = true, features = ["fs", "rt"] } tracing = { workspace = true } diff --git a/crates/trigger/src/cli.rs b/crates/trigger/src/cli.rs index 6c7836be1f..eb698b269e 100644 --- a/crates/trigger/src/cli.rs +++ b/crates/trigger/src/cli.rs @@ -185,6 +185,7 @@ pub struct NoCliArgs; impl, B: RuntimeFactorsBuilder> FactorsTriggerCommand { /// Create a new TriggerExecutorBuilder from this TriggerExecutorCommand. pub async fn run(self) -> Result<()> { + spin_tls::install_default_crypto_provider(); // Handle --help-args-only if self.help_args_only { Self::command() diff --git a/src/bin/spin.rs b/src/bin/spin.rs index ec8dc8aefe..95bffef59f 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -2,6 +2,7 @@ use spin_cli::subprocess::ExitStatusError; #[tokio::main] async fn main() { + spin_tls::install_default_crypto_provider(); if let Err(err) = spin_cli::run().await { let code = match err.downcast_ref::() { // If we encounter an `ExitStatusError` it means a subprocess has already