### Example: Set PIN Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-pin.md Provides an example of setting a new PIN on the device, with basic error handling for potential issues during the process. ```python client_pin = ClientPin(ctap2) try: client_pin.set_pin("1234") print("PIN set successfully") except CtapError as e: print(f"Failed to set PIN: {e}") ``` -------------------------------- ### Example: Get PIN Token Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-pin.md Demonstrates how to obtain a PIN token for specific operations, including error handling for invalid PIN, blocked device, or when no PIN is set. ```python from fido2.ctap2.pin import ClientPin from fido2.ctap2 import Ctap2 from fido2.hid import list_devices device = next(list_devices()) ctap2 = Ctap2(device) client_pin = ClientPin(ctap2) # Get PIN token for operations try: pin_token = client_pin.get_pin_token( pin="1234", permissions=ClientPin.PERMISSION.MAKE_CREDENTIAL, rp_id="example.com" ) except CtapError as e: if e.code == CtapError.ERR.PIN_INVALID: print("Invalid PIN") elif e.code == CtapError.ERR.PIN_BLOCKED: print("Device locked") finally: device.close() ``` -------------------------------- ### Install python-fido2 Source: https://github.com/yubico/python-fido2/blob/main/README.adoc Install the library using pip. ```bash pip install fido2 ``` -------------------------------- ### CtapDevice List Devices Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Example demonstrating how to list available CTAP devices using HidDeviceLinux and close them. ```python from fido2.hid import HidDeviceLinux for device in HidDeviceLinux.list_devices(): print(f"Found device: {device}") device.close() ``` -------------------------------- ### Install u2f-devd on FreeBSD Source: https://github.com/yubico/python-fido2/blob/main/README.adoc Install the security/u2f-devd package on FreeBSD to automate FIDO device access rules. ```bash # pkg install u2f-devd ``` -------------------------------- ### Authentication Flow Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/README.md Outlines the client and server steps involved in the FIDO2 authentication process. ```text Client: request options from server Server: Fido2Server.authenticate_begin() → return PublicKeyCredentialRequestOptions Client: Fido2Client.get_assertion() → sign challenge on device Client: send AuthenticatorAssertionResponse to server Server: Fido2Server.authenticate_complete() → verify signature and counter ``` -------------------------------- ### CTAP1 Registration Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Example demonstrating how to use the Ctap1 class to register a credential. It shows device listing, Ctap1 instantiation, registration call, and error handling for ApduError. Ensure to close the device in a finally block. ```python from fido2.ctap1 import Ctap1, ApduError from fido2.hid import HidDeviceLinux device = next(HidDeviceLinux.list_devices()) try: ctap1 = Ctap1(device) reg_data = ctap1.register(challenge, app_param) except ApduError as e: print(f"Device error: {e.code:04x}") finally: device.close() ``` -------------------------------- ### Install python-fido2 with NFC support Source: https://github.com/yubico/python-fido2/blob/main/README.adoc Install the library with dependencies for NFC authenticator communication. ```bash pip install fido2[pcsc] ``` -------------------------------- ### Example Usage Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Demonstrates how to use the Ctap1 class to register a credential, including device listing, instantiation, error handling, and device closure. ```APIDOC **Example:** ```python from fido2.ctap1 import Ctap1, ApduError from fido2.hid import HidDeviceLinux device = next(HidDeviceLinux.list_devices()) try: ctap1 = Ctap1(device) reg_data = ctap1.register(challenge, app_param) except ApduError as e: print(f"Device error: {e.code:04x}") finally: device.close() ``` ``` -------------------------------- ### Extension Processing Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Demonstrates how to use RegistrationExtensionProcessor and AuthenticationExtensionProcessor to handle client-side extension inputs. ```APIDOC ## Extension Processing Example ```python from fido2.ctap2.extensions import ( RegistrationExtensionProcessor, AuthenticationExtensionProcessor ) # Registration with extensions reg_processor = RegistrationExtensionProcessor() extensions = { "credentialProtectionPolicy": "userVerificationRequired", "hmac-secret": True, "credProps": True } processed = reg_processor.process_client_inputs(extensions) # Authentication with extensions auth_processor = AuthenticationExtensionProcessor() extensions = { "hmac-secret": True } processed = auth_processor.process_client_inputs(extensions) ``` ``` -------------------------------- ### ByteBuffer Example Usage Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-utils.md Demonstrates how to initialize a ByteBuffer and use its unpack method to read bytes and integers according to struct formats. ```python from fido2.utils import ByteBuffer data = b"\x00\x01\x02\x03\x04" buf = ByteBuffer(data) first_byte = buf.unpack("B") # 0 uint32 = buf.unpack(">I") # 0x01020304 ``` -------------------------------- ### Registration Flow Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/README.md Illustrates the sequence of client and server interactions during the FIDO2 registration process. ```text Client: request options from server Server: Fido2Server.register_begin() → return PublicKeyCredentialCreationOptions Client: Fido2Client.make_credential() → create credential on device Client: send AuthenticatorAttestationResponse to server Server: Fido2Server.register_complete() → validate and store credential ``` -------------------------------- ### Fido2Client Example Usage Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-client.md Demonstrates how to set up and use the Fido2Client for FIDO2 registration and authentication. Includes a custom UserInteraction implementation for PIN prompts and touch notifications. ```python from fido2.client import Fido2Client, DefaultClientDataCollector, UserInteraction from fido2.hid import list_devices class MyUserInteraction(UserInteraction): def prompt_up(self): print("Touch the authenticator") def request_pin(self, permissions, rp_id): return input(f"Enter PIN for {rp_id}: ") # Enumerate and use a device device = next(list_devices()) client = Fido2Client( device, collector=DefaultClientDataCollector("https://example.com"), user_interaction=MyUserInteraction() ) # Registration reg_response = client.make_credential(server_options) # Authentication assertion_selection = client.get_assertion(server_options) auth_response = assertion_selection.get_response(0) ``` -------------------------------- ### int2bytes Example Usage Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-utils.md Demonstrates converting an integer to a byte string of a specific length, ensuring correct padding and byte order. ```python from fido2.utils import int2bytes b = int2bytes(256, 2) # b"\x01\x00" ``` -------------------------------- ### Complete Credential Management Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-credman.md Demonstrates a full credential management workflow, including obtaining a PIN token, initializing credential management, retrieving metadata, enumerating RPs and credentials, and deleting a specific credential. Ensure the device is properly connected and accessible. ```python from fido2.ctap2 import Ctap2 from fido2.ctap2.pin import ClientPin from fido2.ctap2.credman import CredentialManagement from fido2.hid import list_devices device = next(list_devices()) try: ctap2 = Ctap2(device) # Get PIN token for credential management client_pin = ClientPin(ctap2) pin_token = client_pin.get_pin_token( pin="1234", permissions=ClientPin.PERMISSION.CREDENTIAL_MGMT ) # Initialize credential management credman = CredentialManagement( ctap2, pin_protocol=2, pin_token=pin_token ) # Get metadata metadata = credman.get_metadata() print(f"Credentials: {metadata.existing_resident_credentials_count}") print(f"Available: {metadata.max_possible_remaining_resident_credentials}") # List all RPs for rp in credman.enumerate_rps(): print(f"\nRP: {rp.rp['name']} ({rp.rp['id']})") print(f"Credentials: {rp.total_credentials}") # List credentials for this RP for cred in credman.enumerate_creds(rp_id=rp.rp['id']): print(f" - {cred.user['name']}") print(f" ID: {cred.credential_id.hex()}") # Delete specific credential for cred in credman.enumerate_creds(rp_id="example.com"): if cred.user['name'] == 'old_user@example.com': credman.delete_cred(cred.credential_id) print(f"Deleted credential for {cred.user['name']}") break finally: device.close() ``` -------------------------------- ### Example: Create CollectedClientData Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-webauthn.md Demonstrates how to create a CollectedClientData object using the `create` class method. This is useful for preparing client data for WebAuthn operations. ```python import os client_data = CollectedClientData.create( type=CollectedClientData.TYPE.CREATE, origin="https://example.com", challenge=os.urandom(32) ) ``` -------------------------------- ### Authentication with PIN Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-pin.md Example of authenticating an existing credential using PIN authentication. Requires a PIN token and specifies the PIN protocol version. ```python # Authentication with PIN pin_auth = calculate_pin_auth(pin_token, client_data_hash) assertion = ctap2.get_assertion( rp_id=rp_id, client_data_hash=client_data_hash, pin_auth=pin_auth, pin_protocol=2 ) ``` -------------------------------- ### Registration with PIN Authentication Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-pin.md Example of registering a new credential using PIN authentication. Requires a PIN token and specifies the PIN protocol version. ```python # Registration with PIN pin_auth = calculate_pin_auth(pin_token, client_data_hash) credential = ctap2.make_credential( client_data_hash=client_data_hash, rp=rp, user=user, pub_key_cred_params=params, pin_auth=pin_auth, # Include PIN auth pin_protocol=2 # Specify protocol version ) ``` -------------------------------- ### CoseKey.supported_algorithms Method Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Retrieves a sequence of all supported COSE algorithm identifiers. The example shows the typical output format. ```python algs = CoseKey.supported_algorithms() # [-7, -8, -35, -36, -37, -257, -259, -260] ``` -------------------------------- ### CBOR Encoding Examples Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cbor.md Demonstrates the encoding of various simple and complex data types into CBOR format using the `fido2.cbor.encode` function. Includes examples for integers, booleans, None, strings (text and bytes), arrays, and maps. ```python from fido2 import cbor # Simple values cbor.encode(0) # b'\x00' (unsigned 0) cbor.encode(-1) # b'\x20' (negative 0) cbor.encode(True) # b'\xf5' cbor.encode(False) # b'\xf4' cbor.encode(None) # b'\xf6' # Strings cbor.encode("hello") # b'\x65hello' (5 chars + text) cbor.encode(b"hello") # b'\x45hello' (5 bytes + byte string) # Collections cbor.encode([1, 2, 3]) # b'\x83\x01\x02\x03' cbor.encode({"a": 1}) # b'\xa1\x61a\x01' # Nested cbor.encode({1: {"a": [1, 2]}}) ``` -------------------------------- ### Example: Change PIN Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-pin.md Illustrates how to change the PIN on a FIDO2 device, including specific checks for an incorrect current PIN and other potential errors. ```python try: client_pin.change_pin("1234", "5678") print("PIN changed") except CtapError as e: if e.code == CtapError.ERR.PIN_INVALID: print("Current PIN incorrect") else: print(f"Error: {e}") ``` -------------------------------- ### CtapDevice Call Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Example of sending a CTAP command with CBOR-encoded data using the call method. ```python response = device.call(0x01, cbor.encode(request)) ``` -------------------------------- ### ES256 Key Creation and Verification Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Demonstrates how to create an ES256 key from CTAP1 data and then use it to verify a signature. Ensure the message and signature are correctly provided. ```python from fido2.cose import ES256 # From CTAP1 public key ctap1_key = b'\x04' + x_bytes + y_bytes # 65 bytes total es256_key = ES256.from_ctap1(ctap1_key) # Verify a signature try: es256_key.verify(message, signature) except InvalidSignature: print("Signature invalid") ``` -------------------------------- ### CoseKey.supported_algorithms Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Get a list of all supported COSE algorithm identifiers. ```APIDOC ## CoseKey.supported_algorithms ### Description Get list of all supported COSE algorithm identifiers. ### Method ```python @classmethod def supported_algorithms(cls) -> Sequence[int] ``` ### Returns Sequence of algorithm IDs ### Example ```python algs = CoseKey.supported_algorithms() # [-7, -8, -35, -36, -37, -257, -259, -260] ``` ``` -------------------------------- ### Error Hierarchy Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/README.md Visualizes the inheritance structure of exceptions within the FIDO2 library and standard library errors. ```text Exception ├── ClientError (fido2-client.md) │ └── PinRequiredError ├── CtapError (fido2-ctap.md) ├── InvalidRegistrationResponse (fido2-server.md) ├── InvalidAuthenticationResponse (fido2-server.md) ├── AttestationFailure (fido2-attestation.md) │ └── InvalidCertificateClaim └── ValueError, OSError (standard library) ``` -------------------------------- ### bytes2int Example Usage Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-utils.md Shows how to convert a byte string representing a number into its integer equivalent using the bytes2int function. ```python from fido2.utils import bytes2int b = b"\x00\x01" n = bytes2int(b) # 1 ``` -------------------------------- ### Create Release Branch Source: https://github.com/yubico/python-fido2/blob/main/RELEASE.adoc Start a new release by creating a dedicated branch. This isolates release-specific changes. ```bash git checkout -b release/x.y.z ``` -------------------------------- ### Request Authentication Extensions with Fido2Server Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Demonstrates how to request extensions during the FIDO2 authentication process using `authenticate_begin`. This example specifically requests the 'hmac-secret' extension. ```python options, state = server.authenticate_begin( extensions={ "hmac-secret": True } ) ``` -------------------------------- ### RS256 Key Parsing and Verification Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Demonstrates how to parse an RS256 key from a COSE dictionary and then use it to verify a signature. Ensure the COSE dictionary, message, and signature are correctly provided. ```python from fido2.cose import RS256 rs256_key = RS256.parse(cose_dict) rs256_key.verify(message, signature) ``` -------------------------------- ### Enumerate FIDO2 Device and Get Info Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md This snippet demonstrates how to find the first available FIDO2 HID device on Linux and retrieve its capabilities, including supported CTAP versions and extensions. Ensure the device is properly connected and recognized by the system. ```python from fido2.hid import HidDeviceLinux from fido2.ctap2 import Ctap2 # Find first device device = next(HidDeviceLinux.list_devices()) try: ctap2 = Ctap2(device) info = ctap2.get_info() print(f"Device versions: {info.versions}") print(f"Extensions: {info.extensions}") finally: device.close() ``` -------------------------------- ### FIDO2 Utility Functions Example Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-utils.md Demonstrates the usage of websafe_encode, websafe_decode, sha256, bytes2int, and int2bytes for FIDO2 operations. This includes generating a challenge, hashing an RP ID, and performing round-trip conversions between bytes and integers, and base64url encoded strings. ```python from fido2.utils import ( websafe_encode, websafe_decode, sha256, bytes2int, int2bytes ) import os # Generate challenge challenge = os.urandom(32) challenge_b64 = websafe_encode(challenge) print(f"Challenge (base64url): {challenge_b64}") # Hash RP ID rp_id = "example.com" rp_id_hash = sha256(rp_id.encode()) print(f"RP ID hash: {rp_id_hash.hex()}") # Convert counter to bytes counter = 42 counter_bytes = int2bytes(counter, 4) counter_back = bytes2int(counter_bytes) assert counter == counter_back # Round-trip encoding original = b"test_data" encoded = websafe_encode(original) decoded = websafe_decode(encoded) assert original == decoded ``` -------------------------------- ### Signature Verification Error Handling Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Demonstrates how to verify a signature using a CoseKey object and handle potential exceptions like InvalidSignature or NotImplementedError. Ensure cryptography library is installed. ```python from cryptography.exceptions import InvalidSignature from fido2.cose import CoseKey key = CoseKey.parse(cose_dict) try: key.verify(message, signature) except InvalidSignature: print("Signature verification failed") except NotImplementedError: print("Algorithm not supported for verification") ``` -------------------------------- ### Custom FIDO2 Extension Processor Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Example of creating a custom extension processor for FIDO2 registration. This class extends the base RegistrationExtensionProcessor and customizes the handling of client inputs for a 'custom-ext'. ```python from fido2.ctap2.extensions import RegistrationExtensionProcessor class CustomExtensionProcessor(RegistrationExtensionProcessor): def process_client_inputs(self, extensions): result = super().process_client_inputs(extensions) if "custom-ext" in extensions: result["custom-ext"] = process_custom(extensions["custom-ext"]) return result ``` -------------------------------- ### Timeout Handling for FIDO2 HID Device Operations Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-hid.md This example shows how to implement a timeout for a FIDO2 HID device operation using a threading.Event and a threading.Timer. This prevents operations from hanging indefinitely. ```python import threading from fido2.hid import list_devices device = next(list_devices()) cancel_event = threading.Event() # Set timeout in another thread timer = threading.Timer(5, cancel_event.set) timer.start() try: response = device.call(cmd, data, event=cancel_event) finally: timer.cancel() device.close() ``` -------------------------------- ### Get Device Info (CTAP2) Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Retrieves information about the FIDO2 device, including supported FIDO versions, extensions, and capabilities. Returns an Info object. ```python def get_info(self) -> Info ``` -------------------------------- ### Handle PIN-related CtapError Codes Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example demonstrating how to handle various PIN-related errors returned as CtapError codes. This includes checking for PIN_NOT_SET, PIN_INVALID, and PIN_BLOCKED states to take appropriate actions. ```python from fido2.ctap2.pin import ClientPin from fido2.ctap import CtapError client_pin = ClientPin(ctap2) try: pin_token = client_pin.get_pin_token("1234") except CtapError as e: if e.code == CtapError.ERR.PIN_NOT_SET: client_pin.set_pin("1234") elif e.code == CtapError.ERR.PIN_INVALID: print("PIN incorrect") elif e.code in (CtapError.ERR.PIN_BLOCKED, CtapError.ERR.PIN_AUTH_BLOCKED): print("Device locked, power cycle needed") ``` -------------------------------- ### Handle AttestationFailure Exception Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of catching and handling AttestationFailure during the verification process. This is useful when attestation verification might fail due to various reasons like invalid format or signature. ```python from fido2.attestation import get_verifier, AttestationFailure verifier = get_verifier(attestation_object.fmt) try: data = verifier.verify(attestation_object, auth_data, client_data_hash) except AttestationFailure as e: print(f"Attestation invalid: {e}") ``` -------------------------------- ### CoseKey.for_alg Method Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Retrieves the CoseKey subclass corresponding to a given COSE algorithm identifier. Example shows getting the ES256 key class and parsing a COSE dictionary. ```python from fido2.cose import CoseKey key_cls = CoseKey.for_alg(-7) # Returns ES256 key = key_cls.parse(cose_dict) ``` -------------------------------- ### Custom FIDO2 Attestation Verification Function Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-attestation.md Implement a custom function to verify FIDO2 attestation objects. This example shows how to get the appropriate verifier based on the attestation format and perform basic validation checks, including AAGUID and certificate chain verification. ```python from fido2.server import Fido2Server from fido2.attestation import get_verifier, InvalidCertificateClaim def verify_attestation(attestation_object, client_data_hash): """Custom attestation verification function.""" verifier = get_verifier(attestation_object.fmt) if not verifier: raise ValueError(f"Unsupported format: {attestation_object.fmt}") try: data = verifier.verify(attestation_object, client_data_hash) # Check AAGUID if needed if data.aaguid != Aaguid.NONE: # Validate against known AAGUIDs pass # Check certificate chain if data.trust_path: # Verify against trusted root CAs pass return data except InvalidCertificateClaim as e: # Log certificate validation failure raise server = Fido2Server( rp={"id": "example.com", "name": "Example"}, verify_attestation=verify_attestation ) ``` -------------------------------- ### Begin User Registration Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-server.md Initiates the user registration process by generating FIDO2 options. Requires user information and optionally accepts existing credentials, resident key requirements, user verification preferences, authenticator attachment preferences, a custom challenge, and extensions. Returns creation options and internal state for completion. ```python from fido2.server import Fido2Server from fido2.webauthn import PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity server = Fido2Server( PublicKeyCredentialRpEntity(id="example.com", name="Example") ) options, state = server.register_begin( user=PublicKeyCredentialUserEntity( id=b"user123", name="alice@example.com", display_name="Alice" ) ) # Send options to client, save state for later verification ``` -------------------------------- ### Begin Authentication Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-server.md Initiates the authentication process by generating FIDO2 options. Optionally accepts a list of allowed credentials, user verification preferences, a custom challenge, and extensions. Returns request options and internal state for verification. ```python options, state = server.authenticate_begin( credentials=[stored_credential] ) # Send options to client, save state for verification ``` -------------------------------- ### Fido2ClientWindows Initialization Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-client.md Initializes the Windows native FIDO2 client using the Windows Hello API. Available on Windows via fido2.client.windows.Fido2ClientWindows. ```python class Fido2ClientWindows(WebAuthnClient): def __init__(self, user_interaction: UserInteraction | None = None) ``` -------------------------------- ### CoseKey.for_name Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Get the CoseKey subclass by algorithm name. Returns the appropriate subclass or UnsupportedKey if the name is not recognized. ```APIDOC ## CoseKey.for_name ### Description Get the CoseKey subclass by algorithm name. ### Method ```python @classmethod def for_name(cls, name: str) -> type[CoseKey] ``` ### Parameters #### Path Parameters - **name** (str) - Required - Algorithm class name (e.g., "ES256") ### Returns CoseKey subclass or `UnsupportedKey` ``` -------------------------------- ### Get FIDO2 Version using importlib.metadata Source: https://github.com/yubico/python-fido2/blob/main/doc/Migration_1-2.adoc The `__version__` attribute has been removed. Use `importlib.metadata.version` to query the package version. ```python from fido2 import __version__ print(__version__) ``` ```python from importlib.metadata import version print(version("fido2")) ``` -------------------------------- ### CoseKey.for_alg Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Get the CoseKey subclass for a COSE algorithm identifier. Returns the appropriate subclass or UnsupportedKey if the algorithm is unknown. ```APIDOC ## CoseKey.for_alg ### Description Get the CoseKey subclass for a COSE algorithm identifier. ### Method ```python @classmethod def for_alg(cls, alg: int) -> type[CoseKey] ``` ### Parameters #### Path Parameters - **alg** (int) - Required - COSE algorithm identifier ### Returns CoseKey subclass or `UnsupportedKey` if algorithm unknown ### Example ```python from fido2.cose import CoseKey key_cls = CoseKey.for_alg(-7) # Returns ES256 key = key_cls.parse(cose_dict) ``` ``` -------------------------------- ### authenticate_begin Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-server.md Initiates the FIDO2 authentication process. It generates the necessary options for the client to select and use a credential for authentication and returns internal state for later verification. ```APIDOC ## authenticate_begin ### Description Initiates the FIDO2 authentication process. It generates the necessary options for the client to select and use a credential for authentication and returns internal state for later verification. ### Method Signature ```python def authenticate_begin( self, credentials: Sequence[AttestedCredentialData | PublicKeyCredentialDescriptor] | None = None, user_verification: UserVerificationRequirement | None = None, challenge: bytes | None = None, extensions: Mapping[str, Any] | None = None, ) -> tuple[CredentialRequestOptions, bytes] ``` ### Parameters #### Credentials - **credentials** (Sequence[AttestedCredentialData | PublicKeyCredentialDescriptor]) - Optional - Allowed credentials; if None, any credential may be used #### User Verification - **user_verification** (UserVerificationRequirement) - Optional - User verification requirement #### Challenge - **challenge** (bytes) - Optional - Custom challenge (must be ≥16 bytes); random if not provided #### Extensions - **extensions** (Mapping[str, Any]) - Optional - WebAuthn extensions to request ### Returns - Tuple of `(CredentialRequestOptions, bytes)` where the bytes are the internal state ### Example ```python options, state = server.authenticate_begin( credentials=[stored_credential] ) # Send options to client, save state for verification ``` ``` -------------------------------- ### Initialize CredentialManagement Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-credman.md Instantiate the CredentialManagement class with a CTAP2 instance and optional PIN protocol and token. Requires PIN authentication via pin_token. ```python class CredentialManagement: def __init__( self, ctap: Ctap2, pin_protocol: int = 2, pin_token: bytes | None = None ) ``` -------------------------------- ### Build Release Artifacts Source: https://github.com/yubico/python-fido2/blob/main/RELEASE.adoc Build the distributable packages (source distribution and wheel) for the release. ```bash uv build ``` -------------------------------- ### Credential Properties Response Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Example response structure when the 'credProps' extension is used, indicating support for resident keys and credential blobs. ```json { "rk": True, # Resident key "credentialBlob": True # Can store blob } ``` -------------------------------- ### Fido2Server Constructor Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-server.md Initializes a new Fido2Server instance. This class handles the server-side logic for FIDO2/WebAuthn registration and authentication flows. ```APIDOC ## Fido2Server Constructor ### Description Initializes a new Fido2Server instance. This class handles the server-side logic for FIDO2/WebAuthn registration and authentication flows. ### Method __init__ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **rp** (PublicKeyCredentialRpEntity) - Required - Relying Party metadata containing ID, name, and other RP information - **attestation** (AttestationConveyancePreference | None) - Optional - Attestation conveyance preference (none, indirect, direct, enterprise) - **verify_origin** (Callable[[str], bool] | None) - Optional - Custom origin verification function; defaults to RP ID-based verification - **verify_attestation** (Callable[[AttestationObject, bytes], None] | None) - Optional - Custom attestation verification function; defaults to ignoring attestation ### Returns `Fido2Server` instance ### Raises: - `AssertionError`: If RP entity has no ID ``` -------------------------------- ### Handle InvalidCertificateClaim Exception Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of catching InvalidCertificateClaim during verification. This specific exception is useful for diagnosing certificate-related issues within the attestation process. ```python from fido2.attestation import InvalidCertificateClaim try: data = verifier.verify(attestation_object, auth_data, client_data_hash) except InvalidCertificateClaim as e: print(f"Certificate invalid: {e}") ``` -------------------------------- ### register_begin Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-server.md Initiates the FIDO2 credential registration process. It generates the necessary options for the client to create a new credential and returns internal state for later verification. ```APIDOC ## register_begin ### Description Initiates the FIDO2 credential registration process. It generates the necessary options for the client to create a new credential and returns internal state for later verification. ### Method Signature ```python def register_begin( self, user: PublicKeyCredentialUserEntity, credentials: Sequence[AttestedCredentialData | PublicKeyCredentialDescriptor] | None = None, resident_key_requirement: ResidentKeyRequirement | None = None, user_verification: UserVerificationRequirement | None = None, authenticator_attachment: AuthenticatorAttachment | None = None, challenge: bytes | None = None, extensions: Mapping[str, Any] | None = None, ) -> tuple[CredentialCreationOptions, bytes] ``` ### Parameters #### User - **user** (PublicKeyCredentialUserEntity) - Required - User information (ID, name, display name) #### Credentials - **credentials** (Sequence[AttestedCredentialData | PublicKeyCredentialDescriptor]) - Optional - List of existing credentials to exclude from registration #### Resident Key Requirement - **resident_key_requirement** (ResidentKeyRequirement) - Optional - Resident key requirement level #### User Verification - **user_verification** (UserVerificationRequirement) - Optional - User verification requirement level #### Authenticator Attachment - **authenticator_attachment** (AuthenticatorAttachment) - Optional - Preferred authenticator type (platform or cross-platform) #### Challenge - **challenge** (bytes) - Optional - Custom challenge (must be ≥16 bytes); random if not provided #### Extensions - **extensions** (Mapping[str, Any]) - Optional - WebAuthn extensions to request ### Returns - Tuple of `(CredentialCreationOptions, bytes)` where the bytes are the internal state required for `register_complete` ### Example ```python from fido2.server import Fido2Server from fido2.webauthn import PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity server = Fido2Server( PublicKeyCredentialRpEntity(id="example.com", name="Example") ) options, state = server.register_begin( user=PublicKeyCredentialUserEntity( id=b"user123", name="alice@example.com", display_name="Alice" ) ) # Send options to client, save state for later verification ``` ``` -------------------------------- ### Handle InvalidAuthenticationResponse During Authentication Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of how to catch and handle an InvalidAuthenticationResponse exception during FIDO2 authentication. This can be triggered by a challenge mismatch or replay detection failures. ```python from fido2.server import InvalidAuthenticationResponse try: credential, counter = server.authenticate_complete(state, response) except InvalidAuthenticationResponse as e: print(f"Authentication failed: {e}") ``` -------------------------------- ### Fido2Server Constructor Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-server.md Initializes the Fido2Server with Relying Party metadata and optional verification configurations. Ensure the RP entity has an ID. ```python def __init__( self, rp: PublicKeyCredentialRpEntity, attestation: AttestationConveyancePreference | None = None, verify_origin: VerifyOrigin | None = None, verify_attestation: VerifyAttestation | None = None, ) ``` -------------------------------- ### Fido2ClientWindows Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-client.md Windows native FIDO2 client using the Windows Hello API. ```APIDOC ## Fido2ClientWindows ### Description Windows native FIDO2 client using the Windows Hello API. Available on Windows via `fido2.client.windows.Fido2ClientWindows` ### Constructor `__init__(self, user_interaction: UserInteraction | None = None)` ``` -------------------------------- ### Get Attestation Verifier Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-attestation.md Retrieve an attestation verifier for a specific format. Use this when you need to verify the authenticity of an authenticator's attestation statement. ```python from fido2.attestation import get_verifier verifier = get_verifier("packed") if verifier: data = verifier.verify(attestation_object, auth_data, client_data_hash) ``` -------------------------------- ### Run Development Tests Source: https://github.com/yubico/python-fido2/blob/main/README.adoc Execute the project's tests using uv and pytest. Note that these tests are destructive and will factory reset the FIDO device. ```bash uv run pytest ``` -------------------------------- ### Process FIDO2 Registration and Authentication Extensions Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Demonstrates how to process client inputs for registration and authentication extensions using the fido2 library. Ensure the correct extension processor is used for each operation. ```python from fido2.ctap2.extensions import ( RegistrationExtensionProcessor, AuthenticationExtensionProcessor ) # Registration with extensions reg_processor = RegistrationExtensionProcessor() extensions = { "credentialProtectionPolicy": "userVerificationRequired", "hmac-secret": True, "credProps": True } processed = reg_processor.process_client_inputs(extensions) # Authentication with extensions auth_processor = AuthenticationExtensionProcessor() extensions = { "hmac-secret": True } processed = auth_processor.process_client_inputs(extensions) ``` -------------------------------- ### Handling CtapError in Python Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of how to catch and interpret CtapError exceptions in Python. It checks for specific error codes like PIN_REQUIRED, NO_CREDENTIALS, and TIMEOUT. ```python from fido2.ctap import CtapError try: response = ctap2.make_credential(...) except CtapError as e: if e.code == CtapError.ERR.PIN_REQUIRED: print("Device requires PIN") elif e.code == CtapError.ERR.NO_CREDENTIALS: print("No credentials on device") elif e.code == CtapError.ERR.TIMEOUT: print("Device timeout") else: print(f"CTAP error 0x{e.code:02x}") ``` -------------------------------- ### Request Registration Extensions with Fido2Server Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Shows how to request specific extensions during the FIDO2 registration process using `register_begin`. This is useful for enabling features like credential protection policies or HMAC secrets. ```python from fido2.server import Fido2Server server = Fido2Server(rp={"id": "example.com", "name": "Example"}) options, state = server.register_begin( user={"id": b"user", "name": "alice", "display_name": "Alice"}, extensions={ "credentialProtectionPolicy": "userVerificationRequired", "credProps": True, "hmac-secret": True } ) ``` -------------------------------- ### CtapDevice Context Manager Usage Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Demonstrates using a CtapDevice instance as a context manager to ensure automatic resource release. ```python with device as dev: response = dev.call(cmd, data) # Device closed automatically ``` -------------------------------- ### Server Registration Flow Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/INDEX.md Initiates the FIDO2 registration process on the server side. Requires server configuration and returns options to the client. The registration is completed by processing the client's response. ```python from fido2.server import Fido2Server from fido2.webauthn import PublicKeyCredentialRpEntity # 1. Create server server = Fido2Server( PublicKeyCredentialRpEntity(id="example.com", name="Example") ) # 2. Start registration (return to client) options, state = server.register_begin( user={"id": b"user1", "name": "alice@example.com", "display_name": "Alice"} ) # 3. Complete registration (receive response from client) credential = server.register_complete(state, response_from_client) # 4. Store credential db.save_credential(user_id, credential) ``` -------------------------------- ### Handling ApduError in Python Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of catching and handling ApduError exceptions in Python for CTAP1 operations. It specifically checks for the user presence required status word (0x6985). ```python from fido2.ctap1 import ApduError, Ctap1 try: reg_data = ctap1.register(challenge, app_param) except ApduError as e: if e.code == 0x6985: print("User touch required") else: print(f"APDU error: {e.code:04x}") ``` -------------------------------- ### Client Registration Flow Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/INDEX.md Handles the FIDO2 registration process on the client side. It involves selecting a device, creating a client instance, and making a new credential. The resulting registration data is then sent to the server. ```python from fido2.client import Fido2Client, DefaultClientDataCollector from fido2.hid import list_devices # 1. Get device device = next(list_devices()) # 2. Create client client = Fido2Client( device, collector=DefaultClientDataCollector("https://example.com") ) # 3. Create credential registration = client.make_credential(server_options) # 4. Send response to server submit_to_server(registration) ``` -------------------------------- ### Get Credential Management Metadata Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-credman.md Retrieve metadata about the credential management capabilities of the authenticator, such as existing and maximum credential counts. Raises CtapError if credential management is not supported. ```python from fido2.ctap2.credman import CredentialManagement credman = CredentialManagement(ctap2, pin_protocol=2, pin_token=pin_token) metadata = credman.get_metadata() print(f"Existing credentials: {metadata.existing_resident_credentials_count}") print(f"Max credentials: {metadata.max_possible_remaining_resident_credentials}") ``` -------------------------------- ### Device Information Extension Configuration Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Configuration for the Device Information extension. Use 'devicePubKey' with 'type' set to 'platform' or 'cross-platform' to query device capabilities and attestation key information. ```python { "devicePubKey": { "type": "platform" # or "cross-platform" } } ``` -------------------------------- ### Configure HMAC-Secret Extension for Registration and Authentication Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Illustrates how to configure the HMAC-secret extension. For registration, it's requested as a boolean. For authentication, it can be configured to create a new secret or retrieve an existing one using salts. ```python # Request HMAC-secret during registration extensions = {"hmac-secret": True} # Later, use during authentication extensions = {"hmac-secret": { "hmacCreateSecret": True, # Generate new secret "hmacGetSecret": { "salt1": b"...", # 32 bytes "salt2": b"..." # 32 bytes (optional) } }} ``` -------------------------------- ### Check for Rogue Authenticators Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-mds.md Retrieves an entry from the MDS based on the Authenticator Attestation GUID (AAGUID) and checks if it is listed on the rogue list. This is useful for identifying authenticators with known vulnerabilities. ```python from fido2.mds3 import get_entry entry = get_entry(aaguid) if entry and entry.rogue_list: print(f"Warning: Known rogue authenticators: {entry.rogue_list}") ``` -------------------------------- ### ES256 from_ctap1 Method Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-cose.md Provides a class method to create an ES256 key from a 65-byte CTAP1 public key format. This is useful for initializing keys from specific hardware token outputs. ```python @classmethod def from_cryptography_key(public_key: ec.EllipticCurvePublicKey) -> ES256 ``` ```python @classmethod def from_ctap1(data: bytes) -> ES256 ``` -------------------------------- ### Handle InvalidSignature Exception Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of catching an InvalidSignature exception, which originates from the cryptography library. This error occurs when a cryptographic signature verification fails, indicating a potential tampering or invalid key. ```python from cryptography.exceptions import InvalidSignature try: cose_key.verify(message, signature) except InvalidSignature: print("Signature verification failed") ``` -------------------------------- ### CTAP2 Class Initialization Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Initializes the CTAP2 command handler with a CtapDevice instance. This is the entry point for interacting with a FIDO2 device. ```python class Ctap2: def __init__(self, device: CtapDevice) ``` -------------------------------- ### Handle InvalidRegistrationResponse During Registration Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/errors-reference.md Example of how to catch and handle an InvalidRegistrationResponse exception during the FIDO2 registration process. This typically occurs due to issues like challenge mismatch or invalid client data. ```python from fido2.server import InvalidRegistrationResponse try: credential = server.register_complete(state, response) except InvalidRegistrationResponse as e: print(f"Registration failed: {e}") ``` -------------------------------- ### Registration Extensions Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Shows how to request extensions during the FIDO2 registration process using `server.register_begin()`. ```APIDOC ### Registration Extensions Extensions requested during `register_begin()`: ```python from fido2.server import Fido2Server server = Fido2Server(rp={"id": "example.com", "name": "Example"}) options, state = server.register_begin( user={"id": b"user", "name": "alice", "display_name": "Alice"}, extensions={ "credentialProtectionPolicy": "userVerificationRequired", "credProps": True, "hmac-secret": True } ) ``` ``` -------------------------------- ### Make Credential (CTAP2) Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap.md Creates a new FIDO2 credential on the device. Requires client data hash, RP and user information, and supported public key credential parameters. Optional parameters include exclude list, extensions, options, and PIN authentication. ```python def make_credential( self, client_data_hash: bytes, rp: Mapping[str, Any], user: Mapping[str, Any], pub_key_cred_params: Sequence[Mapping[str, Any]], exclude_list: Sequence[Mapping[str, Any]] | None = None, extensions: Mapping[str, Any] | None = None, options: Mapping[str, Any] | None = None, pin_auth: bytes | None = None, pin_protocol: int | None = None, ) -> AttestationResponse ``` -------------------------------- ### Authentication Extensions Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-extensions.md Illustrates how to request extensions during the FIDO2 authentication process using `server.authenticate_begin()`. ```APIDOC ### Authentication Extensions Extensions requested during `authenticate_begin()`: ```python options, state = server.authenticate_begin( extensions={ "hmac-secret": True } ) ``` ``` -------------------------------- ### Get PIN Token Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-pin.md Obtains a PIN token for authorized CTAP2 operations. Requires the user's PIN and specifies desired permissions and an optional RP ID for scoped tokens. ```python def get_pin_token( self, pin: str, permissions: PERMISSION = PERMISSION.MAKE_CREDENTIAL | PERMISSION.GET_ASSERTION, rp_id: str | None = None ) -> bytes ``` -------------------------------- ### PublicKeyCredentialCreationOptions Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/types-reference.md Options for creating a new public key credential during registration. ```APIDOC ## Class: PublicKeyCredentialCreationOptions ### Description Registration credential creation options. ### Attributes - **rp** (PublicKeyCredentialRpEntity): Relying Party information. - **user** (PublicKeyCredentialUserEntity): User information. - **challenge** (bytes): The challenge for the registration. - **pub_key_cred_params** (Sequence[PublicKeyCredentialParameters]): List of supported public key credential parameters. - **timeout** (int | None): Timeout in milliseconds for the operation. Optional. - **attestation** (AttestationConveyancePreference): Attestation conveyance preference. Defaults to AttestationConveyancePreference.NONE. - **authenticator_selection** (AuthenticatorSelectionCriteria | None): Criteria for selecting an authenticator. Optional. - **extensions** (Mapping[str, Any] | None): Optional extensions for the creation request. Optional. ### Source `fido2/webauthn.py` ``` -------------------------------- ### CredentialManagement Class Initialization Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-ctap2-credman.md Initializes the CredentialManagement class with a CTAP2 instance, optionally specifying the PIN protocol version and a PIN token obtained from ClientPin.get_pin_token(). ```APIDOC ## Class: CredentialManagement Manage credentials on a CTAP2 device with resident key support. ```python class CredentialManagement: def __init__( self, ctap: Ctap2, pin_protocol: int = 2, pin_token: bytes | None = None ) ``` | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | ctap | Ctap2 | Yes | — | CTAP2 instance | | pin_protocol | int | No | 2 | PIN protocol version (1 or 2) | | pin_token | bytes | No | None | PIN token from ClientPin.get_pin_token() | Requires PIN authentication via pin_token. ``` -------------------------------- ### Get Metadata Entry by AAGUID Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-attestation.md Retrieves metadata for a given authenticator AAGUID using the MDS3 service. Requires the 'fido2.mds3' module. Use this to fetch details like description and certification level. ```python from fido2.mds3 import get_entry # Get metadata for an AAGUID entry = get_entry(data.aaguid) if entry: print(f"Authenticator: {entry.description}") print(f"Certified level: {entry.certification_level}") ``` -------------------------------- ### PublicKeyCredentialCreationOptions Data Structure Source: https://github.com/yubico/python-fido2/blob/main/_autodocs/fido2-webauthn.md Defines the parameters required for creating a new FIDO2/WebAuthn public key credential. Use this when initiating the registration process for a new authenticator. ```python from typing import Any, Mapping, Sequence from dataclasses import dataclass from fido2.attestation import AttestationConveyancePreference from fido2.client import AuthenticatorSelectionCriteria from fido2.constants import UserVerificationRequirement from fido2.data import PublicKeyCredentialDescriptor, PublicKeyCredentialParameters, PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity from fido2.utils import _JsonDataObject @dataclass(frozen=True) class PublicKeyCredentialCreationOptions(_JsonDataObject): rp: PublicKeyCredentialRpEntity user: PublicKeyCredentialUserEntity challenge: bytes pub_key_cred_params: Sequence[PublicKeyCredentialParameters] timeout: int | None = None attestation: AttestationConveyancePreference = AttestationConveyancePreference.NONE authenticator_selection: AuthenticatorSelectionCriteria | None = None extensions: Mapping[str, Any] | None = None ```