1use crate::util::*;
2use crate::messages::*;
3use crate::register::*;
4use crate::authorization::*;
5
6use base64::{encode_config, decode_config, URL_SAFE_NO_PAD};
7use chrono::prelude::*;
8use time::Duration;
9use crate::u2ferror::U2fError;
10
11type Result<T> = ::std::result::Result<T, U2fError>;
12
13#[derive(Clone)]
14pub struct U2f {
15 app_id: String,
16}
17
18#[derive(Deserialize, Serialize, Clone)]
19#[serde(rename_all = "camelCase")]
20pub struct Challenge {
21 pub app_id: String,
22 pub challenge: String,
23 pub timestamp: String,
24}
25
26impl Challenge {
27 pub fn new() -> Self {
28 Challenge {
29 app_id: String::new(),
30 challenge: String::new(),
31 timestamp: String::new()
32 }
33 }
34}
35
36impl U2f {
37 pub fn new(app_id: String) -> Self {
39 U2f {
40 app_id: app_id,
41 }
42 }
43
44 pub fn generate_challenge(&self) -> Result<Challenge> {
45 let utc: DateTime<Utc> = Utc::now();
46
47 let challenge_bytes = generate_challenge(32)?;
48 let challenge = Challenge {
49 challenge : encode_config(&challenge_bytes, URL_SAFE_NO_PAD),
50 timestamp : format!("{:?}", utc),
51 app_id : self.app_id.clone()
52 };
53
54 Ok(challenge.clone())
55 }
56
57 pub fn request(&self, challenge: Challenge, registrations: Vec<Registration>) -> Result<U2fRegisterRequest> {
58 let u2f_request = U2fRegisterRequest {
59 app_id : self.app_id.clone(),
60 register_requests: self.register_request(challenge),
61 registered_keys: self.registered_keys(registrations)
62 };
63
64 Ok(u2f_request)
65 }
66
67 fn register_request(&self, challenge: Challenge) -> Vec<RegisterRequest> {
68 let mut requests: Vec<RegisterRequest> = vec![];
69
70 let request = RegisterRequest {
71 version : U2F_V2.into(),
72 challenge: challenge.challenge
73 };
74 requests.push(request);
75
76 requests
77 }
78
79 pub fn register_response(&self, challenge: Challenge, response: RegisterResponse) -> Result<Registration> {
80 if expiration(challenge.timestamp) > Duration::seconds(300) {
81 return Err(U2fError::ChallengeExpired);
82 }
83
84 let registration_data: Vec<u8> = decode_config(&response.registration_data[..], URL_SAFE_NO_PAD).unwrap();
85 let client_data: Vec<u8> = decode_config(&response.client_data[..], URL_SAFE_NO_PAD).unwrap();
86
87 parse_registration(challenge.app_id, client_data, registration_data)
88 }
89
90 fn registered_keys(&self, registrations: Vec<Registration>) -> Vec<RegisteredKey> {
91 let mut keys: Vec<RegisteredKey> = vec![];
92
93 for registration in registrations {
94 keys.push(get_registered_key(self.app_id.clone(), registration.key_handle));
95 }
96
97 keys
98 }
99
100 pub fn sign_request(&self, challenge: Challenge, registrations: Vec<Registration>) -> U2fSignRequest {
101 let mut keys: Vec<RegisteredKey> = vec![];
102
103 for registration in registrations {
104 keys.push(get_registered_key(self.app_id.clone(), registration.key_handle));
105 }
106
107 let signed_request = U2fSignRequest {
108 app_id : self.app_id.clone(),
109 challenge: encode_config(challenge.challenge.as_bytes(), URL_SAFE_NO_PAD),
110 registered_keys: keys
111 };
112
113 signed_request
114 }
115
116 pub fn sign_response(&self, challenge: Challenge, reg: Registration, sign_resp: SignResponse, counter: u32) -> Result<u32> {
117 if expiration(challenge.timestamp) > Duration::seconds(300) {
118 return Err(U2fError::ChallengeExpired);
119 }
120
121 if sign_resp.key_handle != get_encoded(®.key_handle[..]) {
122 return Err(U2fError::WrongKeyHandler);
123 }
124
125 let client_data: Vec<u8> = decode_config(&sign_resp.client_data[..], URL_SAFE_NO_PAD).map_err(|_e| U2fError::InvalidClientData)?;
126 let sign_data: Vec<u8> = decode_config(&sign_resp.signature_data[..], URL_SAFE_NO_PAD).map_err(|_e| U2fError::InvalidSignatureData)?;
127
128 let public_key = reg.pub_key;
129
130 let auth = parse_sign_response(self.app_id.clone(), client_data.clone(), public_key, sign_data.clone());
131
132 match auth {
133 Ok(ref res) => {
134 if res.counter < counter {
137 return Err(U2fError::CounterTooLow);
138 }
139 else {
140 return Ok(res.counter);
141 }
142 },
143 Err(e) => return Err(e),
144 }
145 }
146}