From 144d059b725e2d178d7f4a6403cde9474fe65dcc Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 11 Aug 2026 00:07:15 +0900 Subject: refactor(util): drop the unused TlsHelper port Composer's Composer\Util\TlsHelper is marked deprecated for removal in Composer 3.0 and has no caller in composer/composer outside its own test: PHP's stream layer verifies certificate hostnames itself, and the one surviving method delegates to composer/ca-bundle. The Rust port had no caller either, so it, its test, and the openssl_x509_parse shim it was the sole user of are removed. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe/src/util.rs | 2 - crates/shirabe/src/util/tls_helper.rs | 149 ---------------------------------- 2 files changed, 151 deletions(-) delete mode 100644 crates/shirabe/src/util/tls_helper.rs (limited to 'crates/shirabe/src') diff --git a/crates/shirabe/src/util.rs b/crates/shirabe/src/util.rs index 35402d79..613b615e 100644 --- a/crates/shirabe/src/util.rs +++ b/crates/shirabe/src/util.rs @@ -28,7 +28,6 @@ pub mod svn; pub mod sync_executor; pub mod sync_helper; pub mod tar; -pub mod tls_helper; pub mod url; pub mod zip; @@ -60,6 +59,5 @@ pub use stream_context_factory::*; pub use svn::*; pub use sync_helper::*; pub use tar::*; -pub use tls_helper::*; pub use url::*; pub use zip::*; diff --git a/crates/shirabe/src/util/tls_helper.rs b/crates/shirabe/src/util/tls_helper.rs deleted file mode 100644 index 0c3f44dc..00000000 --- a/crates/shirabe/src/util/tls_helper.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! ref: composer/src/Composer/Util/TlsHelper.php - -use shirabe_ca_bundle::ca_bundle::CaBundle; -use shirabe_pcre::Preg; -use shirabe_php_shim::{ - PhpMixed, ltrim, php_regex, preg_quote, str_replace, strtolower, substr, substr_count, -}; - -/// Extracted certificate names. Mirrors PHP's `array{cn: string, san: string[]}`. -#[derive(Debug, Clone)] -pub struct CertificateNames { - pub cn: String, - pub san: Vec, -} - -/// Match hostname against a certificate. -/// -/// @deprecated Use composer/ca-bundle and composer/composer 2.2 if you still need PHP 5 -/// compatibility, this class will be removed in Composer 3.0 -#[derive(Debug)] -pub struct TlsHelper; - -impl TlsHelper { - /// Match hostname against a certificate. Sets `cn` to the common name of the - /// certificate iff a match is found. - pub fn check_certificate_host( - certificate: &PhpMixed, - hostname: &str, - cn: &mut Option, - ) -> bool { - let names = Self::get_certificate_names(certificate); - - let Some(names) = names else { - return false; - }; - - let mut combined_names = names.san.clone(); - combined_names.push(names.cn.clone()); - let hostname = strtolower(hostname); - - for cert_name in &combined_names { - let matcher = Self::cert_name_matcher(cert_name); - - if let Some(matcher) = matcher - && matcher(&hostname) - { - *cn = Some(names.cn); - - return true; - } - } - - false - } - - /// Extract DNS names out of an X.509 certificate. - pub fn get_certificate_names(certificate: &PhpMixed) -> Option { - let info: Option<&PhpMixed> = if certificate.as_array().is_some() { - Some(certificate) - } else if CaBundle::is_openssl_parse_safe() { - // TODO(phase-c): openssl_x509_parse on a PEM string certificate. - todo!("openssl_x509_parse for non-array certificates") - } else { - None - }; - - let info = info?.as_array()?; - - let common_name = info - .get("subject") - .and_then(|s| s.as_array()) - .and_then(|s| s.get("commonName")) - .and_then(|c| c.as_string()); - - let common_name = strtolower(common_name?); - let mut subject_alt_names: Vec = Vec::new(); - - if let Some(san) = info - .get("extensions") - .and_then(|e| e.as_array()) - .and_then(|e| e.get("subjectAltName")) - .and_then(|s| s.as_string()) - { - let split = Preg::split(php_regex!("{\\s*,\\s*}"), san); - subject_alt_names = split - .into_iter() - .filter_map(|name| { - if name.starts_with("DNS:") { - Some(strtolower(<rim(&substr(&name, 4, None), None))) - } else { - None - } - }) - .collect(); - } - - Some(CertificateNames { - cn: common_name, - san: subject_alt_names, - }) - } - - /// Get the certificate pin. - pub fn get_certificate_fingerprint(_certificate: &str) -> String { - todo!("openssl public key extraction and sha1 fingerprint") - } - - /// Test if it is safe to use the PHP function openssl_x509_parse(). - pub fn is_openssl_parse_safe() -> bool { - CaBundle::is_openssl_parse_safe() - } - - /// Convert certificate name into matching function. - fn cert_name_matcher(cert_name: &str) -> Option bool>> { - let wildcards = substr_count(cert_name, "*"); - - if wildcards == 0 { - // Literal match. - let cert_name = cert_name.to_string(); - return Some(Box::new(move |hostname: &str| hostname == cert_name)); - } - - if wildcards == 1 { - let components: Vec<&str> = cert_name.split('.').collect(); - - if components.len() < 3 { - // Must have 3+ components - return None; - } - - let first_component = components[0]; - - // Wildcard must be the last character. - if !first_component.ends_with('*') { - return None; - } - - let mut wildcard_regex = preg_quote(cert_name, None); - wildcard_regex = str_replace("\\*", "[a-z0-9-]+", &wildcard_regex); - let wildcard_regex = format!("{{^{}$}}", wildcard_regex); - - return Some(Box::new(move |hostname: &str| { - Preg::is_match(&wildcard_regex, hostname) - })); - } - - None - } -} -- cgit v1.3.1-4-g156e