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