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
use bytes::{Buf, BufMut};
use std::io::Cursor;
use openssl::sha::sha256;


use crate::u2ferror::U2fError;


/// The `Result` type used in this crate.
type Result<T> = ::std::result::Result<T, U2fError>;

#[derive(Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Authorization {
    pub counter: u32,
    pub user_presence: bool,
}

pub fn parse_sign_response(app_id: String, client_data: Vec<u8>, public_key: Vec<u8>, sign_data: Vec<u8>) -> Result<Authorization> {

    if sign_data.len() <= 5 {
        return Err(U2fError::InvalidSignatureData)
    }

    let user_presence_flag = &sign_data[0];
    let counter = &sign_data[1..=4];
    let signature = &sign_data[5..];

    // Let's build the msg to verify the signature
    let app_id_hash = sha256(&app_id.into_bytes());
    let client_data_hash = sha256(&client_data[..]);

    let mut msg = vec![];
    msg.put(app_id_hash.as_ref());
    msg.put(user_presence_flag.clone()); 
    msg.put(counter.clone());  
    msg.put(client_data_hash.as_ref());

    let public_key = super::crypto::NISTP256Key::from_bytes(&public_key)?;

    // The signature is to be verified by the relying party using the public key obtained during registration.
    let verified = public_key.verify_signature(&signature[..], msg.as_ref())?;
    if !verified {
        return Err(U2fError::BadSignature)
    }

    let authorization = Authorization {
        counter: get_counter(counter),
        user_presence: true
    };

    Ok(authorization)
}


fn get_counter(counter: &[u8]) -> u32 {
    let mut buf = Cursor::new(&counter[..]);
    buf.get_u32_be()
}