Skip to content
docsv0.9.0

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. The registration ceremony (attestation, COSE→PEM, credential storage), the challenge lifecycle, and the HTTP endpoints are OTHER slices; this one exists to prove the verification is real before they are built. ES256 (ECDSA P-256 over SHA-256) only for now — the overwhelmingly common authenticator algorithm; EdDSA and RS256 are deferred.

WebAuthnAssertionVerifier::verify()

public function verify(string $credentialId, string $publicKeyPem, string $expectedChallenge, string $rpId, 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
$rpIdstringthe relying-party id whose SHA-256 must open the authenticatorData
$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