From 160c83d242bc7d7609d3297074aa33eb013d6e7a Mon Sep 17 00:00:00 2001 From: Fabian Kaczmarczyck Date: Mon, 8 Feb 2021 17:53:30 +0100 Subject: [PATCH] changes always uv constant to a clearer version --- src/ctap/config_command.rs | 36 +++++++++++++++--------------------- src/ctap/mod.rs | 3 +++ src/ctap/storage.rs | 22 ++++++++++++++++------ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/ctap/config_command.rs b/src/ctap/config_command.rs index edff8f0..0d55717 100644 --- a/src/ctap/config_command.rs +++ b/src/ctap/config_command.rs @@ -12,24 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::check_pin_uv_auth_protocol; use super::command::AuthenticatorConfigParameters; use super::data_formats::{ConfigSubCommand, ConfigSubCommandParams, SetMinPinLengthParams}; use super::pin_protocol_v1::PinProtocolV1; use super::response::ResponseData; use super::status_code::Ctap2StatusCode; use super::storage::PersistentStore; +use super::{check_pin_uv_auth_protocol, ENFORCE_ALWAYS_UV}; use alloc::vec; -/// The specification mandates that authenticators support users disabling -/// alwaysUv unless required not to by specific external certifications. -const CAN_DISABLE_ALWAYS_UV: bool = true; - /// Processes the subcommand toggleAlwaysUv for AuthenticatorConfig. fn process_toggle_always_uv( persistent_store: &mut PersistentStore, ) -> Result { - if !CAN_DISABLE_ALWAYS_UV && persistent_store.has_always_uv()? { + if ENFORCE_ALWAYS_UV { return Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED); } persistent_store.toggle_always_uv()?; @@ -148,15 +144,14 @@ mod test { }; let config_response = process_config(&mut persistent_store, &mut pin_protocol_v1, config_params); - if CAN_DISABLE_ALWAYS_UV { - assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig)); - assert!(!persistent_store.has_always_uv().unwrap()); - } else { + if ENFORCE_ALWAYS_UV { assert_eq!( config_response, Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED) ); - assert!(persistent_store.has_always_uv().unwrap()); + } else { + assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig)); + assert!(!persistent_store.has_always_uv().unwrap()); } } @@ -181,6 +176,13 @@ mod test { }; let config_response = process_config(&mut persistent_store, &mut pin_protocol_v1, config_params); + if ENFORCE_ALWAYS_UV { + assert_eq!( + config_response, + Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED) + ); + return; + } assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig)); assert!(persistent_store.has_always_uv().unwrap()); @@ -192,16 +194,8 @@ mod test { }; let config_response = process_config(&mut persistent_store, &mut pin_protocol_v1, config_params); - if CAN_DISABLE_ALWAYS_UV { - assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig)); - assert!(!persistent_store.has_always_uv().unwrap()); - } else { - assert_eq!( - config_response, - Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED) - ); - assert!(persistent_store.has_always_uv().unwrap()); - } + assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig)); + assert!(!persistent_store.has_always_uv().unwrap()); } fn create_min_pin_config_params( diff --git a/src/ctap/mod.rs b/src/ctap/mod.rs index 748afe6..2180eb7 100644 --- a/src/ctap/mod.rs +++ b/src/ctap/mod.rs @@ -129,6 +129,9 @@ pub const ES256_CRED_PARAM: PublicKeyCredentialParameter = PublicKeyCredentialPa const DEFAULT_CRED_PROTECT: Option = None; // Maximum size stored with the credBlob extension. Must be at least 32. const MAX_CRED_BLOB_LENGTH: usize = 32; +// Enforce the alwaysUv option. With this constant set to true, commands require +// a PIN to be set up. The command toggleAlwaysUv will fail to disable alwaysUv. +pub const ENFORCE_ALWAYS_UV: bool = false; // Checks the PIN protocol parameter against all supported versions. pub fn check_pin_uv_auth_protocol( diff --git a/src/ctap/storage.rs b/src/ctap/storage.rs index b586d6d..3b0fb9e 100644 --- a/src/ctap/storage.rs +++ b/src/ctap/storage.rs @@ -18,10 +18,10 @@ use crate::ctap::data_formats::{ extract_array, extract_text_string, CredentialProtectionPolicy, PublicKeyCredentialSource, PublicKeyCredentialUserEntity, }; -use crate::ctap::key_material; use crate::ctap::pin_protocol_v1::PIN_AUTH_LENGTH; use crate::ctap::status_code::Ctap2StatusCode; use crate::ctap::INITIAL_SIGNATURE_COUNTER; +use crate::ctap::{key_material, ENFORCE_ALWAYS_UV}; use crate::embedded_flash::{new_storage, Storage}; use alloc::string::String; use alloc::vec; @@ -613,6 +613,9 @@ impl PersistentStore { /// Returns whether alwaysUv is enabled. pub fn has_always_uv(&self) -> Result { + if ENFORCE_ALWAYS_UV { + return Ok(true); + } match self.store.find(key::ALWAYS_UV)? { None => Ok(false), Some(value) if value.is_empty() => Ok(true), @@ -622,6 +625,9 @@ impl PersistentStore { /// Enables alwaysUv, when disabled, and vice versa. pub fn toggle_always_uv(&mut self) -> Result<(), Ctap2StatusCode> { + if ENFORCE_ALWAYS_UV { + return Ok(()); + } if self.has_always_uv()? { Ok(self.store.remove(key::ALWAYS_UV)?) } else { @@ -1331,11 +1337,15 @@ mod test { let mut rng = ThreadRng256 {}; let mut persistent_store = PersistentStore::new(&mut rng); - assert!(!persistent_store.has_always_uv().unwrap()); - assert_eq!(persistent_store.toggle_always_uv(), Ok(())); - assert!(persistent_store.has_always_uv().unwrap()); - assert_eq!(persistent_store.toggle_always_uv(), Ok(())); - assert!(!persistent_store.has_always_uv().unwrap()); + if ENFORCE_ALWAYS_UV { + assert!(persistent_store.has_always_uv().unwrap()); + } else { + assert!(!persistent_store.has_always_uv().unwrap()); + assert_eq!(persistent_store.toggle_always_uv(), Ok(())); + assert!(persistent_store.has_always_uv().unwrap()); + assert_eq!(persistent_store.toggle_always_uv(), Ok(())); + assert!(!persistent_store.has_always_uv().unwrap()); + } } #[test]