burnledger 0.4.0 → 0.6.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.
Files changed (104) hide show
  1. package/README.md +11 -4
  2. package/dist/cjs/anchor.d.ts +71 -0
  3. package/dist/cjs/anchor.d.ts.map +1 -0
  4. package/dist/cjs/anchor.js +279 -0
  5. package/dist/cjs/anchor.js.map +1 -0
  6. package/dist/cjs/client.d.ts +26 -2
  7. package/dist/cjs/client.d.ts.map +1 -1
  8. package/dist/cjs/client.js +27 -5
  9. package/dist/cjs/client.js.map +1 -1
  10. package/dist/cjs/enclave-seal.d.ts +101 -0
  11. package/dist/cjs/enclave-seal.d.ts.map +1 -0
  12. package/dist/cjs/enclave-seal.js +479 -0
  13. package/dist/cjs/enclave-seal.js.map +1 -0
  14. package/dist/cjs/errors.d.ts +42 -1
  15. package/dist/cjs/errors.d.ts.map +1 -1
  16. package/dist/cjs/errors.js +44 -2
  17. package/dist/cjs/errors.js.map +1 -1
  18. package/dist/cjs/http.d.ts +21 -1
  19. package/dist/cjs/http.d.ts.map +1 -1
  20. package/dist/cjs/http.js +76 -12
  21. package/dist/cjs/http.js.map +1 -1
  22. package/dist/cjs/index.browser.d.ts +2 -4
  23. package/dist/cjs/index.browser.d.ts.map +1 -1
  24. package/dist/cjs/index.browser.js.map +1 -1
  25. package/dist/cjs/index.d.ts +16 -11
  26. package/dist/cjs/index.d.ts.map +1 -1
  27. package/dist/cjs/index.js +20 -1
  28. package/dist/cjs/index.js.map +1 -1
  29. package/dist/cjs/keys.d.ts +66 -0
  30. package/dist/cjs/keys.d.ts.map +1 -1
  31. package/dist/cjs/keys.js +128 -3
  32. package/dist/cjs/keys.js.map +1 -1
  33. package/dist/cjs/models.d.ts +41 -3
  34. package/dist/cjs/models.d.ts.map +1 -1
  35. package/dist/cjs/models.js +25 -4
  36. package/dist/cjs/models.js.map +1 -1
  37. package/dist/cjs/verify.d.ts +72 -6
  38. package/dist/cjs/verify.d.ts.map +1 -1
  39. package/dist/cjs/verify.js +392 -62
  40. package/dist/cjs/verify.js.map +1 -1
  41. package/dist/cjs/web-verifier.d.ts +54 -5
  42. package/dist/cjs/web-verifier.d.ts.map +1 -1
  43. package/dist/cjs/web-verifier.js +36 -3
  44. package/dist/cjs/web-verifier.js.map +1 -1
  45. package/dist/esm/anchor.d.ts +71 -0
  46. package/dist/esm/anchor.d.ts.map +1 -0
  47. package/dist/esm/anchor.js +275 -0
  48. package/dist/esm/anchor.js.map +1 -0
  49. package/dist/esm/cli.d.ts +45 -14
  50. package/dist/esm/cli.d.ts.map +1 -1
  51. package/dist/esm/cli.js +357 -50
  52. package/dist/esm/cli.js.map +1 -1
  53. package/dist/esm/client.d.ts +26 -2
  54. package/dist/esm/client.d.ts.map +1 -1
  55. package/dist/esm/client.js +27 -5
  56. package/dist/esm/client.js.map +1 -1
  57. package/dist/esm/enclave-seal.d.ts +101 -0
  58. package/dist/esm/enclave-seal.d.ts.map +1 -0
  59. package/dist/esm/enclave-seal.js +472 -0
  60. package/dist/esm/enclave-seal.js.map +1 -0
  61. package/dist/esm/errors.d.ts +42 -1
  62. package/dist/esm/errors.d.ts.map +1 -1
  63. package/dist/esm/errors.js +43 -1
  64. package/dist/esm/errors.js.map +1 -1
  65. package/dist/esm/http.d.ts +21 -1
  66. package/dist/esm/http.d.ts.map +1 -1
  67. package/dist/esm/http.js +75 -12
  68. package/dist/esm/http.js.map +1 -1
  69. package/dist/esm/index.browser.d.ts +2 -4
  70. package/dist/esm/index.browser.d.ts.map +1 -1
  71. package/dist/esm/index.browser.js.map +1 -1
  72. package/dist/esm/index.d.ts +16 -11
  73. package/dist/esm/index.d.ts.map +1 -1
  74. package/dist/esm/index.js +11 -2
  75. package/dist/esm/index.js.map +1 -1
  76. package/dist/esm/keys.d.ts +66 -0
  77. package/dist/esm/keys.d.ts.map +1 -1
  78. package/dist/esm/keys.js +125 -3
  79. package/dist/esm/keys.js.map +1 -1
  80. package/dist/esm/models.d.ts +41 -3
  81. package/dist/esm/models.d.ts.map +1 -1
  82. package/dist/esm/models.js +24 -4
  83. package/dist/esm/models.js.map +1 -1
  84. package/dist/esm/verify.d.ts +72 -6
  85. package/dist/esm/verify.d.ts.map +1 -1
  86. package/dist/esm/verify.js +390 -63
  87. package/dist/esm/verify.js.map +1 -1
  88. package/dist/esm/web-verifier.d.ts +54 -5
  89. package/dist/esm/web-verifier.d.ts.map +1 -1
  90. package/dist/esm/web-verifier.js +40 -3
  91. package/dist/esm/web-verifier.js.map +1 -1
  92. package/package.json +1 -1
  93. package/src/anchor.ts +330 -0
  94. package/src/cli.ts +389 -54
  95. package/src/client.ts +46 -4
  96. package/src/enclave-seal.ts +582 -0
  97. package/src/errors.ts +47 -2
  98. package/src/http.ts +79 -12
  99. package/src/index.browser.ts +2 -2
  100. package/src/index.ts +28 -9
  101. package/src/keys.ts +176 -3
  102. package/src/models.ts +72 -7
  103. package/src/verify.ts +467 -72
  104. package/src/web-verifier.ts +58 -5
package/dist/esm/cli.js CHANGED
@@ -5,15 +5,17 @@ import { readFile } from "node:fs/promises";
5
5
  import { realpathSync } from "node:fs";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { nodeCrypto } from "./crypto-node.js";
8
- import { verifyCertificate, verifyTransparency, publicKeyFromHex } from "./verify.js";
9
- import { parseKeyEntries } from "./keys.js";
10
- const USAGE = "Usage: burnledger check --cert <file> --keys <file> [--online --api-url <url> --api-key <key>]\n";
8
+ import { CERTIFICATE_REVOKED, VerificationError } from "./errors.js";
9
+ import { formatTimestamp, publicKeyFromHex, verifyCertificateWithStatus, verifyTransparency, VALID_REVOCATION_UNKNOWN, } from "./verify.js";
10
+ import { KEY_LIST_STALE, KEY_LIST_VALID, parseKeyListDocument, verifyKeyList, } from "./keys.js";
11
+ import { ANCHOR_INCONSISTENT, checkStatementAnchor } from "./anchor.js";
12
+ const USAGE = "Usage: burnledger check --cert <file> --keys <file> [--online --api-url <url>]\n";
11
13
  function die(msg) { process.stderr.write(msg); process.exit(2); }
12
14
  function parseArgs(argv) {
13
15
  const args = argv.slice(2);
14
16
  if (args[0] !== "check")
15
17
  die(USAGE);
16
- let certPath = "", keysPath = "", online = false, apiUrl = "", apiKey = "";
18
+ let certPath = "", keysPath = "", online = false, apiUrl = "";
17
19
  for (let i = 1; i < args.length; i++) {
18
20
  const a = args[i];
19
21
  if (a === "--cert") {
@@ -28,8 +30,11 @@ function parseArgs(argv) {
28
30
  else if (a === "--api-url") {
29
31
  apiUrl = args[++i] ?? die("--api-url requires a value\n");
30
32
  }
33
+ // Accepted and ignored. The status endpoint is unauthenticated, so the key
34
+ // buys nothing — but it is a published flag that scripts already pass, and
35
+ // failing on an unknown flag would break them for no gain.
31
36
  else if (a === "--api-key") {
32
- apiKey = args[++i] ?? die("--api-key requires a value\n");
37
+ void (args[++i] ?? die("--api-key requires a value\n"));
33
38
  }
34
39
  else
35
40
  die(`Unknown argument: ${a}\n`);
@@ -38,29 +43,46 @@ function parseArgs(argv) {
38
43
  die("Both --cert and --keys are required.\n");
39
44
  if (online) {
40
45
  try {
41
- ({ apiUrl, apiKey } = resolveApiConfig(apiUrl, apiKey, process.env));
46
+ apiUrl = resolveApiBaseUrl(apiUrl, process.env);
42
47
  }
43
48
  catch (e) {
44
49
  die(e.message + "\n");
45
50
  }
46
51
  }
47
- return { certPath, keysPath, online, apiUrl, apiKey };
52
+ return { certPath, keysPath, online, apiUrl };
48
53
  }
49
54
  /** Flag first, then environment — the precedence docs/cli.md promises and the
50
- * Go CLI (cmd/cli/online.go resolveAPIConfig) implements. Exported for testing. */
51
- export function resolveApiConfig(apiUrl, apiKey, env) {
55
+ * Go CLI (cmd/cli/online.go resolveAPIBaseURL) implements. Exported for testing.
56
+ *
57
+ * It no longer resolves a key, and that is the change. GET
58
+ * /v1/certificates/{id}/status is unauthenticated by design: the audience for
59
+ * revocation is a relying party holding a certificate — a regulator, an
60
+ * auditor, the customer's customer — who has no account here and never will.
61
+ * Demanding an API key was what stopped that reader asking the one question the
62
+ * artifact exists to answer. */
63
+ export function resolveApiBaseUrl(apiUrl, env) {
52
64
  apiUrl ||= env.BURNLEDGER_API_URL ?? "";
53
65
  if (!apiUrl)
54
66
  throw new Error("--api-url or BURNLEDGER_API_URL environment variable is required for online mode");
55
- apiKey ||= env.BURNLEDGER_API_KEY ?? "";
56
- if (!apiKey)
57
- throw new Error("--api-key or BURNLEDGER_API_KEY environment variable is required for online mode");
58
- return { apiUrl, apiKey };
67
+ return apiUrl;
59
68
  }
69
+ /** Load the key set and, separately, what the file establishes about the key
70
+ * STATUSES (ADR-017 §5a). The keys load the same way whether or not the file
71
+ * carries a signed statement — key_id == sha256(public_key) makes every
72
+ * identity self-checking — so an unsigned file is not refused. What changes is
73
+ * what this CLI is entitled to say about the statuses and dates. Mirrors
74
+ * loadKeysFromFile in cmd/cli/keys.go. */
60
75
  async function loadKeys(path) {
61
76
  let entries;
77
+ let keyList;
62
78
  try {
63
- entries = parseKeyEntries(JSON.parse(await readFile(path, "utf-8")));
79
+ const doc = parseKeyListDocument(JSON.parse(await readFile(path, "utf-8")));
80
+ entries = doc.keys;
81
+ // A statement that will not verify is a verdict; one that will not PARSE
82
+ // is a hard error, exactly as in Go: someone signed something the reader
83
+ // cannot read, and continuing as though the file were merely unsigned
84
+ // would throw that fact away.
85
+ keyList = await verifyKeyList(nodeCrypto, doc, new Date());
64
86
  }
65
87
  catch (e) {
66
88
  die(e.message + "\n");
@@ -98,23 +120,151 @@ async function loadKeys(path) {
98
120
  }
99
121
  map.set(pki.keyId, pki);
100
122
  }
101
- return map;
123
+ return { keys: map, keyList };
102
124
  }
103
- async function checkRevocation(apiUrl, apiKey, certId) {
104
- const res = await fetch(`${apiUrl}/v1/certificates/${certId}/revocation-status`, {
105
- headers: { Authorization: `Bearer ${apiKey}` },
106
- });
125
+ /** Retrieve the SIGNED status statement for a certificate.
126
+ *
127
+ * It replaces a GET of /v1/certificates/{id}/revocation-status, which returned
128
+ * a bare {"status": "..."} with no signature over it. That answer was the API's
129
+ * word — or the word of whatever --api-url happened to point at — and this CLI
130
+ * printed it. Nothing about it was checkable, so a network attacker, a stale
131
+ * proxy or a wrong URL could suppress a revocation and the reader could not
132
+ * tell. Every field of this response that the verdict acts on is covered by the
133
+ * issuer's signature.
134
+ *
135
+ * No Authorization header is sent. The endpoint takes none, and sending an API
136
+ * key to an arbitrary --api-url is a credential leak the check never needed. */
137
+ async function fetchStatusStatement(apiUrl, certId) {
138
+ const res = await fetch(`${apiUrl.replace(/\/+$/, "")}/v1/certificates/${certId}/status`);
107
139
  if (!res.ok)
108
- throw new Error(`Revocation check failed: HTTP ${res.status}`);
109
- return (await res.json()).data;
140
+ throw new Error(`HTTP ${res.status}`);
141
+ return unwrapStatusStatement(await res.json());
142
+ }
143
+ /** The API wraps every response in {"data": ...}; a caller may hand over either
144
+ * the envelope or the document inside it. Mirrors
145
+ * core.ParseCertificateStatusDocument, so this CLI and the Go one cannot
146
+ * disagree about which shape the endpoint returns. Exported for testing.
147
+ *
148
+ * A document that does not parse THROWS, and the caller turns that into a
149
+ * warning and a VALID_REVOCATION_UNKNOWN verdict. That is deliberate: an answer
150
+ * this build cannot read is silence about revocation, not a finding about the
151
+ * certificate. Handing a half-read document to the verifier instead would
152
+ * report "status statement signature is invalid" — a claim about the issuer —
153
+ * when what actually happened is that something returned nonsense.
154
+ *
155
+ * `status` itself is NOT validated against a known set. A statement saying
156
+ * SUSPENDED is a statement this build cannot read, and the verifier already has
157
+ * the right answer for that: it authenticates the signature first, then reports
158
+ * VALID_REVOCATION_UNKNOWN. Refusing it here would discard the statement before
159
+ * anyone authenticated it. */
160
+ export function unwrapStatusStatement(parsed) {
161
+ if (parsed === null || typeof parsed !== "object") {
162
+ throw new Error("status statement: response is not a JSON object");
163
+ }
164
+ let doc = parsed;
165
+ if (doc.certificate_id === undefined && doc.data !== null && typeof doc.data === "object") {
166
+ doc = doc.data;
167
+ }
168
+ for (const f of ["certificate_id", "status", "key_id"]) {
169
+ if (typeof doc[f] !== "string" || doc[f] === "")
170
+ throw new Error(`status statement: ${f} is missing`);
171
+ }
172
+ for (const f of ["statement_issued_at", "statement_expires_at"])
173
+ requireRfc3339(doc, f);
174
+ if (doc.revoked_at != null)
175
+ requireRfc3339(doc, "revoked_at");
176
+ if (typeof doc.sth_tree_size !== "number")
177
+ throw new Error("status statement: sth_tree_size is not a number");
178
+ // Refuse a short or long value rather than letting it through: a truncated
179
+ // signature or root hash that reaches the verifier is checked against bytes
180
+ // nobody sent.
181
+ requireHex(doc, "sth_root_hash", 32);
182
+ requireHex(doc, "signature", 64);
183
+ return doc;
184
+ }
185
+ function requireRfc3339(doc, field) {
186
+ const v = doc[field];
187
+ if (typeof v !== "string" || Number.isNaN(Date.parse(v))) {
188
+ throw new Error(`status statement: ${field} is not RFC 3339`);
189
+ }
190
+ }
191
+ function requireHex(doc, field, bytes) {
192
+ const v = doc[field];
193
+ if (typeof v !== "string" || !new RegExp(`^[0-9a-fA-F]{${bytes * 2}}$`).test(v)) {
194
+ throw new Error(`status statement: ${field} is not ${bytes} bytes of hex`);
195
+ }
110
196
  }
197
+ /** The verdicts a reader can act on, and therefore the ones that exit 0.
198
+ *
199
+ * VALID_REVOCATION_UNKNOWN is here. It is the verdict every offline run now
200
+ * carries, and it means what an offline run has always meant: the document
201
+ * verified, and nothing was learned about revocation. Failing it would turn
202
+ * every existing `burnledger check` red overnight while telling the reader
203
+ * nothing new — the honest words are on the first line, where a human reads
204
+ * them, and the exit code keeps the meaning it was given. The soft KEY verdicts
205
+ * still exit 1, unchanged: those need a human before the record is relied on. */
206
+ const USABLE_VERDICTS = new Set(["VALID", VALID_REVOCATION_UNKNOWN]);
207
+ /** The verdict word for an authenticated statement that says REVOKED.
208
+ *
209
+ * It is derived from VerificationError.code, never from the error's prose and
210
+ * never from the statement's own `status` field: every other rejection on the
211
+ * status path — unknown key, revoked key, bad signature, a statement about a
212
+ * different certificate — means the statement could not be authenticated, and
213
+ * rendering one of those as "REVOKED" would report an unauthenticated document
214
+ * as a fact about this certificate. */
215
+ const REVOKED = "REVOKED";
111
216
  /** The pass/fail decision behind the exit code. A signature failure, a
112
- * transparency FAILURE (thrown, not NOT_AVAILABLE), or an online-confirmed
113
- * revocation all make the certificate invalid. Exported for testing. */
114
- export function certVerdict(sigResult, transparencyFailed, online, revocation) {
115
- return (sigResult === "VALID" &&
116
- !transparencyFailed &&
117
- !(online && revocation?.status === "REVOKED"));
217
+ * revocation, or a transparency FAILURE (thrown, not NOT_AVAILABLE) all make
218
+ * the certificate unusable. Revocation is no longer a separate input: it is
219
+ * part of the verdict verifyCertificateWithStatus returns. Exported for
220
+ * testing.
221
+ *
222
+ * An INCONSISTENT anchor refuses, mirroring exitCode in cmd/cli/check.go. It is
223
+ * not a doubt: it is a proof, from the issuer's own signatures, that the head a
224
+ * statement was anchored to is not a prefix of the head the log now publishes.
225
+ * An anchor that could NOT be checked does not refuse — the reader is told so,
226
+ * and the statement still stands on its own signature. */
227
+ export function certVerdict(sigResult, transparencyFailed, anchor) {
228
+ if (anchor?.verdict === ANCHOR_INCONSISTENT)
229
+ return false;
230
+ return USABLE_VERDICTS.has(sigResult) && !transparencyFailed;
231
+ }
232
+ /** Verdicts that are neither a pass nor a refusal, and what each one leaves
233
+ * unestablished. ADR-017 §2 calls them results a reader must be SHOWN; the
234
+ * verdict string alone leaves them to guess which half of the check is
235
+ * missing. Mirrors softKeyVerdictNote in cmd/cli/format.go. */
236
+ const SOFT_KEY_VERDICTS = {
237
+ VALID_KEY_WINDOW_UNKNOWN: "signatures verify; the signing key states a validity interval and this " +
238
+ "certificate carries no transparency proof to date it against",
239
+ VALID_KEY_COMPROMISED_LATER: "signatures verify and appear to predate the key's compromise; " +
240
+ "confirm against the witness's record",
241
+ };
242
+ /** What a VALID_REVOCATION_UNKNOWN verdict leaves unestablished, and there are
243
+ * two ways to arrive at it.
244
+ *
245
+ * Offline it is the ordinary case and always was: nothing was asked, so nothing
246
+ * is known. Online it means the ask failed — a status endpoint that did not
247
+ * answer, an answer this build could not read, or one whose window had closed.
248
+ * Both are silence about revocation, and silence is reported as unknown. This
249
+ * CLI used to report both as VALID, which reads as "checked and not revoked".
250
+ * Mirrors revocationUnknownOffline/Online in cmd/cli/format.go. */
251
+ const REVOCATION_UNKNOWN_OFFLINE = "offline — nothing was asked about revocation, so nothing is known; " +
252
+ "re-run with --online to fetch a signed status statement";
253
+ const REVOCATION_UNKNOWN_ONLINE = "no usable signed status statement — the issuer said nothing this " +
254
+ "build could read about revocation, which is not the same as saying the record is live";
255
+ /**
256
+ * The certificate formats whose signing payload covers enclave_pcr0.
257
+ * Mirrors core.SignatureCoversEnclavePCR0 (core/payload.go).
258
+ *
259
+ * A SET, not a single version, and a predicate rather than an equality test.
260
+ * It was `=== "5.0"`, which silently stopped being true the moment v6 was
261
+ * added: v6 signs the measurement exactly as v5 does, and this CLI told the
262
+ * reader the field was under no signature while the Go CLI said the opposite
263
+ * about the same file.
264
+ */
265
+ const ENCLAVE_PCR0_SIGNED_IN = Object.freeze(["5.0", "6.0"]);
266
+ function signatureCoversEnclavePcr0(version) {
267
+ return ENCLAVE_PCR0_SIGNED_IN.includes(version);
118
268
  }
119
269
  /** Byte fields arrive as number arrays (Go [N]byte) or strings; show hex. */
120
270
  function displayHash(v) {
@@ -123,25 +273,54 @@ function displayHash(v) {
123
273
  }
124
274
  return String(v);
125
275
  }
126
- export function formatOutput(cert, sigResult, transparency, transparencyFailed, revocation, online) {
276
+ export function formatOutput(cert, sigResult, transparency, transparencyFailed, status, online, anchor, keyList) {
127
277
  const id = cert.certificate_id.slice(0, 6);
128
278
  const sub = displayHash(cert.subject.identifier_hash);
129
279
  const att = cert.attestation;
130
280
  const L = [];
131
- if (sigResult !== "VALID")
132
- return `Certificate dc_${id}: INVALID (${sigResult})\n`;
133
- if (transparencyFailed)
134
- return `Certificate dc_${id}: INVALID (transparency: ${transparency})\n`;
135
- if (online && revocation?.status === "REVOKED") {
136
- L.push(`Certificate dc_${id}: INVALID (REVOKED)`);
137
- if (revocation.reason)
138
- L.push(` Revocation reason: ${revocation.reason}`);
281
+ // A proven-inconsistent anchor outranks every verdict below it, including
282
+ // REVOKED. The issuer has contradicted itself about an append-only structure,
283
+ // so nothing it says about this record — revoked or live — can be taken at
284
+ // face value, and printing "REVOKED" or "VALID" here would answer a question
285
+ // that is no longer the important one. Mirrors formatResult in
286
+ // cmd/cli/format.go, which puts this branch in the same place.
287
+ if (anchor?.verdict === ANCHOR_INCONSISTENT) {
288
+ L.push(`Verification record dc_${id}: INVALID (LOG_ANCHOR_INCONSISTENT)`);
289
+ L.push(` ${anchor.detail}`);
290
+ L.push(` The certificate itself verified as ${sigResult}; the issuer's log is what does not add up.`);
291
+ pushStatementEvidence(L, status);
292
+ return L.join("\n") + "\n";
293
+ }
294
+ // A soft key verdict is not a forgery: every signature verified, and what
295
+ // could not be established is the key's authority. "INVALID" would send an
296
+ // auditor hunting for tampering that is not there, and "VALID" — which this
297
+ // CLI printed — claims a check that did not happen.
298
+ const note = SOFT_KEY_VERDICTS[sigResult];
299
+ if (note !== undefined)
300
+ return `Verification record dc_${id}: ${sigResult} (${note})\n`;
301
+ // Revocation is now a signed fact, so the reader gets the evidence with the
302
+ // verdict: who said it, when, and which log entry it points at.
303
+ if (sigResult === REVOKED) {
304
+ L.push(`Verification record dc_${id}: INVALID (REVOKED)`);
305
+ pushStatementEvidence(L, status);
306
+ pushAnchorEvidence(L, anchor);
139
307
  return L.join("\n") + "\n";
140
308
  }
141
- const tag = online ? "" : " (offline — revocation status not checked)";
142
- L.push(`Certificate dc_${id}: VALID${tag}`);
309
+ if (!USABLE_VERDICTS.has(sigResult))
310
+ return `Verification record dc_${id}: INVALID (${sigResult})\n`;
311
+ if (transparencyFailed)
312
+ return `Verification record dc_${id}: INVALID (transparency: ${transparency})\n`;
313
+ // The two usable verdicts. VALID is sayable without a qualifier for the first
314
+ // time: it is reached only when a fresh statement, signed by a key from the
315
+ // key file and naming this certificate, said ACTIVE. Everything short of that
316
+ // is VALID_REVOCATION_UNKNOWN and says so in the verdict itself, not in a
317
+ // footnote a script will never read.
318
+ const tag = sigResult === VALID_REVOCATION_UNKNOWN
319
+ ? `${VALID_REVOCATION_UNKNOWN} (${online ? REVOCATION_UNKNOWN_ONLINE : REVOCATION_UNKNOWN_OFFLINE})`
320
+ : "VALID (a signed status statement says this record is live)";
321
+ L.push(`Verification record dc_${id}: ${tag}`);
143
322
  L.push(` Subject: sha256:${sub.slice(0, 6)}...`);
144
- L.push(` Canonical version: ${cert.certificate_format_version}`);
323
+ L.push(` Format version: ${cert.certificate_format_version}`);
145
324
  // v3 carries ONE system list at the top level, with both counts on each
146
325
  // record. Reading att.systems here is what made this CLI die on every real
147
326
  // v3 certificate with "Cannot read properties of null" — the attestation
@@ -159,10 +338,23 @@ export function formatOutput(cert, sigResult, transparency, transparencyFailed,
159
338
  // Its own line, never appended to a verdict (ADR-020), and worded so it
160
339
  // cannot be read as a checked fact: nothing offline can verify a measurement.
161
340
  // Proof is the NSM attestation document.
341
+ //
342
+ // The attribution differs by version. From v5 the field is inside the signing
343
+ // payload, so it is the signer's claim about itself. On v4 — the format that
344
+ // is actually issued, and into which the enclave writes its real measurement —
345
+ // no signature covers it, so calling it the signer's claim names an author
346
+ // nothing established: it is whatever the last holder of the file wrote.
162
347
  const issuer = cert.issuer;
163
348
  const pcr0 = issuer?.enclave_pcr0;
164
349
  if (typeof pcr0 === "string" && pcr0 !== "") {
165
- L.push(` Enclave image (claimed by signer, not verified here): ${pcr0}`);
350
+ const version = cert.certificate_format_version;
351
+ if (signatureCoversEnclavePcr0(version)) {
352
+ L.push(` Enclave image (claimed by signer, not verified here): ${pcr0}`);
353
+ }
354
+ else {
355
+ L.push(` Enclave image (format ${version} puts this field under no signature — ` +
356
+ `unattributable, not verified here): ${pcr0}`);
357
+ }
166
358
  }
167
359
  if (transparency === "INCLUDED") {
168
360
  const t = cert.transparency;
@@ -171,10 +363,90 @@ export function formatOutput(cert, sigResult, transparency, transparencyFailed,
171
363
  else {
172
364
  L.push(` Transparency log: ${transparency === "NOT_AVAILABLE" ? "not included" : transparency}`);
173
365
  }
174
- if (online && revocation)
175
- L.push(` Revocation status: ${revocation.status}`);
366
+ pushStatementEvidence(L, status);
367
+ pushAnchorEvidence(L, anchor);
368
+ pushKeyListEvidence(L, keyList);
176
369
  return L.join("\n") + "\n";
177
370
  }
371
+ /** Where the key statuses this verdict rests on came from, printed on every
372
+ * run — including the ordinary one, where the answer is "an unsigned list".
373
+ *
374
+ * ADR-017 §5a's point is not that an unsigned key list is unusable. It is that
375
+ * the two halves of a key set have different lifetimes: key_id is
376
+ * sha256(public_key), so every key's IDENTITY is self-checking offline forever,
377
+ * while its status and dates are only as good as the endpoint they were
378
+ * fetched from and the moment they were fetched. Mirrors writeKeyListEvidence
379
+ * in cmd/cli/format.go, word for word, so the four verifiers say one thing. */
380
+ function pushKeyListEvidence(L, e) {
381
+ if (e === undefined)
382
+ return;
383
+ if (!e.present) {
384
+ L.push(" Key statuses: unsigned key list — identities are self-checking " +
385
+ "(key_id = sha256(public_key)); statuses and dates are not evidenced");
386
+ return;
387
+ }
388
+ if (e.result === KEY_LIST_VALID) {
389
+ L.push(` Key statuses: signed key_list.v3, VALID until ${e.expiresAt}`);
390
+ if (e.selfSigned) {
391
+ // Said out loud, every time. A list that vouches for itself proves only
392
+ // that whoever wrote it holds the key it names, and a reader who does
393
+ // not know that will read "VALID" as more than it is.
394
+ L.push(" Key list trust: the list is signed by a key inside itself — " +
395
+ "trust-on-first-use, not proof; pin this file and compare it on later runs");
396
+ }
397
+ return;
398
+ }
399
+ if (e.result === KEY_LIST_STALE) {
400
+ L.push(` Key statuses: signed key_list.v3, but its window closed at ${e.expiresAt} — ` +
401
+ "the identities still check, the statuses no longer do");
402
+ return;
403
+ }
404
+ L.push(` Key statuses: signed key_list.v3 did NOT verify (${e.result}) — ` +
405
+ "treat its statuses and dates as unevidenced");
406
+ }
407
+ /** Whether the statement's log anchor was tested, and how it came out.
408
+ *
409
+ * The UNVERIFIED line matters as much as the CONFIRMED one. A statement whose
410
+ * anchor could not be checked is a statement that rests entirely on its
411
+ * issuer's signature, and a reader who is not told that will assume the stronger
412
+ * thing — which is the mistake this whole command has been correcting. Mirrors
413
+ * writeAnchorEvidence in cmd/cli/format.go. */
414
+ function pushAnchorEvidence(L, anchor) {
415
+ if (anchor === undefined)
416
+ return;
417
+ L.push(` Statement log anchor: ${anchor.verdict} (${anchor.detail})`);
418
+ }
419
+ /** What the signed statement said, and by whom.
420
+ *
421
+ * Nothing is printed when there is no statement: the verdict line has already
422
+ * told the reader that revocation is unknown, and a "Revocation status: n/a"
423
+ * line here would put a word where there is no evidence.
424
+ *
425
+ * `Statement signed by` is not decoration. The verdict rests on that key, the
426
+ * key came from the reader's own --keys file, and naming it is what lets an
427
+ * auditor say which key they are trusting rather than "the API said so".
428
+ * Mirrors writeStatementEvidence in cmd/cli/format.go. */
429
+ function pushStatementEvidence(L, status) {
430
+ if (status === undefined)
431
+ return;
432
+ L.push(` Revocation status: ${String(status.status)} (signed status statement)`);
433
+ L.push(` Statement signed by: ${String(status.key_id)}`);
434
+ L.push(` Statement valid: ${formatTimestamp(status.statement_issued_at)} to ` +
435
+ `${formatTimestamp(status.statement_expires_at)}`);
436
+ // The head the issuer had seen when it spoke. Printed as evidence; whether it
437
+ // is a prefix of the head the log publishes now is a separate question, and
438
+ // the "Statement log anchor" line below answers it (anchor.ts).
439
+ L.push(` Statement anchored to: tree size ${String(status.sth_tree_size)}, ` +
440
+ `root ${displayHash(status.sth_root_hash)}`);
441
+ if (status.revoked_at != null)
442
+ L.push(` Revoked at: ${formatTimestamp(status.revoked_at)}`);
443
+ if (status.replacement_certificate_id != null) {
444
+ L.push(` Replaced by: ${String(status.replacement_certificate_id)}`);
445
+ }
446
+ if (status.revocation_log_index != null) {
447
+ L.push(` Revocation log entry: #${String(status.revocation_log_index)}`);
448
+ }
449
+ }
178
450
  /** Accept the raw API response too: GET /v1/certificates/{id} nests the
179
451
  * signed certificate as data.certificate. Exported for testing. */
180
452
  export function unwrapCertificate(parsed) {
@@ -190,13 +462,51 @@ export function unwrapCertificate(parsed) {
190
462
  async function main() {
191
463
  const args = parseArgs(process.argv);
192
464
  const cert = unwrapCertificate(JSON.parse(await readFile(args.certPath, "utf-8")));
193
- const keys = await loadKeys(args.keysPath);
465
+ const { keys, keyList } = await loadKeys(args.keysPath);
466
+ // Fetched first, because the verdict now depends on it. A status statement is
467
+ // an input to the verdict, not a footnote printed beside one:
468
+ // verifyCertificateWithStatus answers REVOKED, VALID or
469
+ // VALID_REVOCATION_UNKNOWN from the same call, and splitting that decision
470
+ // across two checks is how this CLI ended up printing VALID for a certificate
471
+ // whose revocation it had never established.
472
+ let status;
473
+ let anchor;
474
+ if (args.online) {
475
+ try {
476
+ status = await fetchStatusStatement(args.apiUrl, cert.certificate_id);
477
+ }
478
+ catch (e) {
479
+ // Non-fatal, and NOT a pass. Leaving `status` undefined sends the verdict
480
+ // to VALID_REVOCATION_UNKNOWN rather than to VALID: an endpoint that did
481
+ // not answer has said nothing about revocation, and the older code
482
+ // reported that silence as a clean bill of health.
483
+ process.stderr.write(`warning: signed status statement unavailable: ${e instanceof Error ? e.message : String(e)}\n`);
484
+ }
485
+ // The statement's anchor is only checkable against the log, and only with a
486
+ // key the reader already holds. A statement signed by a key that is not in
487
+ // --keys cannot be authenticated at all, so there is nothing to anchor and
488
+ // no anchor line is printed. See anchor.ts for what this does and does not
489
+ // close.
490
+ if (status !== undefined) {
491
+ const key = keys.get(status.key_id);
492
+ if (key !== undefined) {
493
+ anchor = await checkStatementAnchor(nodeCrypto, args.apiUrl, status, key);
494
+ }
495
+ }
496
+ }
497
+ // The verifier's own verdict, never a hardcoded word. VALID_KEY_WINDOW_UNKNOWN
498
+ // and VALID_KEY_COMPROMISED_LATER are cases verifyCertificateWithStatus
499
+ // deliberately refused to call VALID, and this is the tool an auditor runs in
500
+ // a script — the one whose exit code gets trusted.
194
501
  let sigResult = "VALID";
195
502
  try {
196
- await verifyCertificate(nodeCrypto, cert, keys);
503
+ sigResult = await verifyCertificateWithStatus(nodeCrypto, cert, keys, status ?? null);
197
504
  }
198
505
  catch (e) {
199
- sigResult = e instanceof Error ? e.message : "unknown error";
506
+ if (e instanceof VerificationError && e.code === CERTIFICATE_REVOKED)
507
+ sigResult = REVOKED;
508
+ else
509
+ sigResult = e instanceof Error ? e.message : "unknown error";
200
510
  }
201
511
  // NOT_AVAILABLE (no proof) is a legitimate result; only a thrown error is a
202
512
  // transparency FAILURE and must fail the verdict + exit code.
@@ -209,11 +519,8 @@ async function main() {
209
519
  transparency = e instanceof Error ? e.message : "unknown error";
210
520
  transparencyFailed = true;
211
521
  }
212
- let revocation;
213
- if (args.online)
214
- revocation = await checkRevocation(args.apiUrl, args.apiKey, cert.certificate_id);
215
- const valid = certVerdict(sigResult, transparencyFailed, args.online, revocation);
216
- process.stdout.write(formatOutput(cert, sigResult, transparency, transparencyFailed, revocation, args.online));
522
+ const valid = certVerdict(sigResult, transparencyFailed, anchor);
523
+ process.stdout.write(formatOutput(cert, sigResult, transparency, transparencyFailed, status, args.online, anchor, keyList));
217
524
  process.exit(valid ? 0 : 1);
218
525
  }
219
526
  // Only run as a CLI entry point — importing this module (e.g. from tests) must
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -3,14 +3,25 @@
3
3
  * Single class — Node.js is all-async, no sync/async split needed.
4
4
  * Pagination uses AsyncIterable<T> via Paginator.
5
5
  */
6
- import type { ApiKeyListItem, ApiKeyResponse, Attestation, BatchAttestationResponse, CertificateResponse, CertificateStats, ConsistencyProof, InclusionProof, LogEntry, Profile, RevocationStatus, SignedTreeHead, System, SystemHealth, VerifyResult, Webhook, WebhookDelivery, WebhookRotateResponse } from "./models.js";
6
+ import type { ApiKeyListItem, ApiKeyResponse, Attestation, BatchAttestationResponse, BatchRevokeResponse, CertificateResponse, CertificateStats, ConsistencyProof, InclusionProof, LogEntry, Profile, RevocationStatus, SignedTreeHead, System, SystemHealth, VerifyResult, Webhook, WebhookDelivery, WebhookRotateResponse } from "./models.js";
7
7
  import { Paginator } from "./pagination.js";
8
8
  export interface BurnLedgerOptions {
9
9
  apiKey: string;
10
10
  baseUrl?: string;
11
11
  timeout?: number;
12
12
  maxRetries?: number;
13
+ /**
14
+ * Team to act as, sent as X-Team-ID beside the key.
15
+ *
16
+ * Omit it and the API uses the caller's default team — the first one they
17
+ * joined — which is the right answer for a single-team account and the wrong
18
+ * one for anybody else.
19
+ */
20
+ teamId?: string;
13
21
  }
22
+ /** Per-call cap on POST /v1/certificates/batch-revoke, the same 100 the
23
+ * server enforces (service.maxBatchRevoke). Chunk larger sets by this. */
24
+ export declare const MAX_BATCH_REVOKE = 100;
14
25
  export declare class BurnLedger {
15
26
  private readonly transport;
16
27
  constructor(opts: BurnLedgerOptions);
@@ -69,6 +80,11 @@ export declare class BurnLedger {
69
80
  revokeCertificate(certificateId: string, opts: {
70
81
  reason: string;
71
82
  }): Promise<CertificateResponse>;
83
+ /** Revokes up to MAX_BATCH_REVOKE records under one reason. Partial
84
+ * completion is the normal case, not an exception: inspect `errors`. */
85
+ batchRevokeCertificates(certificateIds: string[], opts: {
86
+ reason: string;
87
+ }): Promise<BatchRevokeResponse>;
72
88
  getCertificateStats(): Promise<CertificateStats>;
73
89
  exportCertificates(opts?: {
74
90
  format?: "csv" | "jsonl";
@@ -93,9 +109,17 @@ export declare class BurnLedger {
93
109
  listApiKeys(opts?: {
94
110
  limit?: number;
95
111
  }): Paginator<ApiKeyListItem>;
96
- createApiKey(): Promise<ApiKeyResponse>;
112
+ /** Create an API key. `teamId` pins it to one team the caller belongs to:
113
+ * a pinned key always acts for that team and refuses a conflicting
114
+ * `X-Team-ID` with 403. Omitted means unpinned — the server resolves the
115
+ * team per request, as every key created before pinning existed does. */
116
+ createApiKey(params?: {
117
+ teamId?: string;
118
+ }): Promise<ApiKeyResponse>;
97
119
  revokeApiKey(keyId: string): Promise<void>;
98
120
  getMe(): Promise<Profile>;
121
+ /** Rename the account. `email` must be the current address: changing it
122
+ * needs a dashboard session, and an API key is refused with 403. */
99
123
  updateMe(params: {
100
124
  name: string;
101
125
  email: string;