diff --git a/Cargo.lock b/Cargo.lock index de95a90ab..9ce43d74d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -398,6 +398,16 @@ dependencies = [ "syn", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -693,6 +703,21 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1169,6 +1194,12 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.151" @@ -1334,6 +1365,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "notify" version = "6.1.1" @@ -1417,6 +1466,50 @@ dependencies = [ "pathdiff", ] +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -1816,20 +1909,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "ring" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" -dependencies = [ - "cc", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.48.0", -] - [[package]] name = "roff" version = "0.2.1" @@ -1879,37 +1958,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.14" @@ -1953,6 +2001,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1960,13 +2017,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "sct" -version = "0.7.1" +name = "security-framework" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "ring", - "untrusted", + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -2492,14 +2562,13 @@ dependencies = [ "env_proxy", "flate2", "fontdb", + "native-tls", "notify", "once_cell", "open", "parking_lot", "pathdiff", "rayon", - "rustls", - "rustls-pemfile", "same-file", "self-replace", "semver", @@ -2817,12 +2886,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9df2af067a7953e9c3831320f35c1cc0600c30d44d9f7a12b01db1cd88d6b47" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "ureq" version = "2.9.1" @@ -2832,13 +2895,11 @@ dependencies = [ "base64", "flate2", "log", + "native-tls", "once_cell", - "rustls", - "rustls-webpki", "serde", "serde_json", "url", - "webpki-roots", ] [[package]] @@ -2925,6 +2986,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -3041,12 +3108,6 @@ dependencies = [ "indexmap-nostd", ] -[[package]] -name = "webpki-roots" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" - [[package]] name = "weezl" version = "0.1.7" diff --git a/Cargo.toml b/Cargo.toml index 8f93a1901..62ff3ae0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,7 @@ libfuzzer-sys = "0.4" lipsum = "0.9" log = "0.4" miniz_oxide = "0.7" +native-tls = "0.2" notify = "6" once_cell = "1" open = "5.0.1" @@ -78,8 +79,6 @@ rayon = "1.7.0" regex = "1" resvg = { version = "0.38.0", default-features = false, features = ["raster-images"] } roxmltree = "0.19" -rustls = "0.21" # in sync with ureq -rustls-pemfile = "1" # in sync with rustls rustybuzz = "0.12.1" same-file = "1" self-replace = "1.3.7" @@ -110,7 +109,7 @@ unicode-properties = "0.1" unicode-script = "0.5" unicode-segmentation = "1" unscanny = "0.1" -ureq = "2" +ureq = { version = "2", default-features = false, features = ["native-tls", "gzip"] } usvg = { version = "0.38.0", default-features = false, features = ["text"] } walkdir = "2" wasmi = "0.31.0" diff --git a/crates/typst-cli/Cargo.toml b/crates/typst-cli/Cargo.toml index 286af7f77..d16175edf 100644 --- a/crates/typst-cli/Cargo.toml +++ b/crates/typst-cli/Cargo.toml @@ -35,14 +35,13 @@ ecow = { workspace = true } env_proxy = { workspace = true } flate2 = { workspace = true } fontdb = { workspace = true, features = ["memmap", "fontconfig"] } +native-tls = { workspace = true } notify = { workspace = true } once_cell = { workspace = true } open = { workspace = true } parking_lot = { workspace = true } pathdiff = { workspace = true } rayon = { workspace = true } -rustls = { workspace = true } -rustls-pemfile = { workspace = true } same-file = { workspace = true } self-replace = { workspace = true, optional = true } semver = { workspace = true } diff --git a/crates/typst-cli/src/download.rs b/crates/typst-cli/src/download.rs index a5062fd3f..fc3d3f1ee 100644 --- a/crates/typst-cli/src/download.rs +++ b/crates/typst-cli/src/download.rs @@ -7,6 +7,7 @@ use std::io::{self, ErrorKind, Read, Stderr, Write}; use std::sync::Arc; use std::time::{Duration, Instant}; +use native_tls::{Certificate, TlsConnector}; use once_cell::sync::Lazy; use ureq::Response; @@ -15,23 +16,10 @@ const SPEED_SAMPLES: usize = 5; /// Lazily loads a custom CA certificate if present, but if there's an error /// loading certificate, it just uses the default configuration. -static TLS_CONFIG: Lazy>> = Lazy::new(|| { - crate::ARGS - .cert - .as_ref() - .map(|path| { - let file = std::fs::OpenOptions::new().read(true).open(path)?; - let mut buffer = std::io::BufReader::new(file); - let certs = rustls_pemfile::certs(&mut buffer)?; - let mut store = rustls::RootCertStore::empty(); - store.add_parsable_certificates(&certs); - let config = rustls::ClientConfig::builder() - .with_safe_defaults() - .with_root_certificates(store) - .with_no_client_auth(); - Ok::<_, std::io::Error>(Arc::new(config)) - }) - .and_then(|x| x.ok()) +static CERT: Lazy> = Lazy::new(|| { + let path = crate::ARGS.cert.as_ref()?; + let pem = std::fs::read(path).ok()?; + Certificate::from_pem(&pem).ok() }); /// Download binary data and display its progress. @@ -44,10 +32,13 @@ pub fn download_with_progress(url: &str) -> Result, ureq::Error> { /// Download from a URL. #[allow(clippy::result_large_err)] pub fn download(url: &str) -> Result { - let mut builder = ureq::AgentBuilder::new() - .user_agent(concat!("typst/", env!("CARGO_PKG_VERSION"))); + let mut builder = ureq::AgentBuilder::new(); + let mut tls = TlsConnector::builder(); - // Get the network proxy config from the environment. + // Set user agent. + builder = builder.user_agent(concat!("typst/", env!("CARGO_PKG_VERSION"))); + + // Get the network proxy config from the environment and apply it. if let Some(proxy) = env_proxy::for_url_str(url) .to_url() .and_then(|url| ureq::Proxy::new(url).ok()) @@ -56,12 +47,16 @@ pub fn download(url: &str) -> Result { } // Apply a custom CA certificate if present. - if let Some(config) = &*TLS_CONFIG { - builder = builder.tls_config(config.clone()); + if let Some(cert) = &*CERT { + tls.add_root_certificate(cert.clone()); } - let agent = builder.build(); - agent.get(url).call() + // Configure native TLS. + let connector = + tls.build().map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + builder = builder.tls_connector(Arc::new(connector)); + + builder.build().get(url).call() } /// A wrapper around [`ureq::Response`] that reads the response body in chunks