2.5 KiB
2.5 KiB
apple attestation verifier
(no submodules)
Purpose
Implements the W3C WebAuthn L3 §8.8 apple anonymous attestation format used by macOS Touch ID, iOS Face ID, and other Apple platform authenticators. Apple's format is unusual: there is no signed attStmt field; instead, the leaf certificate in x5c carries an Apple-specific extension whose value is the SHA-256 of authData || clientDataHash. The verifier confirms that nonce binding and surfaces the chain as anonCA attestation per W3C §6.5.3.
Features
- Apple nonce extension OID
1.2.840.113635.100.8.2enforced on the leaf cert. - Extension content decoded via
@suaveplan/x509#decodeAsn1— no inline ASN.1 walking. - Constant-time compare of the extracted nonce against
sha256(authData || clientDataHash). - Constant-time
rpIdHashcompare. - Reports
attestationType: "anonCA"— Apple deliberately uses anonymous CA attestation so the format does not leak per-device identity to the relying party.
Usage: Basic Example
import { verifyAppleAttestation } from "@suaveplan/webauthn/attestation/apple";
const result = await verifyAppleAttestation({
attestationObject,
clientDataHash,
expectedRpIdHash,
});
// result.attestationType === "anonCA"
Usage: Advanced Example
import {
defaultAttestationRegistry,
verifyAppleAttestation,
} from "@suaveplan/webauthn";
const registry = defaultAttestationRegistry();
registry.set("apple", async (input) => {
const r = await verifyAppleAttestation(input);
await validateAppleAttestationRoot(r.trustPath);
return r;
});
API Reference
verifyAppleAttestation: AttestationFormatVerifier— the format verifier.
Implementation Notes
- The nonce extension is wrapped in
SEQUENCE { [1] EXPLICIT OCTET STRING <nonce> }per Apple's documented schema; the verifier walks the decoded ASN.1 tree depth-first and grabs the first universal OCTET STRING it encounters, which is the documented contract. - Chain validation against the Apple WebAuthn attestation root is intentionally NOT performed here — that root is environment-specific and the caller's metadata layer is the right place for it. The verifier surfaces the x5c chain via
trustPath. anonCAis the onlyattestationTypereturned. RPs that need per-device telemetry MUST request a different attestation conveyance preference (attestation: "direct"does NOT produce per-device identity from Apple platform authenticators by design).