secretvm-verify 0.3.9 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@ Attestation verification SDK for confidential computing environments. Verifies I
4
4
 
5
5
  ## What it verifies
6
6
 
7
- - **Intel TDX** — Parses a TDX Quote v4, verifies the ECDSA-P256 signature chain (PCK -> Intermediate -> Root), validates QE report binding, and checks TCB status against Intel's Provisioning Certification Service.
7
+ - **Intel TDX** — Performs full Intel DCAP quote verification, delegating the cryptographic checks to the upstream [`@teekit/qvl`](https://www.npmjs.com/package/@teekit/qvl) library. Verifies the PCK certificate chain against a pinned Intel SGX Root CA, the QE Identity, PCK CRL and Root CA CRL revocation, the TCB Info signature, the TCB status, the quote signature, and the QE report binding. Collateral (TCB Info, QE Identity, CRLs, issuer chains) is fetched from a Provisioning Certificate Caching Service (PCCS) — defaults to SCRT Labs' deployment.
8
8
  - **AMD SEV-SNP** — Parses a SEV-SNP attestation report, fetches the VCEK certificate from AMD's Key Distribution Service, verifies the ECDSA-P384 report signature, and validates the certificate chain (VCEK -> ASK -> ARK).
9
9
  - **NVIDIA GPU** — Submits GPU attestation evidence to NVIDIA's Remote Attestation Service (NRAS), verifies the returned JWT signatures against NVIDIA's published JWKS keys, and extracts per-GPU attestation claims.
10
10
  - **SecretVM workload** — Given a TDX or SEV-SNP quote and a `docker-compose.yaml`, determines whether the quote was produced by a known SecretVM image and verifies the exact compose file that was booted.
@@ -303,17 +303,76 @@ The library contacts these services during verification:
303
303
 
304
304
  | Service | Used by | Purpose |
305
305
  |---------|---------|---------|
306
- | [Intel PCS](https://api.trustedservices.intel.com) | TDX | TCB status lookup |
307
- | [AMD KDS](https://kdsintf.amd.com) | SEV-SNP | VCEK certificate and cert chain |
306
+ | [SCRT PCCS](https://pccs.scrtlabs.com) | TDX | DCAP collateral (TCB Info, QE Identity, PCK CRL, Root CA CRL, issuer chains) |
307
+ | [AMD KDS](https://kdsintf.amd.com) | SEV-SNP | VCEK certificate, AMD CA cert chain (ASK + ARK), CRL |
308
308
  | [NVIDIA NRAS](https://nras.attestation.nvidia.com) | GPU | GPU attestation verification |
309
309
 
310
- **Note:** AMD KDS has rate limits. If you encounter 429 errors, specify the `product` parameter to reduce the number of requests.
310
+ ## AMD KDS caching
311
+
312
+ To minimize calls to `kdsintf.amd.com` (which is rate-limited and returns HTTP 429 under load) the AMD SEV-SNP verifier caches all three KDS responses to disk. The cache is on by default; nothing to enable.
313
+
314
+ | Item | TTL | Cache key |
315
+ |---|---|---|
316
+ | VCEK certificate | 30 days | `(product, chip_id, ucode_SPL, snp_SPL, tee_SPL, bl_SPL)` — full TCB tuple |
317
+ | AMD CA cert chain (ASK + ARK) | 30 days | `product` |
318
+ | CRL | from the CRL's own X.509 `nextUpdate` field (typically ~7 months for AMD); falls back to 7 days if `nextUpdate` is missing or unparseable | `product` |
319
+
320
+ The VCEK cache key includes the full TCB tuple because AMD issues a distinct VCEK per `(chip, TCB version)`. A microcode update on the same chip becomes a cache miss with the new key, fetching the updated VCEK as expected.
321
+
322
+ **Cache location.** Default `~/.cache/secretvm-verify/amd/`. Override with the `SECRETVM_VERIFY_CACHE_DIR` environment variable; the library appends `/amd` to whatever you set:
323
+
324
+ ```sh
325
+ export SECRETVM_VERIFY_CACHE_DIR=/var/cache/myapp
326
+ # → entries land in /var/cache/myapp/amd/{vcek,cert_chain,crl}/
327
+ ```
328
+
329
+ Each cached entry is two files: the payload (DER bytes for VCEK and CRL, PEM text for the cert chain) and a sidecar `<name>.expires` containing the Unix-epoch expiration time.
330
+
331
+ **Inspect cached entries:**
332
+
333
+ ```sh
334
+ ls -lR ~/.cache/secretvm-verify/amd/
335
+
336
+ # Decode a specific VCEK
337
+ openssl x509 -in ~/.cache/secretvm-verify/amd/vcek/<file> -inform DER -text -noout
338
+
339
+ # Decode the CRL — see revoked serials and nextUpdate
340
+ openssl crl -in ~/.cache/secretvm-verify/amd/crl/Genoa -inform DER -text -noout
341
+ ```
342
+
343
+ **Network failure fallback.** If AMD KDS is unreachable or returns an error, the cache falls back to a stale entry rather than failing the verification. Better to verify with a slightly old CRL than to fail every SEV-SNP attestation while KDS is down.
344
+
345
+ **Force a refresh** (skip the cache for this call, fetch fresh, write back to cache):
346
+
347
+ CLI:
348
+ ```sh
349
+ secretvm-verify --secretvm <url> --reload-amd-kds
350
+ secretvm-verify --sev <quote.txt> --product Genoa --reload-amd-kds
351
+ ```
352
+
353
+ Programmatic — pass `true` as the third argument:
354
+
355
+ ```js
356
+ const result = await checkSevCpuAttestation(quote, "Genoa", /* reloadAmdKds */ true);
357
+ const result = await checkSecretVm(url, "", /* reloadAmdKds */ true);
358
+ const result = await checkCpuAttestation(quote, "Genoa", /* reloadAmdKds */ true);
359
+ const result = await checkAgent(agentId, "base", /* reloadAmdKds */ true);
360
+ ```
361
+
362
+ The `--reload-amd-kds` flag has no effect on Intel TDX verification (TDX doesn't cache; the upstream `@teekit/qvl` library manages its own ephemeral state).
363
+
364
+ **To clear the cache entirely:**
365
+
366
+ ```sh
367
+ rm -rf ~/.cache/secretvm-verify/amd
368
+ ```
311
369
 
312
370
  ## Requirements
313
371
 
314
372
  - Node.js >= 18 (uses built-in `crypto`, `fetch`)
315
- - `openssl` CLI (required for AMD SEV-SNP certificate chain verification)
316
- - `yaml` (npm dependency, included)
373
+ - npm dependencies: [`@teekit/qvl`](https://www.npmjs.com/package/@teekit/qvl) (TDX quote verification), [`asn1js`](https://www.npmjs.com/package/asn1js) (parses the CRL's `nextUpdate` field for cache TTL), `ethers` (ERC-8004 agent resolution) — installed automatically.
374
+
375
+ No system-level dependencies. AMD SEV-SNP certificate chains (RSA-PSS) are verified natively via `node:crypto`.
317
376
 
318
377
  ## License
319
378
 
package/dist/agent.d.ts CHANGED
@@ -18,12 +18,18 @@ export declare function resolveAgent(agentId: number, chain: string): Promise<Ag
18
18
  * Discovers teequote and workload endpoints from the metadata, then runs
19
19
  * the full verification flow: TLS cert, CPU quote, TLS binding, GPU quote,
20
20
  * GPU binding, and workload verification.
21
+ *
22
+ * @param reloadAmdKds If true, bypass the local AMD KDS cache and re-fetch
23
+ * VCEK / cert chain / CRL. No effect on TDX agents.
21
24
  */
22
- export declare function verifyAgent(metadata: AgentMetadata): Promise<AttestationResult>;
25
+ export declare function verifyAgent(metadata: AgentMetadata, reloadAmdKds?: boolean): Promise<AttestationResult>;
23
26
  /**
24
27
  * End-to-end ERC-8004 agent verification.
25
28
  *
26
29
  * Resolves the agent's metadata from the on-chain registry, then runs
27
30
  * the full verification flow via verifyAgent.
31
+ *
32
+ * @param reloadAmdKds If true, bypass the local AMD KDS cache and re-fetch
33
+ * VCEK / cert chain / CRL. No effect on TDX agents.
28
34
  */
29
- export declare function checkAgent(agentId: number, chain: string): Promise<AttestationResult>;
35
+ export declare function checkAgent(agentId: number, chain: string, reloadAmdKds?: boolean): Promise<AttestationResult>;
package/dist/agent.js CHANGED
@@ -1,11 +1,10 @@
1
- import crypto from "node:crypto";
2
- import tls from "node:tls";
3
1
  import { ethers } from "ethers";
4
2
  import { getChainConfig, getRpcUrl } from "./chains.js";
5
3
  import { makeResult } from "./types.js";
6
4
  import { checkCpuAttestation } from "./cpu.js";
7
5
  import { checkNvidiaGpuAttestation } from "./nvidia.js";
8
6
  import { verifyWorkload } from "./workload.js";
7
+ import { extractDockerCompose, getTlsCertFingerprint } from "./url.js";
9
8
  const REGISTRY_ABI = [
10
9
  "function tokenURI(uint256 tokenId) view returns (string)",
11
10
  "function agentURI(uint256 agentId) view returns (string)",
@@ -28,44 +27,6 @@ function normalizeServices(raw) {
28
27
  };
29
28
  });
30
29
  }
31
- function getTlsCertFingerprint(host, port) {
32
- return new Promise((resolve, reject) => {
33
- const socket = tls.connect({ host, port, rejectUnauthorized: true }, () => {
34
- const cert = socket.getPeerX509Certificate();
35
- if (!cert) {
36
- socket.destroy();
37
- return reject(new Error("No certificate received"));
38
- }
39
- const fingerprint = crypto
40
- .createHash("sha256")
41
- .update(cert.raw)
42
- .digest();
43
- socket.destroy();
44
- resolve(fingerprint);
45
- });
46
- socket.on("error", reject);
47
- socket.setTimeout(10_000, () => {
48
- socket.destroy();
49
- reject(new Error("TLS connection timed out"));
50
- });
51
- });
52
- }
53
- function extractDockerCompose(raw) {
54
- let text = raw.trim();
55
- const preMatch = text.match(/<pre>([\s\S]*?)<\/pre>/i);
56
- if (preMatch)
57
- text = preMatch[1];
58
- text = text
59
- .replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code)))
60
- .replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
61
- .replace(/&amp;/g, "&")
62
- .replace(/&lt;/g, "<")
63
- .replace(/&gt;/g, ">")
64
- .replace(/&quot;/g, '"')
65
- .replace(/&apos;/g, "'");
66
- text = text.replace(/[\u200B\u200C\u200D\uFEFF]/g, "");
67
- return text;
68
- }
69
30
  function findTeequoteEndpoint(services) {
70
31
  for (const s of services) {
71
32
  if (s.name.toLowerCase() === "teequote" && s.endpoint)
@@ -168,8 +129,11 @@ export async function resolveAgent(agentId, chain) {
168
129
  * Discovers teequote and workload endpoints from the metadata, then runs
169
130
  * the full verification flow: TLS cert, CPU quote, TLS binding, GPU quote,
170
131
  * GPU binding, and workload verification.
132
+ *
133
+ * @param reloadAmdKds If true, bypass the local AMD KDS cache and re-fetch
134
+ * VCEK / cert chain / CRL. No effect on TDX agents.
171
135
  */
172
- export async function verifyAgent(metadata) {
136
+ export async function verifyAgent(metadata, reloadAmdKds = false) {
173
137
  const errors = [];
174
138
  const checks = {};
175
139
  const report = {};
@@ -231,8 +195,12 @@ export async function verifyAgent(metadata) {
231
195
  checks.cpu_quote_fetched = false;
232
196
  return makeResult("ERC-8004", { checks, report, errors });
233
197
  }
234
- const cpuResult = await checkCpuAttestation(cpuData);
198
+ const cpuResult = await checkCpuAttestation(cpuData, "", reloadAmdKds);
235
199
  checks.cpu_attestation_valid = cpuResult.valid;
200
+ // Propagate the inner DCAP/QVL verification verdict for prominent display.
201
+ if (cpuResult.checks.quote_verified !== undefined) {
202
+ checks.cpu_quote_verified = cpuResult.checks.quote_verified;
203
+ }
236
204
  report.cpu = cpuResult.report;
237
205
  report.cpu_type = cpuResult.attestationType;
238
206
  if (!cpuResult.valid)
@@ -340,8 +308,11 @@ export async function verifyAgent(metadata) {
340
308
  *
341
309
  * Resolves the agent's metadata from the on-chain registry, then runs
342
310
  * the full verification flow via verifyAgent.
311
+ *
312
+ * @param reloadAmdKds If true, bypass the local AMD KDS cache and re-fetch
313
+ * VCEK / cert chain / CRL. No effect on TDX agents.
343
314
  */
344
- export async function checkAgent(agentId, chain) {
315
+ export async function checkAgent(agentId, chain, reloadAmdKds = false) {
345
316
  const errors = [];
346
317
  const checks = {};
347
318
  let metadata;
@@ -354,7 +325,7 @@ export async function checkAgent(agentId, chain) {
354
325
  checks.agent_resolved = false;
355
326
  return makeResult("ERC-8004", { checks, errors });
356
327
  }
357
- const result = await verifyAgent(metadata);
328
+ const result = await verifyAgent(metadata, reloadAmdKds);
358
329
  result.checks = { agent_resolved: true, ...result.checks };
359
330
  return result;
360
331
  }
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/amd.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  import { AttestationResult } from "./types.js";
2
- export declare function checkSevCpuAttestation(dataOrUrl: string, product?: string): Promise<AttestationResult>;
2
+ export declare function checkSevCpuAttestation(dataOrUrl: string, product?: string, reloadAmdKds?: boolean): Promise<AttestationResult>;
package/dist/amd.js CHANGED
@@ -1,11 +1,60 @@
1
1
  import crypto from "node:crypto";
2
- import { execFileSync } from "node:child_process";
3
- import { mkdtempSync, writeFileSync, rmSync } from "node:fs";
4
- import { join } from "node:path";
5
- import { tmpdir } from "node:os";
2
+ import { fromBER, Integer, Sequence, UTCTime } from "asn1js";
3
+ import { parseCrlRevokedSerials, normalizeSerialHex } from "@teekit/qvl/utils";
6
4
  import { isVmUrl, fetchCpuQuote } from "./url.js";
7
5
  import { makeResult } from "./types.js";
6
+ import * as kdsCache from "./kdsCache.js";
8
7
  const AMD_KDS_BASE = "https://kdsintf.amd.com";
8
+ /**
9
+ * Parse the `nextUpdate` field from a DER-encoded X.509 CRL.
10
+ *
11
+ * Returns the nextUpdate as a Date, or null if the CRL has no nextUpdate
12
+ * field or parsing fails. We use this to size the AMD CRL cache TTL to the
13
+ * CRL's own expiration window rather than a fixed value.
14
+ *
15
+ * X.509 CRL structure:
16
+ * CertificateList ::= SEQUENCE {
17
+ * tbsCertList SEQUENCE {
18
+ * version Version OPTIONAL, -- INTEGER
19
+ * signature AlgorithmIdentifier, -- SEQUENCE
20
+ * issuer Name, -- SEQUENCE
21
+ * thisUpdate Time, -- UTCTime or GeneralizedTime
22
+ * nextUpdate Time OPTIONAL, -- the field we want
23
+ * ...
24
+ * },
25
+ * ...
26
+ * }
27
+ *
28
+ * GeneralizedTime extends UTCTime in asn1js, so a single `instanceof UTCTime`
29
+ * check catches both encodings; both expose `toDate()`.
30
+ */
31
+ function parseCrlNextUpdate(der) {
32
+ try {
33
+ const parsed = fromBER(der);
34
+ if (parsed.offset === -1)
35
+ return null;
36
+ const certList = parsed.result;
37
+ if (!(certList instanceof Sequence))
38
+ return null;
39
+ const tbsCertList = certList.valueBlock.value[0];
40
+ if (!(tbsCertList instanceof Sequence))
41
+ return null;
42
+ const children = tbsCertList.valueBlock.value;
43
+ let i = 0;
44
+ if (children[i] instanceof Integer)
45
+ i++; // optional version
46
+ i += 3; // signature AlgorithmIdentifier, issuer Name, thisUpdate Time
47
+ if (i >= children.length)
48
+ return null;
49
+ const nextUpdate = children[i];
50
+ if (nextUpdate instanceof UTCTime)
51
+ return nextUpdate.toDate();
52
+ return null;
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
9
58
  const REPORT_SIZE = 0x4a0;
10
59
  const SIG_OFFSET = 0x2a0;
11
60
  const SIG_COMPONENT_SIZE = 72;
@@ -99,31 +148,134 @@ function vcekUrl(product, chipId, tcb) {
99
148
  `?blSPL=${tcb.bootLoader}&teeSPL=${tcb.tee}` +
100
149
  `&snpSPL=${tcb.snp}&ucodeSPL=${tcb.microcode}`);
101
150
  }
102
- async function fetchVcek(product, chipId, reportedTcb) {
151
+ /** Stable cache key for the VCEK fetch — includes the full TCB tuple
152
+ * because AMD issues a distinct VCEK per (chip, ucode, snp, tee, bl) level. */
153
+ function vcekCacheKey(product, chipId, tcb) {
154
+ return (`${product}_${chipId.toString("hex")}` +
155
+ `_bl${tcb.bootLoader}_tee${tcb.tee}` +
156
+ `_snp${tcb.snp}_uc${tcb.microcode}`);
157
+ }
158
+ async function fetchVcek(product, chipId, reportedTcb, reloadAmdKds = false) {
103
159
  const candidates = product ? [product] : ["Genoa", "Milan", "Turin"];
104
160
  for (const name of candidates) {
161
+ const cacheKey = vcekCacheKey(name, chipId, reportedTcb);
162
+ if (!reloadAmdKds) {
163
+ const cached = kdsCache.get("vcek", cacheKey);
164
+ if (cached) {
165
+ return { der: cached, product: name };
166
+ }
167
+ }
105
168
  const url = vcekUrl(name, chipId, reportedTcb);
106
- const resp = await fetch(url);
169
+ let resp;
170
+ try {
171
+ resp = await fetch(url);
172
+ }
173
+ catch (e) {
174
+ // Network failure: fall back to a stale cached entry if we have one.
175
+ const stale = kdsCache.getStale("vcek", cacheKey);
176
+ if (stale)
177
+ return { der: stale, product: name };
178
+ throw e;
179
+ }
107
180
  if (resp.ok) {
108
181
  const der = Buffer.from(await resp.arrayBuffer());
182
+ kdsCache.put("vcek", cacheKey, der, kdsCache.TTL_VCEK_SECONDS);
109
183
  return { der, product: name };
110
184
  }
111
185
  if (resp.status === 429) {
186
+ // Last-ditch fallback: serve a stale cached entry rather than fail.
187
+ const stale = kdsCache.getStale("vcek", cacheKey);
188
+ if (stale)
189
+ return { der: stale, product: name };
112
190
  throw new Error("AMD KDS rate-limited (429). Retry later or specify product.");
113
191
  }
114
192
  if (product) {
193
+ const stale = kdsCache.getStale("vcek", cacheKey);
194
+ if (stale)
195
+ return { der: stale, product: name };
115
196
  throw new Error(`AMD KDS returned ${resp.status}`);
116
197
  }
117
198
  }
118
199
  throw new Error("Could not fetch VCEK for any known product (Genoa/Milan/Turin)");
119
200
  }
120
- async function fetchChainPem(product) {
201
+ async function fetchChainPem(product, reloadAmdKds = false) {
202
+ if (!reloadAmdKds) {
203
+ const cached = kdsCache.get("cert_chain", product);
204
+ if (cached)
205
+ return cached.toString("utf8");
206
+ }
121
207
  const url = `${AMD_KDS_BASE}/vcek/v1/${product}/cert_chain`;
122
- const resp = await fetch(url);
208
+ let resp;
209
+ try {
210
+ resp = await fetch(url);
211
+ }
212
+ catch (e) {
213
+ const stale = kdsCache.getStale("cert_chain", product);
214
+ if (stale)
215
+ return stale.toString("utf8");
216
+ throw e;
217
+ }
123
218
  if (!resp.ok) {
219
+ const stale = kdsCache.getStale("cert_chain", product);
220
+ if (stale)
221
+ return stale.toString("utf8");
124
222
  throw new Error(`AMD KDS cert_chain returned ${resp.status}`);
125
223
  }
126
- return await resp.text();
224
+ const text = await resp.text();
225
+ kdsCache.put("cert_chain", product, Buffer.from(text, "utf8"), kdsCache.TTL_CHAIN_SECONDS);
226
+ return text;
227
+ }
228
+ /** Fetch the AMD VCEK CRL for a product, cache-first.
229
+ *
230
+ * The CRL is consulted to detect chips that AMD has revoked. The cache TTL
231
+ * is computed from the CRL's own X.509 `nextUpdate` field, so the cache
232
+ * naturally aligns with AMD's published refresh schedule. If the CRL has no
233
+ * `nextUpdate` (rare) or parsing fails, we fall back to a 7-day TTL.
234
+ * On network failure we fall back to a stale cached entry rather than
235
+ * failing every SEV verification while KDS is down.
236
+ */
237
+ async function fetchCrl(product, reloadAmdKds = false) {
238
+ if (!reloadAmdKds) {
239
+ const cached = kdsCache.get("crl", product);
240
+ if (cached)
241
+ return cached;
242
+ }
243
+ const url = `${AMD_KDS_BASE}/vcek/v1/${product}/crl`;
244
+ let resp;
245
+ try {
246
+ resp = await fetch(url);
247
+ }
248
+ catch (e) {
249
+ const stale = kdsCache.getStale("crl", product);
250
+ if (stale)
251
+ return stale;
252
+ throw e;
253
+ }
254
+ if (!resp.ok) {
255
+ const stale = kdsCache.getStale("crl", product);
256
+ if (stale)
257
+ return stale;
258
+ throw new Error(`AMD KDS crl returned ${resp.status}`);
259
+ }
260
+ const der = Buffer.from(await resp.arrayBuffer());
261
+ // Use the CRL's own nextUpdate as the TTL when available; fall back to
262
+ // the 7-day default when it's missing or parsing fails.
263
+ let ttl = kdsCache.TTL_CRL_SECONDS;
264
+ const nextUpdate = parseCrlNextUpdate(der);
265
+ if (nextUpdate) {
266
+ const seconds = Math.floor((nextUpdate.getTime() - Date.now()) / 1000);
267
+ if (seconds > 0)
268
+ ttl = seconds;
269
+ }
270
+ kdsCache.put("crl", product, der, ttl);
271
+ return der;
272
+ }
273
+ /** Return true if the VCEK is NOT in the CRL (i.e. not revoked). */
274
+ function checkVcekRevocation(vcekDer, crlDer) {
275
+ const cert = new crypto.X509Certificate(vcekDer);
276
+ const vcekSerial = normalizeSerialHex(cert.serialNumber);
277
+ const revoked = new Set(parseCrlRevokedSerials(crlDer));
278
+ return !revoked.has(vcekSerial);
127
279
  }
128
280
  function splitPem(pem) {
129
281
  const blocks = [];
@@ -134,45 +286,37 @@ function splitPem(pem) {
134
286
  }
135
287
  return blocks;
136
288
  }
137
- /** Verify VCEK → ASK → ARK chain using openssl CLI. */
138
- function verifyCertChainOpenssl(vcekDer, chainPem) {
139
- const td = mkdtempSync(join(tmpdir(), "amd-"));
140
- try {
141
- // Convert VCEK DER to PEM
142
- const vcekPem = execFileSync("openssl", [
143
- "x509",
144
- "-inform",
145
- "DER",
146
- "-outform",
147
- "PEM",
148
- ], { input: vcekDer }).toString();
149
- const vcekPath = join(td, "vcek.pem");
150
- writeFileSync(vcekPath, vcekPem);
151
- const blocks = splitPem(chainPem);
152
- if (blocks.length < 2) {
153
- throw new Error(`Expected at least 2 certs in chain, got ${blocks.length}`);
154
- }
155
- const askPath = join(td, "ask.pem");
156
- const arkPath = join(td, "ark.pem");
157
- writeFileSync(askPath, blocks[0]);
158
- writeFileSync(arkPath, blocks[1]);
159
- try {
160
- execFileSync("openssl", [
161
- "verify",
162
- "-CAfile",
163
- arkPath,
164
- "-untrusted",
165
- askPath,
166
- vcekPath,
167
- ]);
168
- return true;
169
- }
170
- catch {
289
+ /** Verify VCEK → ASK → ARK certificate chain using Node's crypto module. */
290
+ function verifyCertChain(vcekDer, chainPem) {
291
+ const blocks = splitPem(chainPem);
292
+ if (blocks.length < 2) {
293
+ return false;
294
+ }
295
+ const vcek = new crypto.X509Certificate(vcekDer);
296
+ const ask = new crypto.X509Certificate(blocks[0]);
297
+ const ark = new crypto.X509Certificate(blocks[1]);
298
+ const now = new Date();
299
+ // Check validity periods
300
+ for (const cert of [vcek, ask, ark]) {
301
+ if (now < new Date(cert.validFrom) || now > new Date(cert.validTo)) {
171
302
  return false;
172
303
  }
173
304
  }
174
- finally {
175
- rmSync(td, { recursive: true, force: true });
305
+ try {
306
+ // X509Certificate.verify() handles RSA-PSS and ECDSA automatically
307
+ // ARK is self-signed
308
+ if (!ark.verify(ark.publicKey))
309
+ return false;
310
+ // ASK signed by ARK
311
+ if (!ask.verify(ark.publicKey))
312
+ return false;
313
+ // VCEK signed by ASK
314
+ if (!vcek.verify(ask.publicKey))
315
+ return false;
316
+ return true;
317
+ }
318
+ catch {
319
+ return false;
176
320
  }
177
321
  }
178
322
  function verifyReportSignature(rpt, vcekDer) {
@@ -197,7 +341,7 @@ function verifyReportSignature(rpt, vcekDer) {
197
341
  // ---------------------------------------------------------------------------
198
342
  // Public
199
343
  // ---------------------------------------------------------------------------
200
- export async function checkSevCpuAttestation(dataOrUrl, product = "") {
344
+ export async function checkSevCpuAttestation(dataOrUrl, product = "", reloadAmdKds = false) {
201
345
  const data = isVmUrl(dataOrUrl) ? await fetchCpuQuote(dataOrUrl) : dataOrUrl;
202
346
  const errors = [];
203
347
  const checks = {};
@@ -229,7 +373,7 @@ export async function checkSevCpuAttestation(dataOrUrl, product = "") {
229
373
  let vcekDer;
230
374
  let detectedProduct;
231
375
  try {
232
- const result = await fetchVcek(product, rpt.chipId, rpt.reportedTcb);
376
+ const result = await fetchVcek(product, rpt.chipId, rpt.reportedTcb, reloadAmdKds);
233
377
  vcekDer = result.der;
234
378
  detectedProduct = result.product;
235
379
  checks.vcek_fetched = true;
@@ -239,10 +383,10 @@ export async function checkSevCpuAttestation(dataOrUrl, product = "") {
239
383
  checks.vcek_fetched = false;
240
384
  return makeResult("SEV-SNP", { checks, errors });
241
385
  }
242
- // Verify cert chain
386
+ // Verify cert chain (VCEK -> ASK -> ARK)
243
387
  try {
244
- const chainPem = await fetchChainPem(detectedProduct);
245
- checks.cert_chain_valid = verifyCertChainOpenssl(vcekDer, chainPem);
388
+ const chainPem = await fetchChainPem(detectedProduct, reloadAmdKds);
389
+ checks.cert_chain_valid = verifyCertChain(vcekDer, chainPem);
246
390
  if (!checks.cert_chain_valid) {
247
391
  errors.push("Certificate chain verification failed (VCEK → ASK → ARK)");
248
392
  }
@@ -251,6 +395,20 @@ export async function checkSevCpuAttestation(dataOrUrl, product = "") {
251
395
  checks.cert_chain_valid = false;
252
396
  errors.push(`Failed to verify cert chain: ${e.message}`);
253
397
  }
398
+ // CRL revocation check — fetch the AMD VCEK CRL and confirm the leaf
399
+ // cert's serial number is not in the revoked list. Cached for 7 days.
400
+ try {
401
+ const crlDer = await fetchCrl(detectedProduct, reloadAmdKds);
402
+ checks.crl_check_passed = checkVcekRevocation(vcekDer, crlDer);
403
+ if (!checks.crl_check_passed) {
404
+ const cert = new crypto.X509Certificate(vcekDer);
405
+ errors.push(`VCEK serial ${cert.serialNumber} is revoked per AMD CRL`);
406
+ }
407
+ }
408
+ catch (e) {
409
+ checks.crl_check_passed = false;
410
+ errors.push(`CRL revocation check failed: ${e.message}`);
411
+ }
254
412
  // Verify report signature
255
413
  checks.report_signature_valid = verifyReportSignature(rpt, vcekDer);
256
414
  if (!checks.report_signature_valid) {
@@ -259,6 +417,7 @@ export async function checkSevCpuAttestation(dataOrUrl, product = "") {
259
417
  const valid = !!checks.report_parsed &&
260
418
  !!checks.vcek_fetched &&
261
419
  !!checks.cert_chain_valid &&
420
+ !!checks.crl_check_passed &&
262
421
  !!checks.report_signature_valid;
263
422
  const report = {
264
423
  version: rpt.version,