rustls-mitm 0.1.0

SNI-based certificate resolver for rustls that generates per-host TLS certificates on the fly, enabling man-in-the-middle TLS interception
Documentation

rustls-mitm

SNI-based certificate resolver for rustls that generates per-host TLS certificates on the fly, enabling man-in-the-middle TLS interception.

How it works

rustls-mitm provides a ResolvesServerCert implementation that intercepts TLS handshakes: when a client connects, the resolver reads the hostname from the SNI extension in the ClientHello, generates a leaf certificate for that hostname signed by your CA, and caches it in an LRU cache for subsequent connections.

This is runtime-agnostic and crypto-provider-agnostic — it works with any async runtime (tokio, async-std, etc.) and any rustls CryptoProvider (ring, aws-lc-rs, etc.).

Usage

use std::sync::Arc;
use rustls_mitm::{CertificateAuthority, MitmCertResolver};
use tokio_rustls::TlsAcceptor;

// Load or generate a CA
let ca = CertificateAuthority::from_pem_files("ca-cert.pem", "ca-key.pem")?;

// Build a rustls ServerConfig with the MITM resolver
let mut config = MitmCertResolver::new(ca).into_server_config();

// Set ALPN if needed (e.g. for HTTP)
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];

// Use with any TLS acceptor — tokio-rustls, async-rustls, sync rustls, etc.
let acceptor = TlsAcceptor::from(Arc::new(config));

Generating a CA

use rustls_mitm::CertificateAuthority;

let ca = CertificateAuthority::generate()?;
ca.to_pem_files("ca-cert.pem", "ca-key.pem")?;

Clients must trust this CA certificate for interception to work transparently.

Custom cache capacity

The resolver caches generated certificates in an LRU cache (default: 1024 entries):

let resolver = MitmCertResolver::with_cache_capacity(ca, 4096);
let config = resolver.into_server_config();