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

57 lines
1.6 KiB
Rust

//! Combine OpenPGP shards and output the hex-encoded secret.
use std::{
env,
fs::File,
path::{Path, PathBuf},
process::ExitCode,
};
use keyfork_prompt::default_handler;
use keyfork_shard::{openpgp::OpenPGP, Format};
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
fn validate(
shard: impl AsRef<Path>,
key_discovery: Option<&str>,
) -> Result<(File, Option<PathBuf>)> {
let key_discovery = key_discovery.map(PathBuf::from);
key_discovery.as_ref().map(std::fs::metadata).transpose()?;
Ok((File::open(shard)?, key_discovery))
}
fn run() -> Result<()> {
let mut args = env::args();
let program_name = args.next().expect("program name");
let args = args.collect::<Vec<_>>();
let (messages_file, key_discovery) = match args.as_slice() {
[shard, key_discovery] => validate(shard, Some(key_discovery))?,
[shard] => validate(shard, None)?,
_ => panic!("Usage: {program_name} <shard> [key_discovery]"),
};
let openpgp = OpenPGP;
let prompt_handler = default_handler()?;
let bytes = openpgp.decrypt_all_shards_to_secret(key_discovery.as_deref(), messages_file, prompt_handler)?;
print!("{}", smex::encode(bytes));
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
}