diff --git a/src/commands/pki.rs b/src/commands/pki.rs index 1a44dc8e..dc3a3891 100644 --- a/src/commands/pki.rs +++ b/src/commands/pki.rs @@ -16,6 +16,7 @@ use wot::store::Store; pub mod link; pub mod output; +pub mod path; pub mod vouch; use crate::cli; @@ -502,79 +503,6 @@ pub fn authenticate<'store, 'rstore>( } } -// For `sq-wot path`. -fn check_path(sq: &Sq, - certification_network: bool, - trust_amount: Option>, - path: cli::pki::PathArg) - -> Result<()> -{ - tracer!(TRACE, "check_path"); - - // Build the network. - let cert_store = match sq.cert_store() { - Ok(Some(cert_store)) => cert_store, - Ok(None) => { - return Err(anyhow::anyhow!("Certificate store has been disabled")); - } - Err(err) => { - return Err(err).context("Opening certificate store"); - } - }; - - let mut n = wot::NetworkBuilder::rooted(cert_store, &*sq.trust_roots()); - if certification_network { - n = n.certification_network(); - } - let q = n.build(); - - let required_amount = - required_trust_amount(trust_amount, certification_network)?; - - let (khs, userid) = (path.certs()?, path.userid()?); - assert!(khs.len() > 0, "guaranteed by clap"); - - let r = q.lint_path(&khs, &userid, required_amount, sq.policy); - - let target_kh = khs.last().expect("have one"); - - let trust_amount = match r { - Ok(path) => { - print_path_header( - target_kh, - &userid, - path.amount(), - required_amount, - ); - print_path(&path, &userid, " ")?; - - let trust_amount = path.amount(); - if trust_amount >= required_amount { - return Ok(()); - } - - trust_amount - } - Err(err) => { - print_path_header( - target_kh, - &userid, - 0, - required_amount, - ); - - print_path_error(err); - - 0 - } - }; - - Err(anyhow::anyhow!( - "The path is not sufficient to authenticate the binding. \ - Its trust amount is {}, but a trust amount of {} is required.", - trust_amount, required_amount)) -} - pub fn dispatch(sq: Sq, cli: cli::pki::Command) -> Result<()> { tracer!(TRACE, "pki::dispatch"); @@ -611,10 +539,8 @@ pub fn dispatch(sq: Sq, cli: cli::pki::Command) -> Result<()> { None, Some(&cert), *show_paths)?, // Authenticates a given path. - Subcommands::Path(PathCommand { - certification_network, trust_amount, path, - }) => check_path( - &sq, *certification_network, *trust_amount, path)?, + Subcommands::Path(command) => + path::path(sq, command)?, Subcommands::Vouch(command) => self::vouch::vouch(sq, command)?, diff --git a/src/commands/pki/path.rs b/src/commands/pki/path.rs new file mode 100644 index 00000000..0e618056 --- /dev/null +++ b/src/commands/pki/path.rs @@ -0,0 +1,84 @@ +use sequoia_openpgp as openpgp; +use openpgp::Result; + +use anyhow::Context; + +use sequoia_wot as wot; + +use crate::Sq; +use crate::cli::pki::PathCommand; +use crate::commands::pki::print_path; +use crate::commands::pki::print_path_error; +use crate::commands::pki::print_path_header; +use crate::commands::pki::required_trust_amount; + +pub fn path(sq: Sq, c: PathCommand) + -> Result<()> +{ + let PathCommand { + certification_network, trust_amount, path, + } = c; + + // Build the network. + let cert_store = match sq.cert_store() { + Ok(Some(cert_store)) => cert_store, + Ok(None) => { + return Err(anyhow::anyhow!("Certificate store has been disabled")); + } + Err(err) => { + return Err(err).context("Opening certificate store"); + } + }; + + let mut n = wot::NetworkBuilder::rooted(cert_store, &*sq.trust_roots()); + if *certification_network { + n = n.certification_network(); + } + let q = n.build(); + + let required_amount = + required_trust_amount(*trust_amount, *certification_network)?; + + let (khs, userid) = (path.certs()?, path.userid()?); + assert!(khs.len() > 0, "guaranteed by clap"); + + let r = q.lint_path(&khs, &userid, required_amount, sq.policy); + + let target_kh = khs.last().expect("have one"); + + let trust_amount = match r { + Ok(path) => { + print_path_header( + target_kh, + &userid, + path.amount(), + required_amount, + ); + print_path(&path, &userid, " ")?; + + let trust_amount = path.amount(); + if trust_amount >= required_amount { + return Ok(()); + } + + trust_amount + } + Err(err) => { + print_path_header( + target_kh, + &userid, + 0, + required_amount, + ); + + print_path_error(err); + + 0 + } + }; + + Err(anyhow::anyhow!( + "The path is not sufficient to authenticate the binding. \ + Its trust amount is {}, but a trust amount of {} is required.", + trust_amount, required_amount)) +}