volga_dev_cert/
lib.rs

1//! A Rust library for generating self-signed TLS certificates for local development.
2
3use rcgen::{generate_simple_self_signed, CertifiedKey};
4use std::{fs, path::PathBuf, io::{Error, Result, Write}};
5
6pub const DEFAULT_CERT_FOLDER: &str = "cert";
7pub const DEFAULT_CERT_FILE_NAME: &str = "dev-cert.pem";
8pub const DEFAULT_KEY_FILE_NAME: &str = "dev-key.pem";
9
10#[cfg(target_os = "windows")]
11pub const DEV_CERT_NAMES: &[&str] = &["localhost"];
12#[cfg(not(target_os = "windows"))]
13pub const DEV_CERT_NAMES: &[&str] = &["localhost", "0.0.0.0"];
14
15/// Generates self-signed certificate and saves them into `./cert` folder
16#[inline]
17pub fn generate(names: impl Into<Vec<String>>) -> Result<()> {
18    let CertifiedKey { cert, signing_key } = generate_simple_self_signed(names)
19        .map_err(|err| Error::other(format!("{:?}", err)))?;
20    fs::create_dir_all(DEFAULT_CERT_FOLDER)?;
21    fs::write(get_cert_path(), cert.pem())?;
22    fs::write(get_signing_key_path(), signing_key.serialize_pem())?;
23    Ok(())
24}
25
26/// Sends the message to the `stdio` that asks whether to create dev TLS certificate of not
27#[inline]
28pub fn ask_generate() -> Result<bool> {
29    print!("Dev certificate not found. Generate new one? (y/n): ");
30    std::io::stdout().flush()?;
31
32    let mut answer = String::new();
33    std::io::stdin().read_line(&mut answer)?;
34    Ok(answer.trim().eq_ignore_ascii_case("y"))
35}
36
37/// Checks whether dev certificate exists
38#[inline]
39pub fn dev_cert_exists() -> bool {
40    get_cert_path().exists() && 
41    get_signing_key_path().exists()
42}
43
44#[inline]
45pub fn get_cert_path() -> PathBuf {
46    PathBuf::from(DEFAULT_CERT_FOLDER)
47        .join(DEFAULT_CERT_FILE_NAME)
48}
49
50#[inline]
51pub fn get_signing_key_path() -> PathBuf {
52    PathBuf::from(DEFAULT_CERT_FOLDER)
53        .join(DEFAULT_KEY_FILE_NAME)
54}