1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 use crate::errors;
6 use crate::virtualdevices::software_u2f::SoftwareU2FToken;
7 use crate::{RegisterFlags, RegisterResult, SignFlags, SignResult};
8 
9 pub enum TestWireProtocol {
10     CTAP1,
11     CTAP2,
12 }
13 
14 impl TestWireProtocol {
to_webdriver_string(&self) -> String15     pub fn to_webdriver_string(&self) -> String {
16         match self {
17             TestWireProtocol::CTAP1 => "ctap1/u2f".to_string(),
18             TestWireProtocol::CTAP2 => "ctap2".to_string(),
19         }
20     }
21 }
22 
23 pub struct TestTokenCredential {
24     pub credential: Vec<u8>,
25     pub privkey: Vec<u8>,
26     pub user_handle: Vec<u8>,
27     pub sign_count: u64,
28     pub is_resident_credential: bool,
29     pub rp_id: String,
30 }
31 
32 pub struct TestToken {
33     pub id: u64,
34     pub protocol: TestWireProtocol,
35     pub transport: String,
36     pub is_user_consenting: bool,
37     pub has_user_verification: bool,
38     pub is_user_verified: bool,
39     pub has_resident_key: bool,
40     pub u2f_impl: Option<SoftwareU2FToken>,
41     pub credentials: Vec<TestTokenCredential>,
42 }
43 
44 impl TestToken {
new( id: u64, protocol: TestWireProtocol, transport: String, is_user_consenting: bool, has_user_verification: bool, is_user_verified: bool, has_resident_key: bool, ) -> TestToken45     pub fn new(
46         id: u64,
47         protocol: TestWireProtocol,
48         transport: String,
49         is_user_consenting: bool,
50         has_user_verification: bool,
51         is_user_verified: bool,
52         has_resident_key: bool,
53     ) -> TestToken {
54         match protocol {
55             TestWireProtocol::CTAP1 => Self {
56                 id,
57                 protocol,
58                 transport,
59                 is_user_consenting,
60                 has_user_verification,
61                 is_user_verified,
62                 has_resident_key,
63                 u2f_impl: Some(SoftwareU2FToken::new()),
64                 credentials: Vec::new(),
65             },
66             _ => unreachable!(),
67         }
68     }
69 
insert_credential( &mut self, credential: &[u8], privkey: &[u8], rp_id: String, is_resident_credential: bool, user_handle: &[u8], sign_count: u64, )70     pub fn insert_credential(
71         &mut self,
72         credential: &[u8],
73         privkey: &[u8],
74         rp_id: String,
75         is_resident_credential: bool,
76         user_handle: &[u8],
77         sign_count: u64,
78     ) {
79         let c = TestTokenCredential {
80             credential: credential.to_vec(),
81             privkey: privkey.to_vec(),
82             rp_id,
83             is_resident_credential,
84             user_handle: user_handle.to_vec(),
85             sign_count,
86         };
87 
88         match self
89             .credentials
90             .binary_search_by_key(&credential, |probe| &probe.credential)
91         {
92             Ok(_) => {}
93             Err(idx) => self.credentials.insert(idx, c),
94         }
95     }
96 
delete_credential(&mut self, credential: &[u8]) -> bool97     pub fn delete_credential(&mut self, credential: &[u8]) -> bool {
98         debug!("Asking to delete credential",);
99         if let Ok(idx) = self
100             .credentials
101             .binary_search_by_key(&credential, |probe| &probe.credential)
102         {
103             debug!("Asking to delete credential from idx {}", idx);
104             self.credentials.remove(idx);
105             return true;
106         }
107 
108         false
109     }
110 
register(&self) -> crate::Result<RegisterResult>111     pub fn register(&self) -> crate::Result<RegisterResult> {
112         if self.u2f_impl.is_some() {
113             return self.u2f_impl.as_ref().unwrap().register(
114                 RegisterFlags::empty(),
115                 10_000,
116                 vec![0; 32],
117                 vec![0; 32],
118                 vec![],
119             );
120         }
121         Err(errors::AuthenticatorError::U2FToken(
122             errors::U2FTokenError::Unknown,
123         ))
124     }
125 
sign(&self) -> crate::Result<SignResult>126     pub fn sign(&self) -> crate::Result<SignResult> {
127         if self.u2f_impl.is_some() {
128             return self.u2f_impl.as_ref().unwrap().sign(
129                 SignFlags::empty(),
130                 10_000,
131                 vec![0; 32],
132                 vec![vec![0; 32]],
133                 vec![],
134             );
135         }
136         Err(errors::AuthenticatorError::U2FToken(
137             errors::U2FTokenError::Unknown,
138         ))
139     }
140 }
141