forked from mozilla/authenticator-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
107 lines (93 loc) · 3.13 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern crate base64;
extern crate sha2;
extern crate u2fhid;
use sha2::{Digest, Sha256};
use std::io;
use std::sync::mpsc::channel;
use u2fhid::{AuthenticatorTransports, KeyHandle, RegisterFlags, SignFlags, U2FManager};
extern crate env_logger;
extern crate log;
macro_rules! try_or {
($val:expr, $or:expr) => {
match $val {
Ok(v) => v,
Err(e) => {
return $or(e);
}
}
};
}
fn u2f_get_key_handle_from_register_response(register_response: &Vec<u8>) -> io::Result<Vec<u8>> {
if register_response[0] != 0x05 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Reserved byte not set correctly",
));
}
let key_handle_len = register_response[66] as usize;
let mut public_key = register_response.clone();
let mut key_handle = public_key.split_off(67);
let _attestation = key_handle.split_off(key_handle_len);
Ok(key_handle)
}
fn main() {
env_logger::init();
println!("Asking a security key to register now...");
let challenge_str = format!("{}{}",
r#"{"challenge": "1vQ9mxionq0ngCnjD-wTsv1zUSrGRtFqG2xP09SbZ70","#,
r#" "version": "U2F_V2", "appId": "http://demo.yubico.com"}"#);
let mut challenge = Sha256::default();
challenge.input(challenge_str.as_bytes());
let chall_bytes = challenge.result().to_vec();
let mut application = Sha256::default();
application.input(b"http://demo.yubico.com");
let app_bytes = application.result().to_vec();
let manager = U2FManager::new().unwrap();
let flags = RegisterFlags::empty();
let (tx, rx) = channel();
manager
.register(
flags,
15_000,
chall_bytes.clone(),
app_bytes.clone(),
vec![],
move |rv| {
tx.send(rv.unwrap()).unwrap();
},
)
.unwrap();
let register_data = try_or!(rx.recv(), |_| {
panic!("Problem receiving, unable to continue");
});
println!("Register result: {}", base64::encode(®ister_data));
println!("Asking a security key to sign now, with the data from the register...");
let credential = u2f_get_key_handle_from_register_response(®ister_data).unwrap();
let key_handle = KeyHandle {
credential,
transports: AuthenticatorTransports::empty(),
};
let flags = SignFlags::empty();
let (tx, rx) = channel();
manager
.sign(
flags,
15_000,
chall_bytes,
vec![app_bytes],
vec![key_handle],
move |rv| {
tx.send(rv.unwrap()).unwrap();
},
)
.unwrap();
let (_, handle_used, sign_data) = try_or!(rx.recv(), |_| {
println!("Problem receiving");
});
println!("Sign result: {}", base64::encode(&sign_data));
println!("Key handle used: {}", base64::encode(&handle_used));
println!("Done.");
}