Response Objects Schemas - FeitianTech/postquantum-webauthn-platform GitHub Wiki
- Introduction
- AuthenticatorData Binary Format
- AttestationObject Structure
- CBOR Encoding Process
- Response Object Transformation
- Post-Quantum Cryptography Integration
- Complete Response Payload Examples
- Binary Data Handling in Server Routes
This document provides comprehensive documentation for the response object schemas in the Post-Quantum WebAuthn Platform. It details the structure and encoding of key WebAuthn response objects including AuthenticatorData, AttestationObject, and AssertionResponse as defined in the fido2/webauthn.py module. The documentation covers the binary format specifications, CBOR encoding processes, and the transformation of raw binary data into JSON-serializable formats used in API responses. Special attention is given to how post-quantum cryptography affects attestation statement structures and signature formats within the WebAuthn framework.
Section sources
- fido2/webauthn.py
The AuthenticatorData structure is a binary-encoded object that contains critical information about the authenticator state and attested credential data. It follows the WebAuthn specification format with a fixed structure that begins with the RP ID hash and includes flags, counter, and optional credential data.
The binary format consists of:
- rp_id_hash (32 bytes): SHA256 hash of the Relying Party ID
- flags (1 byte): Bit field containing various authenticator state indicators
- counter (4 bytes): Signature counter in big-endian format
- credential_data (variable): Optional attested credential data when AT flag is set
- extensions (variable): Optional CBOR-encoded extensions when ED flag is set
The flags field uses specific bit positions to indicate authenticator state:
- Bit 0 (UP): User Present
- Bit 2 (UV): User Verified
- Bit 3 (BE): Backup Eligibility
- Bit 4 (BS): Backup State
- Bit 6 (AT): Attested credential data present
- Bit 7 (ED): Extension data present
The AuthenticatorData class provides methods to create instances from components and parse binary data into structured objects with proper validation of lengths and formats.
flowchart TD
AuthenticatorData["AuthenticatorData\n(binary structure)"]
rp_id_hash["rp_id_hash\n32 bytes\nSHA256 hash of RP ID"]
flags["flags\n1 byte\nBit field indicators"]
counter["counter\n4 bytes\nBig-endian integer"]
credential_data["credential_data\nVariable length\nAttested credential data"]
extensions["extensions\nVariable length\nCBOR-encoded data"]
AuthenticatorData --> rp_id_hash
AuthenticatorData --> flags
AuthenticatorData --> counter
AuthenticatorData --> credential_data
AuthenticatorData --> extensions
flags_sub[["Flags Bit Field"]]
UP["Bit 0: UP\nUser Present"]
UV["Bit 2: UV\nUser Verified"]
BE["Bit 3: BE\nBackup Eligibility"]
BS["Bit 4: BS\nBackup State"]
AT["Bit 6: AT\nAttested Data"]
ED["Bit 7: ED\nExtensions"]
flags --> flags_sub
flags_sub --> UP
flags_sub --> UV
flags_sub --> BE
flags_sub --> BS
flags_sub --> AT
flags_sub --> ED
Diagram sources
- fido2/webauthn.py
Section sources
- fido2/webauthn.py
The AttestationObject is a CBOR-encoded structure that contains the attestation statement, authenticator data, and format identifier. It serves as the primary container for registration responses in the WebAuthn protocol.
The structure consists of three main components:
- fmt (string): Identifies the attestation format (e.g., "packed", "fido-u2f")
- auth_data (AuthenticatorData): Binary authenticator data structure
- att_stmt (mapping): Attestation statement containing signature and certificate chain
The attestation statement (att_stmt) varies by format but typically includes:
- sig: Signature over the authenticator data and client data hash
- x5c: Certificate chain for X.509 based attestation
- alg: COSE algorithm identifier used for the signature
- Format-specific additional fields
The AttestationObject class provides methods to create instances from components and parse CBOR-encoded data, ensuring proper validation of the internal structures.
classDiagram
class AttestationObject {
+str fmt
+AuthenticatorData auth_data
+Mapping[str, Any] att_stmt
+__init__(bytes _)
+create(str fmt, AuthenticatorData auth_data, Mapping[str, Any] att_stmt)
}
class AuthenticatorData {
+bytes rp_id_hash
+AuthenticatorData.FLAG flags
+int counter
+Optional[AttestedCredentialData] credential_data
+Optional[Mapping] extensions
}
class AttestedCredentialData {
+Aaguid aaguid
+bytes credential_id
+CoseKey public_key
}
AttestationObject --> AuthenticatorData : contains
AuthenticatorData --> AttestedCredentialData : contains when AT flag set
Diagram sources
- fido2/webauthn.py
Section sources
- fido2/webauthn.py
The CBOR (Concise Binary Object Representation) encoding process is implemented in the fido2/cbor.py module and follows the FIDO CTAP specification requirements. The implementation supports a subset of CBOR functionality required for FIDO2 operations, with specific encoding rules for different data types.
The encoding process handles the following data types:
- Integers: Encoded with appropriate major type and additional information
- Booleans: Encoded as single bytes (0xf4 for false, 0xf5 for true)
- Strings: UTF-8 encoded with length prefix
- Bytes: Raw binary data with length prefix
- Arrays: Length-prefixed sequence of encoded items
- Maps: Length-prefixed sequence of key-value pairs
A critical aspect of the CBOR implementation is the canonical encoding requirement for WebAuthn, which mandates that map keys must be sorted in a specific order. The implementation sorts keys by their major type, length, and byte value to ensure consistent encoding across different platforms.
The encoding process also includes special handling for nested structures, ensuring that complex objects like public keys and extension data are properly serialized in CBOR format.
flowchart TD
Start["Start Encoding"]
Input["Input Data\n(Mapping, Sequence, etc.)"]
Input --> TypeCheck["Determine Data Type"]
TypeCheck --> |"Integer"| EncodeInt["Encode Integer\nusing dump_int()"]
TypeCheck --> |"Boolean"| EncodeBool["Encode Boolean\nusing dump_bool()"]
TypeCheck --> |"String"| EncodeString["Encode String\nusing dump_text()"]
TypeCheck --> |"Bytes"| EncodeBytes["Encode Bytes\nusing dump_bytes()"]
TypeCheck --> |"Sequence"| EncodeArray["Encode Array\nusing dump_list()"]
TypeCheck --> |"Mapping"| SortKeys["Sort Map Keys\nby type, length, value"]
SortKeys --> EncodeMap["Encode Map\nusing dump_dict()"]
EncodeInt --> Combine["Combine with Major Type"]
EncodeBool --> Combine
EncodeString --> Combine
EncodeBytes --> Combine
EncodeArray --> Combine
EncodeMap --> Combine
Combine --> Output["CBOR-encoded Bytes"]
Output --> End["End"]
style Start fill:#f9f,stroke:#333
style End fill:#f9f,stroke:#333
Diagram sources
- fido2/cbor.py
Section sources
- fido2/cbor.py
The transformation of raw binary response objects into JSON-serializable formats involves several steps to ensure compatibility with web APIs while preserving the integrity of the cryptographic data. This process is implemented in the server routes and decoder modules.
Binary fields are encoded using base64url encoding without padding, as specified in RFC4648. This encoding is applied to all binary data fields including:
- ClientDataJSON
- AuthenticatorData
- AttestationObject
- Signature values
- User handles
- Public keys
The transformation process maintains the hierarchical structure of the original objects while converting binary data to strings. For example, the AttestationObject is transformed by:
- Decoding the CBOR-encoded attestation object
- Extracting the fmt, auth_data, and att_stmt components
- Converting auth_data to base64url string
- Converting att_stmt signature and certificate chain to base64url strings
- Preserving the fmt as a plain string
The server routes implement this transformation consistently across both registration and authentication flows, ensuring that clients receive properly formatted responses that can be easily processed.
flowchart LR
Raw["Raw Binary Data"]
CBOR["CBOR Decoding"]
Extract["Extract Components"]
Encode["Base64url Encode Binary Fields"]
Structure["Reconstruct JSON Structure"]
Response["API Response"]
Raw --> CBOR
CBOR --> Extract
Extract --> Encode
Encode --> Structure
Structure --> Response
subgraph "Binary Fields"
ClientData["clientDataJSON"]
AuthData["authenticatorData"]
AttestationObj["attestationObject"]
Signature["signature"]
UserHandle["userHandle"]
end
Encode --> ClientData
Encode --> AuthData
Encode --> AttestationObj
Encode --> Signature
Encode --> UserHandle
Section sources
- server/server/routes/simple.py
- server/server/decoder/decode.py
The Post-Quantum WebAuthn Platform integrates post-quantum cryptography through specialized attestation handling and signature verification processes. The implementation supports post-quantum algorithms in the attestation statement structure while maintaining compatibility with the standard WebAuthn protocol.
Post-quantum cryptography affects the attestation statement structure in several ways:
- Algorithm identifiers: PQC algorithms use specific COSE algorithm identifiers that are distinct from classical algorithms
- Signature formats: PQC signatures may have different structures and lengths compared to classical signatures
- Certificate chains: Attestation certificates may use PQC-based public keys and signatures
The platform implements PQC support through:
- Detection of PQC algorithm identifiers in attestation statements
- Specialized verification routines for PQC signatures
- Integration with liboqs for post-quantum cryptographic operations
- Fallback mechanisms for hybrid classical/PQC verification
The attestation verification process first attempts classical verification and then falls back to PQC verification if the attestation format indicates PQC usage. This ensures backward compatibility while enabling post-quantum security.
flowchart TD
Start["Start Attestation Verification"]
CheckFormat["Check Attestation Format"]
CheckFormat --> |"Classical"| Classical["Classical Verification"]
CheckFormat --> |"PQC"| PQC["PQC Verification"]
CheckFormat --> |"Hybrid"| Hybrid["Hybrid Verification"]
Classical --> VerifySig["Verify Signature with\nClassical Algorithm"]
PQC --> VerifyPQCSig["Verify Signature with\nPQC Algorithm"]
Hybrid --> VerifyClassical["Verify Classical Signature"]
Hybrid --> VerifyPQC["Verify PQC Signature"]
VerifySig --> |"Success"| Success["Verification Success"]
VerifySig --> |"Failure"| AttemptPQC["Attempt PQC Verification"]
AttemptPQC --> PQC
VerifyPQCSig --> |"Success"| Success
VerifyPQCSig --> |"Failure"| Failure["Verification Failed"]
VerifyClassical --> |"Success"| VerifyPQC
VerifyPQC --> |"Success"| Success
VerifyClassical --> |"Failure"| Failure
VerifyPQC --> |"Failure"| Failure
style Success fill:#9f9,stroke:#333
style Failure fill:#f99,stroke:#333
Section sources
- server/server/attestation.py
- server/server/pqc.py
This section provides examples of complete response payloads for both registration and authentication flows, showing the transformation from raw binary data to API response format.
{
"status": "OK",
"algo": "ML-DSA-87",
"storedCredential": {
"credentialId": "base64url-encoded-credential-id",
"aaguid": "base64url-encoded-aaguid",
"publicKey": "base64url-encoded-public-key",
"signCount": 0
},
"relyingParty": {
"id": "example.com",
"name": "Example RP"
}
}{
"status": "OK",
"userHandle": "base64url-encoded-user-handle",
"signature": "base64url-encoded-signature",
"authenticatorData": "base64url-encoded-authenticator-data",
"clientDataJSON": "base64url-encoded-client-data"
}In both cases, the binary components are encoded using base64url encoding without padding. The server routes handle the extraction and encoding of these components from the raw WebAuthn responses, ensuring proper formatting for client consumption.
Section sources
- server/server/routes/simple.py
- server/server/routes/simple.py
The server routes implement comprehensive binary data handling to process WebAuthn responses and transform them into appropriate API responses. This involves decoding incoming binary data, processing it through the WebAuthn logic, and encoding the results for API responses.
The binary data handling process includes:
- Decoding base64url-encoded input fields
- Parsing CBOR-encoded structures
- Validating binary formats and lengths
- Converting binary data to appropriate types for processing
- Encoding results back to base64url for API responses
The decoder module provides utilities for handling different binary formats and converting between them. This includes support for hex, base64, base64url, and raw binary formats, allowing flexible processing of binary data in various representations.
The encoding process ensures that all binary data in API responses is properly formatted as base64url strings without padding, following the WebAuthn specification requirements. This consistent encoding approach enables clients to easily decode and process the binary components of the responses.
flowchart LR
Request["HTTP Request"]
DecodeInput["Decode Input Fields\n(base64url → binary)"]
Process["WebAuthn Processing"]
EncodeOutput["Encode Output Fields\n(binary → base64url)"]
Response["HTTP Response"]
Request --> DecodeInput
DecodeInput --> Process
Process --> EncodeOutput
EncodeOutput --> Response
subgraph "Decoder Module"
direction TB
Base64URL["base64url"]
Hex["hex"]
Binary["binary"]
PEM["PEM"]
Base64URL < --> Hex
Hex < --> Binary
Binary < --> PEM
end
DecodeInput --> Base64URL
Hex --> Process
Process --> Hex
Hex --> EncodeOutput
EncodeOutput --> Base64URL
Section sources
- server/server/decoder/decode.py
- server/server/decoder/encode.py
- server/server/static/scripts/shared/binary-utils.js