u2f/
authorization.rs

1use bytes::{Buf, BufMut};
2use std::io::Cursor;
3use openssl::sha::sha256;
4
5
6use crate::u2ferror::U2fError;
7
8
9/// The `Result` type used in this crate.
10type Result<T> = ::std::result::Result<T, U2fError>;
11
12#[derive(Serialize, Clone)]
13#[serde(rename_all = "camelCase")]
14pub struct Authorization {
15    pub counter: u32,
16    pub user_presence: bool,
17}
18
19pub fn parse_sign_response(app_id: String, client_data: Vec<u8>, public_key: Vec<u8>, sign_data: Vec<u8>) -> Result<Authorization> {
20
21    if sign_data.len() <= 5 {
22        return Err(U2fError::InvalidSignatureData)
23    }
24
25    let user_presence_flag = &sign_data[0];
26    let counter = &sign_data[1..=4];
27    let signature = &sign_data[5..];
28
29    // Let's build the msg to verify the signature
30    let app_id_hash = sha256(&app_id.into_bytes());
31    let client_data_hash = sha256(&client_data[..]);
32
33    let mut msg = vec![];
34    msg.put(app_id_hash.as_ref());
35    msg.put(user_presence_flag.clone()); 
36    msg.put(counter.clone());  
37    msg.put(client_data_hash.as_ref());
38
39    let public_key = super::crypto::NISTP256Key::from_bytes(&public_key)?;
40
41    // The signature is to be verified by the relying party using the public key obtained during registration.
42    let verified = public_key.verify_signature(&signature[..], msg.as_ref())?;
43    if !verified {
44        return Err(U2fError::BadSignature)
45    }
46
47    let authorization = Authorization {
48        counter: get_counter(counter),
49        user_presence: true
50    };
51
52    Ok(authorization)
53}
54
55
56fn get_counter(counter: &[u8]) -> u32 {
57    let mut buf = Cursor::new(&counter[..]);
58    buf.get_u32_be()
59}