certifiably/
lib.rs

1use rcgen::{CertifiedKey, generate_simple_self_signed};
2use std::error::Error;
3use std::fs::File;
4use std::io::Write;
5use std::path::Path;
6
7// ?? will need to have real cert management likely using https://crates.io/crates/instant-acme
8
9/// writes crt.pem and key.pem to directory
10pub fn generate_self_signed_localhost_certs(
11    cert_dir_path: impl AsRef<Path>,
12) -> Result<(), Box<dyn Error>> {
13    let cert_path = cert_dir_path.as_ref().join("crt.pem");
14    let key_path = cert_dir_path.as_ref().join("key.pem");
15
16    if cert_path.exists() && key_path.exists() {
17        tracing::debug!("localhost cert already generated!");
18        return Ok(());
19    }
20
21    std::fs::create_dir_all(&cert_dir_path)?;
22
23    let subject_alt_names = vec!["localhost".to_string()];
24
25    let CertifiedKey { cert, signing_key } = match generate_simple_self_signed(subject_alt_names) {
26        Ok(ck) => {
27            tracing::info!("successfully generated localhost cert!");
28            ck
29        }
30        Err(err) => {
31            tracing::error!("failed to create localhost cert.");
32            return Err(err.into());
33        }
34    };
35
36    let mut cert_file = File::create(cert_path)?;
37    let mut key_file = File::create(key_path)?;
38
39    cert_file.write_all(cert.pem().as_bytes())?;
40    key_file.write_all(signing_key.serialize_pem().as_bytes())?;
41
42    Ok(())
43}