@@ -145,7 +145,7 @@ pub trait Customization {
145145 /// this value.
146146 fn max_msg_size ( & self ) -> usize ;
147147
148- /// Sets the number of consecutive failed PINs before blocking interaction.
148+ /// The number of consecutive failed PINs before blocking interaction.
149149 ///
150150 /// # Invariant
151151 ///
@@ -155,6 +155,42 @@ pub trait Customization {
155155 /// The fail retry counter is reset after entering the correct PIN.
156156 fn max_pin_retries ( & self ) -> u8 ;
157157
158+ /// Maximum number of UV retries performed before returning an error.
159+ ///
160+ /// Corresponds to maxUvAttemptsForInternalRetries in CTAP 2.1 onwards.
161+ /// When internal retries are allowed, the authenticator will retry UV
162+ /// before communicating its result through CTAP.
163+ ///
164+ /// # Invariant
165+ ///
166+ /// - Must be in the range [1, `max_uv_retries`].
167+ /// - If `preferred_platform_uv_attempts` is not 1, must be in [1, 5].
168+ #[ cfg( feature = "fingerprint" ) ]
169+ fn max_uv_attempts_for_internal_retries ( & self ) -> u8 ;
170+
171+ /// The number of consecutive failed UV attempts before blocking built-in UV.
172+ ///
173+ /// Corresponds to maxUvRetries in CTAP 2.1 onwards.
174+ ///
175+ /// # Invariant
176+ ///
177+ /// - Must be in the range [1, 25].
178+ #[ cfg( feature = "fingerprint" ) ]
179+ fn max_uv_retries ( & self ) -> u8 ;
180+
181+ /// Preferred number of UV attempts before falling back to PIN.
182+ ///
183+ /// Corresponds to preferredPlatformUvAttempts in CTAP 2.1 onwards.
184+ /// States the preference how often the platform should invoke
185+ /// `getPinUvAuthTokenUsingUvWithPermissions` before falling back to
186+ /// `getPinUvAuthTokenUsingPinWithPermissions` or displaying an error.
187+ ///
188+ /// # Invariant
189+ ///
190+ /// - Must be greater than 0.
191+ #[ cfg( feature = "fingerprint" ) ]
192+ fn preferred_platform_uv_attempts ( & self ) -> usize ;
193+
158194 /// Enables or disables basic attestation for FIDO2.
159195 ///
160196 /// # Invariant
@@ -253,30 +289,11 @@ pub trait Customization {
253289 /// for 10 years.
254290 fn max_supported_resident_keys ( & self ) -> usize ;
255291
256- /// This specifies the preferred number of invocations of the
257- /// `getPinUvAuthTokenUsingUvWithPermissions` subCommand the platform may
258- /// attempt before falling back to the
259- /// `getPinUvAuthTokenUsingPinWithPermissions` subCommand or displaying an
260- /// error.
261- ///
262- /// MUST be greater than zero. If the value is 1 then all uvRetries are
263- /// internal and the platform MUST only invoke the
264- /// getPinUvAuthTokenUsingUvWithPermissions subCommand a single time. If the
265- /// value is > 1 the authenticator MUST only decrement uvRetries by 1 for
266- /// each iteration.
267- fn preferred_platform_uv_attempts ( & self ) -> usize ;
268-
269- /// Sets the number of consecutive failed User Verification attempts before
270- /// blocking built-in UV.
271- ///
272- /// # Invariant
292+ /// Maximum size of a friendly name for a UV template.
273293 ///
274- /// - CTAP2.1: Maximum PIN retries must be 25 at most.
275- fn max_uv_retries ( & self ) -> u8 ;
276-
277- /// The maximum number of times the authenticator will retry internally when
278- /// internalRetry is true as part of the performBuiltInUv() algorithm.
279- fn max_uv_attempts_for_internal_retries ( & self ) -> u8 ;
294+ /// This value limits storage requirements for fingerprints.
295+ #[ cfg( feature = "fingerprint" ) ]
296+ fn max_template_friendly_name ( & self ) -> usize ;
280297}
281298
282299#[ derive( Clone ) ]
@@ -291,39 +308,49 @@ pub struct CustomizationImpl {
291308 pub enterprise_rp_id_list : & ' static [ & ' static str ] ,
292309 pub max_msg_size : usize ,
293310 pub max_pin_retries : u8 ,
311+ #[ cfg( feature = "fingerprint" ) ]
312+ pub max_uv_attempts_for_internal_retries : u8 ,
313+ #[ cfg( feature = "fingerprint" ) ]
314+ pub max_uv_retries : u8 ,
315+ #[ cfg( feature = "fingerprint" ) ]
316+ pub preferred_platform_uv_attempts : usize ,
294317 pub use_batch_attestation : bool ,
295318 pub use_signature_counter : bool ,
296319 pub max_cred_blob_length : usize ,
297320 pub max_credential_count_in_list : Option < usize > ,
298321 pub max_large_blob_array_size : usize ,
299322 pub max_rp_ids_length : usize ,
300323 pub max_supported_resident_keys : usize ,
301- pub preferred_platform_uv_attempts : usize ,
302- pub max_uv_retries : u8 ,
303- pub max_uv_attempts_for_internal_retries : u8 ,
324+ #[ cfg( feature = "fingerprint" ) ]
325+ pub max_template_friendly_name : usize ,
304326}
305327
306328pub const DEFAULT_CUSTOMIZATION : CustomizationImpl = CustomizationImpl {
307329 aaguid : & [ 0 ; AAGUID_LENGTH ] ,
308330 allows_pin_protocol_v1 : true ,
309- default_cred_protect : Some ( CredentialProtectionPolicy :: UserVerificationOptional ) ,
331+ default_cred_protect : None ,
310332 default_min_pin_length : 4 ,
311333 default_min_pin_length_rp_ids : & [ ] ,
312- enforce_always_uv : true ,
334+ enforce_always_uv : false ,
313335 enterprise_attestation_mode : None ,
314336 enterprise_rp_id_list : & [ ] ,
315337 max_msg_size : 7609 ,
316338 max_pin_retries : 8 ,
339+ #[ cfg( feature = "fingerprint" ) ]
340+ max_uv_attempts_for_internal_retries : 1 ,
341+ #[ cfg( feature = "fingerprint" ) ]
342+ max_uv_retries : 8 ,
343+ #[ cfg( feature = "fingerprint" ) ]
344+ preferred_platform_uv_attempts : 1 ,
317345 use_batch_attestation : false ,
318346 use_signature_counter : true ,
319347 max_cred_blob_length : 32 ,
320348 max_credential_count_in_list : None ,
321349 max_large_blob_array_size : 2048 ,
322350 max_rp_ids_length : 8 ,
323351 max_supported_resident_keys : 150 ,
324- preferred_platform_uv_attempts : 5 ,
325- max_uv_retries : 8 ,
326- max_uv_attempts_for_internal_retries : 8 ,
352+ #[ cfg( feature = "fingerprint" ) ]
353+ max_template_friendly_name : 64 ,
327354} ;
328355
329356impl Customization for CustomizationImpl {
@@ -378,6 +405,21 @@ impl Customization for CustomizationImpl {
378405 self . max_pin_retries
379406 }
380407
408+ #[ cfg( feature = "fingerprint" ) ]
409+ fn max_uv_attempts_for_internal_retries ( & self ) -> u8 {
410+ self . max_uv_attempts_for_internal_retries
411+ }
412+
413+ #[ cfg( feature = "fingerprint" ) ]
414+ fn max_uv_retries ( & self ) -> u8 {
415+ self . max_uv_retries
416+ }
417+
418+ #[ cfg( feature = "fingerprint" ) ]
419+ fn preferred_platform_uv_attempts ( & self ) -> usize {
420+ self . preferred_platform_uv_attempts
421+ }
422+
381423 fn use_batch_attestation ( & self ) -> bool {
382424 self . use_batch_attestation
383425 }
@@ -406,16 +448,9 @@ impl Customization for CustomizationImpl {
406448 self . max_supported_resident_keys
407449 }
408450
409- fn preferred_platform_uv_attempts ( & self ) -> usize {
410- self . preferred_platform_uv_attempts
411- }
412-
413- fn max_uv_retries ( & self ) -> u8 {
414- self . max_uv_retries
415- }
416-
417- fn max_uv_attempts_for_internal_retries ( & self ) -> u8 {
418- self . max_uv_attempts_for_internal_retries
451+ #[ cfg( feature = "fingerprint" ) ]
452+ fn max_template_friendly_name ( & self ) -> usize {
453+ self . max_template_friendly_name
419454 }
420455}
421456
@@ -489,6 +524,31 @@ pub fn is_valid(customization: &impl Customization) -> bool {
489524 return false ;
490525 }
491526
527+ #[ cfg( feature = "fingerprint" ) ]
528+ {
529+ // Maximum UV retries must be in range [1, 25].
530+ if customization. max_uv_retries ( ) < 1 || customization. max_uv_retries ( ) > 25 {
531+ return false ;
532+ }
533+
534+ // Maximum internal UV attemps must be in range [1, `max_uv_retries`].
535+ if customization. max_uv_attempts_for_internal_retries ( ) < 1
536+ || customization. max_uv_attempts_for_internal_retries ( ) > customization. max_uv_retries ( )
537+ {
538+ return false ;
539+ }
540+ if customization. preferred_platform_uv_attempts ( ) != 1
541+ && customization. max_uv_attempts_for_internal_retries ( ) > 5
542+ {
543+ return false ;
544+ }
545+
546+ // Preferred number of UV attempts must be positive.
547+ if customization. preferred_platform_uv_attempts ( ) == 0 {
548+ return false ;
549+ }
550+ }
551+
492552 true
493553}
494554
@@ -514,13 +574,21 @@ mod test {
514574 enterprise_rp_id_list : & [ ] ,
515575 max_msg_size : 7609 ,
516576 max_pin_retries : 8 ,
577+ #[ cfg( feature = "fingerprint" ) ]
578+ max_uv_attempts_for_internal_retries : 1 ,
579+ #[ cfg( feature = "fingerprint" ) ]
580+ max_uv_retries : 8 ,
581+ #[ cfg( feature = "fingerprint" ) ]
582+ preferred_platform_uv_attempts : 1 ,
517583 use_batch_attestation : true ,
518584 use_signature_counter : true ,
519585 max_cred_blob_length : 32 ,
520586 max_credential_count_in_list : Some ( 3 ) ,
521587 max_large_blob_array_size : 2048 ,
522588 max_rp_ids_length : 8 ,
523589 max_supported_resident_keys : 150 ,
590+ #[ cfg( feature = "fingerprint" ) ]
591+ max_template_friendly_name : 64 ,
524592 } ;
525593 assert_eq ! ( customization. aaguid( ) , & [ 0 ; AAGUID_LENGTH ] ) ;
526594 assert ! ( customization. allows_pin_protocol_v1( ) ) ;
@@ -535,12 +603,20 @@ mod test {
535603 assert ! ( customization. enterprise_rp_id_list( ) . is_empty( ) ) ;
536604 assert_eq ! ( customization. max_msg_size( ) , 7609 ) ;
537605 assert_eq ! ( customization. max_pin_retries( ) , 8 ) ;
606+ #[ cfg( feature = "fingerprint" ) ]
607+ assert_eq ! ( customization. max_uv_attempts_for_internal_retries( ) , 1 ) ;
608+ #[ cfg( feature = "fingerprint" ) ]
609+ assert_eq ! ( customization. max_uv_retries( ) , 8 ) ;
610+ #[ cfg( feature = "fingerprint" ) ]
611+ assert_eq ! ( customization. preferred_platform_uv_attempts( ) , 1 ) ;
538612 assert ! ( customization. use_batch_attestation( ) ) ;
539613 assert ! ( customization. use_signature_counter( ) ) ;
540614 assert_eq ! ( customization. max_cred_blob_length( ) , 32 ) ;
541615 assert_eq ! ( customization. max_credential_count_in_list( ) , Some ( 3 ) ) ;
542616 assert_eq ! ( customization. max_large_blob_array_size( ) , 2048 ) ;
543617 assert_eq ! ( customization. max_rp_ids_length( ) , 8 ) ;
544618 assert_eq ! ( customization. max_supported_resident_keys( ) , 150 ) ;
619+ #[ cfg( feature = "fingerprint" ) ]
620+ assert_eq ! ( customization. max_template_friendly_name( ) , 64 ) ;
545621 }
546622}
0 commit comments