reactive_graph/tooling/instances/certificates/
mod.rs

1use crate::tooling::instances::certificates::args::GenerateCertificateArgs;
2use rcgen::Ia5String;
3use rcgen::SanType;
4use rustls_cert_gen::CertificateBuilder;
5use std::path::Path;
6use std::path::PathBuf;
7
8pub mod args;
9
10pub const KEYS_DIR_NAME: &str = "keys";
11
12pub const DEFAULT_CERTIFICATE_FILE_NAME: &str = "cert";
13pub const DEFAULT_CA_FILE_NAME: &str = "ca";
14pub const PUBLIC_KEY_FILE_NAME: &str = "cert.pem";
15
16pub const PRIVATE_KEY_FILE_NAME: &str = "cert.key.pem";
17
18pub fn handle_generate_certificate(instance_dir: &Path, args: GenerateCertificateArgs) -> anyhow::Result<()> {
19    let keys_dir = get_keys_dir(instance_dir);
20    generate_certificate(&keys_dir, args)?;
21    Ok(())
22}
23
24pub fn generate_certificate(keys_dir: &Path, args: GenerateCertificateArgs) -> anyhow::Result<()> {
25    let country_name = args.country_name.unwrap_or(String::from("de"));
26    let organization_name = args.organization_name.unwrap_or(String::from("Reactive Graph"));
27    let common_name = args.common_name.unwrap_or(String::from("localhost"));
28
29    let ca = CertificateBuilder::new()
30        .certificate_authority()
31        .country_name(&country_name)?
32        .organization_name(&organization_name)
33        .build()?;
34    let subject_alt_names = vec![SanType::DnsName(Ia5String::try_from(common_name.clone())?)];
35    CertificateBuilder::new()
36        .end_entity()
37        .common_name(&common_name)
38        .subject_alternative_names(subject_alt_names)
39        .build(&ca)?
40        .serialize_pem()
41        .write(keys_dir, DEFAULT_CERTIFICATE_FILE_NAME)?;
42    ca.serialize_pem().write(keys_dir, DEFAULT_CA_FILE_NAME)?;
43    Ok(())
44}
45
46pub fn get_keys_dir(instance_dir: &Path) -> PathBuf {
47    let mut keys_dir = instance_dir.to_owned();
48    keys_dir.push(KEYS_DIR_NAME);
49    keys_dir
50}