From d2db4b5e38e540c6908e877795a79974f46a5f61 Mon Sep 17 00:00:00 2001 From: Icelk Date: Sat, 25 May 2024 23:19:02 +0200 Subject: [PATCH] Fix #8 by using rustls-webpki --- Cargo.toml | 12 +++--------- src/host.rs | 55 ++++++++++++++++++----------------------------------- 2 files changed, 21 insertions(+), 46 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ca2baa6..310e272 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,16 +56,13 @@ dashmap = "5" # HTTPS rustls = { version = "0.23.8", optional = true, features = ["std", "ring", "logging", "tls12"], default-features = false } rustls-pemfile = { version = "2.1", optional = true } -webpki = { version = "0.22.4", optional = true } +rustls-webpki = { version = "0.102", optional = true, default-features = false, features = ["ring", "std"] } # nonce base64 = { version = "0.22", optional = true } memchr = { version = "2", optional = true } rand = { version = "0.8", optional = true, features = ["small_rng"] } -# Automatic hostname -x509-parser = { version = "0.16", optional = true } - # Compression brotli = { version = "6", optional = true } flate2 = { version = "1", optional = true } @@ -88,7 +85,7 @@ libc = { version = "0.2", default-features = false } default = ["full"] # Enable all features -full = ["all-http", "all-compression", "graceful-shutdown", "auto-hostname", "nonce", "websocket", "base"] +full = ["all-http", "all-compression", "graceful-shutdown", "nonce", "websocket", "base"] # Enable basic features (for all devices but embedded) base = ["async-networking", "handover"] @@ -102,7 +99,7 @@ zstd-multithread = ["zstd/zstdmt"] # HTTP standards all-http = ["https", "http2", "http3"] -https = ["rustls", "rustls-pemfile", "webpki", "async-networking"] +https = ["rustls", "rustls-pemfile", "rustls-webpki", "async-networking"] http2 = ["h2", "https"] http3 = ["h3", "h3-quinn", "quinn", "https"] @@ -111,9 +108,6 @@ graceful-shutdown = ["handover"] # Handover handover = ["kvarn_signal"] -# Automatic populating of Host name and alt-names -auto-hostname = ["x509-parser"] - # nonce implementation nonce = ["rand", "base64", "memchr"] diff --git a/src/host.rs b/src/host.rs index ddbaba8..985c6f1 100644 --- a/src/host.rs +++ b/src/host.rs @@ -124,7 +124,7 @@ impl Host { /// # Errors /// /// Will return any error from [`get_certified_key()`]. - #[cfg(all(feature = "https", feature = "auto-hostname"))] + #[cfg(feature = "https")] pub fn read_fs_name_from_cert( cert_path: impl AsRef, private_key_path: impl AsRef, @@ -193,53 +193,34 @@ impl Host { /// # Panics /// /// Panics if `cert.is_empty()` or if the first certificate in `cert` is invalid. - #[cfg(all(feature = "https", feature = "auto-hostname"))] + #[cfg(feature = "https")] pub fn new_name_from_cert( key: sign::CertifiedKey, path: impl AsRef, extensions: Extensions, options: Options, ) -> Self { - use x509_parser::prelude::FromDer; - let tbs = x509_parser::certificate::X509Certificate::from_der(&key.cert[0]) - .expect("certificate invalid, failed to get host name") - .1 - .tbs_certificate; - let mut names = tbs.subject().iter_common_name(); - let name = names - .next() - .expect("no common names were found") - .as_str() - .expect("the common name contains invalid bytes") - .to_owned(); - let mut alt_names = Vec::new(); - for name in names.filter_map(|name| name.as_str().ok()) { - alt_names.push(name.to_compact_string()); - } - let alt_name = tbs - .subject_alternative_name() - .expect("alternative name extension of certificate invalid"); - if let Some(alt_name) = alt_name { - for name in alt_name - .value - .general_names - .iter() - .filter_map(|name| match name { - x509_parser::prelude::GeneralName::DNSName(name) => Some(name), - _ => None, - }) - { - alt_names.push((*name).to_compact_string()); - } - } - let mut me = Self::new(name, key, path, extensions, options); - me.alternative_names = alt_names; + let parsed = rustls_webpki::EndEntityCert::try_from(&key.cert[0]) + .expect("internal certificate has invalid format?"); + let names: Vec<_> = parsed + .valid_dns_names() + .map(|s| s.to_compact_string()) + .collect(); + let mut me = Self::new( + names.first().expect("cert has no name?").clone(), + key, + path, + extensions, + options, + ); + me.alternative_names = names; me } /// Creates a new [`Host`] without a certificate. /// /// This host will only support non-encrypted HTTP/1 connections. - /// Consider enabling the `https` feature and use a self-signed certificate or one from [Let's Encrypt](https://letsencrypt.org/). + /// Consider enabling the `https` feature and use a self-signed certificate + /// or one from [Let's Encrypt](https://letsencrypt.org/). pub fn unsecure( host_name: impl AsRef, path: impl AsRef,