feat: u2f
This commit is contained in:
62
src/fido.rs
Normal file
62
src/fido.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use std::thread;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use authenticator::StatusUpdate;
|
||||
use base64::URL_SAFE_NO_PAD;
|
||||
use rand::Rng;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct U2fV2Challenge {
|
||||
challenge: String,
|
||||
version: String,
|
||||
#[serde(rename = "appId")]
|
||||
app_id: String,
|
||||
}
|
||||
|
||||
impl U2fV2Challenge {
|
||||
pub fn new_random<S>(app_id: S) -> Self where S: Into<String> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut rand_bytes = [0_u8; 32];
|
||||
for i in 0..32 {
|
||||
let b: u8 = rng.gen();
|
||||
rand_bytes[i] = b;
|
||||
}
|
||||
|
||||
let challenge = base64::encode_config(&rand_bytes, URL_SAFE_NO_PAD);
|
||||
Self::new(challenge, app_id)
|
||||
}
|
||||
|
||||
pub fn new<S1, S2>(challenge: S1, app_id: S2) -> Self where S1: Into<String>, S2: Into<String> {
|
||||
Self {
|
||||
challenge: challenge.into(),
|
||||
version: "U2F_V2".into(),
|
||||
app_id: app_id.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_json(&self) -> String {
|
||||
serde_json::to_string(&self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_status_updater() -> Sender<StatusUpdate> {
|
||||
let (status_tx, status_rx) = channel::<StatusUpdate>();
|
||||
thread::spawn(move || loop {
|
||||
match status_rx.recv() {
|
||||
Ok(StatusUpdate::DeviceAvailable { dev_info }) => {
|
||||
debugging!("STATUS: device available: {}", dev_info)
|
||||
}
|
||||
Ok(StatusUpdate::DeviceUnavailable { dev_info }) => {
|
||||
debugging!("STATUS: device unavailable: {}", dev_info)
|
||||
}
|
||||
Ok(StatusUpdate::Success { dev_info }) => {
|
||||
debugging!("STATUS: success using device: {}", dev_info);
|
||||
}
|
||||
Err(_) => {
|
||||
debugging!("STATUS: end");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
status_tx
|
||||
}
|
||||
Reference in New Issue
Block a user