From 9be508e562ed9b0bad269b774e5fcdfeac7f21b6 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 27 Mar 2022 16:00:33 +0800 Subject: [PATCH] feat: u2f* --- src/cmd_u2fregister.rs | 47 +++++++++++++++++++----------------------- src/cmd_u2fsign.rs | 30 ++++++++++++++++++--------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/cmd_u2fregister.rs b/src/cmd_u2fregister.rs index e2b96cc..798d0fa 100644 --- a/src/cmd_u2fregister.rs +++ b/src/cmd_u2fregister.rs @@ -47,12 +47,11 @@ impl Command for CommandImpl { register_tx.send(rv).unwrap(); })); - information!("Start U2F register..."); - information!("App id: {}", app_id); + information!("App id: {}, Start U2F register...", app_id); debugging!("Wait timeout: {} ms", timeout_ms); - let mut manager = AuthenticatorService::new()?; + let mut manager = opt_result!(AuthenticatorService::new(), "Create authenticator service failed: {}"); manager.add_u2f_usb_hid_platform_transports(); - manager.register( + if let Err(e) = manager.register( flags, timeout_ms, chall_bytes, @@ -60,33 +59,29 @@ impl Command for CommandImpl { vec![], status_tx, callback, - )?; + ) { + return simple_error!("Couldn't register: {:?}", e); + }; - let register_result = register_rx.recv()?; + let register_result = opt_result!(register_rx.recv()?, "Register U2F failed: {}"); - let u2f_registration_data = U2fRegistrationData::from(app_id, &u2fv2_challenge_str, register_result?); + let u2f_registration_data = opt_result!( + U2fRegistrationData::from(app_id, &u2fv2_challenge_str, register_result), "Parse registration data failed: {}"); - match u2f_registration_data { - Ok(data) => { - if json_output { - println!("{}", serde_json::to_string_pretty(&data).unwrap()); - } else { - success!("Device info: {}", data.device_info); - success!("Register challenge: {}", u2fv2_challenge_str); - success!("Register challenge base64: {}", base64::encode(&u2fv2_challenge_str)); - if let Some(cert) = data.attestation_cert_pem { - success!("Certificate: {}", cert); - } - if let Some(device_name) = data.device_name { - success!("Device name: {}", device_name); - } - success!("Public key: {}", data.pub_key); - success!("Key handle: {}", data.key_handle); - } + if json_output { + println!("{}", serde_json::to_string_pretty(&u2f_registration_data).unwrap()); + } else { + success!("Device info: {}", u2f_registration_data.device_info); + success!("Register challenge: {}", u2fv2_challenge_str); + success!("Register challenge base64: {}", base64::encode(&u2fv2_challenge_str)); + if let Some(cert) = u2f_registration_data.attestation_cert_pem { + success!("Attestation certificate: {}", cert); } - Err(e) => { - return simple_error!("Parse registration data failed: {}", e); + if let Some(device_name) = u2f_registration_data.device_name { + success!("Device name: {}", device_name); } + success!("Public key: {}", u2f_registration_data.pub_key); + success!("Key handle: {}", u2f_registration_data.key_handle); } Ok(None) } diff --git a/src/cmd_u2fsign.rs b/src/cmd_u2fsign.rs index 0d05fc5..71d2434 100644 --- a/src/cmd_u2fsign.rs +++ b/src/cmd_u2fsign.rs @@ -18,6 +18,7 @@ impl Command for CommandImpl { SubCommand::with_name(self.name()).about("FIDO U2F Sign subcommand") .arg(Arg::with_name("app-id").short("a").long("app-id").default_value("https://example.com").help("App id")) .arg(Arg::with_name("timeout").short("t").long("timeout").default_value("10").help("Timeout in seconds")) + .arg(Arg::with_name("public-key-hex").long("public-key-hex").takes_value(true).help("Public key hex")) .arg(Arg::with_name("key-handle").short("k").long("key-handle").takes_value(true).multiple(true).help("Key handle")) } fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { @@ -57,10 +58,9 @@ impl Command for CommandImpl { let status_tx = fido::start_status_updater(); - information!("Start sign..."); - information!("App id: {}", app_id); - let mut manager = opt_result!( - AuthenticatorService::new(), "Create authenticator service failed: {}"); + information!("App id: {}, Start sign...", app_id); + debugging!("Wait timeout: {} ms", timeout_ms); + let mut manager = opt_result!(AuthenticatorService::new(), "Create authenticator service failed: {}"); manager.add_u2f_usb_hid_platform_transports(); if let Err(e) = manager.sign( flags, @@ -71,13 +71,11 @@ impl Command for CommandImpl { status_tx, callback, ) { - return simple_error!("Couldn't register: {:?}", e); + return simple_error!("Couldn't sign: {:?}", e); } - let sign_result = opt_result!(sign_rx.recv(), - "Problem receiving, unable to continue: {}"); - let (_, handle_used, sign_data, device_info) = - opt_result!(sign_result, "Sign failed: {}"); + let sign_result = opt_result!(sign_rx.recv(), "Problem receiving, unable to continue: {}"); + let (_, handle_used, sign_data, device_info) = opt_result!(sign_result, "Sign failed: {}"); success!("Device info: {}", &device_info); success!("Sign challenge: {}", u2fv2_challenge_str); @@ -86,7 +84,19 @@ impl Command for CommandImpl { success!("Key handle used: {}", base64::encode(&handle_used)); success!("Key handle used: {}", hex::encode(&handle_used)); - // u2f::authorization::parse_sign_response(app_id.to_string(), u2fv2_challenge_str.as_bytes().to_vec(), ) + if let Some(public_key_hex) = sub_arg_matches.value_of("public-key-hex") { + let public_key = opt_result!(hex::decode(public_key_hex), "Parse public key hex failed: {}"); + let authorization = u2f::authorization::parse_sign_response( + app_id.to_string(), + u2fv2_challenge_str.as_bytes().to_vec(), + public_key, + sign_data, + ); + match authorization { + Ok(authorization) => success!("Parse authorization success, counter: {}", authorization.counter), + Err(e) => failure!("Parse authorization failed: {}", e), + } + } Ok(None) }