Skip to main content

ling_http/
tls.rs

1use axum_server::tls_rustls::RustlsConfig;
2#[cfg(feature = "dev-certs")]
3use std::net::SocketAddr;
4use std::path::Path;
5
6/// rustls 0.23 requires a process-wide crypto provider to be installed
7/// before any `ServerConfig` is built. We use `ring` (not `aws-lc-rs`,
8/// axum-server's default) since it builds without needing cmake/NASM.
9/// Safe to call more than once — a second install just fails silently.
10fn ensure_crypto_provider() {
11    let _ = rustls::crypto::ring::default_provider().install_default();
12}
13
14/// Loads a TLS server config from a PEM-encoded certificate + private key
15/// pair on disk. This is the path for real deployments.
16pub async fn load_rustls_config(
17    cert_pem: impl AsRef<Path>,
18    key_pem: impl AsRef<Path>,
19) -> anyhow::Result<RustlsConfig> {
20    ensure_crypto_provider();
21    RustlsConfig::from_pem_file(cert_pem, key_pem)
22        .await
23        .map_err(|e| anyhow::anyhow!("loading TLS cert/key: {e}"))
24}
25
26#[cfg(feature = "dev-certs")]
27pub struct TlsMaterial {
28    pub config: RustlsConfig,
29    /// PEM-encoded self-signed cert, in case a caller wants to print it or
30    /// write it to disk so a browser/curl can be told to trust it.
31    pub cert_pem: String,
32}
33
34/// Generates a throwaway self-signed certificate covering `localhost` and
35/// the given address's IP. **Local development only** — nothing trusts this
36/// cert by default.
37#[cfg(feature = "dev-certs")]
38pub async fn generate_dev_cert(addr: SocketAddr) -> anyhow::Result<TlsMaterial> {
39    ensure_crypto_provider();
40    let names = vec!["localhost".to_string(), addr.ip().to_string()];
41    let rcgen::CertifiedKey { cert, key_pair } = rcgen::generate_simple_self_signed(names)?;
42    let cert_pem = cert.pem();
43    let key_pem = key_pair.serialize_pem();
44
45    let config = RustlsConfig::from_pem(cert_pem.clone().into_bytes(), key_pem.into_bytes())
46        .await
47        .map_err(|e| anyhow::anyhow!("building dev TLS config: {e}"))?;
48
49    Ok(TlsMaterial { config, cert_pem })
50}