diff --git a/Cargo.lock b/Cargo.lock index 10e24131bd..2da47afa54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index bf0a867e1e..49aefd7a93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 = [] diff --git a/README.md b/README.md index ad8dff4a73..4d4a2338ec 100644 --- a/README.md +++ b/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" ] } ``` diff --git a/sqlx-core/Cargo.toml b/sqlx-core/Cargo.toml index 7ea6f33dc2..e1f4108054 100644 --- a/sqlx-core/Cargo.toml +++ b/sqlx-core/Cargo.toml @@ -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 } diff --git a/sqlx-core/src/net/tls/tls_rustls.rs b/sqlx-core/src/net/tls/tls_rustls.rs index 2ea16c854a..d56859808c 100644 --- a/sqlx-core/src/net/tls/tls_rustls.rs +++ b/sqlx-core/src/net/tls/tls_rustls.rs @@ -88,9 +88,16 @@ pub async fn handshake(socket: S, tls_config: TlsConfig<'_>) -> Result) -> Result, 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, diff --git a/sqlx-macros-core/Cargo.toml b/sqlx-macros-core/Cargo.toml index 00b7617c3b..46786b7d8d 100644 --- a/sqlx-macros-core/Cargo.toml +++ b/sqlx-macros-core/Cargo.toml @@ -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 = [] diff --git a/sqlx-macros/Cargo.toml b/sqlx-macros/Cargo.toml index 768db71d8d..5617d3f251 100644 --- a/sqlx-macros/Cargo.toml +++ b/sqlx-macros/Cargo.toml @@ -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"]