first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
# `attest/serialize` — `TPMS_ATTEST` canonical serialiser
## Purpose
`serializeTpmsAttest` re-emits a parsed `TpmsAttest` value as the
TCG-canonical byte string per Library Part 2 §10.12. The serialiser is
the inverse of `parseTpmsAttest`: for any input the parser accepts,
`serialize(parse(bytes))` returns the same bytes. This invariant is
load-bearing for two downstream uses: signature verification (the TPM
endorsement key signed these exact bytes — a re-serialisation that
differed by a single bit would silently fail every signature check) and
proxy / replay use cases that want to forward a verified attest blob
without trusting the originating wire to preserve the formatting.
## Features
- Byte-identical round-trip across all eight `TPMU_ATTEST` variants.
- Re-emits the 32-bit `magic` prefix regardless of source — the
serialiser is the authoritative encoder, not a passthrough.
- Re-emits `TPM2B_*` size prefixes from the decoded payload length so a
mutated stored size is silently ignored.
- Renders the 17-byte `clockInfo` substructure exactly per §10.10.
- Per-variant attested encoder for `CERTIFY`, `QUOTE`, `SESSION_AUDIT`,
`COMMAND_AUDIT`, `TIME`, `CREATION`, `NV`, `NV_DIGEST`.
## Usage: Basic Example
```ts
import {
parseTpmsAttest,
serializeTpmsAttest,
} from "@suaveplan/tpm-struct/attest";
const att = parseTpmsAttest(bytes);
const re = serializeTpmsAttest(att);
// `re` equals `bytes` byte-for-byte.
```
## Usage: Advanced Example
```ts
import {
parseTpmsAttest,
serializeTpmsAttest,
} from "@suaveplan/tpm-struct/attest";
// Proxy / verifier-of-verifiers pattern: validate, normalise, forward.
function relayAttestation(raw: Uint8Array, verifySig: (b: Uint8Array) => boolean) {
const att = parseTpmsAttest(raw);
const canonical = serializeTpmsAttest(att);
if (!verifySig(canonical)) {
throw new Error("attestation signature did not verify");
}
return { att, canonical };
}
```
## API Reference
- **`serializeTpmsAttest(att: TpmsAttest): Uint8Array`** — returns a
fresh byte string. Does not throw on any well-typed input — the
caller must construct `att` through `parseTpmsAttest` (or a Zod-
validated synthetic constructor) so the input is structurally valid.
## Implementation Notes
The serialiser dispatches on `att.type` via a `switch` that the
TypeScript compiler verifies as exhaustive. Each per-variant encoder
walks the §10.11 / §10.12 field order using `TpmBufferWriter` so size
prefixes and big-endian conventions stay locked to the reader semantics.
The serialiser writes into a single growing buffer to avoid the cost of
multiple `Uint8Array` allocations on the encoder hot path.