feat(renew-cmd): added

This commit is contained in:
2023-07-09 20:03:20 +02:00
parent 591858ef05
commit cbb99138a9
7 changed files with 109 additions and 42 deletions

View File

@@ -11,6 +11,7 @@ anyhow = "1.0.66"
async-trait = "0.1.59"
axum = { version = "0.6.1" }
axum-extra = { version = "0.4.1", features = ["typed-routing"] }
chrono = "0.4.26"
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.148", features = ["derive"] }
ssh-key = { version = "0.6.0-pre.0", features = ["ed25519", "p256", "p384", "rsa"] }
@@ -18,6 +19,7 @@ thiserror = "1.0.37"
tokio = { version = "1.22.0", features = ["io-std", "test-util", "tracing", "macros", "fs"] }
tracing = { version = "0.1.37", features = ["release_max_level_debug"] }
tracing-subscriber = "0.3.16"
shell-escape = "0.1.5"
[dev-dependencies]
tempfile = "3.3.0"

View File

@@ -1,6 +1,8 @@
mod certs;
mod renew;
mod routes;
mod util;
pub use certs::*;
pub use renew::*;
pub use routes::*;

49
common/src/renew.rs Normal file
View File

@@ -0,0 +1,49 @@
use std::borrow::Cow;
use std::time::UNIX_EPOCH;
use chrono::Duration;
use shell_escape::escape;
use ssh_key::Certificate;
/// Generates an command to renew the given certs
pub fn renew_command(cert: &Certificate, ca_path: &str, file_name: Option<&str>) -> String {
let validity = cert
.valid_before_time()
.duration_since(cert.valid_after_time())
.unwrap_or(Duration::zero().to_std().unwrap());
let expiry = cert.valid_before_time().checked_add(validity).unwrap();
let expiry_date = expiry.duration_since(UNIX_EPOCH).unwrap();
let host_key = if cert.cert_type().is_host() {
" -h"
} else {
""
};
let opts = cert
.critical_options()
.iter()
.map(|(opt, val)| {
if val.is_empty() {
opt.clone()
} else {
format!("{opt}={val}")
}
})
.map(|arg| format!("-O {}", escape(arg.into())))
.collect::<Vec<_>>()
.join(" ");
let opts = opts.trim();
let renew_command = format!(
"ssh-keygen -s {ca_path} {host_key} -I {} -n {} -z {} -V {:#x}:{:#x} {opts} {}",
escape(cert.key_id().into()),
escape(cert.valid_principals().join(",").into()),
cert.serial() + 1,
cert.valid_after(),
expiry_date.as_secs(),
escape(
file_name
.map(Cow::Borrowed)
.unwrap_or_else(|| escape(format!("{}.pub", cert.key_id()).into()))
)
);
renew_command
}