Files
skills/docs/identity/auth/webauthn/src/attestation/tpm/tpm.md
2026-05-29 08:20:56 +01:00

3.2 KiB

tpm attestation verifier

(no submodules)

Purpose

Implements the W3C WebAuthn L3 §8.3 tpm attestation format used by Windows Hello and other TPM 2.0-backed platform authenticators. The verifier parses the TCG-defined TPMS_ATTEST and TPMT_PUBLIC structures via @suaveplan/tpm-struct, cross-binds them to the credential public key in authData, verifies the extra-data digest under the algorithm specified by attStmt.alg, and checks the signature against the Attestation Identity Key certificate chain.

Features

  • Strict ver === "2.0" enforcement — TPM 1.2 attestation is intentionally unsupported.
  • Three boundary parses: parseTpmsAttest, parseTpmtPublic, and parseCertificate — every byte payload goes through a shared library and never an inline ASN.1 walk.
  • TPM_ST_ATTEST_CERTIFY type pinning — only the certify flavour is accepted (other TPM attest types are not valid here).
  • Constant-time extraData and name compares.
  • Modulus cross-bind: when the credential is RSA and pubArea.type === TPM_ALG_RSA, the modulus on pubArea.unique.modulus must equal the COSE_Key n.
  • Signature verification against the AIK leaf cert via rsaVerifyPkcs1v15 with hash: "SHA-256" (the Windows Hello case). The package supports RSA AIK signatures; ECC AIK keys are accepted only when the leaf cert exposes them via SPKI, but the dominant TPM 2.0 deployments are all RSA.
  • Reports attestationType: "attCA" per W3C §6.5.3 because the chain anchors to a manufacturer-rooted attestation CA.

Usage: Basic Example

import { verifyTpmAttestation } from "@suaveplan/webauthn/attestation/tpm";

const result = await verifyTpmAttestation({
    attestationObject,
    clientDataHash,
    expectedRpIdHash,
});

Usage: Advanced Example

import {
    defaultAttestationRegistry,
    verifyTpmAttestation,
} from "@suaveplan/webauthn";

const r = defaultAttestationRegistry();
r.set("tpm", async (input) => {
    const inner = await verifyTpmAttestation(input);
    await checkTpmCaAllowlist(inner.trustPath);
    return inner;
});

API Reference

  • verifyTpmAttestation: AttestationFormatVerifier — the format verifier.

Implementation Notes

  • The verifier delegates TPMS_ATTEST and TPMT_PUBLIC parsing entirely to @suaveplan/tpm-struct; the binary TCG structures are NOT re-implemented here.
  • extraData is hash(authData || clientDataHash) per W3C §8.3 step 4 — the algorithm is attStmt.alg (a TPM_ALG_ID label, not a COSE alg label).
  • name is computeTpmtPublicName(pubArea) — a hash-prefixed digest computed by @suaveplan/tpm-struct per TPM 2.0 Part 1 §16. The constant-time compare ensures the credential public key in authData matches the one in pubArea.
  • Only RSA AIK signature verification is wired in this initial cut. ECC AIK keys exist in the wild (TPM 2.0 supports them) but every Windows Hello deployment encountered in production uses RSA-2048 AIK keys. ECC support is a clean extension via the same verifyOverCoseKey dispatcher.
  • The package does NOT itself validate the AIK cert chain against a TPM-manufacturer root pool — that policy belongs to the caller via the returned trustPath and an out-of-band attestation-CA allow-list.