chore: re-org u2f code
This commit is contained in:
@@ -34,20 +34,20 @@ impl Command for CommandImpl {
|
|||||||
let json_output = sub_arg_matches.is_present("json");
|
let json_output = sub_arg_matches.is_present("json");
|
||||||
if json_output { rust_util::util_msg::set_logger_std_out(false); }
|
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::<u32>() {
|
let timeout_ms = match sub_arg_matches.value_of("timeout").unwrap().parse::<u32>() {
|
||||||
Ok(t) => (t * 1000) as u64,
|
Ok(t) => (t * 1000) as u64,
|
||||||
Err(e) => return simple_error!("Timeout should be a number: {}", e),
|
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_hex = sub_arg_matches.value_of("challenge");
|
||||||
let challenge_with_timestamp_prefix = sub_arg_matches.is_present("challenge-with-timestamp-prefix");
|
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 = U2fV2Challenge::new_challenge(challenge_hex, app_id, challenge_with_timestamp_prefix)?;
|
||||||
|
|
||||||
let u2fv2_challenge_str = u2fv2_challenge.to_json();
|
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();
|
let flags = RegisterFlags::empty();
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ impl Command for CommandImpl {
|
|||||||
if let Err(e) = manager.register(
|
if let Err(e) = manager.register(
|
||||||
flags,
|
flags,
|
||||||
timeout_ms,
|
timeout_ms,
|
||||||
chall_bytes.clone(),
|
challenge_hash.clone(),
|
||||||
app_bytes.clone(),
|
app_id_hash.clone(),
|
||||||
vec![],
|
vec![],
|
||||||
status_tx,
|
status_tx,
|
||||||
callback,
|
callback,
|
||||||
@@ -84,8 +84,8 @@ impl Command for CommandImpl {
|
|||||||
// +------+-------------------+-----------------+------------+--------------------+
|
// +------+-------------------+-----------------+------------+--------------------+
|
||||||
let mut signed_message = Vec::with_capacity(200);
|
let mut signed_message = Vec::with_capacity(200);
|
||||||
signed_message.push(0x00);
|
signed_message.push(0x00);
|
||||||
signed_message.extend_from_slice(&app_bytes);
|
signed_message.extend_from_slice(&app_id_hash);
|
||||||
signed_message.extend_from_slice(&chall_bytes);
|
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.key_handle);
|
||||||
signed_message.extend_from_slice(&u2f_registration_data.pub_key);
|
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("signed_message", hex::encode(&signed_message));
|
||||||
json.insert("registration_data", hex::encode(®ister_result.0));
|
json.insert("registration_data", hex::encode(®ister_result.0));
|
||||||
json.insert("app_id", app_id.to_string());
|
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", u2fv2_challenge_str);
|
||||||
json.insert("challenge_hash", hex::encode(&chall_bytes));
|
json.insert("challenge_hash", hex::encode(&challenge_hash));
|
||||||
} else {
|
} else {
|
||||||
success!("Device info: {}", u2f_registration_data.device_info);
|
success!("Device info: {}", u2f_registration_data.device_info);
|
||||||
information!("Register challenge: {}", u2fv2_challenge_str);
|
information!("Register challenge: {}", u2fv2_challenge_str);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use openssl::ec::{EcGroup, EcKey, EcPoint};
|
|||||||
use openssl::hash::MessageDigest;
|
use openssl::hash::MessageDigest;
|
||||||
use openssl::nid::Nid;
|
use openssl::nid::Nid;
|
||||||
use openssl::pkey::PKey;
|
use openssl::pkey::PKey;
|
||||||
use openssl::sha::sha256;
|
|
||||||
use openssl::sign::Verifier;
|
use openssl::sign::Verifier;
|
||||||
use rust_util::util_clap::{Command, CommandError};
|
use rust_util::util_clap::{Command, CommandError};
|
||||||
|
|
||||||
@@ -36,13 +35,14 @@ impl Command for CommandImpl {
|
|||||||
let json_output = sub_arg_matches.is_present("json");
|
let json_output = sub_arg_matches.is_present("json");
|
||||||
if json_output { rust_util::util_msg::set_logger_std_out(false); }
|
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::<u32>() {
|
let timeout_ms = match sub_arg_matches.value_of("timeout").unwrap().parse::<u32>() {
|
||||||
Ok(t) => (t * 1000) as u64,
|
Ok(t) => (t * 1000) as u64,
|
||||||
Err(e) => return simple_error!("Timeout should be a number: {}", e),
|
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![];
|
let mut request_key_handles = vec![];
|
||||||
for kh in key_handles {
|
for kh in key_handles {
|
||||||
match hex::decode(kh) {
|
match hex::decode(kh) {
|
||||||
@@ -67,11 +67,10 @@ impl Command for CommandImpl {
|
|||||||
let challenge_hex = sub_arg_matches.value_of("challenge");
|
let challenge_hex = sub_arg_matches.value_of("challenge");
|
||||||
let challenge_with_timestamp_prefix = sub_arg_matches.is_present("challenge-with-timestamp-prefix");
|
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 = U2fV2Challenge::new_challenge(challenge_hex, app_id, challenge_with_timestamp_prefix)?;
|
||||||
|
|
||||||
let u2fv2_challenge_str = u2fv2_challenge.to_json();
|
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();
|
let status_tx = fido::start_status_updater();
|
||||||
|
|
||||||
@@ -82,8 +81,8 @@ impl Command for CommandImpl {
|
|||||||
if let Err(e) = manager.sign(
|
if let Err(e) = manager.sign(
|
||||||
flags,
|
flags,
|
||||||
timeout_ms,
|
timeout_ms,
|
||||||
chall_bytes.clone(),
|
challenge_hash.clone(),
|
||||||
vec![app_bytes.clone()],
|
vec![app_id_hash.clone()],
|
||||||
request_key_handles,
|
request_key_handles,
|
||||||
status_tx,
|
status_tx,
|
||||||
callback,
|
callback,
|
||||||
@@ -98,24 +97,24 @@ impl Command for CommandImpl {
|
|||||||
let counter = &sign_data[1..=4];
|
let counter = &sign_data[1..=4];
|
||||||
let signature = &sign_data[5..];
|
let signature = &sign_data[5..];
|
||||||
|
|
||||||
let client_data = u2fv2_challenge_str.as_bytes().to_vec();
|
// let client_data = u2fv2_challenge_str.as_bytes().to_vec();
|
||||||
let app_id_hash = sha256(app_id.as_bytes());
|
// let app_id_hash = sha256(app_id.as_bytes());
|
||||||
let client_data_hash = sha256(&client_data[..]);
|
// let client_data_hash = sha256(&client_data[..]);
|
||||||
let counter_u32 = u32::from_be_bytes([counter[0], counter[1], counter[2], counter[3]]);
|
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)
|
// application (32B) + user presence (1B) + counter (4B) + client data hash (32B)
|
||||||
let mut signed_message = Vec::with_capacity(128);
|
let mut signed_message = Vec::with_capacity(128);
|
||||||
signed_message.extend_from_slice(&app_id_hash);
|
signed_message.extend_from_slice(&app_id_hash);
|
||||||
signed_message.push(*user_presence_flag);
|
signed_message.push(*user_presence_flag);
|
||||||
signed_message.extend_from_slice(counter);
|
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);
|
success!("Device info: {}", &device_info);
|
||||||
let mut json = BTreeMap::new();
|
let mut json = BTreeMap::new();
|
||||||
if json_output {
|
if json_output {
|
||||||
json.insert("app_id", app_id.to_string());
|
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", 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("device_info", format!("{}", &device_info));
|
||||||
json.insert("signature", hex::encode(&signature));
|
json.insert("signature", hex::encode(&signature));
|
||||||
json.insert("signed_message", hex::encode(&signed_message));
|
json.insert("signed_message", hex::encode(&signed_message));
|
||||||
@@ -143,7 +142,7 @@ impl Command for CommandImpl {
|
|||||||
information!("Public key: {}", hex::encode(&public_key));
|
information!("Public key: {}", hex::encode(&public_key));
|
||||||
let authorization_result = u2f::authorization::parse_sign_response(
|
let authorization_result = u2f::authorization::parse_sign_response(
|
||||||
app_id.to_string(),
|
app_id.to_string(),
|
||||||
client_data,
|
u2fv2_challenge_str.as_bytes().to_vec(),
|
||||||
public_key.clone(),
|
public_key.clone(),
|
||||||
sign_data.clone(),
|
sign_data.clone(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -117,9 +117,7 @@ impl U2fV2Challenge {
|
|||||||
if with_time_stamp_prefix {
|
if with_time_stamp_prefix {
|
||||||
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64;
|
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as u64;
|
||||||
let timestamp_be_bytes = timestamp.to_be_bytes();
|
let timestamp_be_bytes = timestamp.to_be_bytes();
|
||||||
for i in 0..8 {
|
rand_bytes[..8].clone_from_slice(×tamp_be_bytes[..8]);
|
||||||
rand_bytes[i] = timestamp_be_bytes[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let challenge = base64::encode_config(&rand_bytes, URL_SAFE_NO_PAD);
|
let challenge = base64::encode_config(&rand_bytes, URL_SAFE_NO_PAD);
|
||||||
|
|||||||
Reference in New Issue
Block a user