1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
use gpgme;
use structopt;
use gpgme::{Context, Protocol, SignatureSummary};
use std::{error::Error, fs::File, path::PathBuf};
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
struct Cli {
#[structopt(long)]
/// Use the CMS protocol
cms: bool,
#[structopt(parse(from_os_str))]
sigfile: PathBuf,
#[structopt(parse(from_os_str))]
filename: Option<PathBuf>,
}
fn main() -> Result<(), Box<dyn Error>> {
let args = Cli::from_args();
let proto = if args.cms {
Protocol::Cms
} else {
Protocol::OpenPgp
};
let mut ctx = Context::from_protocol(proto)?;
let sigfile = &args.sigfile;
let signature =
File::open(sigfile).map_err(|e| format!("can't open '{}': {:?}", sigfile.display(), e))?;
let result = if let Some(filename) = args.filename.as_ref() {
let signed = File::open(filename)
.map_err(|e| format!("can't open '{}': {:?}", filename.display(), e))?;
ctx.verify_detached(signature, signed)
} else {
ctx.verify_opaque(signature, &mut Vec::new())
};
print_result(&result.map_err(|e| format!("verification failed: {:?}", e))?);
Ok(())
}
fn print_summary(summary: SignatureSummary) {
if summary.contains(SignatureSummary::VALID) {
print!(" valid");
}
if summary.contains(SignatureSummary::GREEN) {
print!(" green");
}
if summary.contains(SignatureSummary::RED) {
print!(" red");
}
if summary.contains(SignatureSummary::KEY_REVOKED) {
print!(" revoked");
}
if summary.contains(SignatureSummary::KEY_EXPIRED) {
print!(" key-expired");
}
if summary.contains(SignatureSummary::SIG_EXPIRED) {
print!(" sig-expired");
}
if summary.contains(SignatureSummary::KEY_MISSING) {
print!(" key-missing");
}
if summary.contains(SignatureSummary::CRL_MISSING) {
print!(" crl-missing");
}
if summary.contains(SignatureSummary::CRL_TOO_OLD) {
print!(" crl-too-old");
}
if summary.contains(SignatureSummary::BAD_POLICY) {
print!(" bad-policy");
}
if summary.contains(SignatureSummary::SYS_ERROR) {
print!(" sys-error");
}
}
fn print_result(result: &gpgme::VerificationResult) {
println!(
"Original file name: {}",
result.filename().unwrap_or("[none]")
);
for (i, sig) in result.signatures().enumerate() {
println!("Signature {}", i);
println!(" status ....: {:?}", sig.status());
print!(" summary ...:");
print_summary(sig.summary());
println!("");
println!(" fingerprint: {}", sig.fingerprint().unwrap_or("[none]"));
println!(" created ...: {:?}", sig.creation_time());
println!(" expires ...: {:?}", sig.expiration_time());
println!(" validity ..: {:?}", sig.validity());
println!(" val.reason : {:?}", sig.nonvalidity_reason());
println!(" pubkey algo: {}", sig.key_algorithm());
println!(" digest algo: {}", sig.hash_algorithm());
println!(" pka address: {}", sig.pka_address().unwrap_or("[none]"));
println!(" pka trust .: {:?}", sig.pka_trust());
println!(
" other flags: {}{}",
if sig.is_wrong_key_usage() {
" wrong-key-usage"
} else {
""
},
if sig.verified_by_chain() {
" chain-model"
} else {
""
}
);
}
}
|