66 lines
1.8 KiB
Rust
66 lines
1.8 KiB
Rust
use std::{
|
|
env,
|
|
fs::File,
|
|
path::{Path, PathBuf},
|
|
process::ExitCode,
|
|
};
|
|
|
|
use keyfork_shard::openpgp::{decrypt, discover_certs, openpgp::Cert, parse_messages};
|
|
|
|
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
|
|
|
|
fn validate<'a>(
|
|
messages_file: impl AsRef<Path>,
|
|
key_discovery: impl Into<Option<&'a str>>,
|
|
) -> Result<(File, 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((File::open(messages_file)?, certs))
|
|
}
|
|
|
|
fn run() -> Result<()> {
|
|
let mut args = env::args();
|
|
let program_name = args.next().expect("program name");
|
|
let args = args.collect::<Vec<_>>();
|
|
let (messages_file, cert_list) = match args.as_slice() {
|
|
[messages_file, key_discovery] => validate(messages_file, key_discovery.as_str())?,
|
|
[messages_file] => validate(messages_file, None)?,
|
|
_ => panic!("Usage: {program_name} messages_file [key_discovery]"),
|
|
};
|
|
|
|
let mut encrypted_messages = parse_messages(messages_file)?;
|
|
|
|
let encrypted_metadata = encrypted_messages
|
|
.pop_front()
|
|
.expect("any pgp encrypted message");
|
|
|
|
decrypt(
|
|
&cert_list,
|
|
&encrypted_metadata,
|
|
encrypted_messages.make_contiguous(),
|
|
)?;
|
|
|
|
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
|
|
}
|