changes always uv constant to a clearer version

This commit is contained in:
Fabian Kaczmarczyck
2021-02-08 17:53:30 +01:00
parent 54e9da7a5b
commit 160c83d242
3 changed files with 34 additions and 27 deletions

View File

@@ -12,24 +12,20 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use super::check_pin_uv_auth_protocol;
use super::command::AuthenticatorConfigParameters; use super::command::AuthenticatorConfigParameters;
use super::data_formats::{ConfigSubCommand, ConfigSubCommandParams, SetMinPinLengthParams}; use super::data_formats::{ConfigSubCommand, ConfigSubCommandParams, SetMinPinLengthParams};
use super::pin_protocol_v1::PinProtocolV1; use super::pin_protocol_v1::PinProtocolV1;
use super::response::ResponseData; use super::response::ResponseData;
use super::status_code::Ctap2StatusCode; use super::status_code::Ctap2StatusCode;
use super::storage::PersistentStore; use super::storage::PersistentStore;
use super::{check_pin_uv_auth_protocol, ENFORCE_ALWAYS_UV};
use alloc::vec; 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. /// Processes the subcommand toggleAlwaysUv for AuthenticatorConfig.
fn process_toggle_always_uv( fn process_toggle_always_uv(
persistent_store: &mut PersistentStore, persistent_store: &mut PersistentStore,
) -> Result<ResponseData, Ctap2StatusCode> { ) -> Result<ResponseData, Ctap2StatusCode> {
if !CAN_DISABLE_ALWAYS_UV && persistent_store.has_always_uv()? { if ENFORCE_ALWAYS_UV {
return Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED); return Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED);
} }
persistent_store.toggle_always_uv()?; persistent_store.toggle_always_uv()?;
@@ -148,15 +144,14 @@ mod test {
}; };
let config_response = let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params); process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
if CAN_DISABLE_ALWAYS_UV { if ENFORCE_ALWAYS_UV {
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert!(!persistent_store.has_always_uv().unwrap());
} else {
assert_eq!( assert_eq!(
config_response, config_response,
Err(Ctap2StatusCode::CTAP2_ERR_OPERATION_DENIED) 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 = let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params); 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_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert!(persistent_store.has_always_uv().unwrap()); assert!(persistent_store.has_always_uv().unwrap());
@@ -192,16 +194,8 @@ mod test {
}; };
let config_response = let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params); process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
if CAN_DISABLE_ALWAYS_UV {
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig)); assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert!(!persistent_store.has_always_uv().unwrap()); 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());
}
} }
fn create_min_pin_config_params( fn create_min_pin_config_params(

View File

@@ -129,6 +129,9 @@ pub const ES256_CRED_PARAM: PublicKeyCredentialParameter = PublicKeyCredentialPa
const DEFAULT_CRED_PROTECT: Option<CredentialProtectionPolicy> = None; const DEFAULT_CRED_PROTECT: Option<CredentialProtectionPolicy> = None;
// Maximum size stored with the credBlob extension. Must be at least 32. // Maximum size stored with the credBlob extension. Must be at least 32.
const MAX_CRED_BLOB_LENGTH: usize = 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. // Checks the PIN protocol parameter against all supported versions.
pub fn check_pin_uv_auth_protocol( pub fn check_pin_uv_auth_protocol(

View File

@@ -18,10 +18,10 @@ use crate::ctap::data_formats::{
extract_array, extract_text_string, CredentialProtectionPolicy, PublicKeyCredentialSource, extract_array, extract_text_string, CredentialProtectionPolicy, PublicKeyCredentialSource,
PublicKeyCredentialUserEntity, PublicKeyCredentialUserEntity,
}; };
use crate::ctap::key_material;
use crate::ctap::pin_protocol_v1::PIN_AUTH_LENGTH; use crate::ctap::pin_protocol_v1::PIN_AUTH_LENGTH;
use crate::ctap::status_code::Ctap2StatusCode; use crate::ctap::status_code::Ctap2StatusCode;
use crate::ctap::INITIAL_SIGNATURE_COUNTER; use crate::ctap::INITIAL_SIGNATURE_COUNTER;
use crate::ctap::{key_material, ENFORCE_ALWAYS_UV};
use crate::embedded_flash::{new_storage, Storage}; use crate::embedded_flash::{new_storage, Storage};
use alloc::string::String; use alloc::string::String;
use alloc::vec; use alloc::vec;
@@ -613,6 +613,9 @@ impl PersistentStore {
/// Returns whether alwaysUv is enabled. /// Returns whether alwaysUv is enabled.
pub fn has_always_uv(&self) -> Result<bool, Ctap2StatusCode> { pub fn has_always_uv(&self) -> Result<bool, Ctap2StatusCode> {
if ENFORCE_ALWAYS_UV {
return Ok(true);
}
match self.store.find(key::ALWAYS_UV)? { match self.store.find(key::ALWAYS_UV)? {
None => Ok(false), None => Ok(false),
Some(value) if value.is_empty() => Ok(true), Some(value) if value.is_empty() => Ok(true),
@@ -622,6 +625,9 @@ impl PersistentStore {
/// Enables alwaysUv, when disabled, and vice versa. /// Enables alwaysUv, when disabled, and vice versa.
pub fn toggle_always_uv(&mut self) -> Result<(), Ctap2StatusCode> { pub fn toggle_always_uv(&mut self) -> Result<(), Ctap2StatusCode> {
if ENFORCE_ALWAYS_UV {
return Ok(());
}
if self.has_always_uv()? { if self.has_always_uv()? {
Ok(self.store.remove(key::ALWAYS_UV)?) Ok(self.store.remove(key::ALWAYS_UV)?)
} else { } else {
@@ -1331,12 +1337,16 @@ mod test {
let mut rng = ThreadRng256 {}; let mut rng = ThreadRng256 {};
let mut persistent_store = PersistentStore::new(&mut rng); let mut persistent_store = PersistentStore::new(&mut rng);
if ENFORCE_ALWAYS_UV {
assert!(persistent_store.has_always_uv().unwrap());
} else {
assert!(!persistent_store.has_always_uv().unwrap()); assert!(!persistent_store.has_always_uv().unwrap());
assert_eq!(persistent_store.toggle_always_uv(), Ok(())); assert_eq!(persistent_store.toggle_always_uv(), Ok(()));
assert!(persistent_store.has_always_uv().unwrap()); assert!(persistent_store.has_always_uv().unwrap());
assert_eq!(persistent_store.toggle_always_uv(), Ok(())); assert_eq!(persistent_store.toggle_always_uv(), Ok(()));
assert!(!persistent_store.has_always_uv().unwrap()); assert!(!persistent_store.has_always_uv().unwrap());
} }
}
#[test] #[test]
fn test_serialize_deserialize_credential() { fn test_serialize_deserialize_credential() {