Skip to content

Commit 08296a2

Browse files
Upgrade rustls to 0.20 (#1505)
* Upgrade rustls to 0.20 * Rustls 0.20.1 is out * Fix merge conflict mistake * Bump rustls-pemfile to 0.3 * Resync Cargo.lock * Bump rustls-pemfile to v1 Co-authored-by: Austin Bonander <[email protected]>
1 parent a97208c commit 08296a2

File tree

7 files changed

+100
-70
lines changed

7 files changed

+100
-70
lines changed

Cargo.lock

+32-24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sqlx-core/Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ _rt-actix = ["tokio-stream"]
9494
_rt-async-std = []
9595
_rt-tokio = ["tokio-stream"]
9696
_tls-native-tls = []
97-
_tls-rustls = ["rustls", "webpki", "webpki-roots"]
97+
_tls-rustls = ["rustls", "rustls-pemfile", "webpki-roots"]
9898

9999
# support offline/decoupled building (enables serialization of `Describe`)
100100
offline = ["serde", "either/serde"]
@@ -147,7 +147,8 @@ percent-encoding = "2.1.0"
147147
rand = { version = "0.8.4", default-features = false, optional = true, features = ["std", "std_rng"] }
148148
regex = { version = "1.5.5", optional = true }
149149
rsa = { version = "0.6.0", optional = true }
150-
rustls = { version = "0.19.1", features = ["dangerous_configuration"], optional = true }
150+
rustls = { version = "0.20.1", features = ["dangerous_configuration"], optional = true }
151+
rustls-pemfile = { version = "1.0", optional = true }
151152
serde = { version = "1.0.132", features = ["derive", "rc"], optional = true }
152153
serde_json = { version = "1.0.73", features = ["raw_value"], optional = true }
153154
sha-1 = { version = "0.10.0", default-features = false, optional = true }
@@ -159,8 +160,7 @@ tokio-stream = { version = "0.1.8", features = ["fs"], optional = true }
159160
smallvec = "1.7.0"
160161
url = { version = "2.2.2", default-features = false }
161162
uuid = { version = "0.8.2", default-features = false, optional = true, features = ["std"] }
162-
webpki = { version = "0.21.4", optional = true }
163-
webpki-roots = { version = "0.21.1", optional = true }
163+
webpki-roots = { version = "0.22.0", optional = true }
164164
whoami = { version = "1.2.1", optional = true }
165165
stringprep = "0.1.2"
166166
bstr = { version = "0.2.17", default-features = false, features = ["std"], optional = true }

sqlx-core/src/error.rs

-8
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,6 @@ impl From<sqlx_rt::native_tls::Error> for Error {
253253
}
254254
}
255255

256-
#[cfg(feature = "_tls-rustls")]
257-
impl From<webpki::InvalidDNSNameError> for Error {
258-
#[inline]
259-
fn from(error: webpki::InvalidDNSNameError) -> Self {
260-
Error::Tls(Box::new(error))
261-
}
262-
}
263-
264256
// Format an error message as a `Protocol` error
265257
macro_rules! err_protocol {
266258
($expr:expr) => {

sqlx-core/src/net/tls/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![allow(dead_code)]
22

3+
use std::convert::TryFrom;
34
use std::io;
45
use std::ops::{Deref, DerefMut};
56
use std::path::PathBuf;
@@ -104,7 +105,7 @@ where
104105
};
105106

106107
#[cfg(feature = "_tls-rustls")]
107-
let host = webpki::DNSNameRef::try_from_ascii_str(host)?;
108+
let host = ::rustls::ServerName::try_from(host).map_err(|err| Error::Tls(err.into()))?;
108109

109110
*self = MaybeTlsStream::Tls(connector.connect(host, stream).await?);
110111

sqlx-core/src/net/tls/rustls.rs

+58-29
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use crate::net::CertificateInput;
22
use rustls::{
3-
Certificate, ClientConfig, RootCertStore, ServerCertVerified, ServerCertVerifier, TLSError,
4-
WebPKIVerifier,
3+
client::{ServerCertVerified, ServerCertVerifier, WebPkiVerifier},
4+
ClientConfig, Error as TlsError, OwnedTrustAnchor, RootCertStore, ServerName,
55
};
66
use std::io::Cursor;
77
use std::sync::Arc;
8-
use webpki::DNSNameRef;
8+
use std::time::SystemTime;
99

1010
use crate::error::Error;
1111

@@ -14,32 +14,47 @@ pub async fn configure_tls_connector(
1414
accept_invalid_hostnames: bool,
1515
root_cert_path: Option<&CertificateInput>,
1616
) -> Result<sqlx_rt::TlsConnector, Error> {
17-
let mut config = ClientConfig::new();
17+
let config = ClientConfig::builder().with_safe_defaults();
1818

19-
if accept_invalid_certs {
19+
let config = if accept_invalid_certs {
2020
config
21-
.dangerous()
22-
.set_certificate_verifier(Arc::new(DummyTlsVerifier));
21+
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
22+
.with_no_client_auth()
2323
} else {
24-
config
25-
.root_store
26-
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
24+
let mut cert_store = RootCertStore::empty();
25+
cert_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
26+
OwnedTrustAnchor::from_subject_spki_name_constraints(
27+
ta.subject,
28+
ta.spki,
29+
ta.name_constraints,
30+
)
31+
}));
2732

2833
if let Some(ca) = root_cert_path {
2934
let data = ca.data().await?;
3035
let mut cursor = Cursor::new(data);
31-
config
32-
.root_store
33-
.add_pem_file(&mut cursor)
34-
.map_err(|_| Error::Tls(format!("Invalid certificate {}", ca).into()))?;
36+
37+
for cert in rustls_pemfile::certs(&mut cursor)
38+
.map_err(|_| Error::Tls(format!("Invalid certificate {}", ca).into()))?
39+
{
40+
cert_store
41+
.add(&rustls::Certificate(cert))
42+
.map_err(|err| Error::Tls(err.into()))?;
43+
}
3544
}
3645

3746
if accept_invalid_hostnames {
47+
let verifier = WebPkiVerifier::new(cert_store, None);
48+
49+
config
50+
.with_custom_certificate_verifier(Arc::new(NoHostnameTlsVerifier { verifier }))
51+
.with_no_client_auth()
52+
} else {
3853
config
39-
.dangerous()
40-
.set_certificate_verifier(Arc::new(NoHostnameTlsVerifier));
54+
.with_root_certificates(cert_store)
55+
.with_no_client_auth()
4156
}
42-
}
57+
};
4358

4459
Ok(Arc::new(config).into())
4560
}
@@ -49,28 +64,42 @@ struct DummyTlsVerifier;
4964
impl ServerCertVerifier for DummyTlsVerifier {
5065
fn verify_server_cert(
5166
&self,
52-
_roots: &RootCertStore,
53-
_presented_certs: &[Certificate],
54-
_dns_name: DNSNameRef<'_>,
67+
_end_entity: &rustls::Certificate,
68+
_intermediates: &[rustls::Certificate],
69+
_server_name: &ServerName,
70+
_scts: &mut dyn Iterator<Item = &[u8]>,
5571
_ocsp_response: &[u8],
56-
) -> Result<ServerCertVerified, TLSError> {
72+
_now: SystemTime,
73+
) -> Result<ServerCertVerified, TlsError> {
5774
Ok(ServerCertVerified::assertion())
5875
}
5976
}
6077

61-
pub struct NoHostnameTlsVerifier;
78+
pub struct NoHostnameTlsVerifier {
79+
verifier: WebPkiVerifier,
80+
}
6281

6382
impl ServerCertVerifier for NoHostnameTlsVerifier {
6483
fn verify_server_cert(
6584
&self,
66-
roots: &RootCertStore,
67-
presented_certs: &[Certificate],
68-
dns_name: DNSNameRef<'_>,
85+
end_entity: &rustls::Certificate,
86+
intermediates: &[rustls::Certificate],
87+
server_name: &ServerName,
88+
scts: &mut dyn Iterator<Item = &[u8]>,
6989
ocsp_response: &[u8],
70-
) -> Result<ServerCertVerified, TLSError> {
71-
let verifier = WebPKIVerifier::new();
72-
match verifier.verify_server_cert(roots, presented_certs, dns_name, ocsp_response) {
73-
Err(TLSError::WebPKIError(webpki::Error::CertNotValidForName)) => {
90+
now: SystemTime,
91+
) -> Result<ServerCertVerified, TlsError> {
92+
match self.verifier.verify_server_cert(
93+
end_entity,
94+
intermediates,
95+
server_name,
96+
scts,
97+
ocsp_response,
98+
now,
99+
) {
100+
Err(TlsError::InvalidCertificateData(reason))
101+
if reason.contains("CertNotValidForName") =>
102+
{
74103
Ok(ServerCertVerified::assertion())
75104
}
76105
res => res,

sqlx-rt/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ runtime-async-std-native-tls = [
2020
runtime-tokio-native-tls = ["_rt-tokio", "_tls-native-tls", "tokio-native-tls"]
2121

2222
runtime-actix-rustls = ["_rt-actix", "_tls-rustls", "tokio-rustls"]
23-
runtime-async-std-rustls = ["_rt-async-std", "_tls-rustls", "async-rustls"]
23+
runtime-async-std-rustls = ["_rt-async-std", "_tls-rustls", "futures-rustls"]
2424
runtime-tokio-rustls = ["_rt-tokio", "_tls-rustls", "tokio-rustls"]
2525

2626
# Not used directly and not re-exported from sqlx
@@ -32,11 +32,11 @@ _tls-rustls = []
3232

3333
[dependencies]
3434
async-native-tls = { version = "0.3.3", optional = true }
35-
async-rustls = { version = "0.2.0", optional = true }
35+
futures-rustls = { version = "0.22.0", optional = true }
3636
actix-rt = { version = "2.0.0", default-features = false, optional = true }
3737
async-std = { version = "1.7.0", features = ["unstable"], optional = true }
3838
tokio-native-tls = { version = "0.3.0", optional = true }
39-
tokio-rustls = { version = "0.22.0", optional = true }
39+
tokio-rustls = { version = "0.23.0", optional = true }
4040
native-tls = { version = "0.2.4", optional = true }
4141
once_cell = { version = "1.4", features = ["std"], optional = true }
4242

sqlx-rt/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,4 @@ pub use async_native_tls::{TlsConnector, TlsStream};
193193
feature = "_rt-actix"
194194
)),
195195
))]
196-
pub use async_rustls::{client::TlsStream, TlsConnector};
196+
pub use futures_rustls::{client::TlsStream, TlsConnector};

0 commit comments

Comments
 (0)