diff options
author | Neal H. Walfield <neal@pep.foundation> | 2022-01-21 10:20:08 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2022-01-24 00:43:17 +0100 |
commit | a9e4a9d6863196bab5e2a59034fb97df70e40fd2 (patch) | |
tree | 0ca158561a24f243b1b1b50e7c58f490ee942b2c /sq | |
parent | bebae0525cce6f31a93e0619007cc6b4720f7f53 (diff) |
sq: Improve sq inspect's display of certifications.
- Better distinguish multiple certifications. Previously just the
issuers of the certification were shown and there can be more than
one issuer subpacket per certification.
- Also, when set, display the signature's creation time, its
expiration time, and the trust depth & trust amount.
Diffstat (limited to 'sq')
-rw-r--r-- | sq/src/commands/inspect.rs | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/sq/src/commands/inspect.rs b/sq/src/commands/inspect.rs index f1fcfc35..9befbace 100644 --- a/sq/src/commands/inspect.rs +++ b/sq/src/commands/inspect.rs @@ -1,8 +1,6 @@ use std::convert::TryFrom; use std::io::{self, Read}; - - use sequoia_openpgp as openpgp; use crate::openpgp::{KeyHandle, Packet, Result}; use crate::openpgp::cert::prelude::*; @@ -16,6 +14,9 @@ use crate::openpgp::packet::key::SecretKeyMaterial; use super::dump::Convert; +use crate::SECONDS_IN_YEAR; +use crate::SECONDS_IN_DAY; + pub fn inspect(m: &clap::ArgMatches, policy: &dyn Policy, output: &mut dyn io::Write) -> Result<()> { let print_certifications = m.is_present("certifications"); @@ -406,25 +407,92 @@ fn inspect_certifications<'a, A>(output: &mut dyn io::Write, if print_certifications { let mut emit_warning = false; for sig in certs { + let time = if let Some(time) = sig.signature_creation_time() { + chrono::DateTime::<chrono::offset::Utc>::from(time) + } else { + // A signature must have a signature creation time + // subpacket to be valid. This signature is not + // valid, so skip it. + continue; + }; + emit_warning = true; + + writeln!(output, " Certification: Creation time: {}", time)?; + + let indent = " "; + + if let Some(e) = sig.signature_expiration_time() { + let e = chrono::DateTime::<chrono::offset::Utc>::from(e); + let diff = e - time; + let years = diff.num_seconds() / (SECONDS_IN_YEAR as i64); + let rest = diff.num_seconds() - years * (SECONDS_IN_YEAR as i64); + let days = rest / (SECONDS_IN_DAY as i64); + let rest = rest - days * (SECONDS_IN_DAY as i64); + + writeln!(output, "{}Expiration time: {} (after {}{}{}{}{})", + indent, + e, + match years { + 0 => "".into(), + 1 => format!("{} year", years), + _ => format!("{} years", years), + }, + if years != 0 && days != 0 { ", " } else { "" }, + match days { + 0 => "".into(), + 1 => format!("{} day", days), + _ => format!("{} days", days), + }, + if years == 0 && days != 0 && rest != 0 { ", " } else { "" }, + if years == 0 { + match rest { + 0 => "".into(), + 1 => format!("{} second", rest), + _ => format!("{} seconds", rest), + } + } else { + "".into() + })?; + } + + if let Some((depth, amount)) = sig.trust_signature() { + writeln!(output, "{}Trust depth: {}", indent, + depth)?; + writeln!(output, "{}Trust amount: {}", indent, + amount)?; + } + for re in sig.regular_expressions() { + if let Ok(re) = String::from_utf8(re.to_vec()) { + writeln!(output, "{}Regular expression: {:?}", indent, + re)?; + } else { + writeln!(output, + "{}Regular expression (invalid UTF-8): {:?}", + indent, + String::from_utf8_lossy(re))?; + } + } + let mut fps: Vec<_> = sig.issuer_fingerprints().collect(); fps.sort(); fps.dedup(); let fps: Vec<KeyHandle> = fps.into_iter().map(|fp| fp.into()).collect(); for fp in fps.iter() { - writeln!(output, "Alleged certifier: {}", fp)?; + writeln!(output, "{}Alleged certifier: {}", indent, fp)?; } let mut keyids: Vec<_> = sig.issuers().collect(); keyids.sort(); keyids.dedup(); for keyid in keyids { if ! fps.iter().any(|fp| fp.aliases(&keyid.into())) { - writeln!(output, "Alleged certifier: {}", keyid)?; + writeln!(output, "{}Alleged certifier: {}", indent, + keyid)?; } } } if emit_warning { - writeln!(output, " Note: \ + writeln!(output, " Note: \ Certifications have NOT been verified!")?; } } else { |