67 lines
1.9 KiB
Rust
67 lines
1.9 KiB
Rust
//! Split a hex-encoded secret into OpenPGP shards
|
|
|
|
use std::{env, path::PathBuf, process::ExitCode, str::FromStr};
|
|
|
|
use keyfork_shard::{Format, openpgp::OpenPGP};
|
|
|
|
#[derive(Clone, Debug)]
|
|
enum Error {
|
|
Usage(String),
|
|
Input,
|
|
}
|
|
|
|
impl std::fmt::Display for Error {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Error::Usage(program_name) => {
|
|
write!(f, "Usage: {program_name} threshold max key_discovery")
|
|
}
|
|
Error::Input => f.write_str("Expected hex encoded input"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
|
|
|
|
fn validate(threshold: &str, max: &str, key_discovery: &str) -> Result<(u8, u8, PathBuf)> {
|
|
let threshold = u8::from_str(threshold)?;
|
|
let max = u8::from_str(max)?;
|
|
let key_discovery = PathBuf::from(key_discovery);
|
|
std::fs::metadata(&key_discovery)?;
|
|
|
|
Ok((threshold, max, key_discovery))
|
|
}
|
|
|
|
fn run() -> Result<()> {
|
|
let mut args = env::args();
|
|
let program_name = args.next().expect("program name");
|
|
let args = args.collect::<Vec<_>>();
|
|
let (threshold, max, key_discovery) = match args.as_slice() {
|
|
[threshold, max, key_discovery] => validate(threshold, max, key_discovery)?,
|
|
_ => return Err(Error::Usage(program_name).into()),
|
|
};
|
|
let input = {
|
|
use std::io::stdin;
|
|
let Some(line) = stdin().lines().next() else {
|
|
return Err(Error::Input.into());
|
|
};
|
|
smex::decode(line?)?
|
|
};
|
|
|
|
let openpgp = OpenPGP;
|
|
|
|
openpgp.shard_and_encrypt(threshold, max, &input, key_discovery.as_path(), std::io::stdout())?;
|
|
Ok(())
|
|
}
|
|
|
|
fn main() -> ExitCode {
|
|
let result = run();
|
|
if let Err(e) = result {
|
|
eprintln!("Error: {e}");
|
|
return ExitCode::FAILURE;
|
|
}
|
|
ExitCode::SUCCESS
|
|
}
|