-
Notifications
You must be signed in to change notification settings - Fork 0
Cross Platform Support
- Introduction
- Architecture Overview
- HID Transport Layer Implementation
- Platform-Specific Implementations
- Client Integration Layer
- Command-Response Protocol
- Cross-Platform Abstraction
- Platform-Specific Challenges
- Testing and Validation
- Extensibility and Future Support
- Conclusion
The Post-Quantum WebAuthn Platform implements a sophisticated cross-platform HID (Human Interface Device) transport layer that enables seamless communication with FIDO2 authenticators across multiple operating systems. This architecture provides a unified interface for authenticator discovery, connection management, and protocol communication while accommodating the unique characteristics and requirements of each platform.
The system supports Windows, macOS, Linux, FreeBSD, NetBSD, and OpenBSD, each with specialized implementations that leverage native APIs and drivers. The architecture ensures consistent behavior across platforms while optimizing for platform-specific capabilities such as USB, NFC, and BLE transport protocols.
The cross-platform support architecture follows a layered approach with clear separation of concerns:
graph TB
subgraph "Application Layer"
WebAuthn[WebAuthn Client]
WindowsAPI[Windows API Wrapper]
end
subgraph "Protocol Layer"
CTAP[CTAP HID Protocol]
PacketFragmentation[Packet Fragmentation]
ChannelManagement[Channel Management]
end
subgraph "Abstraction Layer"
BaseLayer[Base HID Interface]
Descriptor[HidDescriptor]
Connection[CtapHidConnection]
end
subgraph "Platform Layer"
LinuxImpl[Linux - hidraw]
MacOSImpl[macOS - IOKit]
WindowsImpl[Windows - hid.dll]
BSDImpl[BSD Variants - hidraw/uhid]
end
subgraph "Hardware Layer"
USB[USB Transport]
NFC[NFC Transport]
BLE[BLE Transport]
end
WebAuthn --> CTAP
WindowsAPI --> CTAP
CTAP --> PacketFragmentation
CTAP --> ChannelManagement
PacketFragmentation --> BaseLayer
ChannelManagement --> BaseLayer
BaseLayer --> Descriptor
BaseLayer --> Connection
Connection --> LinuxImpl
Connection --> MacOSImpl
Connection --> WindowsImpl
Connection --> BSDImpl
LinuxImpl --> USB
MacOSImpl --> USB
WindowsImpl --> USB
BSDImpl --> USB
LinuxImpl --> NFC
MacOSImpl --> BLE
WindowsImpl --> NFC
WindowsImpl --> BLE
Diagram sources
- fido2/hid/init.py
- fido2/hid/base.py
The HID transport layer provides the foundation for cross-platform authenticator communication through a hierarchical abstraction system.
The transport layer consists of several key components that work together to provide platform-independent functionality:
classDiagram
class HidDescriptor {
+string path
+int vid
+int pid
+int report_size_in
+int report_size_out
+string product_name
+string serial_number
}
class CtapHidConnection {
<<abstract>>
+read_packet() bytes
+write_packet(data) void
+close() void
}
class FileCtapHidConnection {
+int handle
+HidDescriptor descriptor
+close() void
+write_packet(data) void
+read_packet() bytes
}
class CtapHidDevice {
+HidDescriptor descriptor
+int _channel_id
+int _packet_size
+CtapHidConnection _connection
+call(cmd, data) bytes
+ping(msg) bytes
+wink() void
+lock(time) void
+close() void
}
HidDescriptor --> CtapHidDevice : "describes"
CtapHidConnection <|-- FileCtapHidConnection : "extends"
CtapHidConnection <-- CtapHidDevice : "uses"
FileCtapHidConnection <-- CtapHidDevice : "initializes"
Diagram sources
- fido2/hid/base.py
- fido2/hid/base.py
- fido2/hid/base.py
The system automatically detects the operating system and loads the appropriate platform-specific implementation:
flowchart TD
Start([Module Import]) --> DetectPlatform{Detect Platform}
DetectPlatform --> |Linux| LoadLinux[Load linux.py]
DetectPlatform --> |Windows| LoadWindows[Load windows.py]
DetectPlatform --> |macOS| LoadMacOS[Load macos.py]
DetectPlatform --> |FreeBSD| LoadFreeBSD[Load freebsd.py]
DetectPlatform --> |NetBSD| LoadNetBSD[Load netbsd.py]
DetectPlatform --> |OpenBSD| LoadOpenBSD[Load openbsd.py]
DetectPlatform --> |Other| RaiseError[Raise Exception]
LoadLinux --> ExposeAPI[Expose Public API]
LoadWindows --> ExposeAPI
LoadMacOS --> ExposeAPI
LoadFreeBSD --> ExposeAPI
LoadNetBSD --> ExposeAPI
LoadOpenBSD --> ExposeAPI
RaiseError --> End([Error])
ExposeAPI --> End([Success])
Diagram sources
- fido2/hid/init.py
Section sources
- fido2/hid/init.py
- fido2/hid/base.py
Each platform implementation provides optimized access to HID devices while maintaining a consistent interface.
The Linux implementation leverages the hidraw subsystem for direct hardware access:
sequenceDiagram
participant App as Application
participant Linux as Linux Backend
participant HIDRaw as hidraw Driver
participant Device as HID Device
App->>Linux : list_descriptors()
Linux->>HIDRaw : Open /dev/hidraw*
HIDRaw->>Device : Read device properties
Device-->>HIDRaw : Vendor/Product info
HIDRaw-->>Linux : Device descriptor
Linux-->>App : HidDescriptor[]
App->>Linux : open_connection(descriptor)
Linux->>HIDRaw : Create FileCtapHidConnection
HIDRaw-->>Linux : Connection handle
Linux-->>App : LinuxCtapHidConnection
App->>Linux : write_packet(data)
Linux->>HIDRaw : Write with report ID prepended
HIDRaw->>Device : Send HID report
Device-->>HIDRaw : Acknowledge
HIDRaw-->>Linux : Success
App->>Linux : read_packet()
Linux->>HIDRaw : Read report
HIDRaw->>Device : Request report
Device-->>HIDRaw : HID report
HIDRaw-->>Linux : Strip report ID
Linux-->>App : Response data
Diagram sources
- fido2/hid/linux.py
- fido2/hid/linux.py
The macOS implementation uses IOKit framework for comprehensive HID device management:
sequenceDiagram
participant App as Application
participant MacOS as macOS Backend
participant IOKit as IOKit Framework
participant CF as Core Foundation
participant Device as HID Device
App->>MacOS : list_descriptors()
MacOS->>IOKit : Create IOHIDManager
IOKit->>CF : Set device matching criteria
CF-->>IOKit : Matching dictionary
IOKit->>Device : Enumerate devices
Device-->>IOKit : Device list
IOKit-->>MacOS : Device descriptors
MacOS-->>App : HidDescriptor[]
App->>MacOS : open_connection(descriptor)
MacOS->>IOKit : Create IOHIDDevice
IOKit->>Device : Open device
Device-->>IOKit : Open status
IOKit-->>MacOS : Device handle
MacOS->>CF : Create run loop
CF-->>MacOS : Run loop reference
MacOS->>IOKit : Register input callback
IOKit-->>MacOS : Callback registered
MacOS-->>App : MacCtapHidConnection
App->>MacOS : write_packet(data)
MacOS->>IOKit : Set report with callback
IOKit->>Device : Send report
Device-->>IOKit : Report sent
IOKit-->>MacOS : Success
App->>MacOS : read_packet()
MacOS->>CF : Start run loop thread
CF->>Device : Wait for report
Device-->>CF : Report received
CF-->>MacOS : Report data
MacOS-->>App : Response data
Diagram sources
- fido2/hid/macos.py
- fido2/hid/macos.py
The Windows implementation combines SetupAPI and Hid.dll for robust device enumeration and communication:
sequenceDiagram
participant App as Application
participant Windows as Windows Backend
participant SetupAPI as SetupAPI
participant HidDLL as Hid.dll
participant Kernel32 as Kernel32
participant Device as HID Device
App->>Windows : list_descriptors()
Windows->>SetupAPI : SetupDiGetClassDevsA(HID_GUID)
SetupAPI->>Device : Enumerate HID devices
Device-->>SetupAPI : Device list
SetupAPI-->>Windows : Device info set
Windows->>SetupAPI : SetupDiEnumDeviceInterfaces
SetupAPI-->>Windows : Interface details
Windows->>SetupAPI : SetupDiGetDeviceInterfaceDetailA
SetupAPI-->>Windows : Device paths
Windows->>HidDLL : HidD_GetPreparsedData
HidDLL->>Device : Get report descriptor
Device-->>HidDLL : Report descriptor
HidDLL-->>Windows : Capabilities
Windows-->>App : HidDescriptor[]
App->>Windows : open_connection(descriptor)
Windows->>Kernel32 : CreateFileA
Kernel32->>Device : Open device
Device-->>Kernel32 : Handle
Kernel32-->>Windows : Device handle
Windows-->>App : WinCtapHidConnection
App->>Windows : write_packet(data)
Windows->>Kernel32 : WriteFile
Kernel32->>Device : Send report
Device-->>Kernel32 : Written bytes
Kernel32-->>Windows : Success
App->>Windows : read_packet()
Windows->>Kernel32 : ReadFile
Kernel32->>Device : Request report
Device-->>Kernel32 : Report data
Kernel32-->>Windows : Stripped report
Windows-->>App : Response data
Diagram sources
- fido2/hid/windows.py
- fido2/hid/windows.py
The BSD implementations provide support for FreeBSD, NetBSD, and OpenBSD using either hidraw or uhid drivers:
flowchart TD
BSDImpl[BSD Implementation] --> CheckDriver{Driver Type?}
CheckDriver --> |hidraw| HIDRawImpl[Hidraw Implementation]
CheckDriver --> |uhid| UHIDImpl[UHHid Implementation]
HIDRawImpl --> HIDRawOpen[Open /dev/hidraw*]
HIDRawOpen --> HIDRawRead[Read device properties]
HIDRawRead --> HIDRawParse[Parse report descriptor]
HIDRawParse --> HIDRawConn[HidrawCtapHidConnection]
UHIDImpl --> UHIDEnum[Enumerate uhid devices]
UHIDEnum --> UHIDRead[Read sysctl properties]
UHIDRead --> UHIDParse[Parse report descriptor]
UHIDParse --> UHIDConn[FileCtapHidConnection]
HIDRawConn --> UnifiedAPI[Unified API]
UHIDConn --> UnifiedAPI
Diagram sources
- fido2/hid/freebsd.py
- fido2/hid/freebsd.py
Section sources
- fido2/hid/linux.py
- fido2/hid/macos.py
- fido2/hid/windows.py
- fido2/hid/freebsd.py
The client integration layer provides high-level APIs for interacting with authenticators across platforms.
The Windows API wrapper (win_api.py) provides a comprehensive interface to the Windows WebAuthn API:
classDiagram
class WebAuthNClient {
<<interface>>
+make_credential(options) RegistrationResponse
+get_assertion(options) AssertionSelection
}
class WindowsClient {
+HWND handle
+ClientDataCollector _client_data_collector
+bool _allow_hmac_secret
+Sequence~str~ _enterprise_rpid_list
+is_available() bool
+make_credential(options, event) RegistrationResponse
+get_assertion(options, event) AssertionSelection
}
class WebAuthNAssertion {
+DWORD dwVersion
+DWORD cbAuthenticatorData
+PBYTE pbAuthenticatorData
+DWORD cbSignature
+PBYTE pbSignature
+WebAuthNCredential Credential
+DWORD cbUserId
+PBYTE pbUserId
+BytesProperty auth_data
+BytesProperty signature
+BytesProperty user_id
}
class WebAuthNMakeCredentialOptions {
+DWORD dwVersion
+DWORD dwTimeoutMilliseconds
+WebAuthNCredentials CredentialList
+WebAuthNExtensions Extensions
+DWORD dwAuthenticatorAttachment
+BOOL bRequireResidentKey
+DWORD dwUserVerificationRequirement
+DWORD dwAttestationConveyancePreference
}
WebAuthNClient <|-- WindowsClient : "implements"
WindowsClient --> WebAuthNAssertion : "creates"
WindowsClient --> WebAuthNMakeCredentialOptions : "uses"
Diagram sources
- fido2/client/windows.py
- fido2/client/win_api.py
- fido2/client/win_api.py
The higher-level Windows client (windows.py) provides a simplified interface for WebAuthn operations:
sequenceDiagram
participant App as Application
participant WinClient as WindowsClient
participant WinAPI as Windows WebAuthn API
participant Authenticator as FIDO2 Authenticator
App->>WinClient : make_credential(options)
WinClient->>WinClient : Collect client data
WinClient->>WinClient : Prepare WebAuthN options
WinClient->>WinAPI : WebAuthNAuthenticatorMakeCredential
WinAPI->>Authenticator : Create credential request
Authenticator-->>WinAPI : Attestation response
WinAPI-->>WinClient : Credential attestation
WinClient->>WinClient : Process extensions
WinClient-->>App : RegistrationResponse
App->>WinClient : get_assertion(options)
WinClient->>WinClient : Collect client data
WinClient->>WinClient : Prepare assertion options
WinClient->>WinAPI : WebAuthNAuthenticatorGetAssertion
WinAPI->>Authenticator : Authenticate request
Authenticator-->>WinAPI : Assertion response
WinAPI-->>WinClient : Assertion data
WinClient->>WinClient : Process extensions
WinClient-->>App : AssertionSelection
Diagram sources
- fido2/client/windows.py
- fido2/client/windows.py
Section sources
- fido2/client/win_api.py
- fido2/client/windows.py
The CTAP HID protocol implements a sophisticated command-response mechanism with packet fragmentation, channel management, and error handling.
The protocol handles large messages through packet fragmentation:
flowchart TD
LargeMessage[Large Message] --> CheckSize{Size > Packet Limit?}
CheckSize --> |No| SinglePacket[Single Packet]
CheckSize --> |Yes| FragmentMessage[Fragment Message]
FragmentMessage --> InitPacket[Initialization Packet<br/>Header + First Chunk]
InitPacket --> ContPackets[Continuation Packets<br/>Sequence + Chunk]
ContPackets --> MoreData{More Data?}
MoreData --> |Yes| NextChunk[Next Chunk]
NextChunk --> ContPackets
MoreData --> |No| Complete[Complete Message]
SinglePacket --> SendPackets[Send All Packets]
Complete --> SendPackets
SendPackets --> ReceiveResponse[Receive Response]
Diagram sources
- fido2/hid/init.py
The system manages multiple concurrent channels with proper resource allocation:
stateDiagram-v2
[*] --> Idle
Idle --> Initializing : INIT command
Initializing --> Active : Channel established
Active --> Busy : Command in progress
Busy --> Active : Command complete
Active --> Canceling : CANCEL command
Canceling --> Idle : Cleanup complete
Active --> Error : Protocol error
Error --> Idle : Reset
Active --> Closed : Close connection
Closed --> [*]
Diagram sources
- fido2/hid/init.py
Comprehensive error handling ensures robust operation across platforms:
flowchart TD
SendCommand[Send Command] --> ReceiveResponse[Receive Response]
ReceiveResponse --> CheckResponse{Response Type}
CheckResponse --> |KeepAlive| ProcessKeepAlive[Process KeepAlive Status]
CheckResponse --> |Error| HandleError[Handle CTAP Error]
CheckResponse --> |Success| ProcessSuccess[Process Success Response]
ProcessKeepAlive --> Continue[Continue Operation]
HandleError --> CheckErrorCode{Error Code}
CheckErrorCode --> |CHANNEL_BUSY| RetryWithBackoff[Retry with Backoff]
CheckErrorCode --> |Other| RaiseException[Raise Exception]
RetryWithBackoff --> Wait[Wait 100ms]
Wait --> SendCommand
RaiseException --> End[End Operation]
Continue --> SendCommand
ProcessSuccess --> End
Diagram sources
- fido2/hid/init.py
Section sources
- fido2/hid/init.py
The abstraction layer ensures consistent behavior across all supported platforms while allowing for platform-specific optimizations.
flowchart TD
ImportModule[Import HID Module] --> CheckPlatform{sys.platform}
CheckPlatform --> |linux| LoadLinux[Load Linux Backend]
CheckPlatform --> |win32| LoadWindows[Load Windows Backend]
CheckPlatform --> |darwin| LoadMacOS[Load macOS Backend]
CheckPlatform --> |freebsd| LoadFreeBSD[Load FreeBSD Backend]
CheckPlatform --> |netbsd| LoadNetBSD[Load NetBSD Backend]
CheckPlatform --> |openbsd| LoadOpenBSD[Load OpenBSD Backend]
CheckPlatform --> |other| UnsupportedPlatform[Unsupported Platform]
LoadLinux --> ExposeFunctions[Expose Public Functions]
LoadWindows --> ExposeFunctions
LoadMacOS --> ExposeFunctions
LoadFreeBSD --> ExposeFunctions
LoadNetBSD --> ExposeFunctions
LoadOpenBSD --> ExposeFunctions
UnsupportedPlatform --> RaiseException[Raise Exception]
ExposeFunctions --> Ready[Ready for Use]
Diagram sources
- fido2/hid/init.py
The abstraction maintains a consistent interface across all platforms:
| Function | Purpose | Platform Specific Behavior |
|---|---|---|
list_descriptors() |
Discover available devices | Uses platform-specific APIs for device enumeration |
get_descriptor(path) |
Get device properties | Parses device information using platform drivers |
open_connection(descriptor) |
Establish connection | Creates platform-specific connection objects |
parse_report_descriptor() |
Parse HID reports | Handles platform-specific report descriptor formats |
Section sources
- fido2/hid/init.py
- fido2/hid/base.py
Each platform presents unique challenges that require specialized solutions.
Different platforms have varying permission requirements:
| Platform | Permission Model | Requirements |
|---|---|---|
| Linux | File permissions | Read/write access to /dev/hidraw*
|
| macOS | Code signing | Proper entitlements for IOKit access |
| Windows | UAC elevation | Potentially elevated privileges |
| BSD | Device ownership | Correct group membership |
Platform-specific driver dependencies:
graph LR
subgraph "Linux"
LinuxDrivers[Linux Kernel Drivers]
HIDRaw[hidraw module]
USBCore[USB core drivers]
LinuxDrivers --> HIDRaw
HIDRaw --> USBCore
end
subgraph "macOS"
MacOSDrivers[IOKit Framework]
HIDManager[IOHIDManager]
CFBundle[Core Foundation]
MacOSDrivers --> HIDManager
HIDManager --> CFBundle
end
subgraph "Windows"
WindowsDrivers[Windows HID APIs]
SetupAPI[SetupAPI.dll]
HidDLL[Hid.dll]
Kernel32[Kernel32.dll]
WindowsDrivers --> SetupAPI
SetupAPI --> HidDLL
HidDLL --> Kernel32
end
subgraph "BSD"
BSDDrivers[BSD HID Drivers]
HIDRawBSD[hidraw/uhid]
USBBSD[USB drivers]
BSDDrivers --> HIDRawBSD
HIDRawBSD --> USBBSD
end
Different platforms support various transport protocols:
| Platform | USB | NFC | BLE | Other |
|---|---|---|---|---|
| Linux | ✓ | ✓ | ✓ | Smart Card |
| macOS | ✓ | ✗ | ✓ | Internal |
| Windows | ✓ | ✓ | ✓ | Hybrid |
| BSD | ✓ | ✗ | ✗ | Serial |
Section sources
- fido2/hid/linux.py
- fido2/hid/macos.py
- fido2/hid/windows.py
The system includes comprehensive testing to ensure cross-platform reliability.
The test suite validates report descriptor parsing across different formats:
flowchart TD
TestSuite[Test Suite] --> ParseTests[Parse Descriptor Tests]
ParseTests --> ValidDescriptor[Valid FIDO Descriptor]
ParseTests --> InvalidDescriptor[Invalid Descriptor]
ValidDescriptor --> ExtractSizes[Extract Input/Output Sizes]
ExtractSizes --> ValidateSizes{Sizes Match Expected?}
ValidateSizes --> |Yes| PassTest[Pass Test]
ValidateSizes --> |No| FailTest[Fail Test]
InvalidDescriptor --> ExpectError[Expect ValueError]
ExpectError --> CatchError{Catch ValueError?}
CatchError --> |Yes| PassTest
CatchError --> |No| FailTest
Diagram sources
- tests/test_hid.py
The testing framework ensures compatibility across all supported platforms:
| Test Category | Coverage | Validation Method |
|---|---|---|
| Device Discovery | All platforms | Verify device enumeration |
| Connection Establishment | All platforms | Test successful connections |
| Protocol Communication | All platforms | Validate CTAP commands |
| Error Handling | All platforms | Test error scenarios |
| Resource Cleanup | All platforms | Verify proper cleanup |
Section sources
- tests/test_hid.py
The architecture is designed for extensibility and can accommodate future platforms and transport protocols.
To add support for a new platform:
flowchart TD
NewPlatform[New Platform] --> ImplementBackend[Implement Backend]
ImplementBackend --> CreateConnection[Create Connection Class]
CreateConnection --> ImplementDiscovery[Implement Device Discovery]
ImplementDiscovery --> AddToList[Add to Platform List]
AddToList --> WriteTests[Write Platform Tests]
WriteTests --> UpdateDocs[Update Documentation]
UpdateDocs --> Complete[Complete]
The architecture supports additional transport protocols:
graph TB
CurrentProtocols[Current Protocols] --> USB[USB HID]
CurrentProtocols --> NFC[NFC]
CurrentProtocols --> BLE[BLE]
FutureProtocols[Future Protocols] --> SmartCard[Smart Card]
FutureProtocols --> Wireless[Wireless]
FutureProtocols --> Cloud[Cloud-based]
USB -.->|Extension Point| NewTransport[New Transport]
NFC -.->|Extension Point| NewTransport
BLE -.->|Extension Point| NewTransport
SmartCard -.->|Extension Point| NewTransport
Wireless -.->|Extension Point| NewTransport
Cloud -.->|Extension Point| NewTransport
The extensible design follows these principles:
- Interface Consistency: All platform implementations follow the same interface
- Plugin Architecture: New platforms can be added without modifying existing code
- Configuration-Driven: Platform detection and loading are configurable
- Error Isolation: Platform-specific errors are isolated and handled appropriately
The cross-platform support architecture for the Post-Quantum WebAuthn Platform demonstrates sophisticated engineering that balances consistency with platform-specific optimization. Through careful abstraction, comprehensive testing, and extensible design, the system provides reliable authenticator communication across Windows, macOS, Linux, and BSD variants.
The architecture successfully addresses the complex challenges of cross-platform development while maintaining the performance and reliability required for production WebAuthn deployments. The modular design ensures that future enhancements and platform additions can be seamlessly integrated without disrupting existing functionality.
Key strengths of the implementation include:
- Robust Abstraction: Clean separation between platform-specific and common code
- Comprehensive Testing: Extensive test coverage across all supported platforms
- Error Resilience: Sophisticated error handling and recovery mechanisms
- Performance Optimization: Platform-specific optimizations where beneficial
- Extensibility: Clear pathways for adding new platforms and transport protocols
This architecture serves as a model for cross-platform system design, particularly in security-critical applications where reliability and compatibility are paramount.