Skip to content

Commit

Permalink
Add support for custom TLS certificate authority bundle
Browse files Browse the repository at this point in the history
* Custom TLS CA can be configured via one of the
  `MATURIN_CA_BUNDLE`, `REQUESTS_CA_BUNDLE` and `CURL_CA_BUNDLE` env vars.
  • Loading branch information
messense committed Feb 14, 2023
1 parent bfd8a0e commit 5b42294
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 10 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ bytesize = { version = "1.0.1", optional = true }
configparser = { version = "3.0.0", optional = true }
multipart = { version = "0.18.0", features = ["client"], default-features = false, optional = true }
ureq = { version = "2.6.1", features = ["gzip", "socks-proxy"], default-features = false, optional = true }
native-tls-crate = { package = "native-tls", version = "0.2.8", optional = true }
native-tls = { version = "0.2.8", optional = true }
rustls = { version = "0.20.8", optional = true }
rustls-pemfile = { version = "1.0.1", optional = true }
keyring = { version = "1.1.1", optional = true }

[dev-dependencies]
Expand All @@ -103,8 +105,8 @@ upload = ["ureq", "multipart", "configparser", "bytesize", "dialoguer/password"]
# keyring doesn't support *BSD so it's not enabled in `full` by default
password-storage = ["upload", "keyring"]

rustls = ["ureq/tls", "cargo-xwin/rustls-tls"]
native-tls = ["ureq/native-tls", "native-tls-crate", "cargo-xwin/native-tls"]
rustls = ["dep:rustls", "ureq/tls", "cargo-xwin/rustls-tls", "rustls-pemfile"]
native-tls = ["dep:native-tls", "ureq/native-tls", "cargo-xwin/native-tls", "rustls-pemfile"]

# cross compile using zig or xwin
cross-compile = ["zig", "xwin"]
Expand Down
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Respect `rustflags` settings in cargo configuration file in [#1405](https://github.com/PyO3/maturin/pull/1405)
* Bump MSRV to 1.63.0 in [#1407](https://github.com/PyO3/maturin/pull/1407)
* Add support for uniffi 0.23 in [#1481](https://github.com/PyO3/maturin/pull/1481)
* Add support for custom TLS certificate authority bundle in [#1483](https://github.com/PyO3/maturin/pull/1483)

## [0.14.13] - 2023-02-12

Expand Down
56 changes: 49 additions & 7 deletions src/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use fs_err::File;
use multipart::client::lazy::Multipart;
use regex::Regex;
use std::env;
#[cfg(any(feature = "native-tls", feature = "rustls"))]
use std::ffi::OsString;
use std::io;
use std::path::{Path, PathBuf};
use thiserror::Error;
Expand Down Expand Up @@ -84,7 +86,7 @@ pub enum UploadError {
/// TLS error
#[cfg(feature = "native-tls")]
#[error("TLS Error")]
TlsError(#[source] native_tls_crate::Error),
TlsError(#[source] native_tls::Error),
}

impl From<io::Error> for UploadError {
Expand All @@ -100,8 +102,8 @@ impl From<ureq::Error> for UploadError {
}

#[cfg(feature = "native-tls")]
impl From<native_tls_crate::Error> for UploadError {
fn from(error: native_tls_crate::Error) -> Self {
impl From<native_tls::Error> for UploadError {
fn from(error: native_tls::Error) -> Self {
UploadError::TlsError(error)
}
}
Expand Down Expand Up @@ -269,21 +271,61 @@ fn http_proxy() -> Result<String, env::VarError> {
.or_else(|_| env::var("http_proxy"))
}

#[cfg(feature = "native-tls")]
#[cfg(any(feature = "native-tls", feature = "rustls"))]
fn tls_ca_bundle() -> Option<OsString> {
env::var_os("MATURIN_CA_BUNDLE")
.or_else(|| env::var_os("REQUESTS_CA_BUNDLE"))
.or_else(|| env::var_os("CURL_CA_BUNDLE"))
}

// Prefer rustls if both native-tls and rustls features are enabled
#[cfg(all(feature = "native-tls", not(feature = "rustls")))]
#[allow(clippy::result_large_err)]
fn http_agent() -> Result<ureq::Agent, UploadError> {
use std::sync::Arc;

let mut builder =
ureq::builder().tls_connector(Arc::new(native_tls_crate::TlsConnector::new()?));
let mut builder = ureq::builder();
if let Ok(proxy) = http_proxy() {
let proxy = ureq::Proxy::new(proxy)?;
builder = builder.proxy(proxy);
};
let mut tls_builder = native_tls::TlsConnector::builder();
if let Some(ca_bundle) = tls_ca_bundle() {
let mut reader = io::BufReader::new(File::open(ca_bundle)?);
for cert in rustls_pemfile::certs(&mut reader)? {
tls_builder.add_root_certificate(native_tls::Certificate::from_pem(&cert)?);
}
}
builder = builder.tls_connector(Arc::new(tls_builder.build()?));
Ok(builder.build())
}

#[cfg(not(feature = "native-tls"))]
#[cfg(feature = "rustls")]
#[allow(clippy::result_large_err)]
fn http_agent() -> Result<ureq::Agent, UploadError> {
use std::sync::Arc;

let mut builder = ureq::builder();
if let Ok(proxy) = http_proxy() {
let proxy = ureq::Proxy::new(proxy)?;
builder = builder.proxy(proxy);
};
if let Some(ca_bundle) = tls_ca_bundle() {
let mut reader = io::BufReader::new(File::open(ca_bundle)?);
let certs = rustls_pemfile::certs(&mut reader)?;
let mut root_certs = rustls::RootCertStore::empty();
root_certs.add_parsable_certificates(&certs);
let client_config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_certs)
.with_no_client_auth();
Ok(builder.tls_config(Arc::new(client_config)).build())
} else {
Ok(builder.build())
}
}

#[cfg(not(any(feature = "native-tls", feature = "rustls")))]
#[allow(clippy::result_large_err)]
fn http_agent() -> Result<ureq::Agent, UploadError> {
let mut builder = ureq::builder();
Expand Down

0 comments on commit 5b42294

Please sign in to comment.