Skip to main content

size_features/
size_features.rs

1//! What each optional simoom-tls feature adds to a binary that uses it (report rows of
2//! `scripts/size.sh`). A TLS server that, depending on the features compiled in, loads its key
3//! material through `SslContextParameters` (`keystore`, `pkcs12`, `jks`), staples an OCSP
4//! response and checks client certificates against CRLs (`revocation`), negotiates TLS 1.2
5//! (`tls12`), and serves one connection through the blocking adapter (`blocking`). Without
6//! those features it is the plain `size_server` path. Built with the `dist` profile:
7//!
8//! `cargo build -p simoom-tls --profile dist --no-default-features --features rsa,tls12,pkcs12 --example size_features`
9
10use simoom_tls::{ServerConfig, ServerConnection};
11use std::io::{Read, Write};
12use std::sync::Arc;
13
14#[allow(unused_variables, unused_mut)]
15fn config(args: &[String]) -> ServerConfig {
16    let cert = std::fs::read(&args[1]).expect("certificate");
17    let key = std::fs::read(&args[2]).expect("key");
18    #[cfg(feature = "keystore")]
19    let mut cfg = {
20        let p = simoom_tls::params::SslContextParameters::new()
21            .key_pair_pem(&String::from_utf8_lossy(&cert), &String::from_utf8_lossy(&key))
22            .key_password(args.get(3).map(|s| s.as_str()).unwrap_or(""));
23        let p = match args.get(4) {
24            // a key store file instead (PKCS#12 / JKS / JCEKS, detected)
25            Some(ks) => simoom_tls::params::SslContextParameters::new().key_store(ks, args.get(3).map(|s| s.as_str()).unwrap_or("")),
26            None => p,
27        };
28        p.server_config().expect("server config")
29    };
30    #[cfg(not(feature = "keystore"))]
31    let mut cfg = ServerConfig::from_pem(&cert, &key).expect("server config");
32    #[cfg(feature = "revocation")]
33    {
34        let staple = simoom_tls::revocation::StapleSource::new();
35        if let Some(der) = args.get(5).and_then(|p| std::fs::read(p).ok()) {
36            staple.set(Some(der));
37        }
38        cfg.ocsp_staple = Some(staple);
39        if let Some(crl) = args.get(6).and_then(|p| std::fs::read(p).ok()) {
40            let mut pol = simoom_tls::revocation::RevocationPolicy::new();
41            pol.add_crls(&crl).expect("CRL");
42            cfg.client_revocation = Some(pol);
43        }
44    }
45    cfg.with_alpn(&[b"h2", b"http/1.1"])
46}
47
48fn main() {
49    let args: Vec<String> = std::env::args().collect();
50    if args.len() < 3 {
51        eprintln!("usage: size_features CERT.pem KEY.pem [PASSWORD [KEYSTORE [OCSP.der [CRL]]]] < client_flight");
52        std::process::exit(2);
53    }
54    let cfg = Arc::new(config(&args));
55    #[cfg(feature = "blocking")]
56    if std::env::var("SIZE_FEATURES_LISTEN").is_ok() {
57        let l = std::net::TcpListener::bind("127.0.0.1:0").expect("bind");
58        let (tcp, _) = l.accept().expect("accept");
59        let mut s = simoom_tls::blocking::accept(tcp, cfg).expect("handshake");
60        let mut buf = [0u8; 1024];
61        let n = s.read(&mut buf).expect("read");
62        s.write_all(&buf[..n]).expect("write");
63        return;
64    }
65    let mut conn = ServerConnection::new(cfg);
66    let mut input = Vec::new();
67    std::io::stdin().read_to_end(&mut input).expect("stdin");
68    conn.read_tls(&input);
69    if let Err(e) = conn.process_new_packets() {
70        eprintln!("{e:?}");
71    }
72    let out = conn.tls_output().to_vec();
73    conn.consume_tls_output(out.len());
74    std::io::stdout().write_all(&out).expect("stdout");
75    let mut buf = [0u8; 1024];
76    let n = conn.read_plaintext(&mut buf);
77    std::io::stdout().write_all(&buf[..n]).expect("stdout");
78}