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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use bytes::{Bytes, BufMut};
use ring::{digest};
use untrusted::Input;
use byteorder::{ByteOrder, BigEndian};
use webpki::{SignatureAlgorithm, trust_anchor_util, EndEntityCert, ECDSA_P256_SHA256};
use crate::util::*;
use crate::messages::RegisteredKey;
use crate::u2ferror::U2fError;
type Result<T> = ::std::result::Result<T, U2fError>;
#[derive(Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Registration {
pub key_handle: Vec<u8>,
pub pub_key: Vec<u8>,
pub attestation_cert: Option<Vec<u8>>,
}
pub fn parse_registration(app_id: String, client_data: Vec<u8>, registration_data: Vec<u8>) -> Result<Registration> {
let reserved_byte = registration_data[0];
if reserved_byte != 0x05 {
return Err(U2fError::InvalidReservedByte);
}
let mut mem = Bytes::from(registration_data);
let _ = mem.split_to(1);
let public_key = mem.split_to(65);
let key_handle_size = mem.split_to(1);
let key_len = BigEndian::read_uint(&key_handle_size[..], 1);
let key_handle = mem.split_to(key_len as usize);
let cert_len = asn_length(mem.clone()).unwrap();
let attestation_certificate = mem.split_to(cert_len);
trust_anchor_util::cert_der_as_trust_anchor(Input::from(&attestation_certificate[..]))
.map_err(|_e| U2fError::NotTrustedAnchor)?;
let signature = mem;
let app_id_hash = digest::digest(&digest::SHA256, &app_id.into_bytes());
let client_data_hash = digest::digest(&digest::SHA256, &client_data[..]);
let mut msg = vec![0x00];
msg.put(app_id_hash.as_ref());
msg.put(client_data_hash.as_ref());
msg.put(key_handle.clone());
msg.put(public_key.clone());
let input_sig = Input::from(&signature[..]);
let input_msg = Input::from(&msg[..]);
let cert = EndEntityCert::from(Input::from(&attestation_certificate[..]))
.map_err(|_e| U2fError::BadCertificate)?;
let algo : &[&SignatureAlgorithm] = &[&ECDSA_P256_SHA256];
cert.verify_signature(algo[0], input_msg, input_sig).map_err(|_e| U2fError::BadSignature)?;
let registration = Registration {
key_handle: key_handle[..].to_vec(),
pub_key: public_key[..].to_vec(),
attestation_cert: Some(attestation_certificate[..].to_vec()),
};
Ok(registration)
}
pub fn get_registered_key(app_id: String, key_handle: Vec<u8>) -> RegisteredKey {
RegisteredKey {
app_id: app_id,
version: U2F_V2.into(),
key_handle: Some(get_encoded(key_handle.as_slice()))
}
}