Skip to content
docsv0.11.2

WebAuthnAssertionVerifier

Verifies one WebAuthn authentication assertion — the `navigator.credentials.get()` ceremony's proof — against a registered credential's public key, LIVE. This is the crypto throat of the passkey path, kept deliberately narrow (greenhouse H-PASSKEY-1): given the stored public key, the challenge the server issued, the relying-party id, and the three bytes the browser returns (clientDataJSON, authenticatorData, signature), it answers one question — did the holder of THIS credential sign THIS challenge? The verdict is produced here, never read from a flag. Every check of WebAuthn L2 §7.2 that belongs to one assertion is made here: the ceremony type, the challenge, the ORIGIN the browser ran it on (one of the relying party's `allowedOrigins`, so a page on another origin relaying the ceremony is refused), the rpId hash, user presence, user VERIFICATION (required unless the verifier is built with an explicitly relaxed {@see UserVerificationRequirement}), and the signature. The sign-counter comparison needs the stored counter, so the ceremony that owns the store makes it ({@see PasskeyAuthenticator}). The registration ceremony (attestation, COSE→PEM, credential storage), the challenge lifecycle, and the HTTP endpoints are OTHER slices. ES256 (ECDSA P-256 over SHA-256) only for now — the overwhelmingly common authenticator algorithm; EdDSA and RS256 are deferred.

WebAuthnAssertionVerifier::__construct()

public function __construct(Milpa\Auth\WebAuthn\UserVerificationRequirement $userVerification = Milpa\Auth\WebAuthn\UserVerificationRequirement::Required):

Parameters

Parameters of __construct()
NameTypeDescription
$userVerificationUserVerificationRequirement`Required` by default; relax it only on purpose, matching the `userVerification` the host sent

WebAuthnAssertionVerifier::verify()

public function verify(string $credentialId, string $publicKeyPem, string $expectedChallenge, Milpa\Auth\WebAuthn\RelyingParty $rp, string $clientDataJson, string $authenticatorData, string $signature): ?Milpa\Auth\WebAuthn\VerifiedPasskey

Verify one assertion against a registered credential's public key, or refuse it.

Parameters

Parameters of verify()
NameTypeDescription
$credentialIdstring
$publicKeyPemstringthe credential's public key, PEM-encoded (ES256 / P-256)
$expectedChallengestringthe raw challenge bytes the server issued for this assertion
$rpRelyingPartythe relying party: its id's SHA-256 must open the authenticatorData, and the clientDataJSON origin must be one of its allowedOrigins
$clientDataJsonstringthe raw bytes of the browser's clientDataJSON
$authenticatorDatastringthe raw authenticatorData bytes
$signaturestringthe assertion signature (DER ECDSA for ES256)

Returns

the credential proven to have signed this challenge, or null when the proof does not hold — a failed verification is never a soft pass