66 lines
2.4 KiB
Rust
66 lines
2.4 KiB
Rust
use anyhow::{Context, Result};
|
|
use rcgen::{CertificateParams, DistinguishedName, DnType, KeyPair, SanType};
|
|
use std::net::IpAddr;
|
|
use std::path::Path;
|
|
|
|
pub fn issue_node_cert(
|
|
node_id: &str,
|
|
hostname: &str,
|
|
ip: &str,
|
|
ca_cert_path: Option<&str>,
|
|
ca_key_path: Option<&str>,
|
|
) -> Result<(String, String)> {
|
|
let mut dns_names = Vec::new();
|
|
if !node_id.trim().is_empty() {
|
|
dns_names.push(node_id.to_string());
|
|
}
|
|
if !hostname.trim().is_empty() && hostname != node_id {
|
|
dns_names.push(hostname.to_string());
|
|
}
|
|
if dns_names.is_empty() {
|
|
dns_names.push("photoncloud-node".to_string());
|
|
}
|
|
|
|
let mut params =
|
|
CertificateParams::new(dns_names).context("failed to create certificate params")?;
|
|
let mut distinguished_name = DistinguishedName::new();
|
|
if !node_id.trim().is_empty() {
|
|
distinguished_name.push(DnType::CommonName, node_id);
|
|
}
|
|
params.distinguished_name = distinguished_name;
|
|
|
|
if let Ok(ip_addr) = ip.parse::<IpAddr>() {
|
|
params.subject_alt_names.push(SanType::IpAddress(ip_addr));
|
|
}
|
|
|
|
let key_pair = KeyPair::generate().context("failed to generate TLS key pair")?;
|
|
|
|
if let (Some(ca_cert_path), Some(ca_key_path)) = (ca_cert_path, ca_key_path) {
|
|
let ca_cert_pem = std::fs::read_to_string(Path::new(ca_cert_path))
|
|
.with_context(|| format!("failed to read CA cert from {}", ca_cert_path))?;
|
|
let ca_key_pem = std::fs::read_to_string(Path::new(ca_key_path))
|
|
.with_context(|| format!("failed to read CA key from {}", ca_key_path))?;
|
|
|
|
let ca_key_pair =
|
|
KeyPair::from_pem(&ca_key_pem).context("failed to parse CA key pair from PEM")?;
|
|
let ca_params = CertificateParams::from_ca_cert_pem(&ca_cert_pem)
|
|
.context("failed to parse CA certificate")?;
|
|
let ca_cert = ca_params
|
|
.self_signed(&ca_key_pair)
|
|
.context("failed to build CA certificate for signing")?;
|
|
|
|
let cert = params
|
|
.signed_by(&key_pair, &ca_cert, &ca_key_pair)
|
|
.context("failed to sign node certificate")?;
|
|
let cert_pem = cert.pem();
|
|
let key_pem = key_pair.serialize_pem();
|
|
return Ok((cert_pem, key_pem));
|
|
}
|
|
|
|
let cert = params
|
|
.self_signed(&key_pair)
|
|
.context("failed to self-sign node certificate")?;
|
|
let cert_pem = cert.pem();
|
|
let key_pem = key_pair.serialize_pem();
|
|
Ok((cert_pem, key_pem))
|
|
}
|