1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
|
from enum import Enum
from dataclasses import dataclass, field
from typing import List, Literal, Optional, Union
from .cose import COSEAlgorithmIdentifier
################
#
# Fundamental data structures
#
################
class AuthenticatorTransport(str, Enum):
"""How an authenticator communicates to the client/browser.
Members:
`USB`: USB wired connection
`NFC`: Near Field Communication
`BLE`: Bluetooth Low Energy
`INTERNAL`: Direct connection (read: a platform authenticator)
`CABLE`: Cloud Assisted Bluetooth Low Energy
`HYBRID`: A combination of (often separate) data-transport and proximity mechanisms
https://www.w3.org/TR/webauthn-2/#enum-transport
"""
USB = "usb"
NFC = "nfc"
BLE = "ble"
INTERNAL = "internal"
CABLE = "cable"
HYBRID = "hybrid"
class AuthenticatorAttachment(str, Enum):
"""How an authenticator is connected to the client/browser.
Members:
`PLATFORM`: A non-removable authenticator, like TouchID or Windows Hello
`CROSS_PLATFORM`: A "roaming" authenticator, like a YubiKey
https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment
"""
PLATFORM = "platform"
CROSS_PLATFORM = "cross-platform"
class ResidentKeyRequirement(str, Enum):
"""The Relying Party's preference for the authenticator to create a dedicated "client-side" credential for it. Requiring an authenticator to store a dedicated credential should not be done lightly due to the limited storage capacity of some types of authenticators.
Members:
`DISCOURAGED`: The authenticator should not create a dedicated credential
`PREFERRED`: The authenticator can create and store a dedicated credential, but if it doesn't that's alright too
`REQUIRED`: The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur.
https://www.w3.org/TR/webauthn-2/#enum-residentKeyRequirement
"""
DISCOURAGED = "discouraged"
PREFERRED = "preferred"
REQUIRED = "required"
class UserVerificationRequirement(str, Enum):
"""The degree to which the Relying Party wishes to verify a user's identity.
Members:
`REQUIRED`: User verification must occur
`PREFERRED`: User verification would be great, but if not that's okay too
`DISCOURAGED`: User verification should not occur, but it's okay if it does
https://www.w3.org/TR/webauthn-2/#enumdef-userverificationrequirement
"""
REQUIRED = "required"
PREFERRED = "preferred"
DISCOURAGED = "discouraged"
class AttestationConveyancePreference(str, Enum):
"""The Relying Party's interest in receiving an attestation statement.
Members:
`NONE`: The Relying Party isn't interested in receiving an attestation statement
`INDIRECT`: The Relying Party is interested in an attestation statement, but the client is free to generate it as it sees fit
`DIRECT`: The Relying Party is interested in an attestation statement generated directly by the authenticator
`ENTERPRISE`: The Relying Party is interested in a statement with identifying information. Typically used within organizations
https://www.w3.org/TR/webauthn-2/#enum-attestation-convey
"""
NONE = "none"
INDIRECT = "indirect"
DIRECT = "direct"
ENTERPRISE = "enterprise"
class PublicKeyCredentialType(str, Enum):
"""The type of credential that should be returned by an authenticator. There's but a single member because this is a specific subclass of a higher-level `CredentialType` that can be of other types.
Members:
`PUBLIC_KEY`: The literal string `"public-key"`
https://www.w3.org/TR/webauthn-2/#enumdef-publickeycredentialtype
"""
PUBLIC_KEY = "public-key"
class AttestationFormat(str, Enum):
"""The "syntax" of an attestation statement. Formats should be registered with the IANA and include documented signature verification steps.
Members:
`PACKED`
`TPM`
`ANDROID_KEY`
`ANDROID_SAFETYNET`
`FIDO_U2F`
`APPLE`
`NONE`
https://www.iana.org/assignments/webauthn/webauthn.xhtml
"""
PACKED = "packed"
TPM = "tpm"
ANDROID_KEY = "android-key"
ANDROID_SAFETYNET = "android-safetynet"
FIDO_U2F = "fido-u2f"
APPLE = "apple"
NONE = "none"
class ClientDataType(str, Enum):
"""Specific values included in authenticator registration and authentication responses to help avoid certain types of "signature confusion attacks".
Members:
`WEBAUTHN_CREATE`: The string "webauthn.create". Synonymous with `navigator.credentials.create()` in the browser
`WEBAUTHN_GET`: The string "webauthn.get". Synonymous with `navigator.credentials.get()` in the browser
https://www.w3.org/TR/webauthn-2/#dom-collectedclientdata-type
"""
WEBAUTHN_CREATE = "webauthn.create"
WEBAUTHN_GET = "webauthn.get"
class TokenBindingStatus(str, Enum):
"""
https://www.w3.org/TR/webauthn-2/#dom-tokenbinding-status
"""
PRESENT = "present"
SUPPORTED = "supported"
@dataclass
class TokenBinding:
"""
https://www.w3.org/TR/webauthn-2/#dictdef-tokenbinding
"""
status: TokenBindingStatus
id: Optional[str] = None
@dataclass
class PublicKeyCredentialRpEntity:
"""Information about the Relying Party.
Attributes:
`name`: A user-readable name for the Relying Party
(optional) `id`: A unique, constant value assigned to the Relying Party. Authenticators use this value to associate a credential with a particular Relying Party user
https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialrpentity
"""
name: str
id: Optional[str] = None
@dataclass
class PublicKeyCredentialUserEntity:
"""Information about a user of a Relying Party.
Attributes:
`id`: An "opaque byte sequence" that uniquely identifies a user. Typically something like a UUID, but never user-identifying like an email address. Cannot exceed 64 bytes. These bytes should be stored internally alongside your normal user identifier and only used for WebAuthn.
`name`: A value which a user can see to determine which account this credential is associated with. A username or email address is fine here.
`display_name`: A user-friendly representation of a user, like a full name.
https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialuserentity
"""
id: bytes
name: str
display_name: str
@dataclass
class PublicKeyCredentialParameters:
"""Information about a cryptographic algorithm that may be used when creating a credential.
Attributes:
`type`: The literal string `"public-key"`
`alg`: A numeric indicator of a particular algorithm
https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialparameters
"""
type: Literal["public-key"]
alg: COSEAlgorithmIdentifier
@dataclass
class PublicKeyCredentialDescriptor:
"""Information about a generated credential.
Attributes:
`type`: The literal string `"public-key"`
`id`: The sequence of bytes representing the credential's ID
(optional) `transports`: The types of connections to the client/browser the authenticator supports
https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialdescriptor
"""
id: bytes
type: Literal[PublicKeyCredentialType.PUBLIC_KEY] = PublicKeyCredentialType.PUBLIC_KEY
transports: Optional[List[AuthenticatorTransport]] = None
@dataclass
class AuthenticatorSelectionCriteria:
"""A Relying Party's requirements for the types of authenticators that may interact with the client/browser.
Attributes:
(optional) `authenticator_attachment`: How the authenticator can be connected to the client/browser
(optional) `resident_key`: Whether the authenticator should be able to store a credential on itself
(optional) `require_resident_key`: DEPRECATED, set a value for `resident_key` instead
(optional) `user_verification`: How the authenticator should be capable of determining user identity
https://www.w3.org/TR/webauthn-2/#dictdef-authenticatorselectioncriteria
"""
authenticator_attachment: Optional[AuthenticatorAttachment] = None
resident_key: Optional[ResidentKeyRequirement] = None
require_resident_key: Optional[bool] = False
user_verification: Optional[
UserVerificationRequirement
] = UserVerificationRequirement.PREFERRED
@dataclass
class CollectedClientData:
"""Decoded ClientDataJSON
Attributes:
`type`: Either `"webauthn.create"` or `"webauthn.get"`, for registration and authentication ceremonies respectively
`challenge`: The challenge passed to the authenticator within the options
`origin`: The base domain with protocol on which the registration or authentication ceremony took place (e.g. "https://foo.bar")
(optional) `cross_origin`: Whether or not the the registration or authentication ceremony took place on a different origin (think within an <iframe>)
(optional) `token_binding`: Information on the state of the Token Binding protocol
https://www.w3.org/TR/webauthn-2/#dictdef-collectedclientdata
"""
type: ClientDataType
challenge: bytes
origin: str
cross_origin: Optional[bool] = None
token_binding: Optional[TokenBinding] = None
################
#
# Registration
#
################
@dataclass
class PublicKeyCredentialCreationOptions:
"""Registration Options.
Attributes:
`rp`: Information about the Relying Party
`user`: Information about the user
`challenge`: A unique byte sequence to be returned by the authenticator. Helps prevent replay attacks
`pub_key_cred_params`: Cryptographic algorithms supported by the Relying Party when verifying signatures
(optional) `timeout`: How long the client/browser should give the user to interact with an authenticator
(optional) `exclude_credentials`: A list of credentials associated with the user to prevent them from re-enrolling one of them
(optional) `authenticator_selection`: Additional qualities about the authenticators the user can use to complete registration
(optional) `attestation`: The Relying Party's desire for a declaration of an authenticator's provenance via attestation statement
https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialcreationoptions
"""
rp: PublicKeyCredentialRpEntity
user: PublicKeyCredentialUserEntity
challenge: bytes
pub_key_cred_params: List[PublicKeyCredentialParameters]
timeout: Optional[int] = None
exclude_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None
authenticator_selection: Optional[AuthenticatorSelectionCriteria] = None
attestation: AttestationConveyancePreference = AttestationConveyancePreference.NONE
@dataclass
class AuthenticatorAttestationResponse:
"""The `response` property on a registration credential.
Attributes:
`client_data_json`: Information the authenticator collects about the client/browser it communicates with
`attestation_object`: Encoded information about an attestation
(optional) `transports`: The authenticator's supported methods of communication with a client/browser
https://www.w3.org/TR/webauthn-2/#authenticatorattestationresponse
"""
client_data_json: bytes
attestation_object: bytes
# Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
transports: Optional[List[AuthenticatorTransport]] = None
@dataclass
class RegistrationCredential:
"""A registration-specific subclass of PublicKeyCredential returned from `navigator.credentials.create()`
Attributes:
`id`: The Base64URL-encoded representation of raw_id
`raw_id`: A byte sequence representing the credential's unique identifier
`response`: The authenticator's attesation data
`type`: The literal string `"public-key"`
https://www.w3.org/TR/webauthn-2/#publickeycredential
"""
id: str
raw_id: bytes
response: AuthenticatorAttestationResponse
authenticator_attachment: Optional[AuthenticatorAttachment] = None
type: Literal[PublicKeyCredentialType.PUBLIC_KEY] = PublicKeyCredentialType.PUBLIC_KEY
@dataclass
class AttestationStatement:
"""A collection of all possible fields that may exist in an attestation statement. Combinations of these fields are specific to a particular attestation format.
https://www.w3.org/TR/webauthn-2/#sctn-defined-attestation-formats
TODO: Decide if this is acceptable, or if we want to split this up into multiple
format-specific classes that define only the fields that are present for a given
attestation format.
"""
sig: Optional[bytes] = None
x5c: Optional[List[bytes]] = None
response: Optional[bytes] = None
alg: Optional[COSEAlgorithmIdentifier] = None
ver: Optional[str] = None
cert_info: Optional[bytes] = None
pub_area: Optional[bytes] = None
@dataclass
class AuthenticatorDataFlags:
"""Flags the authenticator will set about information contained within the `attestationObject.authData` property.
Attributes:
`up`: [U]ser was [P]resent
`uv`: [U]ser was [V]erified
`be`: [B]ackup [E]ligible
`bs`: [B]ackup [S]tate
`at`: [AT]tested credential is included
`ed`: [E]xtension [D]ata is included
https://www.w3.org/TR/webauthn-2/#flags
"""
up: bool
uv: bool
be: bool
bs: bool
at: bool
ed: bool
@dataclass
class AttestedCredentialData:
"""Information about a credential.
Attributes:
`aaguid`: A 128-bit identifier indicating the type and vendor of the authenticator
`credential_id`: The ID of the private/public key pair generated by the authenticator
`credential_public_key`: The public key generated by the authenticator
https://www.w3.org/TR/webauthn-2/#attested-credential-data
"""
aaguid: bytes
credential_id: bytes
credential_public_key: bytes
@dataclass
class AuthenticatorData:
"""Context the authenticator provides about itself and the environment in which the registration or authentication ceremony took place.
Attributes:
`rp_id_hash`: A SHA-256 hash of the website origin on which the registration or authentication ceremony took place
`flags`: Properties about the user and registration, where applicable
`sign_count`: The number of times the credential was used
(optional) `attested_credential_data`: Information about the credential created during a registration ceremony
(optional) `extensions`: CBOR-encoded extension data corresponding to extensions specified in the registration or authentication ceremony options
https://www.w3.org/TR/webauthn-2/#sctn-attestation
https://www.w3.org/TR/webauthn-2/#sctn-attested-credential-data
"""
rp_id_hash: bytes
flags: AuthenticatorDataFlags
sign_count: int
attested_credential_data: Optional[AttestedCredentialData] = None
extensions: Optional[bytes] = None
@dataclass
class AttestationObject:
"""Information about an attestation, including a statement and authenticator data.
Attributes:
`fmt`: The attestation statement's format
`att_stmt`: An attestation statement to be verified according to the format
`auth_data`: Contextual information provided by authenticator
https://www.w3.org/TR/webauthn-2/#sctn-attestation
"""
fmt: AttestationFormat
auth_data: AuthenticatorData
att_stmt: AttestationStatement = field(default_factory=AttestationStatement)
################
#
# Authentication
#
################
@dataclass
class PublicKeyCredentialRequestOptions:
"""Authentication Options.
Attributes:
`challenge`: A unique byte sequence to be returned by the authenticator. Helps prevent replay attacks
(optional) `timeout`: How long the client/browser should give the user to interact with an authenticator
(optional) `rp_id`: The unique, constant identifier assigned to the Relying Party
(optional) `allow_credentials`: A list of credentials associated with the user that they can use to complete the authentication
(optional) `user_verification`: How the authenticator should be capable of determining user identity
https://www.w3.org/TR/webauthn-2/#dictionary-assertion-options
"""
challenge: bytes
timeout: Optional[int] = None
rp_id: Optional[str] = None
allow_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None
user_verification: Optional[
UserVerificationRequirement
] = UserVerificationRequirement.PREFERRED
@dataclass
class AuthenticatorAssertionResponse:
"""The `response` property on an authentication credential.
Attributes:
`client_data_json`: Information the authenticator collects about the client/browser it communicates with
`authenticator_data`: Contextual information provided by authenticator
`signature`: A byte sequence signed by the authenticator's private key, to be verified with a user's public key
(optional) `user_handle`: The user ID specified for the user during attestation
https://www.w3.org/TR/webauthn-2/#authenticatorassertionresponse
"""
client_data_json: bytes
authenticator_data: bytes
signature: bytes
user_handle: Optional[bytes] = None
@dataclass
class AuthenticationCredential:
"""An authentication-specific subclass of PublicKeyCredential. Returned from `navigator.credentials.get()`
Attributes:
`id`: The Base64URL-encoded representation of raw_id
`raw_id`: A byte sequence representing the credential's unique identifier
`response`: The authenticator's assertion data
`type`: The literal string `"public-key"`
https://www.w3.org/TR/webauthn-2/#publickeycredential
"""
id: str
raw_id: bytes
response: AuthenticatorAssertionResponse
authenticator_attachment: Optional[AuthenticatorAttachment] = None
type: Literal[PublicKeyCredentialType.PUBLIC_KEY] = PublicKeyCredentialType.PUBLIC_KEY
################
#
# Credential Backup State
#
################
class CredentialDeviceType(str, Enum):
"""A determination of the number of devices a credential can be used from
Members:
`SINGLE_DEVICE`: A credential that is bound to a single device
`MULTI_DEVICE`: A credential that can be used from multiple devices (e.g. passkeys)
https://w3c.github.io/webauthn/#sctn-credential-backup (L3 Draft)
"""
SINGLE_DEVICE = "single_device"
MULTI_DEVICE = "multi_device"
|