Compare commits

..

No commits in common. "488e9f48da4c8e620bc0d883c468558d42f1dffb" and "8792ef69e105391c53717d8ec64e660edb194fdd" have entirely different histories.

4 changed files with 54 additions and 11 deletions

38
Cargo.lock generated
View File

@ -709,6 +709,19 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "env_logger"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
dependencies = [
"humantime",
"is-terminal",
"log",
"regex",
"termcolor",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -915,6 +928,12 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.59" version = "0.1.59"
@ -1042,6 +1061,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"card-backend-pcsc", "card-backend-pcsc",
"clap", "clap",
"env_logger",
"keyfork-derive-openpgp", "keyfork-derive-openpgp",
"keyfork-derive-util", "keyfork-derive-util",
"keyfork-mnemonic-util", "keyfork-mnemonic-util",
@ -2264,6 +2284,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "termcolor"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "terminal_size" name = "terminal_size"
version = "0.3.0" version = "0.3.0"
@ -2607,6 +2636,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"

View File

@ -23,3 +23,4 @@ card-backend-pcsc = "0.5.0"
openpgp-card-sequoia = "0.2.0" openpgp-card-sequoia = "0.2.0"
openpgp-card = "0.4.1" openpgp-card = "0.4.1"
keyfork-prompt = { version = "0.1.0", path = "../keyfork-prompt" } keyfork-prompt = { version = "0.1.0", path = "../keyfork-prompt" }
env_logger = "0.10.1"

View File

@ -1,9 +1,13 @@
use super::Keyfork; use super::Keyfork;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use std::collections::HashSet;
use card_backend_pcsc::PcscBackend; use card_backend_pcsc::PcscBackend;
use openpgp_card_sequoia::{state::Open, types::KeyType, Card}; use openpgp_card::card_do::ApplicationIdentifier;
use openpgp_card_sequoia::{
state::Open,
types::KeyType,
Card,
};
use keyfork_derive_openpgp::openpgp::{self, packet::UserID, types::KeyFlags, Cert}; use keyfork_derive_openpgp::openpgp::{self, packet::UserID, types::KeyFlags, Cert};
use keyfork_derive_util::{ use keyfork_derive_util::{
@ -45,7 +49,7 @@ fn derive_key(seed: &[u8], index: u8) -> Result<Cert> {
// TODO: extract into crate // TODO: extract into crate
/// Factory reset the current card so long as it does not match the last-used backend. /// Factory reset the current card so long as it does not match the last-used backend.
fn factory_reset_current_card( fn factory_reset_current_card(
seen_cards: &mut HashSet<String>, previous_backend: &mut Option<ApplicationIdentifier>,
cert: &Cert, cert: &Cert,
) -> Result<()> { ) -> Result<()> {
let policy = openpgp::policy::NullPolicy::new(); let policy = openpgp::policy::NullPolicy::new();
@ -71,12 +75,12 @@ fn factory_reset_current_card(
if let Some(current_backend) = PcscBackend::cards(None)?.next().transpose()? { if let Some(current_backend) = PcscBackend::cards(None)?.next().transpose()? {
let mut card = Card::<Open>::new(current_backend)?; let mut card = Card::<Open>::new(current_backend)?;
let mut transaction = card.transaction()?; let mut transaction = card.transaction()?;
let application_identifier = transaction.application_identifier()?.ident(); let application_identifier = transaction.application_identifier()?;
if seen_cards.contains(&application_identifier) { if previous_backend.is_some_and(|pb| pb == application_identifier) {
// we were given the same card, error // we were given the same card, error
panic!("Previously used card {application_identifier} was reused"); panic!("Previously used card {application_identifier} was reused");
} else { } else {
seen_cards.insert(application_identifier); let _ = previous_backend.insert(application_identifier);
} }
transaction.factory_reset()?; transaction.factory_reset()?;
let mut admin = transaction.to_admin_card("12345678")?; let mut admin = transaction.to_admin_card("12345678")?;
@ -94,17 +98,15 @@ fn generate_shard_secret(threshold: u8, max: u8, keys_per_shard: u8) -> Result<(
let seed = keyfork_plumbing::generate_entropy_of_size(256 / 8)?; let seed = keyfork_plumbing::generate_entropy_of_size(256 / 8)?;
let mut pm = PromptManager::new(std::io::stdin(), std::io::stderr())?; let mut pm = PromptManager::new(std::io::stdin(), std::io::stderr())?;
let mut certs = vec![]; let mut certs = vec![];
let mut seen_cards: HashSet<String> = HashSet::new(); let mut last_card = None;
for index in 0..max { for index in 0..max {
let cert = derive_key(&seed, index)?; let cert = derive_key(&seed, index)?;
for i in 0..keys_per_shard { for i in 0..keys_per_shard {
pm.prompt_message(&Message::Text(format!( pm.prompt_message(&Message::Text(format!(
"Please insert key #{} for user #{}", "Please insert user {index} key {i}"
i + 1,
index + 1,
)))?; )))?;
factory_reset_current_card(&mut seen_cards, &cert)?; factory_reset_current_card(&mut last_card, &cert)?;
} }
certs.push(cert); certs.push(cert);
} }

View File

@ -9,6 +9,8 @@ mod cli;
fn main() -> ExitCode { fn main() -> ExitCode {
let opts = cli::Keyfork::parse(); let opts = cli::Keyfork::parse();
env_logger::init();
if let Err(e) = opts.command .handle(&opts) { if let Err(e) = opts.command .handle(&opts) {
println!("Unable to run command: {e}"); println!("Unable to run command: {e}");
let mut source = e.source(); let mut source = e.source();