Use rustls-tls with manual SSL_CERT_FILE implementation

This commit is contained in:
Charlie Marsh 2024-03-10 22:12:36 -04:00
parent b9b4109ad8
commit 425bcb9e4b
4 changed files with 44 additions and 52 deletions

52
Cargo.lock generated
View file

@ -2857,7 +2857,6 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls-native-certs",
"rustls-pemfile",
"serde",
"serde_json",
@ -2873,6 +2872,7 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots",
"winreg",
]
@ -3092,18 +3092,6 @@ dependencies = [
"sct",
]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
@ -3160,15 +3148,6 @@ 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"
@ -3211,29 +3190,6 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "security-framework"
version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
dependencies = [
"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]]
name = "serde"
version = "1.0.197"
@ -4915,6 +4871,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "weezl"
version = "0.1.8"

View file

@ -76,7 +76,7 @@ rand = { version = "0.8.5" }
rayon = { version = "1.8.0" }
reflink-copy = { version = "0.1.14" }
regex = { version = "1.10.2" }
reqwest = { version = "0.11.23", default-features = false, features = ["json", "gzip", "brotli", "stream", "rustls-tls-native-roots"] }
reqwest = { version = "0.11.23", default-features = false, features = ["json", "gzip", "brotli", "stream", "rustls-tls"] }
reqwest-middleware = { version = "0.2.4" }
reqwest-retry = { version = "0.3.0" }
rkyv = { version = "0.7.43", features = ["strict", "validation"] }

View file

@ -1,8 +1,10 @@
use std::ffi::OsStr;
use std::fmt::Debug;
use std::io::Read;
use http::HeaderValue;
use netrc::{Netrc, Result};
use reqwest::{Request, Response};
use netrc::Netrc;
use reqwest::{Certificate, Request, Response};
use reqwest_middleware::{Middleware, Next};
use task_local_extensions::Extensions;
use url::Url;
@ -56,7 +58,7 @@ pub(crate) struct NetrcMiddleware {
}
impl NetrcMiddleware {
pub(crate) fn new() -> Result<Self> {
pub(crate) fn new() -> netrc::Result<Self> {
Netrc::new().map(|nrc| NetrcMiddleware { nrc })
}
}
@ -121,3 +123,18 @@ where
header.set_sensitive(true);
header
}
#[derive(thiserror::Error, Debug)]
pub(crate) enum CertificateError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
}
/// Return the `Certificate` from the provided file.
pub(crate) fn read_certificate(ssl_cert_file: &OsStr) -> Result<Certificate, CertificateError> {
let mut buf = Vec::new();
fs_err::File::open(ssl_cert_file)?.read_to_end(&mut buf)?;
Ok(Certificate::from_pem(&buf)?)
}

View file

@ -29,7 +29,7 @@ use uv_warnings::warn_user_once;
use crate::cached_client::CacheControl;
use crate::html::SimpleHtml;
use crate::middleware::{NetrcMiddleware, OfflineMiddleware};
use crate::middleware::{read_certificate, NetrcMiddleware, OfflineMiddleware};
use crate::remote_metadata::wheel_metadata_from_remote_zip;
use crate::rkyvutil::OwnedArchive;
use crate::{CachedClient, CachedClientError, Error, ErrorKind};
@ -111,12 +111,25 @@ impl RegistryClientBuilder {
// Initialize the base client.
let client = self.client.unwrap_or_else(|| {
// Disallow any connections.
let client_core = ClientBuilder::new()
let builder = ClientBuilder::new()
.user_agent(user_agent_string)
.pool_max_idle_per_host(20)
.timeout(std::time::Duration::from_secs(timeout));
client_core.build().expect("Failed to build HTTP client.")
// Add the `SSL_CERT_FILE`, if set.
let builder = if let Some(ssl_cert_file) = env::var_os("SSL_CERT_FILE") {
match read_certificate(&ssl_cert_file) {
Ok(certificate) => builder.add_root_certificate(certificate),
Err(err) => {
warn!("Failed to read SSL certificate file: {err}");
builder
}
}
} else {
builder
};
builder.build().expect("Failed to build HTTP client.")
});
// Wrap in any relevant middleware.