1use rcgen::{generate_simple_self_signed, CertifiedKey};
4use std::{fs, path::PathBuf, io::{Error, Result, Write}};
5
6pub const DEFAULT_CERT_FOLDER: &str = "cert";
8
9pub const DEFAULT_CERT_FILE_NAME: &str = "dev-cert.pem";
11
12pub const DEFAULT_KEY_FILE_NAME: &str = "dev-key.pem";
14
15#[cfg(target_os = "windows")]
17pub const DEV_CERT_NAMES: &[&str] = &["localhost"];
18#[cfg(not(target_os = "windows"))]
20pub const DEV_CERT_NAMES: &[&str] = &["localhost", "0.0.0.0"];
21
22#[inline]
24pub fn generate(names: impl Into<Vec<String>>) -> Result<()> {
25 let CertifiedKey { cert, signing_key } = generate_simple_self_signed(names)
26 .map_err(|err| Error::other(format!("{:?}", err)))?;
27 fs::create_dir_all(DEFAULT_CERT_FOLDER)?;
28 fs::write(get_cert_path(), cert.pem())?;
29 fs::write(get_signing_key_path(), signing_key.serialize_pem())?;
30 Ok(())
31}
32
33#[inline]
35pub fn ask_generate() -> Result<bool> {
36 print!("Dev certificate not found. Generate new one? (y/n): ");
37 std::io::stdout().flush()?;
38
39 let mut answer = String::new();
40 std::io::stdin().read_line(&mut answer)?;
41 Ok(answer.trim().eq_ignore_ascii_case("y"))
42}
43
44#[inline]
46pub fn dev_cert_exists() -> bool {
47 get_cert_path().exists() &&
48 get_signing_key_path().exists()
49}
50
51#[inline]
53pub fn get_cert_path() -> PathBuf {
54 PathBuf::from(DEFAULT_CERT_FOLDER)
55 .join(DEFAULT_CERT_FILE_NAME)
56}
57
58#[inline]
60pub fn get_signing_key_path() -> PathBuf {
61 PathBuf::from(DEFAULT_CERT_FOLDER)
62 .join(DEFAULT_KEY_FILE_NAME)
63}