Biometric Enrollment - FeitianTech/postquantum-webauthn-platform GitHub Wiki
- Introduction
- Architecture Overview
- Command Structure and Implementation
- Parameter Encoding via CBOR
- Response Formats
- Extensions Framework Integration
- Security Considerations
- Error Handling
- Test Examples
- Best Practices
The Biometric Enrollment extension is a specialized CTAP2 (Client-to-Authenticator Protocol version 2) extension that enables biometric authentication capabilities, specifically fingerprint enrollment and management. This extension provides a comprehensive framework for managing biometric templates, sensor configuration, and user verification workflows within authenticator devices.
The extension supports the FIDO2.1 specification's biometric enrollment capabilities and includes backward compatibility with prototype implementations. It operates through a series of discrete commands that handle enrollment initiation, sample capture, template management, and sensor configuration negotiation.
The Biometric Enrollment extension follows a layered architecture that separates concerns between command processing, parameter encoding, and response handling:
graph TB
subgraph "Client Layer"
Client[Fido2Client]
Extensions[Extensions Framework]
end
subgraph "CTAP2 Layer"
BioEnrollment[BioEnrollment Base Class]
FPBioEnrollment[FPBioEnrollment Implementation]
Commands[Command Handlers]
end
subgraph "Transport Layer"
CTAP2[Ctap2 Object]
HID[HID Transport]
end
subgraph "Hardware Layer"
Sensor[Fingerprint Sensor]
Storage[Template Storage]
Security[Security Engine]
end
Client --> Extensions
Extensions --> BioEnrollment
BioEnrollment --> FPBioEnrollment
FPBioEnrollment --> Commands
Commands --> CTAP2
CTAP2 --> HID
HID --> Sensor
HID --> Storage
HID --> Security
Diagram sources
- fido2/ctap2/bio.py
- fido2/ctap2/base.py
Section sources
- fido2/ctap2/bio.py
- fido2/ctap2/base.py
The Biometric Enrollment extension implements six primary commands, each serving a specific function in the biometric enrollment workflow:
classDiagram
class FPBioEnrollment {
+CMD.ENROLL_BEGIN : 0x01
+CMD.ENROLL_CAPTURE_NEXT : 0x02
+CMD.ENROLL_CANCEL : 0x03
+CMD.ENUMERATE_ENROLLMENTS : 0x04
+CMD.SET_NAME : 0x05
+CMD.REMOVE_ENROLLMENT : 0x06
+CMD.GET_SENSOR_INFO : 0x07
}
class BioEnrollment {
+RESULT.MODALITY : 0x01
+RESULT.FINGERPRINT_KIND : 0x02
+RESULT.MAX_SAMPLES_REQUIRED : 0x03
+RESULT.TEMPLATE_ID : 0x04
+RESULT.LAST_SAMPLE_STATUS : 0x05
+RESULT.REMAINING_SAMPLES : 0x06
+RESULT.TEMPLATE_INFOS : 0x07
+RESULT.MAX_TEMPLATE_FRIENDLY_NAME : 0x08
}
class FeedbackCodes {
+FP_GOOD : 0x00
+FP_TOO_HIGH : 0x01
+FP_TOO_LOW : 0x02
+FP_TOO_LEFT : 0x03
+FP_TOO_RIGHT : 0x04
+FP_TOO_FAST : 0x05
+FP_TOO_SLOW : 0x06
+FP_POOR_QUALITY : 0x07
+FP_TOO_SKEWED : 0x08
+FP_TOO_SHORT : 0x09
+FP_MERGE_FAILURE : 0x0A
+FP_EXISTS : 0x0B
+FP_DATABASE_FULL : 0x0C
+NO_USER_ACTIVITY : 0x0D
+NO_UP_TRANSITION : 0x0E
}
FPBioEnrollment --> BioEnrollment
FPBioEnrollment --> FeedbackCodes
Diagram sources
- fido2/ctap2/bio.py
| Command | Value | Purpose | Authentication Required |
|---|---|---|---|
| ENROLL_BEGIN | 0x01 | Initiate fingerprint enrollment process | Yes |
| ENROLL_CAPTURE_NEXT | 0x02 | Capture additional fingerprint samples | Yes |
| ENROLL_CANCEL | 0x03 | Cancel ongoing enrollment | No |
| ENUMERATE_ENROLLMENTS | 0x04 | List all enrolled fingerprints | Yes |
| SET_NAME | 0x05 | Rename a fingerprint template | Yes |
| REMOVE_ENROLLMENT | 0x06 | Delete a fingerprint template | Yes |
| GET_SENSOR_INFO | 0x07 | Retrieve sensor capabilities | No |
Section sources
- fido2/ctap2/bio.py
The Biometric Enrollment extension uses CBOR (Concise Binary Object Representation) for parameter encoding, providing efficient binary serialization of command parameters. The encoding follows a structured approach:
flowchart TD
Start([Command Execution]) --> CheckAuth{Authentication<br/>Required?}
CheckAuth --> |Yes| BuildMsg[Build Message<br/>struct.pack(">BB", modality, sub_cmd)]
CheckAuth --> |No| CallDirect[Direct Call]
BuildMsg --> AddParams{Parameters<br/>Present?}
AddParams --> |Yes| EncodeCBOR[Encode Parameters<br/>cbor.encode(params)]
AddParams --> |No| SkipParams[Skip Parameters]
EncodeCBOR --> SignMsg[Sign Message<br/>pin_uv_protocol.authenticate]
SkipParams --> SignMsg
SignMsg --> SendCommand[Send to Authenticator]
CallDirect --> SendCommand
SendCommand --> End([Response Received])
Diagram sources
- fido2/ctap2/bio.py
The extension defines specific parameter types for different command contexts:
| Parameter Type | Value | Description |
|---|---|---|
| TEMPLATE_ID | 0x01 | Unique identifier for fingerprint templates |
| TEMPLATE_NAME | 0x02 | Human-readable name for templates |
| TIMEOUT_MS | 0x03 | Timeout duration in milliseconds |
For the ENROLL_BEGIN command with a timeout parameter:
- Modality (Fingerprint):
0x01 - Sub-command:
0x01 - Parameters:
{0x03: timeout_ms}encoded as CBOR
Section sources
- fido2/ctap2/bio.py
- fido2/ctap2/bio.py
The Biometric Enrollment extension returns structured responses using CBOR-encoded dictionaries. Each command returns specific result codes and data structures:
classDiagram
class ResponseFormat {
+RESULT.MODALITY : int
+RESULT.FINGERPRINT_KIND : int
+RESULT.MAX_SAMPLES_REQUIRED : int
+RESULT.TEMPLATE_ID : bytes
+RESULT.LAST_SAMPLE_STATUS : int
+RESULT.REMAINING_SAMPLES : int
+RESULT.TEMPLATE_INFOS : list
+RESULT.MAX_TEMPLATE_FRIENDLY_NAME : int
}
class TemplateInfo {
+TEMPLATE_INFO.ID : bytes
+TEMPLATE_INFO.NAME : str
}
class EnrollmentContext {
+template_id : bytes
+remaining : int
+capture() : bytes
+cancel() : void
}
ResponseFormat --> TemplateInfo
EnrollmentContext --> ResponseFormat
Diagram sources
- fido2/ctap2/bio.py
sequenceDiagram
participant Client as Client Application
participant Bio as BioEnrollment
participant Auth as Authenticator
Client->>Bio : enroll_begin(timeout)
Bio->>Auth : ENROLL_BEGIN command
Auth-->>Bio : {TEMPLATE_ID, LAST_SAMPLE_STATUS, REMAINING_SAMPLES}
Bio-->>Client : (template_id, feedback, remaining)
loop Until completion
Client->>Bio : enroll_capture_next(template_id)
Bio->>Auth : ENROLL_CAPTURE_NEXT command
Auth-->>Bio : {LAST_SAMPLE_STATUS, REMAINING_SAMPLES}
Bio-->>Client : (feedback, remaining)
end
Client->>Bio : enroll_capture_next(final_template_id)
Bio->>Auth : ENROLL_CAPTURE_NEXT command
Auth-->>Bio : {TEMPLATE_ID, LAST_SAMPLE_STATUS, REMAINING_SAMPLES}
Bio-->>Client : final_template_id
Diagram sources
- fido2/ctap2/bio.py
Section sources
- fido2/ctap2/bio.py
- fido2/ctap2/bio.py
The Biometric Enrollment extension integrates seamlessly with the broader Extensions framework, providing standardized processing for biometric operations:
classDiagram
class ExtensionProcessor {
<<abstract>>
+permissions : ClientPin.PERMISSION
+inputs : dict
+outputs : dict
}
class RegistrationExtensionProcessor {
+prepare_inputs(pin_token) : dict
+prepare_outputs(response, pin_token) : dict
}
class AuthenticationExtensionProcessor {
+prepare_inputs(selected, pin_token) : dict
+prepare_outputs(response, pin_token) : dict
}
class BioEnrollmentExtension {
+is_supported(ctap) : bool
+make_credential(ctap, options, pin_protocol) : Processor
+get_assertion(ctap, options, pin_protocol) : Processor
}
ExtensionProcessor <|-- RegistrationExtensionProcessor
ExtensionProcessor <|-- AuthenticationExtensionProcessor
BioEnrollmentExtension --> RegistrationExtensionProcessor
BioEnrollmentExtension --> AuthenticationExtensionProcessor
Diagram sources
- fido2/ctap2/extensions.py
The extension advertises its capabilities through the CTAP2 Info object, which includes:
-
Options:
"bioEnroll"flag indicating support -
Versions:
"FIDO_2_1_PRE"for prototype support - Extensions: Not explicitly listed in extensions field
Section sources
- fido2/ctap2/extensions.py
- fido2/ctap2/bio.py
The Biometric Enrollment extension implements multiple security layers to protect biometric data and prevent unauthorized access:
Biometric templates are protected through several mechanisms:
- Cryptographic Binding: Templates are cryptographically bound to the authenticator
- Local Storage: Templates stored locally with hardware-based protection
- Access Control: Requires PIN/UV authentication for sensitive operations
- Template Validation: Hardware-level validation prevents template manipulation
The extension incorporates sophisticated spoof detection mechanisms:
flowchart TD
Scan[Fingerprint Scan] --> QualityCheck{Quality Check}
QualityCheck --> |Pass| AntiSpoof[Anti-Spoof Detection]
QualityCheck --> |Fail| PoorQuality[Poor Quality Feedback]
AntiSpoof --> LivenessCheck[Liveness Detection]
LivenessCheck --> |Pass| MergeAttempt[Merge Attempt]
LivenessCheck --> |Fail| SpoofDetected[Spoof Detected]
MergeAttempt --> |Success| StoreTemplate[Store Template]
MergeAttempt --> |Failure| MergeFailure[Merge Failure]
SpoofDetected --> RejectScan[Reject Scan]
PoorQuality --> RetryPrompt[Retry Prompt]
MergeFailure --> RetryPrompt
Diagram sources
- fido2/ctap2/bio.py
The authenticator implements rate limiting to prevent abuse:
- Database Full Protection: Limits on maximum templates per device
- Operation Throttling: Delays between repeated operations
- User Activity Monitoring: Detects automated scanning attempts
- Timeout Enforcement: Configurable timeouts for user interaction
Authentication requirements vary by operation:
| Operation | Authentication Level | Protection Method |
|---|---|---|
| GET_SENSOR_INFO | None | Public access |
| ENROLL_BEGIN | PIN/UV | Full authentication |
| ENROLL_CAPTURE_NEXT | PIN/UV | Full authentication |
| ENUMERATE_ENROLLMENTS | PIN/UV | Full authentication |
| SET_NAME | PIN/UV | Full authentication |
| REMOVE_ENROLLMENT | PIN/UV | Full authentication |
| ENROLL_CANCEL | None | Emergency cancellation |
Section sources
- fido2/ctap2/bio.py
- fido2/ctap2/bio.py
The Biometric Enrollment extension implements comprehensive error handling through CTAP2 error codes and custom exception types:
classDiagram
class CtapError {
+ERR.SUCCESS : 0x00
+ERR.INVALID_COMMAND : 0x01
+ERR.INVALID_PARAMETER : 0x02
+ERR.LIMIT_EXCEEDED : 0x15
+ERR.FP_DATABASE_FULL : 0x17
+ERR.INVALID_CREDENTIAL : 0x22
+ERR.UNSUPPORTED_OPTION : 0x2B
+ERR.INVALID_OPTION : 0x2C
+ERR.PIN_INVALID : 0x31
+ERR.PIN_BLOCKED : 0x32
+ERR.UNAUTHORIZED_PERMISSION : 0x40
}
class CaptureError {
+code : int
+__init__(code)
}
class BioEnrollmentErrors {
+FP_DATABASE_FULL : 0x0C
+FP_EXISTS : 0x0B
+FP_MERGE_FAILURE : 0x0A
+NO_USER_ACTIVITY : 0x0D
+INVALID_OPTION : 0x2C
}
CtapError --> BioEnrollmentErrors
CaptureError --> BioEnrollmentErrors
Diagram sources
- fido2/ctap.py
- fido2/ctap2/bio.py
The extension handles errors through multiple mechanisms:
- Exception Propagation: Custom exceptions for specific failure modes
- Feedback Codes: Real-time feedback during enrollment process
- Graceful Degradation: Fallback behavior for unsupported operations
- User Communication: Clear error messaging for user-facing operations
| Error Condition | Error Code | Handling Strategy |
|---|---|---|
| Insufficient samples | FP_MERGE_FAILURE (0x0A) | Prompt for additional scans |
| Template exists | FP_EXISTS (0x0B) | Inform user and suggest rename |
| Database full | FP_DATABASE_FULL (0x0C) | Suggest deleting old templates |
| Invalid permission | UNAUTHORIZED_PERMISSION (0x40) | Request PIN/UV authentication |
| Unsupported option | INVALID_OPTION (0x2C) | Graceful degradation |
Section sources
- fido2/ctap.py
- fido2/ctap2/bio.py
- fido2/ctap2/bio.py
The test suite demonstrates comprehensive coverage of Biometric Enrollment functionality:
sequenceDiagram
participant Test as Test Suite
participant Bio as FPBioEnrollment
participant Auth as Authenticator
Test->>Bio : get_bio(ctap2, pin_protocol)
Test->>Bio : enumerate_enrollments()
Bio-->>Test : Empty list
Test->>Bio : enroll()
loop Enrollment Process
Test->>Bio : context.capture()
Bio->>Auth : ENROLL_BEGIN/CAPTURE_NEXT
Auth-->>Bio : Feedback + Remaining count
Bio-->>Test : Status update
end
Test->>Bio : enumerate_enrollments()
Bio-->>Test : Single template with name
Test->>Bio : set_name(template_id, "Test Name")
Test->>Bio : remove_enrollment(template_id)
Test->>Bio : enumerate_enrollments()
Bio-->>Test : Empty list
Diagram sources
- tests/device/test_bioenroll.py
The test suite validates sensor capability discovery:
# Example sensor info validation
info = bio.get_fingerprint_sensor_info()
assert info.get(2) in (1, None) # FINGERPRINT_KIND
assert info.get(3, 1) > 0 # MAX_SAMPLES_REQUIRED
assert info.get(8, 1) > 0 # MAX_TEMPLATE_FRIENDLY_NAMEThe tests demonstrate integration with WebAuthn credential creation:
- Setup: Configure authenticator with biometric enrollment
- Registration: Create credential requiring biometric verification
- Authentication: Verify biometric authentication works correctly
- Cleanup: Remove enrollment and verify cleanup
Section sources
- tests/device/test_bioenroll.py
- Capability Checking: Always verify biometric enrollment support before attempting operations
- Error Handling: Implement robust error handling for all enrollment operations
- User Experience: Provide clear feedback during enrollment process
- Security: Require appropriate authentication for sensitive operations
- Resource Management: Clean up temporary enrollment data appropriately
- Testing: Thoroughly test all error conditions and edge cases
- Documentation: Maintain clear documentation of enrollment workflows
- Compatibility: Test with multiple authenticator implementations
- Performance: Optimize for responsive user experience
- Accessibility: Provide clear guidance for users during enrollment
- Device Compatibility: Verify authenticator support for biometric enrollment
- User Training: Provide clear instructions for biometric enrollment
- Fallback Options: Implement alternative authentication methods
- Monitoring: Track enrollment success rates and error patterns
- Maintenance: Regular testing of biometric functionality