2023-05-30 21:15:22 +00:00
|
|
|
use anyhow::{Context, Result};
|
2023-05-30 17:34:57 +00:00
|
|
|
|
|
|
|
use sequoia_openpgp::{
|
|
|
|
cert::CertBuilder,
|
2023-05-31 15:27:45 +00:00
|
|
|
packet::{signature::SignatureBuilder, Signature},
|
2023-05-30 17:34:57 +00:00
|
|
|
types::{KeyFlags, SignatureType},
|
2023-05-31 15:27:45 +00:00
|
|
|
Cert,
|
2023-05-30 17:34:57 +00:00
|
|
|
};
|
|
|
|
|
2023-05-31 15:27:45 +00:00
|
|
|
use spec::{KeyFlag, Spec};
|
2023-05-30 17:34:57 +00:00
|
|
|
|
2023-05-30 21:15:22 +00:00
|
|
|
mod paths;
|
|
|
|
mod setup;
|
|
|
|
mod spec;
|
2023-05-30 17:34:57 +00:00
|
|
|
|
|
|
|
fn main() -> Result<()> {
|
2023-05-30 21:15:22 +00:00
|
|
|
let (paths, spec) = crate::setup::setup().context("Failed to setup application")?;
|
2023-05-31 15:27:45 +00:00
|
|
|
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)> {
|
2023-05-30 17:34:57 +00:00
|
|
|
let mut builder = CertBuilder::new()
|
2023-05-30 21:15:22 +00:00
|
|
|
.set_primary_key_flags(
|
|
|
|
spec.primary
|
|
|
|
.flags
|
|
|
|
.iter()
|
|
|
|
.fold(KeyFlags::empty(), KeyFlag::fold),
|
|
|
|
)
|
2023-05-30 17:34:57 +00:00
|
|
|
.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(
|
2023-05-30 21:15:22 +00:00
|
|
|
sub_key.flags.iter().fold(KeyFlags::empty(), KeyFlag::fold),
|
2023-05-30 17:34:57 +00:00
|
|
|
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 {
|
2023-05-30 21:15:22 +00:00
|
|
|
sig_builder = sig_builder
|
|
|
|
.add_notation(key, value, None, false)
|
|
|
|
.context(format!(
|
|
|
|
"Failed to add notation to signature builder for {}",
|
|
|
|
&user_id.value
|
|
|
|
))?;
|
2023-05-30 17:34:57 +00:00
|
|
|
}
|
2023-05-30 21:15:22 +00:00
|
|
|
builder = builder
|
|
|
|
.add_userid_with(user_id.value.clone(), sig_builder)
|
|
|
|
.context(format!(
|
|
|
|
"Failed to add user ID {} to certificate builder",
|
|
|
|
&user_id.value
|
|
|
|
))?;
|
2023-05-30 17:34:57 +00:00
|
|
|
}
|
|
|
|
|
2023-05-31 15:27:45 +00:00
|
|
|
builder
|
2023-05-30 21:15:22 +00:00
|
|
|
.generate()
|
2023-05-31 15:27:45 +00:00
|
|
|
.context("Failed to generate certificate!")
|
2023-05-30 17:34:57 +00:00
|
|
|
}
|