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\VerifiedPasskeyVerify one assertion against a registered credential's public key, or refuse it.
Parameters
| Name | Type | Description |
|---|---|---|
| $credentialId | string | |
| $publicKeyPem | string | the credential's public key, PEM-encoded (ES256 / P-256) |
| $expectedChallenge | string | the raw challenge bytes the server issued for this assertion |
| $rpId | string | the relying-party id whose SHA-256 must open the authenticatorData |
| $clientDataJson | string | the raw bytes of the browser's clientDataJSON |
| $authenticatorData | string | the raw authenticatorData bytes |
| $signature | string | the 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