Make U2FManager API sync
This commit is contained in:
Родитель
faf54245d3
Коммит
9fe604ebf6
|
@ -4,7 +4,6 @@ extern crate u2fhid;
|
|||
use crypto::digest::Digest;
|
||||
use crypto::sha2::Sha256;
|
||||
use std::io;
|
||||
use std::sync::mpsc::channel;
|
||||
use u2fhid::U2FManager;
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
|
@ -40,18 +39,7 @@ fn main() {
|
|||
|
||||
let mut manager = U2FManager::new();
|
||||
|
||||
let (reg_tx, reg_rx) = channel();
|
||||
manager.register(15, chall_bytes, app_bytes, move |reg_result| {
|
||||
// Ship back to the main thread
|
||||
if let Err(e) = reg_tx.send(reg_result) {
|
||||
panic!("Could not send: {}", e);
|
||||
}
|
||||
}).expect("manager.register() failed");
|
||||
|
||||
let register_data = match reg_rx.recv().expect("Should not error on register receive") {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("Register failure: {}", e),
|
||||
};
|
||||
let register_data = manager.register(15, chall_bytes, app_bytes).unwrap();
|
||||
println!("Register result: {}", base64::encode(®ister_data));
|
||||
|
||||
println!("Asking a security key to sign now, with the data from the register...");
|
||||
|
@ -62,18 +50,7 @@ fn main() {
|
|||
let mut app_bytes: Vec<u8> = vec![0; application.output_bytes()];
|
||||
application.result(&mut app_bytes);
|
||||
|
||||
let (sig_tx, sig_rx) = channel();
|
||||
manager.sign(15, chall_bytes, app_bytes, key_handle, move |sig_result| {
|
||||
// Ship back to the main thread
|
||||
if let Err(e) = sig_tx.send(sig_result) {
|
||||
panic!("Could not send: {}", e);
|
||||
}
|
||||
}).expect("manager.sign() failed");
|
||||
|
||||
let sign_data = match sig_rx.recv().expect("Should not error on signature receive") {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("Sign failure: {}", e),
|
||||
};
|
||||
let sign_data = manager.sign(15, chall_bytes, app_bytes, key_handle).unwrap();
|
||||
println!("Sign result: {}", base64::encode(&sign_data));
|
||||
|
||||
println!("Done.");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::io;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::time::Duration;
|
||||
use std::thread;
|
||||
|
||||
|
@ -24,12 +25,13 @@ impl PlatformManager {
|
|||
Self { thread: None }
|
||||
}
|
||||
|
||||
pub fn register<F>(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>, callback: F) -> io::Result<()>
|
||||
where F: FnOnce(io::Result<Vec<u8>>), F: Send + 'static
|
||||
pub fn register(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>) -> io::Result<Vec<u8>>
|
||||
{
|
||||
// Abort any prior register/sign calls.
|
||||
self.cancel();
|
||||
|
||||
let (tx, rx) = channel();
|
||||
|
||||
self.thread = Some(RunLoop::new(move |alive| {
|
||||
let mut monitor = Monitor::new()?;
|
||||
let mut devices = DeviceMap::new();
|
||||
|
@ -37,8 +39,7 @@ impl PlatformManager {
|
|||
// Helper to stop monitor and call back.
|
||||
let complete = |monitor: &mut Monitor, rv| {
|
||||
monitor.stop();
|
||||
callback(rv);
|
||||
Ok(())
|
||||
tx.send(rv).map(|_| ()).map_err(|_| util::io_err("error sending"))
|
||||
};
|
||||
|
||||
while alive() {
|
||||
|
@ -61,15 +62,19 @@ impl PlatformManager {
|
|||
complete(&mut monitor, Err(util::io_err("cancelled or timed out")))
|
||||
}, timeout)?);
|
||||
|
||||
Ok(())
|
||||
match rx.recv() {
|
||||
Ok(rv) => rv,
|
||||
Err(_) => Err(io::Error::new(io::ErrorKind::Other, "error receiving"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign<F>(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>, key_handle: Vec<u8>, callback: F) -> io::Result<()>
|
||||
where F: FnOnce(io::Result<Vec<u8>>), F: Send + 'static
|
||||
pub fn sign(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>, key_handle: Vec<u8>) -> io::Result<Vec<u8>>
|
||||
{
|
||||
// Abort any prior register/sign calls.
|
||||
self.cancel();
|
||||
|
||||
let (tx, rx) = channel();
|
||||
|
||||
self.thread = Some(RunLoop::new(move |alive| {
|
||||
let mut monitor = Monitor::new()?;
|
||||
let mut devices = DeviceMap::new();
|
||||
|
@ -77,8 +82,7 @@ impl PlatformManager {
|
|||
// Helper to stop monitor and call back.
|
||||
let complete = |monitor: &mut Monitor, rv| {
|
||||
monitor.stop();
|
||||
callback(rv);
|
||||
Ok(())
|
||||
tx.send(rv).map(|_| ()).map_err(|_| util::io_err("error sending"))
|
||||
};
|
||||
|
||||
while alive() {
|
||||
|
@ -116,10 +120,12 @@ impl PlatformManager {
|
|||
complete(&mut monitor, Err(util::io_err("cancelled or timed out")))
|
||||
}, timeout)?);
|
||||
|
||||
Ok(())
|
||||
match rx.recv() {
|
||||
Ok(rv) => rv,
|
||||
Err(_) => Err(io::Error::new(io::ErrorKind::Other, "error receiving"))
|
||||
}
|
||||
}
|
||||
|
||||
// This might block.
|
||||
pub fn cancel(&mut self) {
|
||||
if let Some(mut thread) = self.thread.take() {
|
||||
thread.cancel();
|
||||
|
|
|
@ -94,6 +94,8 @@ impl Monitor {
|
|||
Ok(())
|
||||
}, 0 /* no timeout */)?;
|
||||
|
||||
// TODO what if dlopen() failed?
|
||||
|
||||
Ok(Self { rx, thread })
|
||||
}
|
||||
|
||||
|
|
|
@ -12,21 +12,17 @@ impl U2FManager {
|
|||
Self { platform: PlatformManager::new() }
|
||||
}
|
||||
|
||||
// Cannot block.
|
||||
pub fn register<F>(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>, callback: F) -> io::Result<()>
|
||||
where F: FnOnce(io::Result<Vec<u8>>), F: Send + 'static
|
||||
pub fn register(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>) -> io::Result<Vec<u8>>
|
||||
{
|
||||
if challenge.len() != PARAMETER_SIZE ||
|
||||
application.len() != PARAMETER_SIZE {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid parameter sizes"));
|
||||
}
|
||||
|
||||
self.platform.register(timeout, challenge, application, callback)
|
||||
self.platform.register(timeout, challenge, application)
|
||||
}
|
||||
|
||||
// Cannot block.
|
||||
pub fn sign<F>(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>, key_handle: Vec<u8>, callback: F) -> io::Result<()>
|
||||
where F: FnOnce(io::Result<Vec<u8>>), F: Send + 'static
|
||||
pub fn sign(&mut self, timeout: u64, challenge: Vec<u8>, application: Vec<u8>, key_handle: Vec<u8>) -> io::Result<Vec<u8>>
|
||||
{
|
||||
if challenge.len() != PARAMETER_SIZE ||
|
||||
application.len() != PARAMETER_SIZE {
|
||||
|
@ -37,10 +33,9 @@ impl U2FManager {
|
|||
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Key handle too large"));
|
||||
}
|
||||
|
||||
self.platform.sign(timeout, challenge, application, key_handle, callback)
|
||||
self.platform.sign(timeout, challenge, application, key_handle)
|
||||
}
|
||||
|
||||
// Cannot block. Cancels a single operation.
|
||||
pub fn cancel<F>(&mut self) {
|
||||
self.platform.cancel();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче