mirror of
https://github.com/launchbadge/sqlx.git
synced 2026-03-19 08:39:44 +00:00
Upgrade to rustls 0.23 (#3399)
This commit is contained in:
@@ -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 }
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user