bolt-web 0.2.9

⚡ A high-performance, minimalist web framework for Rust, inspired by Express.js and Gin.
Documentation
use std::{
    io::{
        self, Cursor,
        ErrorKind::{InvalidData, InvalidInput},
    },
    sync::Arc,
};

use rustls::pki_types::{CertificateDer, PrivateKeyDer};
use rustls::{ServerConfig, version::TLS13};
use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys};

pub fn tls_config(cert_path: &str, key_path: &str) -> io::Result<Arc<ServerConfig>> {
    let certs = load_certs(cert_path)?;
    let key = load_private_key(key_path)?;

    let mut config = ServerConfig::builder_with_protocol_versions(&[&TLS13])
        .with_no_client_auth()
        .with_single_cert(certs, key)
        .map_err(|e| io::Error::new(InvalidInput, e.to_string()))?;

    config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];

    Ok(Arc::new(config))
}

fn load_certs(path: &str) -> io::Result<Vec<CertificateDer<'static>>> {
    let input = std::fs::read(path)?;
    let mut cursor = Cursor::new(input);

    let mut out = Vec::new();
    for cert in certs(&mut cursor) {
        out.push(CertificateDer::from(cert?));
    }

    Ok(out)
}

fn load_private_key(path: &str) -> io::Result<PrivateKeyDer<'static>> {
    let input = std::fs::read(path)?;

    let mut cursor = Cursor::new(&input);
    for key in pkcs8_private_keys(&mut cursor) {
        let pk = key?;
        return Ok(PrivateKeyDer::from(pk));
    }

    let mut cursor = Cursor::new(&input);
    for key in rsa_private_keys(&mut cursor) {
        let rk = key?;
        return Ok(PrivateKeyDer::from(rk));
    }

    Err(io::Error::new(InvalidData, "no valid private key found"))
}