4.6 KiB
public/public — TPMT_PUBLIC parser
(no submodules)
- serialize — `serializeTpmtPublic` re-emits a parsed…-
serialize —
serializeTpmtPublicre-emits a parsedTpmtPublicvalue as the TCG-canonical byte string per Library Part 2 §12.2. I… -
serialize —
serializeTpmtPublicre-emits a parsed… -
serialize —
serializeTpmtPublicre-emits a parsedTpmtPublicvalue as the TCG-canonical byte string per Library Part 2 §12.2. I… -
serialize —
serializeTpmtPublicre-emits a parsed… -
serialize —
serializeTpmtPublicre-emits a parsedTpmtPublicvalue as the TCG-canonical byte string per Library Part 2 §12.2. I… -
serialize —
serializeTpmtPublicre-emits a parsed… -
serialize —
serializeTpmtPublicre-emits a parsedTpmtPublicvalue as the TCG-canonical byte string per Library Part 2 §12.2. I… -
serialize —
serializeTpmtPublicre-emits a parsedTpmtPublicvalue as the TCG-canonical byte string per Library Part 2 §12.2. I…
Purpose
parseTpmtPublic decodes a TCG TPM 2.0 TPMT_PUBLIC byte string per
Library Part 2 §12.2 into a discriminated-union value keyed on the
TPMI_ALG_PUBLIC type field. The four supported branches —
TPM_ALG_RSA, TPM_ALG_ECC, TPM_ALG_KEYEDHASH, TPM_ALG_SYMCIPHER —
each decode their own TPMS_*_PARMS parameter substructure and matching
TPMU_PUBLIC_ID unique slot. The parser is the central seam between the
on-the-wire byte format and every downstream consumer of TPM public
areas: computeTpmtPublicName re-emits the bytes through
serializeTpmtPublic and hashes them for the canonical Part 1 §16 name
digest, while the WebAuthn tpm-format verifier validates the pubArea
against the credential public key in authData.attestedCredentialData.
Features
- Full §12.2 field order enforcement (
type→nameAlg→objectAttributes→authPolicy→parameters→unique). - RSA-2048/3072/4096 with default-exponent (
0→65537) normalisation per §12.2.3.5 plus arawExponentslot preserved for round-trip fidelity. - ECC P-256/P-384/P-521/BN-256/BN-638/SM2-256 with
curveIDlookup via the §11.2.5 registry; unknown curves raiseCURVE_UNSUPPORTED. - KEYEDHASH NULL / HMAC / XOR schemes per §12.2.3.3.
- SYMCIPHER with full
TPMT_SYM_DEF_OBJECTdecoding per §12.2.3.4. objectAttributesdecoded into rawuint32+ typed flag struct; reserved bits non-zero raiseOBJECT_ATTRIBUTES_RESERVED_NONZERO.- Boundary Zod schema (
TpmtPublicSchema) validates the constructed result before returning — malformed parser output raisesMALFORMED. - OTel histograms (
tpm_struct.parse_tpmt_public_duration_ms{type,outcome})- counters (
tpm_struct.parse_total{kind="public",outcome}andtpm_struct.parse_errors_total{code}).
- counters (
Usage: Basic Example
import { parseTpmtPublic } from "@suaveplan/tpm-struct/public";
const pub = parseTpmtPublic(pubAreaBytes);
if (pub.type === "TPM_ALG_RSA") {
console.log(pub.parameters.keyBits, pub.parameters.exponent);
console.log(pub.unique.modulus.byteLength);
}
Usage: Advanced Example
import { createHash } from "node:crypto";
import {
computeTpmtPublicName,
parseTpmtPublic,
} from "@suaveplan/tpm-struct";
const pub = parseTpmtPublic(pubAreaBytes);
if (pub.nameAlg === "TPM_ALG_SHA256" && pub.type === "TPM_ALG_ECC") {
const name = computeTpmtPublicName(pub, {
digest: (b) => new Uint8Array(createHash("sha256").update(b).digest()),
});
// `name` is `0x000b || sha256(serializeTpmtPublic(pub))` — feed this
// into the WebAuthn `tpm`-attestation name-match step (W3C WebAuthn
// L3 §8.3 step 5).
}
API Reference
parseTpmtPublic(bytes: Uint8Array): TpmtPublic— returns a discriminated-union value. ThrowsTpmStructErrorwith one ofALG_UNSUPPORTED,CURVE_UNSUPPORTED,OBJECT_ATTRIBUTES_RESERVED_NONZERO,PARAMETERS_INVALID,TRUNCATED, orMALFORMED.TpmtPublic— discriminator union overtype. Each branch carriesnameAlg,objectAttributes,authPolicy,parameters,unique.
Implementation Notes
The parser is deliberately straight-line: every field decode advances the
underlying TpmBufferReader's cursor by exactly the bytes named in the
spec. assertEnd() is called at the end of every successful parse so a
trailing byte is reported as TRUNCATED rather than silently dropped.
The exponent-zero normalisation rule is preserved alongside rawExponent
because re-serialisation must emit the original bytes so the §16 name
digest stays stable.