keyfork/keyfork-shard/src/bin/keyfork-shard-combine-openp...

66 lines
1.6 KiB
Rust

use std::{
env,
io::{stdin, stdout},
path::PathBuf,
process::ExitCode,
};
use keyfork_shard::openpgp::{combine, discover_certs, openpgp::Cert, parse_messages};
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
fn validate<'a>(
key_discovery: impl Into<Option<&'a str>>,
) -> Result<Vec<Cert>> {
let key_discovery = key_discovery.into().map(PathBuf::from);
key_discovery.as_ref().map(std::fs::metadata).transpose()?;
// Load certs from path
let certs = key_discovery
.map(discover_certs)
.transpose()?
.unwrap_or(vec![]);
Ok(certs)
}
fn run() -> Result<()> {
let mut args = env::args();
let program_name = args.next().expect("program name");
let args = args.collect::<Vec<_>>();
let cert_list = match args.as_slice() {
[key_discovery] => validate(key_discovery.as_str())?,
[] => validate(None)?,
_ => panic!("Usage: {program_name} threshold [key_discovery]"),
};
let mut encrypted_messages = parse_messages(stdin())?;
let encrypted_metadata = encrypted_messages
.pop_front()
.expect("any pgp encrypted message");
combine(
cert_list,
&encrypted_metadata,
encrypted_messages.into(),
stdout(),
)?;
Ok(())
}
fn main() -> ExitCode {
let result = run();
if let Err(e) = result {
eprintln!("Error: {e}");
let mut source = e.source();
while let Some(new_error) = source.take() {
eprintln!("Source: {new_error}");
source = new_error.source();
}
return ExitCode::FAILURE;
}
ExitCode::SUCCESS
}