CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-yubico

Python library for communicating with Yubico YubiKey hardware authentication tokens

Pending
Overview
Eval results
Files

device-discovery.mddocs/

Device Discovery and Connection

YubiKey device discovery and connection management, supporting multiple connected devices, automatic device type detection, and device-specific class instantiation.

Capabilities

Primary Device Discovery

The main function for locating and connecting to YubiKey devices, with automatic version detection and appropriate class instantiation.

def find_yubikey(debug=False, skip=0):
    """
    Locate and connect to a YubiKey device.
    
    This is the primary entry point for YubiKey communication. It automatically
    detects the connected YubiKey model and returns the appropriate class instance.
    
    Parameters:
    - debug (bool): Enable debug output for troubleshooting
    - skip (int): Number of YubiKey devices to skip (for multiple devices)
    
    Returns:
    YubiKey: Connected YubiKey instance (YubiKeyUSBHID, YubiKeyNEO_USBHID, or YubiKey4_USBHID)
    
    Raises:
    YubiKeyError: If no YubiKey device is found
    YubiKeyUSBHIDError: If USB communication fails
    """

Usage example:

import yubico

# Connect to first available YubiKey
try:
    yk = yubico.find_yubikey()
    print(f"Connected to YubiKey version {yk.version()}")
except yubico.yubico_exception.YubiKeyError:
    print("No YubiKey found")

# Connect to second YubiKey if multiple are connected
try:
    yk2 = yubico.find_yubikey(skip=1)
    print(f"Connected to second YubiKey: {yk2.version()}")
except yubico.yubico_exception.YubiKeyError:
    print("Second YubiKey not found")

# Enable debug output
yk_debug = yubico.find_yubikey(debug=True)

Alternative Discovery Function

Lower-level device discovery function available in the yubikey module.

def find_key(debug=False, skip=0):
    """
    Locate a connected YubiKey (alternative interface).
    
    This function provides the same functionality as find_yubikey() but is
    available directly from the yubikey module.
    
    Parameters:
    - debug (bool): Enable debug output
    - skip (int): Number of YubiKeys to skip
    
    Returns:
    YubiKey: Connected YubiKey instance
    
    Raises:
    YubiKeyError: If no YubiKey found
    YubiKeyUSBHIDError: If USB communication fails
    """

Low-Level HID Device Connection

Direct USB HID device connection for advanced use cases requiring low-level access.

class YubiKeyHIDDevice:
    def __init__(self, debug=False, skip=0):
        """
        Connect directly to YubiKey USB HID interface.
        
        This class provides low-level access to the YubiKey USB HID interface
        without the higher-level abstractions of the main YubiKey classes.
        
        Parameters:
        - debug (bool): Enable debug output
        - skip (int): Number of devices to skip
        
        Raises:
        YubiKeyUSBHIDError: If device connection fails
        """
    
    def status(self):
        """
        Poll YubiKey for status information.
        
        Returns:
        YubiKeyUSBHIDStatus: Device status object
        """

Device Type Detection

The discovery system automatically detects YubiKey models and returns the appropriate class:

Supported Device Types

  • YubiKey 1.x - 2.1.3: Returns YubiKeyUSBHID instance
  • YubiKey NEO (2.1.4 - 2.1.9): Returns YubiKeyNEO_USBHID instance
  • YubiKey NEO (3.x): Returns YubiKeyNEO_USBHID instance
  • YubiKey 4 (4.x+): Returns YubiKey4_USBHID instance

Version Detection Logic

The discovery system uses firmware version information to determine the appropriate class:

# Internal logic (for reference)
if (2, 1, 4) <= yk_version <= (2, 1, 9):
    return YubiKeyNEO_USBHID(debug, skip, hid_device)
if yk_version < (3, 0, 0):
    return YubiKeyUSBHID(debug, skip, hid_device)
if yk_version < (4, 0, 0):
    return YubiKeyNEO_USBHID(debug, skip, hid_device)
return YubiKey4_USBHID(debug, skip, hid_device)

Error Handling

Common connection errors and their meanings:

try:
    yk = yubico.find_yubikey()
except yubico.yubico_exception.YubiKeyError as e:
    if "No YubiKey found" in str(e):
        print("No YubiKey device is connected")
    else:
        print(f"YubiKey error: {e.reason}")
except yubico.yubikey_usb_hid.YubiKeyUSBHIDError as e:
    print(f"USB communication error: {e.reason}")

Multiple Device Handling

When multiple YubiKeys are connected, use the skip parameter:

# Get all connected YubiKeys
yubikeys = []
skip = 0
while True:
    try:
        yk = yubico.find_yubikey(skip=skip)
        yubikeys.append(yk)
        print(f"Found YubiKey {skip + 1}: {yk.version()}")
        skip += 1
    except yubico.yubico_exception.YubiKeyError:
        break

print(f"Total YubiKeys found: {len(yubikeys)}")

Install with Tessl CLI

npx tessl i tessl/pypi-python-yubico

docs

challenge-response.md

configuration.md

device-discovery.md

device-interface.md

exceptions.md

index.md

utilities.md

tile.json