Compare commits
2 Commits
c868afedbf
...
77648c7d6d
Author | SHA1 | Date |
---|---|---|
Ryan Heywood | 77648c7d6d | |
Ryan Heywood | d5c3587343 |
|
@ -11,16 +11,15 @@ use card_backend_pcsc::PcscBackend;
|
|||
use openpgp_card_sequoia::{state::Open, types::KeyType, Card};
|
||||
|
||||
use keyfork_derive_openpgp::{
|
||||
openpgp::{self, packet::UserID, types::KeyFlags, Cert, serialize::Marshal, armor::{Writer, Kind}},
|
||||
openpgp::{self, packet::UserID, types::KeyFlags, Cert},
|
||||
XPrv,
|
||||
};
|
||||
use keyfork_derive_util::{DerivationIndex, DerivationPath, VariableLengthSeed};
|
||||
use keyfork_derive_util::{DerivationIndex, DerivationPath};
|
||||
use keyfork_prompt::{
|
||||
default_terminal,
|
||||
validators::{SecurePinValidator, Validator},
|
||||
DefaultTerminal, Message, PromptHandler,
|
||||
};
|
||||
use keyfork_mnemonic_util::Mnemonic;
|
||||
|
||||
use keyfork_shard::{openpgp::OpenPGP, Format};
|
||||
|
||||
|
@ -30,8 +29,6 @@ pub struct PinLength(usize);
|
|||
|
||||
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
|
||||
|
||||
// TODO: refactor to use mnemonic derived seed instead of 256 bit entropy to allow for possible
|
||||
// recovery in the future.
|
||||
fn derive_key(seed: [u8; 32], index: u8) -> Result<Cert> {
|
||||
let subkeys = vec![
|
||||
KeyFlags::empty().set_certification(),
|
||||
|
@ -193,42 +190,31 @@ fn generate_shard_secret(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn bottoms_up(key_discovery: &Path, threshold: u8, output_shardfile: &Path, output_cert: &Path, user_id: &str,) -> Result<()> {
|
||||
let entropy = keyfork_entropy::generate_entropy_of_const_size::<{ 256 / 8 }>()?;
|
||||
let mnemonic = Mnemonic::from_nonstandard_bytes(entropy);
|
||||
// TODO: make this return const size, since is hash based
|
||||
let seed = mnemonic.generate_seed(None);
|
||||
|
||||
// TODO: should this allow for customizing the account index from 0? Potential for key reuse
|
||||
// errors.
|
||||
let path = DerivationPath::default()
|
||||
.chain_push(DerivationIndex::new(u32::from_be_bytes(*b"\x00pgp"), true)?)
|
||||
.chain_push(DerivationIndex::new(u32::from_be_bytes(*b"\x00\x00dr"), true)?)
|
||||
.chain_push(DerivationIndex::new(0, true)?);
|
||||
let subkeys = [
|
||||
KeyFlags::empty().set_certification(),
|
||||
KeyFlags::empty().set_signing(),
|
||||
KeyFlags::empty()
|
||||
.set_transport_encryption()
|
||||
.set_storage_encryption(),
|
||||
KeyFlags::empty().set_authentication(),
|
||||
];
|
||||
let xprv = XPrv::new(VariableLengthSeed::new(&seed))
|
||||
.expect("could not construct master key from seed")
|
||||
.derive_path(&path)?;
|
||||
let userid = UserID::from(user_id);
|
||||
|
||||
let cert = keyfork_derive_openpgp::derive(xprv, &subkeys, &userid)?;
|
||||
let certfile = File::create(output_cert)?;
|
||||
let mut w = Writer::new(certfile, Kind::PublicKey)?;
|
||||
cert.serialize(&mut w)?;
|
||||
w.finalize()?;
|
||||
fn bottoms_up(key_discovery: &Path, threshold: u8, output: &Option<PathBuf>) -> Result<()> {
|
||||
let seed = keyfork_entropy::generate_entropy_of_const_size::<{ 256 / 8 }>()?;
|
||||
let stdout = std::io::stdout();
|
||||
if output.is_none() {
|
||||
assert!(
|
||||
!stdout.is_terminal(),
|
||||
"not printing shard to terminal, redirect output"
|
||||
);
|
||||
}
|
||||
|
||||
let opgp = OpenPGP::<DefaultTerminal>::new();
|
||||
let certs = OpenPGP::<DefaultTerminal>::discover_certs(key_discovery)?;
|
||||
|
||||
let shardfile = File::create(output_shardfile)?;
|
||||
opgp.shard_and_encrypt(threshold, certs.len() as u8, &entropy, &certs[..], shardfile)?;
|
||||
if let Some(output_file) = output {
|
||||
let output = File::create(output_file)?;
|
||||
opgp.shard_and_encrypt(threshold, certs.len() as u8, &seed, &certs[..], output)?;
|
||||
} else {
|
||||
opgp.shard_and_encrypt(
|
||||
threshold,
|
||||
certs.len() as u8,
|
||||
&seed,
|
||||
&certs[..],
|
||||
std::io::stdout(),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -273,15 +259,7 @@ pub enum WizardSubcommands {
|
|||
|
||||
/// The file to write the generated shard file to.
|
||||
#[arg(long)]
|
||||
output_shardfile: PathBuf,
|
||||
|
||||
/// The file to write the generated OpenPGP certificate to.
|
||||
#[arg(long)]
|
||||
output_cert: PathBuf,
|
||||
|
||||
/// The User ID for the generated OpenPGP certificate.
|
||||
#[arg(long, default_value = "Disaster Recovery")]
|
||||
user_id: String,
|
||||
output: Option<PathBuf>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -297,10 +275,8 @@ impl WizardSubcommands {
|
|||
WizardSubcommands::BottomsUp {
|
||||
key_discovery,
|
||||
threshold,
|
||||
output_shardfile,
|
||||
output_cert,
|
||||
user_id,
|
||||
} => bottoms_up(key_discovery, *threshold, output_shardfile, output_cert, user_id),
|
||||
output,
|
||||
} => bottoms_up(key_discovery, *threshold, output),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue