Skip to main content

phemios_core/
network_tls.rs

1//! Certificate trust for owned or explicitly imported loopback servers; never a global TLS bypass.
2use super::Client;
3use std::sync::Arc;
4
5impl Client {
6    /// Authenticate a trusted, explicitly imported or process-owned loopback identity.
7    /// The exact supplied certificate is the sole HTTPS/WSS trust root; remote overrides are refused.
8    pub fn login_pinned(
9        server: &str,
10        username: &str,
11        password: &str,
12        certificate: &[u8],
13    ) -> Result<Self, String> {
14        let server = super::server_address(server)?;
15        let uri: ureq::http::Uri = server.parse().map_err(|_| "Adresse locale TLS invalide.")?;
16        if uri.scheme_str() != Some("https")
17            || uri.host() != Some("127.0.0.1")
18            || uri.port_u16().is_none_or(|port| port == 0)
19            || certificate.len() > 8192
20        {
21            return Err("L’identité TLS embarquée est réservée à la boucle locale.".into());
22        }
23        let certificate = rustls::pki_types::CertificateDer::from(certificate.to_vec());
24        let mut roots = rustls::RootCertStore::empty();
25        roots
26            .add(certificate.clone())
27            .map_err(|_| "Certificat du moteur local invalide.")?;
28        let tls = rustls::ClientConfig::builder()
29            .with_root_certificates(roots)
30            .with_no_client_auth();
31        let trusted = ureq::tls::Certificate::from_der(certificate.as_ref()).to_owned();
32        let agent = ureq::Agent::config_builder()
33            .timeout_global(Some(std::time::Duration::from_secs(30)))
34            .max_redirects(0)
35            .http_status_as_error(false)
36            .tls_config(
37                ureq::tls::TlsConfig::builder()
38                    .root_certs([trusted].into())
39                    .build(),
40            )
41            .build()
42            .into();
43        Self::authenticate(&server, username, password, agent, Some(Arc::new(tls)))
44    }
45}
46
47#[cfg(test)]
48#[path = "network_tls_tests.rs"]
49mod tests;