diff --git a/src/ctap/mod.rs b/src/ctap/mod.rs index e7793fc..46f7f07 100644 --- a/src/ctap/mod.rs +++ b/src/ctap/mod.rs @@ -464,7 +464,7 @@ where }; let mut auth_data = self.generate_auth_data(&rp_id_hash, flags)?; - auth_data.append(&mut self.persistent_store.aaguid()?); + auth_data.extend(&self.persistent_store.aaguid()?); // The length is fixed to 0x20 or 0x70 and fits one byte. if credential_id.len() > 0xFF { return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_RESPONSE_TOO_LONG); @@ -493,7 +493,6 @@ where // decide whether batch attestation is needed. let (signature, x5c) = match self.persistent_store.attestation_private_key()? { Some(attestation_private_key) => { - let attestation_private_key = array_ref![attestation_private_key, 0, 32]; let attestation_key = crypto::ecdsa::SecKey::from_bytes(attestation_private_key).unwrap(); let attestation_certificate = self @@ -722,7 +721,6 @@ where String::from("clientPin"), self.persistent_store.pin_hash()?.is_some(), ); - let aaguid = self.persistent_store.aaguid()?; Ok(ResponseData::AuthenticatorGetInfo( AuthenticatorGetInfoResponse { versions: vec![ @@ -731,7 +729,7 @@ where String::from(FIDO2_VERSION_STRING), ], extensions: Some(vec![String::from("hmac-secret")]), - aaguid: *array_ref![aaguid, 0, 16], + aaguid: self.persistent_store.aaguid()?, options: Some(options_map), max_msg_size: Some(1024), pin_protocols: Some(vec![ @@ -855,7 +853,7 @@ mod test { 0x02, 0x81, 0x6B, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x03, 0x50, ]); - expected_response.extend(ctap_state.persistent_store.aaguid().unwrap()); + expected_response.extend(&ctap_state.persistent_store.aaguid().unwrap()); expected_response.extend(&[ 0x04, 0xA3, 0x62, 0x72, 0x6B, 0xF5, 0x62, 0x75, 0x70, 0xF5, 0x69, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x50, 0x69, 0x6E, 0xF4, 0x05, 0x19, 0x04, 0x00, 0x06, 0x81, 0x01, @@ -954,7 +952,7 @@ mod test { 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0x41, 0x00, 0x00, 0x00, 0x00, ]; - expected_auth_data.extend(ctap_state.persistent_store.aaguid().unwrap()); + expected_auth_data.extend(&ctap_state.persistent_store.aaguid().unwrap()); expected_auth_data.extend(&[0x00, 0x20]); assert_eq!( auth_data[0..expected_auth_data.len()], @@ -991,7 +989,7 @@ mod test { 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0x41, 0x00, 0x00, 0x00, 0x00, ]; - expected_auth_data.extend(ctap_state.persistent_store.aaguid().unwrap()); + expected_auth_data.extend(&ctap_state.persistent_store.aaguid().unwrap()); expected_auth_data.extend(&[0x00, ENCRYPTED_CREDENTIAL_ID_SIZE as u8]); assert_eq!( auth_data[0..expected_auth_data.len()], @@ -1136,7 +1134,7 @@ mod test { 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0xC1, 0x00, 0x00, 0x00, 0x00, ]; - expected_auth_data.extend(ctap_state.persistent_store.aaguid().unwrap()); + expected_auth_data.extend(&ctap_state.persistent_store.aaguid().unwrap()); expected_auth_data.extend(&[0x00, 0x20]); assert_eq!( auth_data[0..expected_auth_data.len()], diff --git a/src/ctap/storage.rs b/src/ctap/storage.rs index bc3afe4..5e8a9ea 100644 --- a/src/ctap/storage.rs +++ b/src/ctap/storage.rs @@ -105,7 +105,7 @@ enum Key { MinPinLengthRpIds, } -pub struct MasterKeys(Vec); +pub struct MasterKeys([u8; 64]); impl MasterKeys { pub fn encryption(&self) -> &[u8; 32] { @@ -382,10 +382,10 @@ impl PersistentStore { if entry.data.len() != 64 { return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR); } - Ok(MasterKeys(entry.data.to_vec())) + Ok(MasterKeys(*array_ref![entry.data, 0, 64])) } - pub fn pin_hash(&self) -> Result>, Ctap2StatusCode> { + pub fn pin_hash(&self) -> Result, Ctap2StatusCode> { let data = match self.store.find_one(&Key::PinHash) { None => return Ok(None), Some((_, entry)) => entry.data, @@ -393,7 +393,7 @@ impl PersistentStore { if data.len() != PIN_AUTH_LENGTH { return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR); } - Ok(Some(data.to_vec())) + Ok(Some(*array_ref![data, 0, PIN_AUTH_LENGTH])) } pub fn set_pin_hash( @@ -575,7 +575,7 @@ impl PersistentStore { Ok(()) } - pub fn aaguid(&self) -> Result, Ctap2StatusCode> { + pub fn aaguid(&self) -> Result<[u8; AAGUID_LENGTH], Ctap2StatusCode> { let (_, entry) = self .store .find_one(&Key::Aaguid) @@ -584,7 +584,7 @@ impl PersistentStore { if data.len() != AAGUID_LENGTH { return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR); } - Ok(data.to_vec()) + Ok(*array_ref![data, 0, AAGUID_LENGTH]) } pub fn set_aaguid(&mut self, aaguid: &[u8; AAGUID_LENGTH]) -> Result<(), Ctap2StatusCode> { @@ -954,14 +954,14 @@ mod test { // Setting the pin hash sets the pin hash. let random_data = rng.gen_uniform_u8x32(); assert_eq!(random_data.len(), 2 * PIN_AUTH_LENGTH); - let pin_hash_1 = array_ref!(random_data, 0, PIN_AUTH_LENGTH); - let pin_hash_2 = array_ref!(random_data, PIN_AUTH_LENGTH, PIN_AUTH_LENGTH); + let pin_hash_1 = *array_ref!(random_data, 0, PIN_AUTH_LENGTH); + let pin_hash_2 = *array_ref!(random_data, PIN_AUTH_LENGTH, PIN_AUTH_LENGTH); persistent_store.set_pin_hash(&pin_hash_1).unwrap(); - assert_eq!(persistent_store.pin_hash().unwrap().unwrap(), pin_hash_1); - assert_eq!(persistent_store.pin_hash().unwrap().unwrap(), pin_hash_1); + assert_eq!(persistent_store.pin_hash().unwrap(), Some(pin_hash_1)); + assert_eq!(persistent_store.pin_hash().unwrap(), Some(pin_hash_1)); persistent_store.set_pin_hash(&pin_hash_2).unwrap(); - assert_eq!(persistent_store.pin_hash().unwrap().unwrap(), pin_hash_2); - assert_eq!(persistent_store.pin_hash().unwrap().unwrap(), pin_hash_2); + assert_eq!(persistent_store.pin_hash().unwrap(), Some(pin_hash_2)); + assert_eq!(persistent_store.pin_hash().unwrap(), Some(pin_hash_2)); // Resetting the storage resets the pin hash. persistent_store.reset(&mut rng).unwrap(); @@ -1013,7 +1013,7 @@ mod test { persistent_store .set_attestation_certificate(key_material::ATTESTATION_CERTIFICATE) .unwrap(); - assert_eq!(persistent_store.aaguid().unwrap(), key_material::AAGUID); + assert_eq!(&persistent_store.aaguid().unwrap(), key_material::AAGUID); // The persistent keys stay initialized and preserve their value after a reset. persistent_store.reset(&mut rng).unwrap(); @@ -1025,7 +1025,7 @@ mod test { persistent_store.attestation_certificate().unwrap().unwrap(), key_material::ATTESTATION_CERTIFICATE ); - assert_eq!(persistent_store.aaguid().unwrap(), key_material::AAGUID); + assert_eq!(&persistent_store.aaguid().unwrap(), key_material::AAGUID); } #[cfg(feature = "with_ctap2_1")]