Upgrade to rustls 0.23 (#3399)

This commit is contained in:
Dirkjan Ochtman 2024-08-05 01:39:13 +02:00 committed by GitHub
parent 4acecfc636
commit a892ebc6e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 358 additions and 110 deletions

View file

@ -66,7 +66,7 @@ jobs:
strategy:
matrix:
runtime: [async-std, tokio]
tls: [native-tls, rustls, none]
tls: [native-tls, rustls-aws-lc-rs, rustls-ring, none]
steps:
- uses: actions/checkout@v4
@ -147,7 +147,7 @@ jobs:
matrix:
postgres: [15, 11]
runtime: [async-std, tokio]
tls: [native-tls, rustls, none]
tls: [native-tls, rustls-aws-lc-rs, rustls-ring, none]
needs: check
steps:
- uses: actions/checkout@v4
@ -247,7 +247,7 @@ jobs:
matrix:
mysql: [8]
runtime: [async-std, tokio]
tls: [native-tls, rustls, none]
tls: [native-tls, rustls-aws-lc-rs, rustls-ring, none]
needs: check
steps:
- uses: actions/checkout@v4
@ -335,7 +335,7 @@ jobs:
matrix:
mariadb: [verylatest, 11_4, 10_11, 10_4]
runtime: [async-std, tokio]
tls: [native-tls, rustls, none]
tls: [native-tls, rustls-aws-lc-rs, rustls-ring, none]
needs: check
steps:
- uses: actions/checkout@v4

228
Cargo.lock generated
View file

@ -349,6 +349,33 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "aws-lc-rs"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8a47f2fb521b70c11ce7369a6c5fa4bd6af7e5d62ec06303875bafe7c6ba245"
dependencies = [
"aws-lc-sys",
"mirai-annotations",
"paste",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2927c7af777b460b7ccd95f8b67acd7b4c04ec8896bf0c8e80ba30523cffc057"
dependencies = [
"bindgen",
"cc",
"cmake",
"dunce",
"fs_extra",
"libc",
"paste",
]
[[package]]
name = "axum"
version = "0.5.17"
@ -444,12 +471,6 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.0"
@ -484,6 +505,29 @@ dependencies = [
"num-traits",
]
[[package]]
name = "bindgen"
version = "0.69.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
dependencies = [
"bitflags 2.4.2",
"cexpr",
"clang-sys",
"itertools 0.10.5",
"lazy_static",
"lazycell",
"log",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn 2.0.52",
"which",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
@ -684,6 +728,19 @@ name = "cc"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
dependencies = [
"jobserver",
"libc",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
@ -737,6 +794,17 @@ dependencies = [
"half",
]
[[package]]
name = "clang-sys"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "4.5.2"
@ -797,6 +865,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "cmake"
version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
dependencies = [
"cc",
]
[[package]]
name = "colorchoice"
version = "1.0.0"
@ -1110,6 +1187,12 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
[[package]]
name = "dunce"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
[[package]]
name = "either"
version = "1.10.0"
@ -1348,6 +1431,12 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "funty"
version = "2.0.0"
@ -1834,6 +1923,15 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "jobserver"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.69"
@ -1861,12 +1959,28 @@ dependencies = [
"spin 0.5.2",
]
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libloading"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
]
[[package]]
name = "libm"
version = "0.2.8"
@ -2009,6 +2123,12 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "mirai-annotations"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1"
[[package]]
name = "mockall"
version = "0.11.4"
@ -2483,6 +2603,16 @@ dependencies = [
"termtree",
]
[[package]]
name = "prettyplease"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
dependencies = [
"proc-macro2",
"syn 2.0.52",
]
[[package]]
name = "proc-macro-crate"
version = "3.1.0"
@ -2803,6 +2933,12 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.37.27"
@ -2832,31 +2968,44 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.21.11"
version = "0.23.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0"
dependencies = [
"aws-lc-rs",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"sct",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.21.7",
"base64 0.22.0",
"rustls-pki-types",
]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.102.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78"
dependencies = [
"aws-lc-rs",
"ring",
"rustls-pki-types",
"untrusted",
]
@ -2920,16 +3069,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "seahash"
version = "4.1.0"
@ -3061,6 +3200,12 @@ dependencies = [
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook"
version = "0.3.17"
@ -4237,9 +4382,24 @@ dependencies = [
[[package]]
name = "webpki-roots"
version = "0.25.4"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix 0.38.31",
]
[[package]]
name = "whoami"
@ -4466,3 +4626,17 @@ name = "zeroize"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
]

View file

@ -78,7 +78,9 @@ runtime-tokio = ["_rt-tokio", "sqlx-core/_rt-tokio", "sqlx-macros?/_rt-tokio"]
# TLS features
tls-native-tls = ["sqlx-core/_tls-native-tls", "sqlx-macros?/_tls-native-tls"]
tls-rustls = ["sqlx-core/_tls-rustls", "sqlx-macros?/_tls-rustls"]
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"]
# No-op feature used by the workflows to compile without TLS enabled. Not meant for general use.
tls-none = []
@ -86,10 +88,10 @@ tls-none = []
# Legacy Runtime + TLS features
runtime-async-std-native-tls = ["runtime-async-std", "tls-native-tls"]
runtime-async-std-rustls = ["runtime-async-std", "tls-rustls"]
runtime-async-std-rustls = ["runtime-async-std", "tls-rustls-ring"]
runtime-tokio-native-tls = ["runtime-tokio", "tls-native-tls"]
runtime-tokio-rustls = ["runtime-tokio", "tls-rustls"]
runtime-tokio-rustls = ["runtime-tokio", "tls-rustls-ring"]
# for conditional compilation
_rt-async-std = []

View file

@ -75,7 +75,7 @@ SQLx is an async, pure Rust<sub>†</sub> SQL crate featuring compile-time check
† The SQLite driver uses the libsqlite3 C library as SQLite is an embedded database (the only way
we could be pure Rust for SQLite is by porting _all_ of SQLite to Rust).
†† SQLx uses `#![forbid(unsafe_code)]` unless the `sqlite` feature is enabled.
†† SQLx uses `#![forbid(unsafe_code)]` unless the `sqlite` feature is enabled.
The SQLite driver directly invokes the SQLite3 API via `libsqlite3-sys`, which requires `unsafe`.
</small></small>
@ -128,15 +128,19 @@ SQLx is compatible with the [`async-std`], [`tokio`], and [`actix`] runtimes; an
sqlx = { version = "0.7", features = [ "runtime-tokio" ] }
# tokio + native-tls
sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-native-tls" ] }
# tokio + rustls
sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls" ] }
# tokio + rustls with ring
sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls-ring" ] }
# tokio + rustls with aws-lc-rs
sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls-aws-lc-rs" ] }
# async-std (no TLS)
sqlx = { version = "0.7", features = [ "runtime-async-std" ] }
# async-std + native-tls
sqlx = { version = "0.7", features = [ "runtime-async-std", "tls-native-tls" ] }
# async-std + rustls
sqlx = { version = "0.7", features = [ "runtime-async-std", "tls-rustls" ] }
# async-std + rustls with ring
sqlx = { version = "0.7", features = [ "runtime-async-std", "tls-rustls-ring" ] }
# async-std + rustls with aws-lc-rs
sqlx = { version = "0.7", features = [ "runtime-async-std", "tls-rustls-aws-lc-rs" ] }
```
#### Cargo Feature Flags
@ -387,7 +391,7 @@ Differences from `query()`:
[dotenv]: https://github.com/dotenv-rs/dotenv#examples
The biggest downside to `query!()` is that the output type cannot be named (due to Rust not
officially supporting anonymous records). To address that, there is a `query_as!()` macro that is
officially supporting anonymous records). To address that, there is a `query_as!()` macro that is
mostly identical except that you can name the output type.
```rust

View file

@ -22,6 +22,8 @@ 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-none = []
@ -36,9 +38,9 @@ tokio = { workspace = true, optional = true }
# TLS
native-tls = { version = "0.2.10", optional = true }
rustls = { version = "0.21.11", default-features = false, features = ["dangerous_configuration", "tls12"], optional = true }
rustls-pemfile = { version = "1.0", optional = true }
webpki-roots = { version = "0.25", 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 }
# Type Integrations
bit-vec = { workspace = true, optional = true }

View file

@ -2,12 +2,15 @@ use futures_util::future;
use std::io::{self, BufReader, Cursor, Read, Write};
use std::sync::Arc;
use std::task::{Context, Poll};
use std::time::SystemTime;
use rustls::{
client::{ServerCertVerified, ServerCertVerifier, WebPkiVerifier},
CertificateError, ClientConfig, ClientConnection, Error as TlsError, OwnedTrustAnchor,
RootCertStore, ServerName,
client::{
danger::{ServerCertVerified, ServerCertVerifier},
WebPkiServerVerifier,
},
crypto::{verify_tls12_signature, verify_tls13_signature, CryptoProvider},
pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime},
CertificateError, ClientConfig, ClientConnection, Error as TlsError, RootCertStore,
};
use crate::error::Error;
@ -85,7 +88,15 @@ pub async fn handshake<S>(socket: S, tls_config: TlsConfig<'_>) -> Result<Rustls
where
S: Socket,
{
let config = ClientConfig::builder().with_safe_defaults();
#[cfg(all(feature = "_tls-rustls-aws-lc-rs", not(feature = "_tls-rustls-ring")))]
let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
#[cfg(feature = "_tls-rustls-ring")]
let provider = Arc::new(rustls::crypto::ring::default_provider());
// Unwrapping is safe here because we use a default provider.
let config = ClientConfig::builder_with_provider(provider.clone())
.with_safe_default_protocol_versions()
.unwrap();
// authentication using user's key and its associated certificate
let user_auth = match (tls_config.client_cert_path, tls_config.client_key_path) {
@ -105,47 +116,47 @@ where
let config = if tls_config.accept_invalid_certs {
if let Some(user_auth) = user_auth {
config
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
.dangerous()
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier { provider }))
.with_client_auth_cert(user_auth.0, user_auth.1)
.map_err(Error::tls)?
} else {
config
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
.dangerous()
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier { provider }))
.with_no_client_auth()
}
} else {
let mut cert_store = RootCertStore::empty();
cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
}));
cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
if let Some(ca) = tls_config.root_cert_path {
let data = ca.data().await?;
let mut cursor = Cursor::new(data);
for cert in rustls_pemfile::certs(&mut cursor)
.map_err(|_| Error::Tls(format!("Invalid certificate {ca}").into()))?
{
cert_store
.add(&rustls::Certificate(cert))
.map_err(|err| Error::Tls(err.into()))?;
for result in rustls_pemfile::certs(&mut cursor) {
let Ok(cert) = result else {
return Err(Error::Tls(format!("Invalid certificate {ca}").into()));
};
cert_store.add(cert).map_err(|err| Error::Tls(err.into()))?;
}
}
if tls_config.accept_invalid_hostnames {
let verifier = WebPkiVerifier::new(cert_store, None);
let verifier = WebPkiServerVerifier::builder(Arc::new(cert_store))
.build()
.map_err(|err| Error::Tls(err.into()))?;
if let Some(user_auth) = user_auth {
config
.dangerous()
.with_custom_certificate_verifier(Arc::new(NoHostnameTlsVerifier { verifier }))
.with_client_auth_cert(user_auth.0, user_auth.1)
.map_err(Error::tls)?
} else {
config
.dangerous()
.with_custom_certificate_verifier(Arc::new(NoHostnameTlsVerifier { verifier }))
.with_no_client_auth()
}
@ -161,7 +172,7 @@ where
}
};
let host = rustls::ServerName::try_from(tls_config.hostname).map_err(Error::tls)?;
let host = ServerName::try_from(tls_config.hostname.to_owned()).map_err(Error::tls)?;
let mut socket = RustlsSocket {
inner: StdSocket::new(socket),
@ -175,69 +186,94 @@ where
Ok(socket)
}
fn certs_from_pem(pem: Vec<u8>) -> Result<Vec<rustls::Certificate>, Error> {
fn certs_from_pem(pem: Vec<u8>) -> Result<Vec<CertificateDer<'static>>, Error> {
let cur = Cursor::new(pem);
let mut reader = BufReader::new(cur);
rustls_pemfile::certs(&mut reader)?
.into_iter()
.map(|v| Ok(rustls::Certificate(v)))
rustls_pemfile::certs(&mut reader)
.map(|result| result.map_err(|err| Error::Tls(err.into())))
.collect()
}
fn private_key_from_pem(pem: Vec<u8>) -> Result<rustls::PrivateKey, Error> {
fn private_key_from_pem(pem: Vec<u8>) -> Result<PrivateKeyDer<'static>, Error> {
let cur = Cursor::new(pem);
let mut reader = BufReader::new(cur);
loop {
match rustls_pemfile::read_one(&mut reader)? {
Some(
rustls_pemfile::Item::RSAKey(key)
| rustls_pemfile::Item::PKCS8Key(key)
| rustls_pemfile::Item::ECKey(key),
) => return Ok(rustls::PrivateKey(key)),
None => break,
_ => {}
}
match rustls_pemfile::private_key(&mut reader) {
Ok(Some(key)) => Ok(key),
Ok(None) => Err(Error::Configuration("no keys found pem file".into())),
Err(e) => Err(Error::Configuration(e.to_string().into())),
}
Err(Error::Configuration("no keys found pem file".into()))
}
struct DummyTlsVerifier;
#[derive(Debug)]
struct DummyTlsVerifier {
provider: Arc<CryptoProvider>,
}
impl ServerCertVerifier for DummyTlsVerifier {
fn verify_server_cert(
&self,
_end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_end_entity: &CertificateDer<'_>,
_intermediates: &[CertificateDer<'_>],
_server_name: &ServerName<'_>,
_ocsp_response: &[u8],
_now: SystemTime,
_now: UnixTime,
) -> Result<ServerCertVerified, TlsError> {
Ok(ServerCertVerified::assertion())
}
fn verify_tls12_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, TlsError> {
verify_tls12_signature(
message,
cert,
dss,
&self.provider.signature_verification_algorithms,
)
}
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, TlsError> {
verify_tls13_signature(
message,
cert,
dss,
&self.provider.signature_verification_algorithms,
)
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
self.provider
.signature_verification_algorithms
.supported_schemes()
}
}
#[derive(Debug)]
pub struct NoHostnameTlsVerifier {
verifier: WebPkiVerifier,
verifier: Arc<WebPkiServerVerifier>,
}
impl ServerCertVerifier for NoHostnameTlsVerifier {
fn verify_server_cert(
&self,
end_entity: &rustls::Certificate,
intermediates: &[rustls::Certificate],
server_name: &ServerName,
scts: &mut dyn Iterator<Item = &[u8]>,
end_entity: &CertificateDer<'_>,
intermediates: &[CertificateDer<'_>],
server_name: &ServerName<'_>,
ocsp_response: &[u8],
now: SystemTime,
now: UnixTime,
) -> Result<ServerCertVerified, TlsError> {
match self.verifier.verify_server_cert(
end_entity,
intermediates,
server_name,
scts,
ocsp_response,
now,
) {
@ -247,4 +283,26 @@ impl ServerCertVerifier for NoHostnameTlsVerifier {
res => res,
}
}
fn verify_tls12_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, TlsError> {
self.verifier.verify_tls12_signature(message, cert, dss)
}
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &CertificateDer<'_>,
dss: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, TlsError> {
self.verifier.verify_tls13_signature(message, cert, dss)
}
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
self.verifier.supported_verify_schemes()
}
}

View file

@ -15,7 +15,8 @@ _rt-async-std = ["async-std", "sqlx-core/_rt-async-std"]
_rt-tokio = ["tokio", "sqlx-core/_rt-tokio"]
_tls-native-tls = ["sqlx-core/_tls-native-tls"]
_tls-rustls = ["sqlx-core/_tls-rustls"]
_tls-rustls-aws-lc-rs = ["sqlx-core/_tls-rustls-aws-lc-rs"]
_tls-rustls-ring = ["sqlx-core/_tls-rustls-ring"]
# SQLx features
derive = []

View file

@ -18,7 +18,8 @@ _rt-async-std = ["sqlx-macros-core/_rt-async-std"]
_rt-tokio = ["sqlx-macros-core/_rt-tokio"]
_tls-native-tls = ["sqlx-macros-core/_tls-native-tls"]
_tls-rustls = ["sqlx-macros-core/_tls-rustls"]
_tls-rustls-aws-lc-rs = ["sqlx-macros-core/_tls-rustls-aws-lc-rs"]
_tls-rustls-ring = ["sqlx-macros-core/_tls-rustls-ring"]
# SQLx features
derive = ["sqlx-macros-core/derive"]

View file

@ -1,6 +1,6 @@
The async SQL toolkit for Rust, built with ❤️ by [the LaunchBadge team].
See our [README] to get started or [browse our example projects].
See our [README] to get started or [browse our example projects].
Have a question? [Check our FAQ] or [open a discussion].
### Runtime Support
@ -15,36 +15,42 @@ You choose which runtime SQLx uses by default by enabling one of the following f
The `runtime-actix` feature also exists but is an alias of `runtime-tokio`.
If more than one runtime feature is enabled, the Tokio runtime is used if a Tokio context exists on the current
thread, i.e. [`tokio::runtime::Handle::try_current()`] returns `Ok`; `async-std` is used otherwise.
thread, i.e. [`tokio::runtime::Handle::try_current()`] returns `Ok`; `async-std` is used otherwise.
Note that while SQLx no longer produces a compile error if zero or multiple runtime features are enabled,
which is useful for libraries building on top of it,
which is useful for libraries building on top of it,
**the use of nearly any async function in the API will panic without at least one runtime feature enabled**.
The chief exception is the SQLite driver, which is runtime-agnostic, including its integration with the query macros.
However, [`SqlitePool`][crate::sqlite::SqlitePool] _does_ require runtime support for timeouts and spawning
The chief exception is the SQLite driver, which is runtime-agnostic, including its integration with the query macros.
However, [`SqlitePool`][crate::sqlite::SqlitePool] _does_ require runtime support for timeouts and spawning
internal management tasks.
### TLS Support
For securely communicating with SQL servers over an untrusted network connection such as the internet,
For securely communicating with SQL servers over an untrusted network connection such as the internet,
you can enable Transport Layer Security (TLS) by enabling one of the following features:
* `tls-native-tls`: Enables the [`native-tls`] backend which uses the OS-native TLS capabilities:
* SecureTransport on macOS.
* SChannel on Windows.
* OpenSSL on all other platforms.
* `tls-rustls`: Enables the [RusTLS] backend, a crossplatform TLS library.
* Only supports TLS revisions 1.2 and 1.3.
* If you get `HandshakeFailure` errors when using this feature, it likely means your database server does not support
* `tls-rustls`: Enables the [rustls] backend, a cross-platform TLS library.
* Only supports TLS revisions 1.2 and 1.3.
* If you get `HandshakeFailure` errors when using this feature, it likely means your database server does not support
these newer revisions. This might be resolved by enabling or switching to the `tls-native-tls` feature.
* rustls supports several providers of cryptographic primitives. The default
(enabled when you use the `tls-rustls` feature or `tls-rustls-ring`) is the
`ring` provider, which has fewer build-time dependencies but also has fewer
features. Alternatively, you can use `tls-rustls-aws-lc-rs` to use the
`aws-lc-rs` provider, which enables additional cipher suite support at the cost
of more onerous build requirements (depending on platform support).
If more than one TLS feature is enabled, the `tls-native-tls` feature takes precedent so that it is only necessary to enable
it to see if it resolves the `HandshakeFailure` error without disabling `tls-rustls`.
Consult the user manual for your database to find the TLS versions it supports.
If your connection configuration requires a TLS upgrade but TLS support was not enabled, the connection attempt
If your connection configuration requires a TLS upgrade but TLS support was not enabled, the connection attempt
will return an error.
The legacy runtime+TLS combination feature flags are still supported, but for forward-compatibility, use of the separate
@ -59,4 +65,4 @@ runtime and TLS feature flags is recommended.
[async-std]: https://www.async.rs
[`tokio::runtime::Handle::try_current()`]: https://docs.rs/tokio/latest/tokio/runtime/struct.Handle.html#method.try_current
[`native-tls`]: https://docs.rs/native-tls/latest/native_tls/
[RusTLS]: https://docs.rs/rustls/latest/rustls/
[rustls]: https://docs.rs/rustls/latest/rustls/