u2f/
register.rs

1use bytes::{Bytes, BufMut};
2use openssl::sha::sha256;
3use byteorder::{ByteOrder, BigEndian};
4
5use crate::util::*;
6use crate::messages::RegisteredKey;
7use crate::u2ferror::U2fError;
8use std::convert::TryFrom;
9
10/// The `Result` type used in this crate.
11type Result<T> = ::std::result::Result<T, U2fError>;
12
13// Single enrolment or pairing between an application and a token.
14#[derive(Serialize, Clone)]
15#[serde(rename_all = "camelCase")]
16pub struct Registration {
17    pub key_handle: Vec<u8>,
18    pub pub_key: Vec<u8>,
19
20    // AttestationCert can be null for Authenticate requests.
21    pub attestation_cert: Option<Vec<u8>>,
22    pub device_name: Option<String>,
23}
24
25pub fn parse_registration(app_id: String, client_data: Vec<u8>, registration_data: Vec<u8>) -> Result<Registration> {
26    let reserved_byte = registration_data[0];
27    if reserved_byte != 0x05 {
28        return Err(U2fError::InvalidReservedByte);
29    }
30
31    let mut mem = Bytes::from(registration_data);
32    
33    //Start parsing ... advance the reserved byte.
34    let _ = mem.split_to(1);
35
36    // P-256 NIST elliptic curve
37    let public_key = mem.split_to(65);
38
39    // Key Handle
40    let key_handle_size = mem.split_to(1);
41    let key_len = BigEndian::read_uint(&key_handle_size[..], 1);
42    let key_handle = mem.split_to(key_len as usize);
43
44    // The certificate length needs to be inferred by parsing.
45    let cert_len = asn_length(mem.clone()).unwrap();
46    let attestation_certificate = mem.split_to(cert_len);
47
48    // Remaining data corresponds to the signature 
49    let signature = mem;
50
51    // Let's build the msg to verify the signature
52    let app_id_hash = sha256(&app_id.into_bytes());
53    let client_data_hash = sha256(&client_data[..]);
54
55    let mut msg = vec![0x00]; // A byte reserved for future use [1 byte] with the value 0x00
56    msg.put(app_id_hash.as_ref());
57    msg.put(client_data_hash.as_ref());
58    msg.put(key_handle.clone()); 
59    msg.put(public_key.clone()); 
60
61
62    // The signature is to be verified by the relying party using the public key certified
63    // in the attestation certificate.
64    let cerificate_public_key = super::crypto::X509PublicKey::try_from(&attestation_certificate[..])?;
65
66    if !(cerificate_public_key.is_secp256r1()?) {
67        return Err(U2fError::BadCertificate);
68    }
69
70    let verified = cerificate_public_key.verify_signature(&signature[..], &msg[..])?;
71
72    if !verified {
73        return Err(U2fError::BadCertificate);
74    }
75
76    let registration = Registration {
77        key_handle: key_handle[..].to_vec(),
78        pub_key: public_key[..].to_vec(), 
79        attestation_cert: Some(attestation_certificate[..].to_vec()),
80        device_name: cerificate_public_key.common_name(),
81    };
82
83    Ok(registration)
84}
85
86pub fn get_registered_key(app_id: String, key_handle: Vec<u8>) -> RegisteredKey {
87    RegisteredKey {
88        app_id: app_id,
89        version: U2F_V2.into(),
90        key_handle: Some(get_encoded(key_handle.as_slice()))
91    }
92}