diff --git a/irrd/webui/auth/endpoints_mfa.py b/irrd/webui/auth/endpoints_mfa.py index d6783a8..25b1db4 100644 --- a/irrd/webui/auth/endpoints_mfa.py +++ b/irrd/webui/auth/endpoints_mfa.py @@ -12,12 +12,14 @@ from starlette.responses import JSONResponse, RedirectResponse, Response from starlette_wtf import StarletteForm, csrf_protect from webauthn import base64url_to_bytes +from webauthn.helpers import ( + parse_authentication_credential_json, + parse_registration_credential_json, +) from webauthn.helpers.structs import ( AttestationConveyancePreference, - AuthenticationCredential, AuthenticatorSelectionCriteria, PublicKeyCredentialDescriptor, - RegistrationCredential, UserVerificationRequirement, ) from wtforms_bootstrap5 import RendererContext @@ -178,7 +180,7 @@ async def webauthn_verify_authentication_response( wn_origin, wn_rpid = get_webauthn_origin_rpid() try: expected_challenge = base64.b64decode(request.session[WN_CHALLENGE_SESSION_KEY]) - credential = AuthenticationCredential.model_validate_json(await request.body()) + credential = parse_authentication_credential_json(await request.json()) query = session_provider.session.query(AuthWebAuthn).filter_by( user=request.auth.user, credential_id=credential.raw_id ) @@ -226,7 +228,7 @@ async def webauthn_register(request: Request) -> Response: rp_id=wn_rpid, # An assigned random identifier; # never anything user-identifying like an email address - user_id=str(request.auth.user.pk), + user_id=request.auth.user.pk.bytes, # A user-visible hint of which account this credential belongs to user_name=request.auth.user.email, authenticator_selection=AuthenticatorSelectionCriteria( @@ -256,7 +258,7 @@ async def webauthn_verify_registration_response( try: expected_challenge = base64.b64decode(request.session[WN_CHALLENGE_SESSION_KEY]) body = await request.json() - credential = RegistrationCredential.model_validate_json(body["registration_response"]) + credential = parse_registration_credential_json(body["registration_response"]) verification = webauthn.verify_registration_response( credential=credential, expected_challenge=expected_challenge, diff --git a/poetry.lock b/poetry.lock index 9517d7e..5a7d204 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3331,21 +3331,20 @@ anyio = ">=3.0.0" [[package]] name = "webauthn" -version = "1.11.1" +version = "2.1.0" description = "Pythonic WebAuthn" optional = false python-versions = "*" files = [ - {file = "webauthn-1.11.1-py3-none-any.whl", hash = "sha256:13592ee71489b571cb6e4a5d8b3c34f7b040cd3539a9d94b6b7d23fa88df5dfb"}, - {file = "webauthn-1.11.1.tar.gz", hash = "sha256:24eda57903897369797f52a377f8c470e7057e79da5525779d0720a9fcc11926"}, + {file = "webauthn-2.1.0-py3-none-any.whl", hash = "sha256:9e1cf916e5ed7c01d54a6dfcc19dacbd2b87b81d2648f001b1fcbcb7aa2ff130"}, + {file = "webauthn-2.1.0.tar.gz", hash = "sha256:b196a4246c2818820857ba195c6e6e5398c761117f2269e3d2deab11c7995fc4"}, ] [package.dependencies] asn1crypto = ">=1.4.0" cbor2 = ">=5.4.6" -cryptography = ">=41.0.4" -pydantic = ">=1.10.11" -pyOpenSSL = ">=23.2.0" +cryptography = ">=41.0.7" +pyOpenSSL = ">=23.3.0" [[package]] name = "websockets" @@ -3736,4 +3735,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "8f1b01adce4d16c113c408910e7201833ac7f17a0ae0876b80858d5db9bd30c3" +content-hash = "8ae05c2ebbd4b0d2b4d6c1c2b902e6ace719778a11402372034db45724d15a75" diff --git a/pyproject.toml b/pyproject.toml index f75b963..d131cfb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ python-multipart = "0.0.9" imia = "0.5.3" starlette-wtf = "0.4.3" limits = "3.10.1" -webauthn = "1.11.1" +webauthn = "2.1.0" pyotp = "2.9.0" click = "8.1.7" zxcvbn = "4.4.28"