tba-protocol-webauthn 0.4.0.dev2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. tba_protocol_webauthn/__init__.py +131 -0
  2. tba_protocol_webauthn/attestation/__init__.py +8 -0
  3. tba_protocol_webauthn/attestation/adapters.py +51 -0
  4. tba_protocol_webauthn/attestation/registry.py +59 -0
  5. tba_protocol_webauthn/bindings.py +46 -0
  6. tba_protocol_webauthn/ceremonies/__init__.py +21 -0
  7. tba_protocol_webauthn/ceremonies/authentication.py +169 -0
  8. tba_protocol_webauthn/ceremonies/registration.py +220 -0
  9. tba_protocol_webauthn/claims.py +5 -0
  10. tba_protocol_webauthn/codecs/__init__.py +23 -0
  11. tba_protocol_webauthn/codecs/attestation_object.py +55 -0
  12. tba_protocol_webauthn/codecs/authenticator_data.py +120 -0
  13. tba_protocol_webauthn/codecs/client_data.py +107 -0
  14. tba_protocol_webauthn/codecs/credential_public_key.py +10 -0
  15. tba_protocol_webauthn/compatibility.py +11 -0
  16. tba_protocol_webauthn/configuration.py +33 -0
  17. tba_protocol_webauthn/errors.py +29 -0
  18. tba_protocol_webauthn/extensions/__init__.py +17 -0
  19. tba_protocol_webauthn/extensions/registry.py +68 -0
  20. tba_protocol_webauthn/features.py +41 -0
  21. tba_protocol_webauthn/migrations.py +23 -0
  22. tba_protocol_webauthn/protocol.py +40 -0
  23. tba_protocol_webauthn/py.typed +0 -0
  24. tba_protocol_webauthn/related_origins.py +21 -0
  25. tba_protocol_webauthn/schemas.py +29 -0
  26. tba_protocol_webauthn/versions.py +54 -0
  27. tba_protocol_webauthn/wire_schemas/__init__.py +27 -0
  28. tba_protocol_webauthn/wire_schemas/common.py +113 -0
  29. tba_protocol_webauthn/wire_schemas/level2.py +29 -0
  30. tba_protocol_webauthn/wire_schemas/level3.py +29 -0
  31. tba_protocol_webauthn-0.4.0.dev2.dist-info/METADATA +27 -0
  32. tba_protocol_webauthn-0.4.0.dev2.dist-info/RECORD +33 -0
  33. tba_protocol_webauthn-0.4.0.dev2.dist-info/WHEEL +4 -0
@@ -0,0 +1,68 @@
1
+ """Typed validation registry for WebAuthn extension inputs and outputs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Callable, Mapping
6
+
7
+ ExtensionValidator = Callable[[object], object]
8
+
9
+
10
+ def validate_appid(value: object) -> str:
11
+ if not isinstance(value, str) or not value.startswith("https://"):
12
+ raise ValueError("appid must be an HTTPS URL")
13
+ return value
14
+
15
+
16
+ def validate_cred_props(value: object) -> bool:
17
+ if not isinstance(value, bool):
18
+ raise ValueError("credProps.rk must be boolean")
19
+ return value
20
+
21
+
22
+ def validate_credential_protection(value: object) -> int:
23
+ if not isinstance(value, int) or value not in {1, 2, 3}:
24
+ raise ValueError("credentialProtectionPolicy is invalid")
25
+ return value
26
+
27
+
28
+ def validate_large_blob(value: object) -> Mapping[str, object]:
29
+ if not isinstance(value, Mapping):
30
+ raise ValueError("largeBlob extension value must be an object")
31
+ if "supported" in value and not isinstance(value["supported"], bool):
32
+ raise ValueError("largeBlob.supported must be boolean")
33
+ return value
34
+
35
+
36
+ def validate_payment(value: object) -> Mapping[str, object]:
37
+ if not isinstance(value, Mapping):
38
+ raise ValueError("payment extension value must be an object")
39
+ return value
40
+
41
+
42
+ class ExtensionRegistry:
43
+ def __init__(self) -> None:
44
+ self._validators: dict[str, ExtensionValidator] = {
45
+ "appid": validate_appid,
46
+ "credProps": validate_cred_props,
47
+ "credentialProtectionPolicy": validate_credential_protection,
48
+ "largeBlob": validate_large_blob,
49
+ "payment": validate_payment,
50
+ }
51
+
52
+ def validate(
53
+ self, values: Mapping[str, object], *, allowed: frozenset[str]
54
+ ) -> dict[str, object]:
55
+ unknown = set(values).difference(allowed)
56
+ if unknown:
57
+ raise ValueError(f"WebAuthn extensions are not enabled: {sorted(unknown)}")
58
+ return {name: self._validators[name](value) for name, value in values.items()}
59
+
60
+
61
+ __all__ = [
62
+ "ExtensionRegistry",
63
+ "validate_appid",
64
+ "validate_cred_props",
65
+ "validate_credential_protection",
66
+ "validate_large_blob",
67
+ "validate_payment",
68
+ ]
@@ -0,0 +1,41 @@
1
+ from .versions import WebAuthnVersion
2
+
3
+
4
+ class WebAuthnFeature:
5
+ """Feature-name constants used by versioned protocol configuration."""
6
+
7
+ REGISTRATION = "registration"
8
+ AUTHENTICATION = "authentication"
9
+ DISCOVERABLE_CREDENTIALS = "discoverable-credentials"
10
+ USER_VERIFICATION = "user-verification"
11
+ ATTESTATION = "attestation"
12
+ BACKUP_STATE = "backup-state"
13
+ JSON_SERIALIZATION = "json-serialization"
14
+ CONDITIONAL_MEDIATION = "conditional-mediation"
15
+ RELATED_ORIGINS = "related-origins"
16
+
17
+
18
+ BASE_FEATURES = frozenset(
19
+ {
20
+ WebAuthnFeature.REGISTRATION,
21
+ WebAuthnFeature.AUTHENTICATION,
22
+ WebAuthnFeature.DISCOVERABLE_CREDENTIALS,
23
+ WebAuthnFeature.USER_VERIFICATION,
24
+ WebAuthnFeature.ATTESTATION,
25
+ WebAuthnFeature.BACKUP_STATE,
26
+ }
27
+ )
28
+ LEVEL_3_FEATURES = BASE_FEATURES | {
29
+ WebAuthnFeature.JSON_SERIALIZATION,
30
+ WebAuthnFeature.CONDITIONAL_MEDIATION,
31
+ WebAuthnFeature.RELATED_ORIGINS,
32
+ }
33
+
34
+
35
+ def features_for(version: str) -> frozenset[str]:
36
+ if version not in {WebAuthnVersion.LEVEL_2, WebAuthnVersion.LEVEL_3}:
37
+ raise ValueError(f"unsupported WebAuthn version: {version}")
38
+ return LEVEL_3_FEATURES if version == WebAuthnVersion.LEVEL_3 else BASE_FEATURES
39
+
40
+
41
+ __all__ = ["BASE_FEATURES", "LEVEL_3_FEATURES", "WebAuthnFeature", "features_for"]
@@ -0,0 +1,23 @@
1
+ from .versions import WebAuthnVersion, resolve_revision
2
+
3
+
4
+ def migration_path(source: str, target: str) -> tuple[str, ...]:
5
+ source_version = resolve_revision(source).identifier
6
+ target_version = resolve_revision(target).identifier
7
+ if source_version == target_version:
8
+ return ()
9
+ if (
10
+ source_version == WebAuthnVersion.LEVEL_2
11
+ and target_version == WebAuthnVersion.LEVEL_3
12
+ ):
13
+ return (
14
+ "enable-level-3-json-serialization",
15
+ "enable-conditional-mediation-when-client-capable",
16
+ "configure-related-origin-policy-explicitly",
17
+ )
18
+ raise ValueError(
19
+ f"unsupported WebAuthn migration: {source_version} -> {target_version}"
20
+ )
21
+
22
+
23
+ __all__ = ["migration_path"]
@@ -0,0 +1,40 @@
1
+ """Reportable WebAuthn protocol surface."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ from tba_capability_public_key_authentication import (
8
+ PublicKeyAuthenticationCapability,
9
+ )
10
+ from tba_capability_public_key_registration import PublicKeyRegistrationCapability
11
+
12
+ from .bindings import CAPABILITY_REQUIREMENTS
13
+ from .configuration import WebAuthnConfiguration
14
+ from .features import features_for
15
+ from .versions import CURRENT_VERSION
16
+
17
+
18
+ @dataclass(frozen=True, slots=True)
19
+ class WebAuthnProtocol:
20
+ registration: PublicKeyRegistrationCapability
21
+ authentication: PublicKeyAuthenticationCapability
22
+ configuration: WebAuthnConfiguration = WebAuthnConfiguration()
23
+
24
+ def capability_report(self) -> dict[str, object]:
25
+ return {
26
+ "protocol": "webauthn",
27
+ "revision": CURRENT_VERSION.identifier,
28
+ "supported_features": tuple(
29
+ sorted(features_for(self.configuration.version))
30
+ ),
31
+ "enabled_features": tuple(sorted(self.configuration.enabled_features)),
32
+ "requirements": CAPABILITY_REQUIREMENTS,
33
+ "capabilities": {
34
+ "registration": self.registration.capability_report(),
35
+ "authentication": self.authentication.capability_report(),
36
+ },
37
+ }
38
+
39
+
40
+ __all__ = ["WebAuthnProtocol"]
File without changes
@@ -0,0 +1,21 @@
1
+ """Explicit Level 3 related-origin policy."""
2
+
3
+ from urllib.parse import urlsplit
4
+
5
+
6
+ def origin_is_allowed(
7
+ origin: str, expected_origin: str, related_origins: tuple[str, ...] = ()
8
+ ) -> bool:
9
+ def normalized(value: str) -> str:
10
+ parsed = urlsplit(value)
11
+ if parsed.scheme != "https" or not parsed.hostname:
12
+ raise ValueError("related origins must be HTTPS origins")
13
+ return f"https://{parsed.netloc}"
14
+
15
+ supplied = normalized(origin)
16
+ return supplied == normalized(expected_origin) or supplied in {
17
+ normalized(value) for value in related_origins
18
+ }
19
+
20
+
21
+ __all__ = ["origin_is_allowed"]
@@ -0,0 +1,29 @@
1
+ """Public versioned WebAuthn schema surface."""
2
+
3
+ from .wire_schemas.common import (
4
+ AuthenticatorAssertionResponse,
5
+ AuthenticatorAttestationResponse,
6
+ AuthenticatorSelectionCriteria,
7
+ CollectedClientData,
8
+ PublicKeyCredential,
9
+ PublicKeyCredentialCreationOptions,
10
+ PublicKeyCredentialDescriptor,
11
+ PublicKeyCredentialParameters,
12
+ PublicKeyCredentialRequestOptions,
13
+ PublicKeyCredentialRpEntity,
14
+ PublicKeyCredentialUserEntity,
15
+ )
16
+
17
+ __all__ = [
18
+ "AuthenticatorAssertionResponse",
19
+ "AuthenticatorAttestationResponse",
20
+ "AuthenticatorSelectionCriteria",
21
+ "CollectedClientData",
22
+ "PublicKeyCredential",
23
+ "PublicKeyCredentialCreationOptions",
24
+ "PublicKeyCredentialDescriptor",
25
+ "PublicKeyCredentialParameters",
26
+ "PublicKeyCredentialRequestOptions",
27
+ "PublicKeyCredentialRpEntity",
28
+ "PublicKeyCredentialUserEntity",
29
+ ]
@@ -0,0 +1,54 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ class WebAuthnVersion:
5
+ """String constants; version history remains owned by this protocol package."""
6
+
7
+ LEVEL_2 = "level-2"
8
+ LEVEL_3 = "level-3"
9
+
10
+
11
+ @dataclass(frozen=True, slots=True)
12
+ class WebAuthnRevision:
13
+ version: str
14
+ publication_date: str
15
+ status: str
16
+ specification_uri: str
17
+
18
+ @property
19
+ def identifier(self) -> str:
20
+ return self.version
21
+
22
+
23
+ WEB_AUTHN_REVISIONS = {
24
+ WebAuthnVersion.LEVEL_2: WebAuthnRevision(
25
+ WebAuthnVersion.LEVEL_2,
26
+ "2021-04-08",
27
+ "W3C Recommendation",
28
+ "https://www.w3.org/TR/webauthn-2/",
29
+ ),
30
+ WebAuthnVersion.LEVEL_3: WebAuthnRevision(
31
+ WebAuthnVersion.LEVEL_3,
32
+ "2026-05-26",
33
+ "W3C Candidate Recommendation Snapshot",
34
+ "https://www.w3.org/TR/webauthn-3/",
35
+ ),
36
+ }
37
+
38
+ CURRENT_VERSION = WEB_AUTHN_REVISIONS[WebAuthnVersion.LEVEL_2]
39
+
40
+
41
+ def resolve_revision(value: str) -> WebAuthnRevision:
42
+ try:
43
+ return WEB_AUTHN_REVISIONS[value]
44
+ except KeyError as exc:
45
+ raise ValueError(f"unsupported WebAuthn version: {value}") from exc
46
+
47
+
48
+ __all__ = [
49
+ "CURRENT_VERSION",
50
+ "WEB_AUTHN_REVISIONS",
51
+ "WebAuthnRevision",
52
+ "WebAuthnVersion",
53
+ "resolve_revision",
54
+ ]
@@ -0,0 +1,27 @@
1
+ from .common import (
2
+ AuthenticatorAssertionResponse,
3
+ AuthenticatorAttestationResponse,
4
+ AuthenticatorSelectionCriteria,
5
+ CollectedClientData,
6
+ PublicKeyCredential,
7
+ PublicKeyCredentialCreationOptions,
8
+ PublicKeyCredentialDescriptor,
9
+ PublicKeyCredentialParameters,
10
+ PublicKeyCredentialRequestOptions,
11
+ PublicKeyCredentialRpEntity,
12
+ PublicKeyCredentialUserEntity,
13
+ )
14
+
15
+ __all__ = [
16
+ "AuthenticatorAssertionResponse",
17
+ "AuthenticatorAttestationResponse",
18
+ "AuthenticatorSelectionCriteria",
19
+ "CollectedClientData",
20
+ "PublicKeyCredential",
21
+ "PublicKeyCredentialCreationOptions",
22
+ "PublicKeyCredentialDescriptor",
23
+ "PublicKeyCredentialParameters",
24
+ "PublicKeyCredentialRequestOptions",
25
+ "PublicKeyCredentialRpEntity",
26
+ "PublicKeyCredentialUserEntity",
27
+ ]
@@ -0,0 +1,113 @@
1
+ """W3C WebAuthn wire structures represented with byte-preserving values."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Mapping
7
+
8
+
9
+ @dataclass(frozen=True, slots=True)
10
+ class PublicKeyCredentialRpEntity:
11
+ id: str
12
+ name: str
13
+
14
+
15
+ @dataclass(frozen=True, slots=True)
16
+ class PublicKeyCredentialUserEntity:
17
+ id: bytes
18
+ name: str
19
+ display_name: str
20
+
21
+
22
+ @dataclass(frozen=True, slots=True)
23
+ class PublicKeyCredentialParameters:
24
+ alg: int
25
+ type: str = "public-key"
26
+
27
+
28
+ @dataclass(frozen=True, slots=True)
29
+ class PublicKeyCredentialDescriptor:
30
+ id: bytes
31
+ type: str = "public-key"
32
+ transports: tuple[str, ...] = ()
33
+
34
+
35
+ @dataclass(frozen=True, slots=True)
36
+ class AuthenticatorSelectionCriteria:
37
+ authenticator_attachment: str | None = None
38
+ resident_key: str = "preferred"
39
+ require_resident_key: bool = False
40
+ user_verification: str = "preferred"
41
+
42
+
43
+ @dataclass(frozen=True, slots=True)
44
+ class PublicKeyCredentialCreationOptions:
45
+ challenge: bytes
46
+ rp: PublicKeyCredentialRpEntity
47
+ user: PublicKeyCredentialUserEntity
48
+ pub_key_cred_params: tuple[PublicKeyCredentialParameters, ...]
49
+ timeout: int | None = None
50
+ exclude_credentials: tuple[PublicKeyCredentialDescriptor, ...] = ()
51
+ authenticator_selection: AuthenticatorSelectionCriteria | None = None
52
+ attestation: str = "none"
53
+ extensions: Mapping[str, object] = field(default_factory=dict)
54
+
55
+
56
+ @dataclass(frozen=True, slots=True)
57
+ class PublicKeyCredentialRequestOptions:
58
+ challenge: bytes
59
+ timeout: int | None = None
60
+ rp_id: str | None = None
61
+ allow_credentials: tuple[PublicKeyCredentialDescriptor, ...] = ()
62
+ user_verification: str = "preferred"
63
+ extensions: Mapping[str, object] = field(default_factory=dict)
64
+ hints: tuple[str, ...] = ()
65
+
66
+
67
+ @dataclass(frozen=True, slots=True)
68
+ class CollectedClientData:
69
+ type: str
70
+ challenge: str
71
+ origin: str
72
+ cross_origin: bool = False
73
+ top_origin: str | None = None
74
+
75
+
76
+ @dataclass(frozen=True, slots=True)
77
+ class AuthenticatorAttestationResponse:
78
+ client_data_json: bytes
79
+ attestation_object: bytes
80
+ transports: tuple[str, ...] = ()
81
+
82
+
83
+ @dataclass(frozen=True, slots=True)
84
+ class AuthenticatorAssertionResponse:
85
+ client_data_json: bytes
86
+ authenticator_data: bytes
87
+ signature: bytes
88
+ user_handle: bytes | None = None
89
+
90
+
91
+ @dataclass(frozen=True, slots=True)
92
+ class PublicKeyCredential:
93
+ id: str
94
+ raw_id: bytes
95
+ response: AuthenticatorAttestationResponse | AuthenticatorAssertionResponse
96
+ type: str = "public-key"
97
+ authenticator_attachment: str | None = None
98
+ client_extension_results: Mapping[str, object] = field(default_factory=dict)
99
+
100
+
101
+ __all__ = [
102
+ "AuthenticatorAssertionResponse",
103
+ "AuthenticatorAttestationResponse",
104
+ "AuthenticatorSelectionCriteria",
105
+ "CollectedClientData",
106
+ "PublicKeyCredential",
107
+ "PublicKeyCredentialCreationOptions",
108
+ "PublicKeyCredentialDescriptor",
109
+ "PublicKeyCredentialParameters",
110
+ "PublicKeyCredentialRequestOptions",
111
+ "PublicKeyCredentialRpEntity",
112
+ "PublicKeyCredentialUserEntity",
113
+ ]
@@ -0,0 +1,29 @@
1
+ """WebAuthn Level 2 schema surface."""
2
+
3
+ from .common import (
4
+ AuthenticatorAssertionResponse,
5
+ AuthenticatorAttestationResponse,
6
+ AuthenticatorSelectionCriteria,
7
+ CollectedClientData,
8
+ PublicKeyCredential,
9
+ PublicKeyCredentialCreationOptions,
10
+ PublicKeyCredentialDescriptor,
11
+ PublicKeyCredentialParameters,
12
+ PublicKeyCredentialRequestOptions,
13
+ PublicKeyCredentialRpEntity,
14
+ PublicKeyCredentialUserEntity,
15
+ )
16
+
17
+ __all__ = [
18
+ "AuthenticatorAssertionResponse",
19
+ "AuthenticatorAttestationResponse",
20
+ "AuthenticatorSelectionCriteria",
21
+ "CollectedClientData",
22
+ "PublicKeyCredential",
23
+ "PublicKeyCredentialCreationOptions",
24
+ "PublicKeyCredentialDescriptor",
25
+ "PublicKeyCredentialParameters",
26
+ "PublicKeyCredentialRequestOptions",
27
+ "PublicKeyCredentialRpEntity",
28
+ "PublicKeyCredentialUserEntity",
29
+ ]
@@ -0,0 +1,29 @@
1
+ """WebAuthn Level 3 schema surface; additional behavior is feature-gated."""
2
+
3
+ from .level2 import (
4
+ AuthenticatorAssertionResponse,
5
+ AuthenticatorAttestationResponse,
6
+ AuthenticatorSelectionCriteria,
7
+ CollectedClientData,
8
+ PublicKeyCredential,
9
+ PublicKeyCredentialCreationOptions,
10
+ PublicKeyCredentialDescriptor,
11
+ PublicKeyCredentialParameters,
12
+ PublicKeyCredentialRequestOptions,
13
+ PublicKeyCredentialRpEntity,
14
+ PublicKeyCredentialUserEntity,
15
+ )
16
+
17
+ __all__ = [
18
+ "AuthenticatorAssertionResponse",
19
+ "AuthenticatorAttestationResponse",
20
+ "AuthenticatorSelectionCriteria",
21
+ "CollectedClientData",
22
+ "PublicKeyCredential",
23
+ "PublicKeyCredentialCreationOptions",
24
+ "PublicKeyCredentialDescriptor",
25
+ "PublicKeyCredentialParameters",
26
+ "PublicKeyCredentialRequestOptions",
27
+ "PublicKeyCredentialRpEntity",
28
+ "PublicKeyCredentialUserEntity",
29
+ ]
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: tba-protocol-webauthn
3
+ Version: 0.4.0.dev2
4
+ Summary: Versioned W3C Web Authentication relying-party protocol implementation.
5
+ License-Expression: Apache-2.0
6
+ Requires-Python: >=3.10,<3.15
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Dist: cbor2 (==6.1.3)
14
+ Requires-Dist: tba-capability-public-key-authentication (==0.4.0.dev2)
15
+ Requires-Dist: tba-capability-public-key-registration (==0.4.0.dev2)
16
+ Requires-Dist: tba-concrete-cose (==0.4.0.dev2)
17
+ Requires-Dist: tba-contracts-identity (==0.4.0.dev2)
18
+ Requires-Dist: tba-primitives-identity (==0.4.0.dev2)
19
+ Requires-Dist: tba-provider-cose-cryptography (==0.4.0.dev2)
20
+ Description-Content-Type: text/markdown
21
+
22
+ # tba-protocol-webauthn
23
+
24
+ Versioned W3C WebAuthn relying-party schemas, codecs, registration verification, authentication verification, feature selection, and capability bindings.
25
+
26
+ This package does not implement CTAP transports or durable storage.
27
+
@@ -0,0 +1,33 @@
1
+ tba_protocol_webauthn/__init__.py,sha256=nYDWfgjqsFK10COJ3k3kN6kp_erTjBOHYBma2soKPmM,3722
2
+ tba_protocol_webauthn/attestation/__init__.py,sha256=-yDXKkd41PuwvN5EjITsnVb0bRxkQvNKJX_TYxDkhHY,249
3
+ tba_protocol_webauthn/attestation/adapters.py,sha256=FSY8g2vw8BgLDb8i88vvNiQG7NCu5fLbip7h_Q8pzIM,1596
4
+ tba_protocol_webauthn/attestation/registry.py,sha256=GgvGYPVZyumLO4WVs0KoPJmccoZlBvuWJL-W-z8s7O0,1883
5
+ tba_protocol_webauthn/bindings.py,sha256=N2gRryTBOcrj83j8gwNEG1hATiz35yP2Ppw7YIlQELo,1535
6
+ tba_protocol_webauthn/ceremonies/__init__.py,sha256=yf1tXHjovfo5eiJMtNVdS5w4BnYLyRQaTL5u9RvybNY,519
7
+ tba_protocol_webauthn/ceremonies/authentication.py,sha256=6FatOwG-wJGZVMumn-vgpwNJuTkSFohE3tUdmDEV2Mw,6056
8
+ tba_protocol_webauthn/ceremonies/registration.py,sha256=h8v3_cDkFBuO7WztrD6OQZ4W0aj_mWdmXt-GbgzirGI,8410
9
+ tba_protocol_webauthn/claims.py,sha256=2jMEjSZ4RiMaUW9TR6udTS6P198w_p7WMpV4xsiB43c,145
10
+ tba_protocol_webauthn/codecs/__init__.py,sha256=adQ3NI9Xrin8xJopRrJtZBz82sPYpOuICec89SuxYdw,674
11
+ tba_protocol_webauthn/codecs/attestation_object.py,sha256=VwITXFxeH0aqnIycdifNNL9nZ7aK6t1cTfAwcjr7g0U,1772
12
+ tba_protocol_webauthn/codecs/authenticator_data.py,sha256=DHF1x5l_V8VAZsYKFEJrg6oDsOpuzwOAtSW84WiC9nI,3873
13
+ tba_protocol_webauthn/codecs/client_data.py,sha256=hnCI9O1Vp0dRTo_VsWMx_HJHvEECKxiAJ6v4oTHkmcc,3590
14
+ tba_protocol_webauthn/codecs/credential_public_key.py,sha256=JXkUj2xxP8D8_Fxi6cKtqwx85LTQnCjWMjk2_G5_rb8,224
15
+ tba_protocol_webauthn/compatibility.py,sha256=ZvQT6YJkGT3zSA1_wU8lVoWw4SWp8pDDCa_0u-2WiGE,284
16
+ tba_protocol_webauthn/configuration.py,sha256=M5nxrDF1lja-ArjO17rnaisOi3mTkuNW1kV2zYqSdXc,1135
17
+ tba_protocol_webauthn/errors.py,sha256=CyQXnWZRiupEdFMLETv_ly0-aT8sjcMpSO7zSUBCn2s,631
18
+ tba_protocol_webauthn/extensions/__init__.py,sha256=31N9MOqbbZcLCcsvN6UzxKGihiethGR4Jm12HBtpq34,355
19
+ tba_protocol_webauthn/extensions/registry.py,sha256=E5BX463p-VcTcMGBfKzJ_DXTRFEq1xdkBtPIFxS-awU,2194
20
+ tba_protocol_webauthn/features.py,sha256=O3mJ8TyJRskrqdzSTvanszcASqfok14HtlVBIMZrr4M,1330
21
+ tba_protocol_webauthn/migrations.py,sha256=RulW7sNxuep_mSulHtj_fGn8YQxXXyZmJmgI3x7WnsA,753
22
+ tba_protocol_webauthn/protocol.py,sha256=2B_4hA9FbV64FWLF3Afp-EeYjZ9_8dPb2N4-7P-4e4E,1349
23
+ tba_protocol_webauthn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ tba_protocol_webauthn/related_origins.py,sha256=QDs9E3QGEcEb2MXJI8SFZe2was7VLYNYm0IG0mx8OLM,636
25
+ tba_protocol_webauthn/schemas.py,sha256=vWIcfx6oxqE0HY2zEJlqXCFk2dc-2XxeI974MKNYOoI,877
26
+ tba_protocol_webauthn/versions.py,sha256=WTe4lJDrEU9g4AStll6Bvs7zr4grEIf-uiqIzy4qPEE,1243
27
+ tba_protocol_webauthn/wire_schemas/__init__.py,sha256=pTcT6YUn2GRcWJsIj54uCpBtVoKmAu7aAoYk9TQrRvo,815
28
+ tba_protocol_webauthn/wire_schemas/common.py,sha256=NkhH_HMnoYck0QYNrI7DC4924cYzC02zxwaKLwI8va4,3097
29
+ tba_protocol_webauthn/wire_schemas/level2.py,sha256=lXIzQtZtjijhK93aJJXSGBey4xP25Jb9ctAQZWR83wE,855
30
+ tba_protocol_webauthn/wire_schemas/level3.py,sha256=V69uaDDPXn1bDYFspKZT3f_-hvO42wurxmjiQ437nSc,893
31
+ tba_protocol_webauthn-0.4.0.dev2.dist-info/METADATA,sha256=OC7vHYTSzT33DVv9fUn72rSQ3jxzBaPlNYOUBQVejIw,1192
32
+ tba_protocol_webauthn-0.4.0.dev2.dist-info/WHEEL,sha256=L-WvLdSBvJWHXv5zrQxDvNRnIgoBzLUpcbuiw19KCuQ,88
33
+ tba_protocol_webauthn-0.4.0.dev2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.5.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any