diff --git a/Cargo.lock b/Cargo.lock index 3e101ff0577..38f48af2bce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -345,6 +345,7 @@ dependencies = [ "pathdiff", "rand", "regex", + "rpassword", "rusqlite", "rustc-hash 2.1.1", "rustc-stable-hash", @@ -3684,6 +3685,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rpassword" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39" +dependencies = [ + "libc", + "rtoolbox", + "windows-sys 0.59.0", +] + +[[package]] +name = "rtoolbox" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cc970b249fbe527d6e02e0a227762c9108b2f49d81094fe357ffc6d14d7f6f" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "rusqlite" version = "0.37.0" diff --git a/Cargo.toml b/Cargo.toml index e80e07f64ed..95042990c16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,6 +81,7 @@ proptest = "1.9.0" pulldown-cmark = { version = "0.13.0", default-features = false, features = ["html"] } rand = "0.9.2" regex = "1.12.2" +rpassword = "7.4.0" rusqlite = { version = "0.37.0", features = ["bundled"] } rustc-hash = "2.1.1" rustc-stable-hash = "0.1.2" @@ -221,6 +222,7 @@ unicode-ident.workspace = true url.workspace = true walkdir.workspace = true winnow.workspace = true +rpassword.workspace = true [target.'cfg(target_has_atomic = "64")'.dependencies] tracing-chrome.workspace = true diff --git a/src/cargo/util/context/schema.rs b/src/cargo/util/context/schema.rs index 2dcd9ef6643..43dc17b67a4 100644 --- a/src/cargo/util/context/schema.rs +++ b/src/cargo/util/context/schema.rs @@ -51,6 +51,9 @@ pub struct CargoHttpConfig { pub debug: Option, pub multiplexing: Option, pub ssl_version: Option, + pub client_ssl_cert: Option, + pub client_ssl_key: Option, + pub client_ssl_key_protected: Option, } /// The `[future-incompat-report]` stable diff --git a/src/cargo/util/network/http.rs b/src/cargo/util/network/http.rs index 3c8133df2f1..ffa453d8b37 100644 --- a/src/cargo/util/network/http.rs +++ b/src/cargo/util/network/http.rs @@ -69,6 +69,22 @@ pub fn configure_http_handle(gctx: &GlobalContext, handle: &mut Easy) -> CargoRe if let Some(check) = http.check_revoke { handle.ssl_options(SslOpt::new().no_revoke(!check))?; } + if let Some(client_ssl_cert) = &http.client_ssl_cert { + let client_ssl_cert = client_ssl_cert.resolve_path(gctx); + handle.ssl_cert(&client_ssl_cert)?; + } + if let Some(client_ssl_key) = &http.client_ssl_key { + let client_ssl_key = client_ssl_key.resolve_path(gctx); + handle.ssl_key(&client_ssl_key)?; + + if http.client_ssl_key_protected.unwrap_or_default() { + let key_password = rpassword::prompt_password(format!( + "Password for certificate key file {}:", + client_ssl_key.display() + ))?; + handle.key_password(&key_password)?; + } + } if let Some(user_agent) = &http.user_agent { handle.useragent(user_agent)?;