mirror of
https://github.com/launchbadge/sqlx
synced 2024-12-05 01:59:10 +00:00
Support building with rustls but native certificates (#3551)
This adds an alternative TLS configuration that relies on rustls-native-certs, for users who cannot bundle the MPL-licensed webpki-roots. The approach is copied from reqwest: * https://github.com/seanmonstar/reqwest/blob/3ad6e02cd/Cargo.toml#L48 * https://github.com/seanmonstar/reqwest/blob/3ad6e02cd/src/async_impl/client.rs#L513 — except error handling is relaxed to accommodate for tls_config.root_cert_path.
This commit is contained in:
parent
3e140ba384
commit
35c78f5175
7 changed files with 69 additions and 14 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -3119,6 +3119,19 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.1.2"
|
||||
|
@ -3540,6 +3553,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rust_decimal",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
@ -82,7 +82,9 @@ runtime-tokio = ["_rt-tokio", "sqlx-core/_rt-tokio", "sqlx-macros?/_rt-tokio"]
|
|||
tls-native-tls = ["sqlx-core/_tls-native-tls", "sqlx-macros?/_tls-native-tls"]
|
||||
tls-rustls = ["tls-rustls-ring"] # For backwards compatibility
|
||||
tls-rustls-aws-lc-rs = ["sqlx-core/_tls-rustls-aws-lc-rs", "sqlx-macros?/_tls-rustls-aws-lc-rs"]
|
||||
tls-rustls-ring = ["sqlx-core/_tls-rustls-ring", "sqlx-macros?/_tls-rustls-ring"]
|
||||
tls-rustls-ring = ["tls-rustls-ring-webpki"] # For backwards compatibility
|
||||
tls-rustls-ring-webpki = ["sqlx-core/_tls-rustls-ring-webpki", "sqlx-macros?/_tls-rustls-ring-webpki"]
|
||||
tls-rustls-ring-native-roots = ["sqlx-core/_tls-rustls-ring-native-roots", "sqlx-macros?/_tls-rustls-ring-native-roots"]
|
||||
|
||||
# No-op feature used by the workflows to compile without TLS enabled. Not meant for general use.
|
||||
tls-none = []
|
||||
|
|
12
README.md
12
README.md
|
@ -136,8 +136,10 @@ SQLx is compatible with the [`async-std`], [`tokio`], and [`actix`] runtimes; an
|
|||
sqlx = { version = "0.8", features = [ "runtime-tokio" ] }
|
||||
# tokio + native-tls
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-native-tls" ] }
|
||||
# tokio + rustls with ring
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls-ring" ] }
|
||||
# tokio + rustls with ring and WebPKI CA certificates
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls-ring-webpki" ] }
|
||||
# tokio + rustls with ring and platform's native CA certificates
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls-ring-native-roots" ] }
|
||||
# tokio + rustls with aws-lc-rs
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls-aws-lc-rs" ] }
|
||||
|
||||
|
@ -145,8 +147,10 @@ sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls-aws-lc-rs" ]
|
|||
sqlx = { version = "0.8", features = [ "runtime-async-std" ] }
|
||||
# async-std + native-tls
|
||||
sqlx = { version = "0.8", features = [ "runtime-async-std", "tls-native-tls" ] }
|
||||
# async-std + rustls with ring
|
||||
sqlx = { version = "0.8", features = [ "runtime-async-std", "tls-rustls-ring" ] }
|
||||
# async-std + rustls with ring and WebPKI CA certificates
|
||||
sqlx = { version = "0.8", features = [ "runtime-async-std", "tls-rustls-ring-webpki" ] }
|
||||
# async-std + rustls with ring and platform's native CA certificates
|
||||
sqlx = { version = "0.8", features = [ "runtime-async-std", "tls-rustls-ring-native-roots" ] }
|
||||
# async-std + rustls with aws-lc-rs
|
||||
sqlx = { version = "0.8", features = [ "runtime-async-std", "tls-rustls-aws-lc-rs" ] }
|
||||
```
|
||||
|
|
|
@ -22,9 +22,10 @@ json = ["serde", "serde_json"]
|
|||
_rt-async-std = ["async-std", "async-io"]
|
||||
_rt-tokio = ["tokio", "tokio-stream"]
|
||||
_tls-native-tls = ["native-tls"]
|
||||
_tls-rustls-aws-lc-rs = ["_tls-rustls", "rustls/aws-lc-rs"]
|
||||
_tls-rustls-ring = ["_tls-rustls", "rustls/ring"]
|
||||
_tls-rustls = ["rustls", "rustls-pemfile", "webpki-roots"]
|
||||
_tls-rustls-aws-lc-rs = ["_tls-rustls", "rustls/aws-lc-rs", "webpki-roots"]
|
||||
_tls-rustls-ring-webpki = ["_tls-rustls", "rustls/ring", "webpki-roots"]
|
||||
_tls-rustls-ring-native-roots = ["_tls-rustls", "rustls/ring", "rustls-native-certs"]
|
||||
_tls-rustls = ["rustls", "rustls-pemfile"]
|
||||
_tls-none = []
|
||||
|
||||
# support offline/decoupled building (enables serialization of `Describe`)
|
||||
|
@ -41,6 +42,7 @@ native-tls = { version = "0.2.10", optional = true }
|
|||
rustls = { version = "0.23.11", default-features = false, features = ["std", "tls12"], optional = true }
|
||||
rustls-pemfile = { version = "2", optional = true }
|
||||
webpki-roots = { version = "0.26", optional = true }
|
||||
rustls-native-certs = { version = "0.8.0", optional = true }
|
||||
|
||||
# Type Integrations
|
||||
bit-vec = { workspace = true, optional = true }
|
||||
|
|
|
@ -88,9 +88,16 @@ pub async fn handshake<S>(socket: S, tls_config: TlsConfig<'_>) -> Result<Rustls
|
|||
where
|
||||
S: Socket,
|
||||
{
|
||||
#[cfg(all(feature = "_tls-rustls-aws-lc-rs", not(feature = "_tls-rustls-ring")))]
|
||||
#[cfg(all(
|
||||
feature = "_tls-rustls-aws-lc-rs",
|
||||
not(feature = "_tls-rustls-ring-webpki"),
|
||||
not(feature = "_tls-rustls-ring-native-roots")
|
||||
))]
|
||||
let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
|
||||
#[cfg(feature = "_tls-rustls-ring")]
|
||||
#[cfg(any(
|
||||
feature = "_tls-rustls-ring-webpki",
|
||||
feature = "_tls-rustls-ring-native-roots"
|
||||
))]
|
||||
let provider = Arc::new(rustls::crypto::ring::default_provider());
|
||||
|
||||
// Unwrapping is safe here because we use a default provider.
|
||||
|
@ -127,8 +134,10 @@ where
|
|||
.with_no_client_auth()
|
||||
}
|
||||
} else {
|
||||
let mut cert_store = RootCertStore::empty();
|
||||
cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||
#[cfg(any(feature = "_tls-rustls-aws-lc-rs", feature = "_tls-rustls-ring-webpki"))]
|
||||
let mut cert_store = certs_from_webpki();
|
||||
#[cfg(feature = "_tls-rustls-ring-native-roots")]
|
||||
let mut cert_store = certs_from_native_store();
|
||||
|
||||
if let Some(ca) = tls_config.root_cert_path {
|
||||
let data = ca.data().await?;
|
||||
|
@ -204,6 +213,28 @@ fn private_key_from_pem(pem: Vec<u8>) -> Result<PrivateKeyDer<'static>, Error> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "_tls-rustls-aws-lc-rs", feature = "_tls-rustls-ring-webpki"))]
|
||||
fn certs_from_webpki() -> RootCertStore {
|
||||
RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned())
|
||||
}
|
||||
|
||||
#[cfg(feature = "_tls-rustls-ring-native-roots")]
|
||||
fn certs_from_native_store() -> RootCertStore {
|
||||
let mut root_cert_store = RootCertStore::empty();
|
||||
|
||||
let load_results = rustls_native_certs::load_native_certs();
|
||||
for e in load_results.errors {
|
||||
log::warn!("Error loading native certificates: {e:?}");
|
||||
}
|
||||
for cert in load_results.certs {
|
||||
if let Err(e) = root_cert_store.add(cert.into()) {
|
||||
log::warn!("rustls failed to parse native certificate: {e:?}");
|
||||
}
|
||||
}
|
||||
|
||||
root_cert_store
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DummyTlsVerifier {
|
||||
provider: Arc<CryptoProvider>,
|
||||
|
|
|
@ -16,7 +16,8 @@ _rt-tokio = ["tokio", "sqlx-core/_rt-tokio"]
|
|||
|
||||
_tls-native-tls = ["sqlx-core/_tls-native-tls"]
|
||||
_tls-rustls-aws-lc-rs = ["sqlx-core/_tls-rustls-aws-lc-rs"]
|
||||
_tls-rustls-ring = ["sqlx-core/_tls-rustls-ring"]
|
||||
_tls-rustls-ring-webpki = ["sqlx-core/_tls-rustls-ring-webpki"]
|
||||
_tls-rustls-ring-native-roots = ["sqlx-core/_tls-rustls-ring-native-roots"]
|
||||
|
||||
_sqlite = []
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ _rt-tokio = ["sqlx-macros-core/_rt-tokio"]
|
|||
|
||||
_tls-native-tls = ["sqlx-macros-core/_tls-native-tls"]
|
||||
_tls-rustls-aws-lc-rs = ["sqlx-macros-core/_tls-rustls-aws-lc-rs"]
|
||||
_tls-rustls-ring = ["sqlx-macros-core/_tls-rustls-ring"]
|
||||
_tls-rustls-ring-webpki = ["sqlx-macros-core/_tls-rustls-ring-webpki"]
|
||||
_tls-rustls-ring-native-roots = ["sqlx-macros-core/_tls-rustls-ring-native-roots"]
|
||||
|
||||
# SQLx features
|
||||
derive = ["sqlx-macros-core/derive"]
|
||||
|
|
Loading…
Reference in a new issue