# rustls-mitm
SNI-based certificate resolver for [rustls](https://github.com/rustls/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`](https://docs.rs/rustls/latest/rustls/server/trait.ResolvesServerCert.html) 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
```rust,ignore
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
```rust,ignore
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):
```rust,ignore
let resolver = MitmCertResolver::with_cache_capacity(ca, 4096);
let config = resolver.into_server_config();
```