j7s-ca/src/bin/mk_ca.rs

67 lines
1.9 KiB
Rust

#![feature(duration_constructors)]
use anyhow::Result;
use clap::Parser;
use rcgen::{
BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyPair, KeyUsagePurpose,
};
use std::fs;
use time::{Duration, OffsetDateTime};
/// Generate a Certificate Authority with some opinionated
/// options selected.
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// Name of the organization for the CA.
#[arg(long)]
org_name: String,
/// Days for CA to valid for.
#[arg(long, default_value = "3650")]
valid_length: i64,
/// Output directory for artifacts.
#[arg(long, short)]
output: String,
}
fn main() -> Result<()> {
let args = Args::parse();
let mut params: CertificateParams = Default::default();
let earliest_date = OffsetDateTime::now_utc();
let latest_date = OffsetDateTime::now_utc()
.checked_add(Duration::days(args.valid_length))
.ok_or(anyhow::Error::msg("Could not get date."))?;
params.not_before = earliest_date;
params.not_after = latest_date;
params.distinguished_name = DistinguishedName::new();
params
.distinguished_name
.push(DnType::OrganizationName, args.org_name);
params.distinguished_name.push(DnType::CommonName, "CA");
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
params.key_usages.push(KeyUsagePurpose::DigitalSignature);
params.key_usages.push(KeyUsagePurpose::KeyCertSign);
params.key_usages.push(KeyUsagePurpose::CrlSign);
let key_pair = KeyPair::generate()?;
let cert = params.self_signed(&key_pair)?;
let pem_serialized = cert.pem();
println!("Saving artifacts.");
fs::create_dir_all(&args.output)?;
fs::write(
format!("{}/cert.pem", &args.output),
pem_serialized.as_bytes(),
)?;
fs::write(
format!("{}/key.pem", &args.output),
key_pair.serialize_pem().as_bytes(),
)?;
Ok(())
}