1use 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#[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#[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#[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}