//! introducer add subcommand use anyhow::Result; use sequoia_cert_store::Store; use sequoia_openpgp::cert::ValidCert; use sequoia_openpgp::cert; use sequoia_openpgp::parse::Parse; use sequoia_openpgp::{Fingerprint, KeyHandle}; use sequoia_openpgp::types::RevocationStatus; use crate::cli::cli_args::IntroducerAddCommand; use crate::commands::CommandError; use crate::common::crypto; use crate::config::HuskConfigContainer; use crate::types::husk_context::HuskContext; use crate::types::introducer::Introducer; pub async fn dispatch(cmd: IntroducerAddCommand, config: HuskConfigContainer) -> Result<()> { let context = HuskContext::new(&config.into())?; let policy = &context.policy; let cert_store = &context.cert_store; if let Some(cert_file) = cmd.cert_file { let c = cert::Cert::from_file(cert_file)?; let vc = c.with_policy(policy, None)?; // guards if vc.alive().is_err() { return Err(CommandError::CertNotAlive(vc.fingerprint()).into()); } if matches!(vc.revocation_status(), RevocationStatus::Revoked(_)) { return Err(CommandError::CertRevoked(vc.fingerprint()).into()); } if !crypto::can_certify(&vc) { return Err(CommandError::CertNotUsable(vc.fingerprint()).into()); } Introducer::create(&context, &vc, cmd.domains)?; } else if let Some(cert) = cmd.cert { let fpr = Fingerprint::from_hex(cert.as_str())?; let certs = cert_store.lookup_by_cert(&KeyHandle::from(&fpr)) .map_err(|_| CommandError::CertNotFound(fpr.clone()))?; let certs: Vec = certs.iter() .filter_map(|c| c.with_policy(policy, None).ok() ) .filter(|vc| crypto::can_certify(vc)) .collect(); if let Some(cert) = certs.first() { Introducer::create(&context, cert, cmd.domains)?; } else { return Err(CommandError::CertNotUsable(fpr).into()); } } Ok(()) }