openpgp-key-janitor/src/main.rs
2023-05-31 18:13:49 +02:00

73 lines
2.2 KiB
Rust

use anyhow::{Context, Result};
use sequoia_openpgp::{
cert::CertBuilder,
packet::{signature::SignatureBuilder, Signature},
types::{KeyFlags, SignatureType},
Cert,
};
use spec::{KeyFlag, Spec};
mod paths;
mod setup;
mod spec;
fn main() -> Result<()> {
let (paths, spec) = crate::setup::setup().context("Failed to setup application")?;
let (cert, rev) = paths.load()?.ok_or(()).or_else(|()| generate_new(spec))?;
paths
.write(cert, rev)
.context("Failed to store certificate!")?;
Ok(())
}
fn generate_new(spec: Spec) -> Result<(Cert, Signature)> {
let mut builder = CertBuilder::new()
.set_primary_key_flags(
spec.primary
.flags
.iter()
.fold(KeyFlags::empty(), KeyFlag::fold),
)
.set_validity_period(
spec.primary
.expiry
.validity_period
.or(spec.expiry.validity_period),
)
.set_cipher_suite(spec.primary.cipher_suite);
for sub_key in spec.subs {
builder = builder.add_subkey_with(
sub_key.flags.iter().fold(KeyFlags::empty(), KeyFlag::fold),
sub_key
.expiry
.validity_period
.or(spec.expiry.validity_period),
Some(sub_key.cipher_suite),
SignatureBuilder::new(SignatureType::SubkeyBinding),
)?;
}
for user_id in spec.user_ids {
let mut sig_builder = SignatureBuilder::new(SignatureType::PositiveCertification);
for (key, value) in user_id.notation {
sig_builder = sig_builder
.add_notation(key, value, None, false)
.context(format!(
"Failed to add notation to signature builder for {}",
&user_id.value
))?;
}
builder = builder
.add_userid_with(user_id.value.clone(), sig_builder)
.context(format!(
"Failed to add user ID {} to certificate builder",
&user_id.value
))?;
}
builder
.generate()
.context("Failed to generate certificate!")
}