~zethra/pygmisrv

a0a93e039565c9771dfa582fbbb403f425b9ae1c — Ben Aaron Goldberg 16 days ago 236c110 master
Add cert generation
1 files changed, 53 insertions(+), 3 deletions(-)

M src/tls.rs
M src/tls.rs => src/tls.rs +53 -3
@@ 5,8 5,6 @@
// This Source Code Form is "Incompatible With Secondary Licenses", as
// defined by the Mozilla Public License, v. 2.0.

#![allow(unused_imports)]

use anyhow::{anyhow, Context, Result};
use async_rustls::rustls::internal::msgs::handshake::DigitallySignedStruct;
use async_rustls::rustls::{


@@ 25,7 23,7 @@ use std::time::{Duration, UNIX_EPOCH};
use std::{
    fs::{self, File},
    io::BufReader,
    path::{Path, PathBuf},
    path::Path,
    sync::Arc,
};



@@ 125,6 123,9 @@ pub fn load_config(
    cert_path: &Path,
    key_path: &Path,
) -> Result<ServerConfig> {
    if !cert_path.exists() || !key_path.exists() {
        gen_cert_and_key(domain, cert_path, key_path)?;
    }
    let cert_chain = load_cert(cert_path)?;
    let key = load_key(key_path)?;
    let signing_key = sign::any_supported_type(&key)


@@ 144,3 145,52 @@ pub fn load_config(

    Ok(config)
}

fn gen_cert_and_key(
    domain: &str,
    cert_path: &Path,
    key_path: &Path,
) -> Result<()> {
    log::debug!("Generating cert+key for {}", domain);
    make_dir_for_file(cert_path)?;
    make_dir_for_file(key_path)?;
    let mut params = CertificateParams::new(vec![domain.to_owned()]);
    let mut distinguished_name = DistinguishedName::new();
    distinguished_name.push(DnType::CommonName, domain);
    // distinguished_name.push(DnType::OrganizationName, &CONF.organization);
    params.distinguished_name = distinguished_name;
    let not_before = UNIX_EPOCH.elapsed().context("Time is broken")?;
    // Plus 5 years
    let not_after = not_before + Duration::from_secs(5 * 365 * 24 * 60 * 60);
    params.not_before = DateTime::<Utc>::from_utc(
        NaiveDateTime::from_timestamp(not_before.as_secs() as i64, 0),
        Utc,
    );
    params.not_after = DateTime::<Utc>::from_utc(
        NaiveDateTime::from_timestamp(not_after.as_secs() as i64, 0),
        Utc,
    );
    let cert = GenCert::from_params(params).with_context(|| {
        format!("Error generating cert for domain: `{}`", domain)
    })?;
    let crt = cert.serialize_pem().with_context(|| {
        format!("Error serializing cert for domain: `{}`", domain)
    })?;
    let key = cert.serialize_private_key_pem();

    fs::write(&cert_path, crt).with_context(|| {
        format!("Error writing cert for domain: `{}`", domain)
    })?;
    fs::write(&key_path, key)
        .with_context(|| format!("Error write key for domain: `{}`", domain))?;
    Ok(())
}

fn make_dir_for_file(file_path: &Path) -> Result<()> {
    if let Some(dir_path) = file_path.parent() {
        if !dir_path.exists() {
            fs::create_dir_all(dir_path)?;
        }
    }
    Ok(())
}