CTAP2 Commands - FeitianTech/postquantum-webauthn-platform GitHub Wiki

CTAP2 Commands

Table of Contents

  1. Introduction
  2. CMD Enum Constants
  3. HID Transport Layer Interaction
  4. Error Handling and Status Codes
  5. MakeCredential Command
  6. GetAssertion Command
  7. GetInfo Command
  8. ClientPIN Command
  9. Reset Command
  10. GetNextAssertion Command
  11. CredentialManagement Command
  12. LargeBlobs Command
  13. Config Command
  14. Authenticator State Management
  15. Test Suite Examples
  16. Conclusion

Introduction

This document provides a comprehensive analysis of the CTAP2 commands implemented in the FIDO2 library. The CTAP2 (Client to Authenticator Protocol 2) specification enables strong authentication using public key cryptography, allowing users to securely authenticate to online services without relying on passwords. The implementation covers all major CTAP2 commands including MakeCredential, GetAssertion, GetInfo, ClientPIN, Reset, GetNextAssertion, CredentialManagement, LargeBlobs, and Config. Each command is analyzed in detail with respect to its implementation, parameter handling, response processing, and interaction with the authenticator via the HID transport layer.

Section sources

CMD Enum Constants

The CTAP2 commands are defined as constants within the Ctap2.CMD enum class, with each command assigned a specific byte value. These constants are used to identify the type of command being sent to the authenticator. The implementation includes both standard commands and prototype/pre-release commands for experimental features.

classDiagram
class Ctap2$CMD {
+MAKE_CREDENTIAL 0x01
+GET_ASSERTION 0x02
+GET_INFO 0x04
+CLIENT_PIN 0x06
+RESET 0x07
+GET_NEXT_ASSERTION 0x08
+BIO_ENROLLMENT 0x09
+CREDENTIAL_MGMT 0x0A
+SELECTION 0x0B
+LARGE_BLOBS 0x0C
+CONFIG 0x0D
+BIO_ENROLLMENT_PRE 0x40
+CREDENTIAL_MGMT_PRE 0x41
}

Diagram sources

The command constants are defined as follows:

  • MAKE_CREDENTIAL (0x01): Creates a new credential
  • GET_ASSERTION (0x02): Gets an assertion for a credential
  • GET_INFO (0x04): Retrieves authenticator information
  • CLIENT_PIN (0x06): Handles PIN-related operations
  • RESET (0x07): Resets the authenticator
  • GET_NEXT_ASSERTION (0x08): Gets the next assertion when multiple credentials match
  • BIO_ENROLLMENT (0x09): Manages biometric enrollment
  • CREDENTIAL_MGMT (0x0A): Manages resident credentials
  • SELECTION (0x0B): Allows user selection of authenticator
  • LARGE_BLOBS (0x0C): Handles large blob storage
  • CONFIG (0x0D): Configures authenticator features

Additionally, there are prototype commands for pre-release features:

  • BIO_ENROLLMENT_PRE (0x40): Prototype biometric enrollment
  • CREDENTIAL_MGMT_PRE (0x41): Prototype credential management

Section sources

HID Transport Layer Interaction

CTAP2 commands are transmitted to the authenticator through the HID (Human Interface Device) transport layer, which provides a standardized way to communicate with USB devices. The communication follows a request-response pattern where commands are sent as CBOR-encoded messages and responses are received in the same format.

sequenceDiagram
participant Client as "Client Application"
participant Ctap2 as "Ctap2 Instance"
participant Device as "CtapHidDevice"
Client->>Ctap2 : Call command method
Ctap2->>Ctap2 : Package command with parameters
Ctap2->>Device : send_cbor(CMD, data)
Device->>Device : Format as CTAPHID.CBOR packet
Device->>Authenticator : Send via HID
Authenticator->>Device : Return response
Device->>Ctap2 : Parse response
Ctap2->>Ctap2 : Validate CBOR encoding
Ctap2->>Client : Return parsed response

Diagram sources

The send_cbor method in the Ctap2 class is responsible for sending commands to the authenticator. It packages the command byte and CBOR-encoded data into a request, validates the message size against the authenticator's maximum message size, and sends it through the device's call method. The response is then parsed, with status codes checked and CBOR decoding performed. The implementation ensures canonical CBOR encoding is used for security and interoperability.

Section sources

Error Handling and Status Codes

The CTAP2 implementation includes comprehensive error handling through the CtapError class, which maps CTAP2 error codes to descriptive constants. When a command fails, the authenticator returns an error status that is raised as a CtapError exception in the client code.

classDiagram
class CtapError$ERR {
+SUCCESS 0x00
+CREDENTIAL_EXCLUDED 0x0B
+PROCESSING 0x01
+INVALID_COMMAND 0x02
+INVALID_PARAMETER 0x03
+INVALID_LENGTH 0x04
+INVALID_SEQ 0x05
+TIMEOUT 0x06
+CHANNEL_BUSY 0x0A
+LOCK_REQUIRED 0x0B
+INVALID_CHANNEL 0x0C
+CBOR_UNEXPECTED_TYPE 0x10
+INVALID_CBOR 0x11
+MISSING_PARAMETER 0x12
+LIMIT_EXCEEDED 0x13
+BAD_CREDENTIAL 0x14
+CREDENTIAL_EXISTS 0x15
+NOT_ALLOWED 0x16
+PIN_REQUIRED 0x17
+PIN_INVALID 0x18
+PIN_BLOCKED 0x19
+PIN_AUTH_INVALID 0x1A
+PIN_AUTH_BLOCKED 0x1B
+PIN_NOT_SET 0x1C
+RESIDENT_CREDENTIALS_FULL 0x1D
+NOT_BIO_ENROLLMENT_AUTHORIZER 0x1E
+UNSUPPORTED_ALGORITHM 0x1F
+UNSUPPORTED_OPTION 0x20
+UNSUPPORTED_EXTENSION 0x21
+CREDENTIAL_MGMT_NOT_SUPPORTED 0x22
+KEY_STORE_FULL 0x23
+NOT_FPUV_AUTHORIZER 0x24
+USER_ACTION_TIMEOUT 0x25
+USER_ACTION_REQUIRED 0x26
+USER_NOT_PRESENT 0x27
+OPERATION_DENIED 0x28
+OPERATION_NOT_SUPPORTED 0x29
+OPERATION_ABORTED 0x2A
+INVALID_DURATION 0x2B
+USER_ACTION_REQUIRED 0x2C
+UNSUPPORTED_OPTION 0x2D
+PROCESSING 0x2E
+IDLE 0x2F
+INVALID_CBOR 0x30
+INVALID_COMMAND 0x31
+INVALID_PARAMETER 0x32
+INVALID_LENGTH 0x33
+INVALID_SEQ 0x34
+TIMEOUT 0x35
+CHANNEL_BUSY 0x36
+LOCK_REQUIRED 0x37
+INVALID_CHANNEL 0x38
+COMMAND_TOO_LARGE 0x39
+ACTION_TIMEOUT 0x3A
+UP_REQUIRED 0x3B
+UV_BLOCKED 0x3C
+INTEGRITY_FAILURE 0x3D
+INVALID_SUBCOMMAND 0x3E
+UV_INVALID 0x3F
+UNAUTHORIZED_PERMISSION 0x40
+OTHER 0x7F
}

Diagram sources

The error handling process works as follows:

  1. The authenticator returns a status byte in the response
  2. If the status is not 0x00 (SUCCESS), a CtapError is raised
  3. The error code is mapped to a descriptive constant
  4. The exception includes both the numeric code and descriptive name

Common error scenarios include:

  • PIN-related errors (PIN_INVALID, PIN_BLOCKED, PIN_NOT_SET)
  • Credential management errors (CREDENTIAL_EXISTS, RESIDENT_CREDENTIALS_FULL)
  • Authentication errors (USER_NOT_PRESENT, OPERATION_DENIED)
  • Protocol errors (INVALID_CBOR, INVALID_COMMAND)

Section sources

MakeCredential Command

The MakeCredential command is used to create a new credential on the authenticator. This is typically the first step in the registration process where a user enrolls a new authenticator with a relying party.

sequenceDiagram
participant Client
participant Ctap2
participant Authenticator
Client->>Ctap2 : make_credential()
Ctap2->>Ctap2 : Package parameters
Ctap2->>Authenticator : Send CMD=0x01
Authenticator->>Authenticator : Generate key pair
Authenticator->>Authenticator : Create attestation
Authenticator->>Ctap2 : Return attestation
Ctap2->>Ctap2 : Parse response
Ctap2->>Client : Return AttestationResponse

Diagram sources

The make_credential method accepts several parameters:

  • client_data_hash: SHA256 hash of the ClientData
  • rp: Relying Party information
  • user: User information
  • key_params: List of acceptable credential types
  • exclude_list: Optional list of credentials to exclude
  • extensions: Optional dict of extensions
  • options: Optional dict of options
  • pin_uv_param: Optional PIN/UV auth parameter
  • pin_uv_protocol: Version of PIN/UV protocol used

The command returns an AttestationResponse object containing the attestation statement, authenticator data, and other relevant information. The implementation ensures the request is properly formatted with all required parameters and handles error conditions appropriately.

Section sources

GetAssertion Command

The GetAssertion command is used to authenticate a user by retrieving an assertion for a previously created credential. This command is used during the login process to verify the user's identity.

sequenceDiagram
participant Client
participant Ctap2
participant Authenticator
Client->>Ctap2 : get_assertion()
Ctap2->>Ctap2 : Package parameters
Ctap2->>Authenticator : Send CMD=0x02
Authenticator->>Authenticator : Verify user presence
Authenticator->>Authenticator : Generate assertion
Authenticator->>Ctap2 : Return assertion
Ctap2->>Ctap2 : Parse response
Ctap2->>Client : Return AssertionResponse

Diagram sources

The get_assertion method accepts the following parameters:

  • rp_id: The Relying Party ID
  • client_data_hash: SHA256 hash of the ClientData
  • allow_list: Optional list of allowed credentials
  • extensions: Optional dict of extensions
  • options: Optional dict of options
  • pin_uv_param: Optional PIN/UV auth parameter
  • pin_uv_protocol: Version of PIN/UV protocol used

The command returns an AssertionResponse object containing the credential used, authenticator data, signature, and user information. The implementation includes a convenience method get_assertions that handles multiple matching credentials by calling get_next_assertion as needed.

Section sources

GetInfo Command

The GetInfo command retrieves information about the authenticator's capabilities and configuration. This command is typically called during initialization to determine what features are supported.

flowchart TD
A[Call get_info()] --> B[Send CMD=0x04]
B --> C{Response Received?}
C --> |Yes| D[Parse CBOR Response]
D --> E[Create Info Object]
E --> F[Cache Result]
F --> G[Return Info]
C --> |No| H[Raise CtapError]

Diagram sources

The get_info method returns an Info object containing various fields such as:

  • versions: Supported CTAP versions
  • extensions: Supported extensions
  • aaguid: Authenticator Attestation GUID
  • options: Boolean options (e.g., clientPin, up, uv)
  • max_msg_size: Maximum message size
  • pin_uv_protocols: Supported PIN/UV protocols
  • transports: Supported transports
  • algorithms: Supported algorithms
  • max_large_blob: Maximum large blob size

The Info object is cached after the first call and used throughout the session to determine the authenticator's capabilities. This information is critical for determining which commands and features are available.

Section sources

ClientPIN Command

The ClientPIN command handles all PIN-related operations on the authenticator, including setting, changing, and verifying PINs, as well as obtaining PIN/UV tokens for authentication.

classDiagram
class ClientPin$CMD {
+GET_PIN_RETRIES 0x01
+GET_KEY_AGREEMENT 0x02
+SET_PIN 0x03
+CHANGE_PIN 0x04
+GET_TOKEN_USING_PIN_LEGACY 0x05
+GET_TOKEN_USING_UV 0x06
+GET_UV_RETRIES 0x07
+GET_TOKEN_USING_PIN 0x09
}
class ClientPin$RESULT {
+KEY_AGREEMENT 0x01
+PIN_UV_TOKEN 0x02
+PIN_RETRIES 0x03
+POWER_CYCLE_STATE 0x04
+UV_RETRIES 0x05
}
class ClientPin$PERMISSION {
+MAKE_CREDENTIAL 0x01
+GET_ASSERTION 0x02
+CREDENTIAL_MGMT 0x04
+BIO_ENROLL 0x08
+LARGE_BLOB_WRITE 0x10
+AUTHENTICATOR_CFG 0x20
+PERSISTENT_CREDENTIAL_MGMT 0x40
}

Diagram sources

The ClientPin class implements the PIN/UV protocol with support for both version 1 and version 2. It provides methods for:

  • get_pin_token: Obtain a PIN/UV token using a PIN
  • get_uv_token: Obtain a PIN/UV token using built-in user verification
  • get_pin_retries: Get the number of PIN retries remaining
  • get_uv_retries: Get the number of UV retries remaining
  • set_pin: Set a new PIN
  • change_pin: Change an existing PIN

The implementation uses elliptic curve cryptography for key agreement and HMAC-based authentication to secure the communication between client and authenticator.

Section sources

Reset Command

The Reset command performs a factory reset of the authenticator, erasing all credentials, PIN, and other user data. This is a security-sensitive operation that typically requires user confirmation.

flowchart TD
A[Call reset()] --> B[Send CMD=0x07]
B --> C{Response Received?}
C --> |Yes| D[Log Reset Completion]
D --> E[Return None]
C --> |No| F[Raise CtapError]

Diagram sources

The reset method is straightforward, sending the RESET command (0x07) to the authenticator and waiting for a response. If the command succeeds, it logs the completion and returns None. If the command fails, a CtapError is raised with the appropriate error code.

This command is typically used when a user wants to completely wipe their authenticator, such as when transferring ownership or troubleshooting issues. The implementation ensures that no sensitive data remains on the device after a reset.

Section sources

GetNextAssertion Command

The GetNextAssertion command is used to retrieve additional assertions when multiple credentials match the request parameters in a GetAssertion call.

sequenceDiagram
participant Client
participant Ctap2
participant Authenticator
Client->>Ctap2 : get_next_assertion()
Ctap2->>Authenticator : Send CMD=0x08
Authenticator->>Ctap2 : Return next assertion
Ctap2->>Ctap2 : Parse response
Ctap2->>Client : Return AssertionResponse

Diagram sources

The get_next_assertion method is called after an initial get_assertion call when multiple credentials match the request. The first response includes a number_of_credentials field indicating how many total responses are available. The client can then call get_next_assertion repeatedly to retrieve the remaining assertions.

The implementation includes a convenience method get_assertions that automatically handles this process by calling get_next_assertion the appropriate number of times and returning a list of all assertions.

Section sources

CredentialManagement Command

The CredentialManagement command allows management of resident credentials on the authenticator, including enumeration, deletion, and updating user information.

classDiagram
class CredentialManagement$CMD {
+GET_CREDS_METADATA 0x01
+ENUMERATE_RPS_BEGIN 0x02
+ENUMERATE_RPS_NEXT 0x03
+ENUMERATE_CREDS_BEGIN 0x04
+ENUMERATE_CREDS_NEXT 0x05
+DELETE_CREDENTIAL 0x06
+UPDATE_USER_INFO 0x07
}
class CredentialManagement$PARAM {
+RP_ID_HASH 0x01
+CREDENTIAL_ID 0x02
+USER 0x03
}
class CredentialManagement$RESULT {
+EXISTING_CRED_COUNT 0x01
+MAX_REMAINING_COUNT 0x02
+RP 0x03
+RP_ID_HASH 0x04
+TOTAL_RPS 0x05
+USER 0x06
+CREDENTIAL_ID 0x07
+PUBLIC_KEY 0x08
+TOTAL_CREDENTIALS 0x09
+CRED_PROTECT 0x0A
+LARGE_BLOB_KEY 0x0B
}

Diagram sources

The CredentialManagement class provides methods for:

  • get_metadata: Get credentials metadata
  • enumerate_rps_begin and enumerate_rps_next: Enumerate Relying Parties
  • enumerate_creds_begin and enumerate_creds_next: Enumerate credentials for an RP
  • delete_cred: Delete a credential
  • update_user_info: Update user information for a credential

These operations require appropriate permissions and are typically protected by PIN/UV authentication. The implementation handles both the standard credential management commands and the prototype version for backward compatibility.

Section sources

LargeBlobs Command

The LargeBlobs command manages large blob storage on the authenticator, allowing applications to store additional data associated with credentials.

classDiagram
class LargeBlobs {
+read_blob_array() Sequence~Mapping~
+write_blob_array(blob_array) None
+get_blob(large_blob_key) bytes | None
+put_blob(large_blob_key, data) None
+delete_blob(large_blob_key) None
}

Diagram sources

The LargeBlobs class provides methods for:

  • read_blob_array: Read the entire large blobs array
  • write_blob_array: Write the entire large blobs array
  • get_blob: Get a specific blob using its largeBlobKey
  • put_blob: Store a blob using its largeBlobKey
  • delete_blob: Delete a blob using its largeBlobKey

The implementation handles fragmentation for large messages, compression using zlib, and encryption using AES-GCM. Blobs are stored in a CBOR-encoded array on the authenticator and can be accessed only with appropriate permissions.

Section sources

Config Command

The Config command allows configuration of various authenticator features through subcommands.

classDiagram
class Config$CMD {
+ENABLE_ENTERPRISE_ATT 0x01
+TOGGLE_ALWAYS_UV 0x02
+SET_MIN_PIN_LENGTH 0x03
+VENDOR_PROTOTYPE 0xFF
}
class Config$PARAM {
+NEW_MIN_PIN_LENGTH 0x01
+MIN_PIN_LENGTH_RPIDS 0x02
+FORCE_CHANGE_PIN 0x03
}

Diagram sources

The Config class provides methods for:

  • enable_enterprise_attestation: Enable enterprise attestation
  • toggle_always_uv: Toggle the alwaysUV setting
  • set_min_pin_length: Set the minimum PIN length

These configuration options allow administrators to control various security and usability aspects of the authenticator. The implementation ensures that configuration changes are authenticated using PIN/UV tokens when required.

Section sources

Authenticator State Management

The CTAP2 implementation maintains state information about the authenticator, including configuration settings, counter values, and cached information.

classDiagram
class Ctap2 {
-device CtapDevice
-_strict_cbor bool
-_max_msg_size int
-_info Info
+info Info
+__init__(device, strict_cbor)
}

Diagram sources

The Ctap2 class maintains several state variables:

  • _info: Cached result of the GetInfo command
  • _max_msg_size: Maximum message size for CBOR commands
  • _strict_cbor: Whether to enforce canonical CBOR encoding

The authenticator counter is stored in the authenticator data and incremented with each successful authentication. This counter helps prevent replay attacks by ensuring each authentication is unique. The implementation properly handles counter validation and storage.

Section sources

Test Suite Examples

The test suite provides practical examples of complete command flows, demonstrating how the CTAP2 commands are used in real scenarios.

sequenceDiagram
participant Test
participant Ctap2
participant MockDevice
Test->>Ctap2 : mock_ctap()
Ctap2->>MockDevice : Initialize mock
MockDevice->>Ctap2 : Return mock device
Ctap2->>Test : Return ctap instance
Test->>Ctap2 : get_info()
Ctap2->>MockDevice : call(CTAPHID.CBOR)
MockDevice->>Ctap2 : Return _INFO
Ctap2->>Test : Return Info object
Test->>Test : Assert properties

Diagram sources

The test suite includes tests for:

  • Parsing of Info objects
  • Creation and parsing of attested credential data
  • Parsing of authenticator data
  • Packed attestation verification
  • GetAssertion command flow
  • PIN protocol operations

These tests validate that the implementation correctly handles both successful operations and error conditions, ensuring robustness and compliance with the CTAP2 specification.

Section sources

Conclusion

The CTAP2 implementation in the FIDO2 library provides a comprehensive and secure interface for communicating with FIDO2 authenticators. Each command is carefully implemented to follow the CTAP2 specification, with proper error handling, security considerations, and feature support. The modular design separates concerns between command execution, transport layer communication, and higher-level functionality, making the code maintainable and extensible. The implementation supports all major CTAP2 commands and provides a solid foundation for building secure authentication systems.