i need update break change rustls,but this can't be update to rustls version="0.22".
see:
- old cargo.toml
tokio-rustls = {version= "0.24.1" , optional = true}
rustls = { version = "0.21.10", features = ["dangerous_configuration"], optional = true }
webpki-roots = { version = "0.26.0", optional = true }
rustls-pemfile = { version = "2.0.0", optional = true }
- old code
use rustls::{
client::{ServerCertVerified, ServerCertVerifier, WebPkiVerifier},
CertificateError, ClientConfig, Error as TlsError, OwnedTrustAnchor, RootCertStore, ServerName,
};
use std::io::Cursor;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::SystemTime;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub enum Error {
E(String),
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum CertificateInput {
/// PEM encoded certificate(s)
Inline(Vec<u8>),
/// Path to a file containing PEM encoded certificate(s)
File(PathBuf),
}
pub async fn configure_tls_connector(
accept_invalid_certs: bool,
accept_invalid_hostnames: bool,
root_cert_path: Option<&CertificateInput>,
) -> Result<crate::rt::TlsConnector, Error> {
let config = ClientConfig::builder().with_safe_defaults();
let config = if accept_invalid_certs {
config
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
.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.to_vec(),
ta.subject_public_key_info.to_vec(),
ta.name_constraints.clone().map(|v| v.to_vec()),
)
}));
if let Some(ca) = root_cert_path {
let data = ca.data().await?;
let mut cursor = Cursor::new(data);
for cert_result in rustls_pemfile::certs(&mut cursor)
{
let cert = cert_result.map_err(|_| Error::E(format!("Invalid certificate {}", ca)))?;
cert_store
.add(&rustls::Certificate(cert.as_ref().to_vec()))
.map_err(|err| Error::E(err.to_string()))?;
}
}
if accept_invalid_hostnames {
let verifier = WebPkiVerifier::new(cert_store, None);
config
.with_custom_certificate_verifier(Arc::new(NoHostnameTlsVerifier { verifier }))
.with_no_client_auth()
} else {
config
.with_root_certificates(cert_store)
.with_no_client_auth()
}
};
Ok(Arc::new(config).into())
}
struct DummyTlsVerifier;
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]>,
_ocsp_response: &[u8],
_now: SystemTime,
) -> Result<ServerCertVerified, TlsError> {
Ok(ServerCertVerified::assertion())
}
}
pub struct NoHostnameTlsVerifier {
verifier: WebPkiVerifier,
}
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]>,
ocsp_response: &[u8],
now: SystemTime,
) -> Result<ServerCertVerified, TlsError> {
match self.verifier.verify_server_cert(
end_entity,
intermediates,
server_name,
scts,
ocsp_response,
now,
) {
Err(TlsError::InvalidCertificate(reason))
if reason == CertificateError::NotValidForName =>
{
Ok(ServerCertVerified::assertion())
}
res => res,
}
}
}