Skip to content

Commit 70bc3ed

Browse files
committed
Refactors fingerprint code
Introduces a compile flag to toggle fingerprint code. Makes data structures and style match the library's current standard. Removes some undesired customization and debug features.
1 parent c02a599 commit 70bc3ed

18 files changed

Lines changed: 1612 additions & 1084 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ with_ctap1 = ["opensk/with_ctap1"]
4343
with_nfc = ["libtock_drivers/with_nfc"]
4444
vendor_hid = ["opensk/vendor_hid"]
4545
ed25519 = ["ed25519-compact", "opensk/ed25519"]
46+
fingerprint = ["opensk/fingerprint"]
4647

4748
[dev-dependencies]
4849
enum-iterator = "0.6.0"

libraries/opensk/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ with_ctap1 = []
4242
vendor_hid = []
4343
fuzz = ["arbitrary", "std"]
4444
ed25519 = ["ed25519-compact"]
45+
fingerprint = []
4546

4647
[dev-dependencies]
4748
enum-iterator = "0.6.0"

libraries/opensk/src/api/customization.rs

Lines changed: 118 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

306328
pub 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

329356
impl 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

Comments
 (0)