1use bytes::Buf;
2use serde::Serialize;
3use std::io::Cursor;
4
5use crate::register::sha256;
6use crate::u2ferror::U2fError;
7
8type Result<T> = ::std::result::Result<T, U2fError>;
10
11#[derive(Serialize, Clone)]
12#[serde(rename_all = "camelCase")]
13pub struct Authorization {
14 pub counter: u32,
15 pub user_presence: bool,
16}
17
18pub fn parse_sign_response(app_id: String, client_data: Vec<u8>, public_key: Vec<u8>, sign_data: Vec<u8>) -> Result<Authorization> {
19 if sign_data.len() <= 5 {
20 return Err(U2fError::InvalidSignatureData);
21 }
22
23 let user_presence_flag = &sign_data[0];
24 let counter = &sign_data[1..=4];
25 let signature = &sign_data[5..];
26
27 let app_id_hash = sha256(&app_id.into_bytes());
29 let client_data_hash = sha256(&client_data[..]);
30
31 let mut msg = vec![];
32 msg.extend_from_slice(app_id_hash.as_ref());
33 msg.push(*user_presence_flag);
34 msg.extend_from_slice(counter);
35 msg.extend_from_slice(client_data_hash.as_ref());
36
37 let public_key = super::crypto::NISTP256Key::from_bytes(&public_key)?;
38
39 let verified = public_key.verify_signature(signature, msg.as_ref())?;
41 if !verified {
42 return Err(U2fError::BadSignature);
43 }
44
45 let authorization = Authorization {
46 counter: get_counter(counter),
47 user_presence: true,
48 };
49
50 Ok(authorization)
51}
52
53fn get_counter(counter: &[u8]) -> u32 {
54 let mut buf = Cursor::new(counter);
55 buf.get_u32_be()
56}