diff --git a/Cargo.lock b/Cargo.lock index 30718897bf..72b0f0be2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -370,6 +370,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "aws-lc-rs" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fcc8f365936c834db5514fc45aee5b1202d677e6b40e48468aaaa8183ca8c7" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079" +dependencies = [ + "bindgen 0.69.5", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "aws-runtime" version = "1.4.3" @@ -680,6 +703,29 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.11.0", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.90", + "which 4.4.2", +] + [[package]] name = "bindgen" version = "0.70.1" @@ -1069,6 +1115,15 @@ dependencies = [ "error-code", ] +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "codepage" version = "0.1.2" @@ -2482,6 +2537,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.1", "tower-service", + "webpki-roots 0.26.8", ] [[package]] @@ -2910,6 +2966,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.168" @@ -2972,7 +3034,7 @@ version = "0.14.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78a09b56be5adbcad5aa1197371688dc6bb249a26da3bca2011ee2fb987ebfb" dependencies = [ - "bindgen", + "bindgen 0.70.1", "errno", "libc", ] @@ -3563,7 +3625,7 @@ dependencies = [ "tempfile", "unicode-segmentation", "uuid", - "which", + "which 7.0.0", ] [[package]] @@ -3719,6 +3781,8 @@ dependencies = [ "rstest", "rstest_reuse", "rusqlite", + "rustls 0.23.20", + "rustls-native-certs 0.8.1", "scopeguard", "serde", "serde_json", @@ -3749,7 +3813,8 @@ dependencies = [ "v_htmlescape", "wax", "web-time", - "which", + "webpki-roots 1.0.0", + "which 7.0.0", "windows 0.56.0", "winreg", ] @@ -4059,7 +4124,7 @@ dependencies = [ "nu-utils", "num-format", "tempfile", - "which", + "which 7.0.0", ] [[package]] @@ -5512,6 +5577,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.90", +] + [[package]] name = "print-positions" version = "0.6.1" @@ -6028,6 +6103,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", + "webpki-roots 0.26.8", "windows-registry", ] @@ -6272,6 +6348,8 @@ version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ + "aws-lc-rs", + "log", "once_cell", "ring", "rustls-pki-types", @@ -6347,6 +6425,7 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -7648,10 +7727,13 @@ dependencies = [ "log", "native-tls", "once_cell", + "rustls 0.23.20", + "rustls-pki-types", "serde", "serde_json", "socks", "url", + "webpki-roots 0.26.8", ] [[package]] @@ -8153,6 +8235,36 @@ dependencies = [ "url", ] +[[package]] +name = "webpki-roots" +version = "0.26.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.42", +] + [[package]] name = "which" version = "7.0.0" diff --git a/Cargo.toml b/Cargo.toml index b66828415b..5392c637cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -148,6 +148,8 @@ rstest = { version = "0.23", default-features = false } rstest_reuse = "0.7" rusqlite = "0.31" rust-embed = "8.7.0" +rustls = "0.23" +rustls-native-certs = "0.8" scopeguard = { version = "1.2.0" } serde = { version = "1.0" } serde_json = "1.0.97" @@ -164,7 +166,7 @@ tempfile = "3.20" titlecase = "3.5" toml = "0.8" trash = "5.2" -update-informer = { version = "1.2.0", default-features = false, features = ["github", "native-tls", "ureq"] } +update-informer = { version = "1.2.0", default-features = false, features = ["github", "ureq"] } umask = "2.1" unicode-segmentation = "1.12" unicode-width = "0.2" @@ -187,6 +189,7 @@ windows = "0.56" windows-sys = "0.48" winreg = "0.52" memchr = "2.7.4" +webpki-roots = "1.0" [workspace.lints.clippy] # Warning: workspace lints affect library code as well as tests, so don't enable lints that would be too noisy in tests like that. @@ -202,7 +205,7 @@ nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.104.2" } nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.104.2" } nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.104.2", optional = true } nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.104.2" } -nu-command = { path = "./crates/nu-command", version = "0.104.2" } +nu-command = { path = "./crates/nu-command", version = "0.104.2", default-features = false, features = ["os"] } nu-engine = { path = "./crates/nu-engine", version = "0.104.2" } nu-explore = { path = "./crates/nu-explore", version = "0.104.2" } nu-lsp = { path = "./crates/nu-lsp/", version = "0.104.2" } @@ -269,10 +272,14 @@ plugin = [ "nu-protocol/plugin", ] +native-tls = ["nu-command/native-tls"] +rustls-tls = ["nu-command/rustls-tls"] + default = [ "plugin", "trash-support", "sqlite", + "rustls-tls" ] stable = ["default"] # NOTE: individual features are also passed to `nu-cmd-lang` that uses them to generate the feature matrix in the `version` command diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 026a776103..03aa886310 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -91,6 +91,8 @@ rusqlite = { workspace = true, features = [ "backup", "chrono", ], optional = true } +rustls = { workspace = true, optional = true } +rustls-native-certs = { workspace = true, optional = true } rmp = { workspace = true } scopeguard = { workspace = true } serde = { workspace = true, features = ["derive"] } @@ -108,7 +110,6 @@ ureq = { workspace = true, default-features = false, features = [ "charset", "gzip", "json", - "native-tls", ], optional = true } url = { workspace = true } uu_cp = { workspace = true, optional = true } @@ -131,6 +132,7 @@ which = { workspace = true, optional = true } unicode-width = { workspace = true } data-encoding = { version = "2.9.0", features = ["alloc"] } web-time = { workspace = true } +webpki-roots = { workspace = true, optional = true } [target.'cfg(windows)'.dependencies] winreg = { workspace = true } @@ -165,7 +167,7 @@ features = [ workspace = true [features] -default = ["os"] +default = ["os", "rustls-tls"] os = [ # include other features "js", @@ -197,11 +199,24 @@ js = ["getrandom", "getrandom/js", "rand", "uuid"] # interface requires openssl which is not easy to embed into wasm, # using rustls could solve this issue. network = [ + # these two don't require openssl "multipart-rs", - "native-tls", - "update-informer/native-tls", - "ureq", "uuid", + "ureq", + "update-informer" +] + +native-tls = [ + "dep:native-tls", + "update-informer/native-tls", + "ureq/native-tls", +] +rustls-tls = [ + "dep:rustls", + "dep:rustls-native-certs", + "dep:webpki-roots", + "update-informer/rustls-tls", + "ureq/tls", # ureq 3 will has the feature rustls instead ] plugin = ["nu-parser/plugin", "os"] diff --git a/crates/nu-command/src/network/http/client.rs b/crates/nu-command/src/network/http/client.rs index 4d5529b48c..7efbd86512 100644 --- a/crates/nu-command/src/network/http/client.rs +++ b/crates/nu-command/src/network/http/client.rs @@ -1,4 +1,4 @@ -use crate::formats::value_to_json_value; +use crate::{formats::value_to_json_value, network::tls::tls}; use base64::{ Engine, alphabet, engine::{GeneralPurpose, general_purpose::PAD}, @@ -56,20 +56,9 @@ pub fn http_client( engine_state: &EngineState, stack: &mut Stack, ) -> Result { - let tls = native_tls::TlsConnector::builder() - .danger_accept_invalid_certs(allow_insecure) - .build() - .map_err(|e| ShellError::GenericError { - error: format!("Failed to build network tls: {}", e), - msg: String::new(), - span: None, - help: None, - inner: vec![], - })?; - let mut agent_builder = ureq::builder() .user_agent("nushell") - .tls_connector(std::sync::Arc::new(tls)); + .tls_connector(std::sync::Arc::new(tls(allow_insecure)?)); if let RedirectMode::Manual | RedirectMode::Error = redirect_mode { agent_builder = agent_builder.redirects(0); diff --git a/crates/nu-command/src/network/mod.rs b/crates/nu-command/src/network/mod.rs index ca6f850155..dbf66e03c8 100644 --- a/crates/nu-command/src/network/mod.rs +++ b/crates/nu-command/src/network/mod.rs @@ -2,6 +2,8 @@ mod http; #[cfg(feature = "network")] mod port; +#[cfg(feature = "network")] +pub mod tls; mod url; #[cfg(feature = "network")] mod version_check; diff --git a/crates/nu-command/src/network/tls/impl_native_tls.rs b/crates/nu-command/src/network/tls/impl_native_tls.rs new file mode 100644 index 0000000000..29b8a62aba --- /dev/null +++ b/crates/nu-command/src/network/tls/impl_native_tls.rs @@ -0,0 +1,16 @@ +use nu_protocol::ShellError; +use ureq::TlsConnector; + +#[doc = include_str!("./tls.rustdoc.md")] +pub fn tls(allow_insecure: bool) -> Result { + native_tls::TlsConnector::builder() + .danger_accept_invalid_certs(allow_insecure) + .build() + .map_err(|e| ShellError::GenericError { + error: format!("Failed to build network tls: {}", e), + msg: String::new(), + span: None, + help: None, + inner: vec![], + }) +} diff --git a/crates/nu-command/src/network/tls/impl_rustls.rs b/crates/nu-command/src/network/tls/impl_rustls.rs new file mode 100644 index 0000000000..b05ba3aaa2 --- /dev/null +++ b/crates/nu-command/src/network/tls/impl_rustls.rs @@ -0,0 +1,251 @@ +use std::{ + ops::Deref, + sync::{Arc, LazyLock, OnceLock}, +}; + +use nu_engine::command_prelude::IoError; +use nu_protocol::ShellError; +use rustls::{ + DigitallySignedStruct, RootCertStore, SignatureScheme, + client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, + crypto::CryptoProvider, + pki_types::{CertificateDer, ServerName, UnixTime}, +}; +use ureq::TlsConnector; + +// TODO: replace all these generic errors with proper errors + +/// Stores the crypto provider used by `rustls`. +/// +/// This struct lives in the [`CRYPTO_PROVIDER`] static. +/// It can't be created manually. +/// +/// ## Purpose +/// +/// Nushell does **not** use the global `rustls` crypto provider. +/// You **must** set a provider here—otherwise, any networking command +/// that uses `rustls` won't be able to build a TLS connector. +/// +/// This only matters if the **`rustls-tls`** feature is enabled. +/// Builds with **`native-tls`** ignore this completely. +/// +/// ## How to set the provider +/// +/// * [`NuCryptoProvider::default`] +/// Uses a built-in provider that works with official `nu` builds. +/// This might change in future versions. +/// +/// * [`NuCryptoProvider::set`] +/// Lets you provide your own `CryptoProvider` using a closure: +/// +/// ```rust +/// use nu_command::tls::CRYPTO_PROVIDER; +/// +/// // Call once at startup +/// CRYPTO_PROVIDER.set(|| Ok(rustls::crypto::aws_lc_rs::default_provider())); +/// ``` +/// +/// Only the first successful call takes effect. Later calls do nothing and return `false`. +#[derive(Debug)] +pub struct NuCryptoProvider(OnceLock, ShellError>>); + +/// Global [`NuCryptoProvider`] instance. +/// +/// When the **`rustls-tls`** feature is active, call +/// [`CRYPTO_PROVIDER.default()`](NuCryptoProvider::default) or +/// [`CRYPTO_PROVIDER.set(...)`](NuCryptoProvider::set) once at startup +/// to pick the [`CryptoProvider`] that [`rustls`] will use. +/// +/// Later TLS code gets the provider using [`get`](NuCryptoProvider::get). +/// If no provider was set or the closure returned an error, `get` returns a [`ShellError`]. +pub static CRYPTO_PROVIDER: NuCryptoProvider = NuCryptoProvider(OnceLock::new()); + +impl NuCryptoProvider { + /// Returns the current [`CryptoProvider`]. + /// + /// Comes from the first call to [`default`](Self::default) or [`set`](Self::set). + /// + /// # Errors + /// - If no provider was set. + /// - If the `set` closure returned an error. + pub fn get(&self) -> Result, ShellError> { + // we clone here as the Arc for Ok is super cheap and basically all APIs expect an owned + // ShellError, so we might as well clone here already + match self.0.get() { + Some(val) => val.clone(), + None => Err(ShellError::GenericError { + error: "tls crypto provider not found".to_string(), + msg: "no crypto provider for rustls was defined".to_string(), + span: None, + help: Some("ensure that nu_command::tls::CRYPTO_PROVIDER is set".to_string()), + inner: vec![], + }), + } + } + + /// Sets a custom [`CryptoProvider`]. + /// + /// Call once at startup, before any TLS code runs. + /// The closure runs immediately and the result (either `Ok` or `Err`) is stored. + /// Returns whether the provider was stored successfully. + pub fn set(&self, f: impl FnOnce() -> Result) -> bool { + let value = f().map(Arc::new); + self.0.set(value).is_ok() + } + + /// Sets a default [`CryptoProvider`] used in official `nu` builds. + /// + /// Should work on most systems, but may not work in every setup. + /// If it fails, use [`set`](Self::set) to install a custom one. + /// Returns whether the provider was stored successfully. + pub fn default(&self) -> bool { + self.set(|| Ok(rustls::crypto::aws_lc_rs::default_provider())) + } +} + +#[cfg(feature = "os")] +static ROOT_CERT_STORE: LazyLock, ShellError>> = LazyLock::new(|| { + let mut roots = RootCertStore::empty(); + + let native_certs = rustls_native_certs::load_native_certs(); + + let errors: Vec<_> = native_certs + .errors + .into_iter() + .map(|err| match err.kind { + rustls_native_certs::ErrorKind::Io { inner, path } => ShellError::Io( + IoError::new_internal_with_path(inner, err.context, nu_protocol::location!(), path), + ), + rustls_native_certs::ErrorKind::Os(error) => ShellError::GenericError { + error: error.to_string(), + msg: err.context.to_string(), + span: None, + help: None, + inner: vec![], + }, + rustls_native_certs::ErrorKind::Pem(error) => ShellError::GenericError { + error: error.to_string(), + msg: err.context.to_string(), + span: None, + help: None, + inner: vec![], + }, + _ => ShellError::GenericError { + error: String::from("unknown error loading native certs"), + msg: err.context.to_string(), + span: None, + help: None, + inner: vec![], + }, + }) + .collect(); + if !errors.is_empty() { + return Err(ShellError::GenericError { + error: String::from("error loading native certs"), + msg: String::from("could not load native certs"), + span: None, + help: None, + inner: errors, + }); + } + + for cert in native_certs.certs { + roots.add(cert).map_err(|err| ShellError::GenericError { + error: err.to_string(), + msg: String::from("could not add root cert"), + span: None, + help: None, + inner: vec![], + })?; + } + + Ok(Arc::new(roots)) +}); + +#[cfg(not(feature = "os"))] +static ROOT_CERT_STORE: LazyLock, ShellError>> = LazyLock::new(|| { + Ok(Arc::new(rustls::RootCertStore { + roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(), + })) +}); + +#[doc = include_str!("./tls.rustdoc.md")] +pub fn tls(allow_insecure: bool) -> Result { + let crypto_provider = CRYPTO_PROVIDER.get()?; + + let make_protocol_versions_error = |err: rustls::Error| ShellError::GenericError { + error: err.to_string(), + msg: "crypto provider is incompatible with protocol versions".to_string(), + span: None, + help: None, + inner: vec![], + }; + + let client_config = match allow_insecure { + false => rustls::ClientConfig::builder_with_provider(crypto_provider) + .with_safe_default_protocol_versions() + .map_err(make_protocol_versions_error)? + .with_root_certificates(ROOT_CERT_STORE.deref().clone()?) + .with_no_client_auth(), + true => rustls::ClientConfig::builder_with_provider(crypto_provider) + .with_safe_default_protocol_versions() + .map_err(make_protocol_versions_error)? + .dangerous() + .with_custom_certificate_verifier(Arc::new(UnsecureServerCertVerifier)) + .with_no_client_auth(), + }; + + Ok(Arc::new(client_config)) +} + +#[derive(Debug)] +struct UnsecureServerCertVerifier; + +impl ServerCertVerifier for UnsecureServerCertVerifier { + fn verify_server_cert( + &self, + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, + _ocsp_response: &[u8], + _now: UnixTime, + ) -> Result { + Ok(ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + vec![ + SignatureScheme::RSA_PKCS1_SHA1, + SignatureScheme::ECDSA_SHA1_Legacy, + SignatureScheme::RSA_PKCS1_SHA256, + SignatureScheme::ECDSA_NISTP256_SHA256, + SignatureScheme::RSA_PKCS1_SHA384, + SignatureScheme::ECDSA_NISTP384_SHA384, + SignatureScheme::RSA_PKCS1_SHA512, + SignatureScheme::ECDSA_NISTP521_SHA512, + SignatureScheme::RSA_PSS_SHA256, + SignatureScheme::RSA_PSS_SHA384, + SignatureScheme::RSA_PSS_SHA512, + SignatureScheme::ED25519, + SignatureScheme::ED448, + ] + } +} diff --git a/crates/nu-command/src/network/tls/mod.rs b/crates/nu-command/src/network/tls/mod.rs new file mode 100644 index 0000000000..8def117100 --- /dev/null +++ b/crates/nu-command/src/network/tls/mod.rs @@ -0,0 +1,26 @@ +//! TLS support for networking commands. +//! +//! This module is available when the `network` feature is enabled. It requires +//! either the `native-tls` or `rustls-tls` feature to be selected. +//! +//! See [`tls`] for how to get a TLS connector. + +#[cfg(feature = "native-tls")] +#[path = "impl_native_tls.rs"] +mod impl_tls; + +#[cfg(feature = "rustls-tls")] +#[path = "impl_rustls.rs"] +mod impl_tls; + +#[cfg(all(not(feature = "native-tls"), not(feature = "rustls-tls")))] +compile_error!( + "No TLS backend enabled. Please enable either the `native-tls` or `rustls-tls` feature." +); + +#[cfg(all(feature = "native-tls", feature = "rustls-tls"))] +compile_error!( + "Multiple TLS backends enabled. Please enable only one of `native-tls` or `rustls-tls`, not both." +); + +pub use impl_tls::*; diff --git a/crates/nu-command/src/network/tls/tls.rustdoc.md b/crates/nu-command/src/network/tls/tls.rustdoc.md new file mode 100644 index 0000000000..2e8f7c0542 --- /dev/null +++ b/crates/nu-command/src/network/tls/tls.rustdoc.md @@ -0,0 +1,31 @@ +Provide a [`TlsConnector`] for [`ureq`]. + +This is used by Nushell's networking commands (`http`) to handle secure +(or optionally insecure) HTTP connections. +The returned connector enables `ureq` to perform HTTPS requests. +If `allow_insecure` is set to `true`, certificate verification is disabled. + +This function is only available when the `network` feature is enabled, +and requires exactly one of the `native-tls` or `rustls-tls` features to +be active. + +# With `native-tls` + +When built with `native-tls`, this uses the platform TLS backend: +- OpenSSL on most Unix systems +- SChannel on Windows + +These are mature and widely-deployed TLS implementations. +Expect strong platform integration. + +# With `rustls-tls` + +When built with `rustls-tls`, this uses the pure-Rust [`rustls`] library for TLS. +This has several benefits: +- Easier cross-compilation (no need for OpenSSL headers or linker setup) +- Works with `musl` targets out of the box +- Can be compiled to WASM + +A [`NuCryptoProvider`] must be configured before calling this function. +Use [`CRYPTO_PROVIDER.default()`](NuCryptoProvider::default) or +[`CRYPTO_PROVIDER.set(...)`](NuCryptoProvider::set) to initialize it. \ No newline at end of file diff --git a/crates/nu-command/src/network/version_check.rs b/crates/nu-command/src/network/version_check.rs index a61319c4a4..7d230d3bf9 100644 --- a/crates/nu-command/src/network/version_check.rs +++ b/crates/nu-command/src/network/version_check.rs @@ -6,6 +6,8 @@ use update_informer::{ registry, }; +use super::tls::tls; + #[derive(Clone)] pub struct VersionCheck; @@ -92,7 +94,7 @@ impl HttpClient for NativeTlsHttpClient { headers: update_informer::http_client::HeaderMap, ) -> update_informer::Result { let agent = ureq::AgentBuilder::new() - .tls_connector(std::sync::Arc::new(native_tls::TlsConnector::new()?)) + .tls_connector(std::sync::Arc::new(tls(false)?)) .build(); let mut req = agent.get(url).timeout(timeout); diff --git a/src/main.rs b/src/main.rs index dd0664b0bf..09d53b1ebf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,6 +82,9 @@ fn main() -> Result<()> { // TODO: make this conditional in the future ctrlc_protection(&mut engine_state); + #[cfg(feature = "rustls-tls")] + nu_command::tls::CRYPTO_PROVIDER.default(); + // Begin: Default NU_LIB_DIRS, NU_PLUGIN_DIRS // Set default NU_LIB_DIRS and NU_PLUGIN_DIRS here before the env.nu is processed. If // the env.nu file exists, these values will be overwritten, if it does not exist, or