From 4a90258b6baab70323459984ce9e1e1c90353524 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Tue, 12 Apr 2022 23:06:59 +0800 Subject: [PATCH] chore: re-org u2f code --- src/cmd_u2fregister.rs | 20 ++++++++++---------- src/cmd_u2fsign.rs | 29 ++++++++++++++--------------- src/fido.rs | 4 +--- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/cmd_u2fregister.rs b/src/cmd_u2fregister.rs index b9fc7ea..d19701e 100644 --- a/src/cmd_u2fregister.rs +++ b/src/cmd_u2fregister.rs @@ -34,20 +34,20 @@ impl Command for CommandImpl { let json_output = sub_arg_matches.is_present("json"); if json_output { rust_util::util_msg::set_logger_std_out(false); } - let app_id = sub_arg_matches.value_of("app-id").unwrap(); let timeout_ms = match sub_arg_matches.value_of("timeout").unwrap().parse::() { Ok(t) => (t * 1000) as u64, Err(e) => return simple_error!("Timeout should be a number: {}", e), }; + let app_id = sub_arg_matches.value_of("app-id").unwrap(); + let challenge_hex = sub_arg_matches.value_of("challenge"); let challenge_with_timestamp_prefix = sub_arg_matches.is_present("challenge-with-timestamp-prefix"); let u2fv2_challenge = U2fV2Challenge::new_challenge(challenge_hex, app_id, challenge_with_timestamp_prefix)?; - let u2fv2_challenge_str = u2fv2_challenge.to_json(); - let chall_bytes = digest::sha256(&u2fv2_challenge_str); - let app_bytes = digest::sha256(app_id); + let app_id_hash = digest::sha256(app_id); + let challenge_hash = digest::sha256(&u2fv2_challenge_str); let flags = RegisterFlags::empty(); @@ -65,8 +65,8 @@ impl Command for CommandImpl { if let Err(e) = manager.register( flags, timeout_ms, - chall_bytes.clone(), - app_bytes.clone(), + challenge_hash.clone(), + app_id_hash.clone(), vec![], status_tx, callback, @@ -84,8 +84,8 @@ impl Command for CommandImpl { // +------+-------------------+-----------------+------------+--------------------+ let mut signed_message = Vec::with_capacity(200); signed_message.push(0x00); - signed_message.extend_from_slice(&app_bytes); - signed_message.extend_from_slice(&chall_bytes); + signed_message.extend_from_slice(&app_id_hash); + signed_message.extend_from_slice(&challenge_hash); signed_message.extend_from_slice(&u2f_registration_data.key_handle); signed_message.extend_from_slice(&u2f_registration_data.pub_key); // +------+--------------------+---------------------+------------+------------+------+ @@ -112,9 +112,9 @@ impl Command for CommandImpl { json.insert("signed_message", hex::encode(&signed_message)); json.insert("registration_data", hex::encode(®ister_result.0)); json.insert("app_id", app_id.to_string()); - json.insert("app_id_hash", hex::encode(&app_bytes)); + json.insert("app_id_hash", hex::encode(&app_id_hash)); json.insert("challenge", u2fv2_challenge_str); - json.insert("challenge_hash", hex::encode(&chall_bytes)); + json.insert("challenge_hash", hex::encode(&challenge_hash)); } else { success!("Device info: {}", u2f_registration_data.device_info); information!("Register challenge: {}", u2fv2_challenge_str); diff --git a/src/cmd_u2fsign.rs b/src/cmd_u2fsign.rs index aa757be..034e484 100644 --- a/src/cmd_u2fsign.rs +++ b/src/cmd_u2fsign.rs @@ -10,7 +10,6 @@ use openssl::ec::{EcGroup, EcKey, EcPoint}; use openssl::hash::MessageDigest; use openssl::nid::Nid; use openssl::pkey::PKey; -use openssl::sha::sha256; use openssl::sign::Verifier; use rust_util::util_clap::{Command, CommandError}; @@ -36,13 +35,14 @@ impl Command for CommandImpl { let json_output = sub_arg_matches.is_present("json"); if json_output { rust_util::util_msg::set_logger_std_out(false); } - let app_id = sub_arg_matches.value_of("app-id").unwrap(); let timeout_ms = match sub_arg_matches.value_of("timeout").unwrap().parse::() { Ok(t) => (t * 1000) as u64, Err(e) => return simple_error!("Timeout should be a number: {}", e), }; - let key_handles = opt_value_result!( sub_arg_matches.values_of("key-handle"), "Key handle is required"); + let app_id = sub_arg_matches.value_of("app-id").unwrap(); + + let key_handles = opt_value_result!( sub_arg_matches.values_of("key-handle"), "Key handle is required"); let mut request_key_handles = vec![]; for kh in key_handles { match hex::decode(kh) { @@ -67,11 +67,10 @@ impl Command for CommandImpl { let challenge_hex = sub_arg_matches.value_of("challenge"); let challenge_with_timestamp_prefix = sub_arg_matches.is_present("challenge-with-timestamp-prefix"); let u2fv2_challenge = U2fV2Challenge::new_challenge(challenge_hex, app_id, challenge_with_timestamp_prefix)?; - let u2fv2_challenge_str = u2fv2_challenge.to_json(); - let chall_bytes = digest::sha256(&u2fv2_challenge_str); - let app_bytes = digest::sha256(app_id); + let app_id_hash = digest::sha256(app_id); + let challenge_hash = digest::sha256(&u2fv2_challenge_str); let status_tx = fido::start_status_updater(); @@ -82,8 +81,8 @@ impl Command for CommandImpl { if let Err(e) = manager.sign( flags, timeout_ms, - chall_bytes.clone(), - vec![app_bytes.clone()], + challenge_hash.clone(), + vec![app_id_hash.clone()], request_key_handles, status_tx, callback, @@ -98,24 +97,24 @@ impl Command for CommandImpl { let counter = &sign_data[1..=4]; let signature = &sign_data[5..]; - let client_data = u2fv2_challenge_str.as_bytes().to_vec(); - let app_id_hash = sha256(app_id.as_bytes()); - let client_data_hash = sha256(&client_data[..]); + // let client_data = u2fv2_challenge_str.as_bytes().to_vec(); + // let app_id_hash = sha256(app_id.as_bytes()); + // let client_data_hash = sha256(&client_data[..]); let counter_u32 = u32::from_be_bytes([counter[0], counter[1], counter[2], counter[3]]); // application (32B) + user presence (1B) + counter (4B) + client data hash (32B) let mut signed_message = Vec::with_capacity(128); signed_message.extend_from_slice(&app_id_hash); signed_message.push(*user_presence_flag); signed_message.extend_from_slice(counter); - signed_message.extend_from_slice(&client_data_hash); + signed_message.extend_from_slice(&challenge_hash); success!("Device info: {}", &device_info); let mut json = BTreeMap::new(); if json_output { json.insert("app_id", app_id.to_string()); - json.insert("app_id_hash", hex::encode(&app_bytes)); + json.insert("app_id_hash", hex::encode(&app_id_hash)); json.insert("challenge", u2fv2_challenge_str.to_string()); - json.insert("challenge_hash", hex::encode(&chall_bytes)); + json.insert("challenge_hash", hex::encode(&challenge_hash)); json.insert("device_info", format!("{}", &device_info)); json.insert("signature", hex::encode(&signature)); json.insert("signed_message", hex::encode(&signed_message)); @@ -143,7 +142,7 @@ impl Command for CommandImpl { information!("Public key: {}", hex::encode(&public_key)); let authorization_result = u2f::authorization::parse_sign_response( app_id.to_string(), - client_data, + u2fv2_challenge_str.as_bytes().to_vec(), public_key.clone(), sign_data.clone(), ); diff --git a/src/fido.rs b/src/fido.rs index 5a74448..6111c14 100644 --- a/src/fido.rs +++ b/src/fido.rs @@ -117,9 +117,7 @@ impl U2fV2Challenge { if with_time_stamp_prefix { let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64; let timestamp_be_bytes = timestamp.to_be_bytes(); - for i in 0..8 { - rand_bytes[i] = timestamp_be_bytes[i]; - } + rand_bytes[..8].clone_from_slice(×tamp_be_bytes[..8]); } let challenge = base64::encode_config(&rand_bytes, URL_SAFE_NO_PAD);