burnledger 0.9.1 → 0.10.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 (60) hide show
  1. package/dist/cjs/audit-pack.d.ts +201 -0
  2. package/dist/cjs/audit-pack.d.ts.map +1 -0
  3. package/dist/cjs/audit-pack.js +867 -0
  4. package/dist/cjs/audit-pack.js.map +1 -0
  5. package/dist/cjs/client.d.ts +41 -1
  6. package/dist/cjs/client.d.ts.map +1 -1
  7. package/dist/cjs/client.js +58 -0
  8. package/dist/cjs/client.js.map +1 -1
  9. package/dist/cjs/index.d.ts +46 -2
  10. package/dist/cjs/index.d.ts.map +1 -1
  11. package/dist/cjs/index.js +69 -2
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/models.d.ts +28 -2
  14. package/dist/cjs/models.d.ts.map +1 -1
  15. package/dist/cjs/models.js +19 -1
  16. package/dist/cjs/models.js.map +1 -1
  17. package/dist/cjs/run-record.d.ts +130 -0
  18. package/dist/cjs/run-record.d.ts.map +1 -0
  19. package/dist/cjs/run-record.js +272 -0
  20. package/dist/cjs/run-record.js.map +1 -0
  21. package/dist/cjs/verify.d.ts +58 -0
  22. package/dist/cjs/verify.d.ts.map +1 -1
  23. package/dist/cjs/verify.js +207 -5
  24. package/dist/cjs/verify.js.map +1 -1
  25. package/dist/esm/audit-pack.d.ts +201 -0
  26. package/dist/esm/audit-pack.d.ts.map +1 -0
  27. package/dist/esm/audit-pack.js +858 -0
  28. package/dist/esm/audit-pack.js.map +1 -0
  29. package/dist/esm/cli.d.ts +33 -0
  30. package/dist/esm/cli.d.ts.map +1 -1
  31. package/dist/esm/cli.js +225 -5
  32. package/dist/esm/cli.js.map +1 -1
  33. package/dist/esm/client.d.ts +41 -1
  34. package/dist/esm/client.d.ts.map +1 -1
  35. package/dist/esm/client.js +59 -1
  36. package/dist/esm/client.js.map +1 -1
  37. package/dist/esm/index.d.ts +46 -2
  38. package/dist/esm/index.d.ts.map +1 -1
  39. package/dist/esm/index.js +52 -1
  40. package/dist/esm/index.js.map +1 -1
  41. package/dist/esm/models.d.ts +28 -2
  42. package/dist/esm/models.d.ts.map +1 -1
  43. package/dist/esm/models.js +18 -1
  44. package/dist/esm/models.js.map +1 -1
  45. package/dist/esm/run-record.d.ts +130 -0
  46. package/dist/esm/run-record.d.ts.map +1 -0
  47. package/dist/esm/run-record.js +262 -0
  48. package/dist/esm/run-record.js.map +1 -0
  49. package/dist/esm/verify.d.ts +58 -0
  50. package/dist/esm/verify.d.ts.map +1 -1
  51. package/dist/esm/verify.js +200 -8
  52. package/dist/esm/verify.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/audit-pack.ts +1067 -0
  55. package/src/cli.ts +234 -5
  56. package/src/client.ts +82 -1
  57. package/src/index.ts +117 -1
  58. package/src/models.ts +47 -3
  59. package/src/run-record.ts +371 -0
  60. package/src/verify.ts +228 -8
@@ -0,0 +1,201 @@
1
+ /** Audit pack verification (docs/audit-pack.md).
2
+ *
3
+ * A port of core/auditpack.go and core/auditpack_footer.go, verdict for
4
+ * verdict and reason string for reason string. Every record inside a pack is
5
+ * verified exactly as `burnledger check --cert` verifies one, through the same
6
+ * verifyCertificateWithStatus and verifyTransparency. What this file adds is
7
+ * the framing — header, footer, digest, cursor chain — that lets a reader tell
8
+ * a whole page from a subset and a whole set of pages from a partial one, and
9
+ * the footer's signed statement, which is the issuer's word on the count and
10
+ * digest rather than the host's.
11
+ *
12
+ * The single-record verifier reports a refusal by THROWING a VerificationError
13
+ * whose message is prose, where Go returns a named verdict. A pack result is
14
+ * read beside the Go one — testdata/audit_pack/index.json pins the two to the
15
+ * same strings — so the throw is mapped back to Go's name here rather than
16
+ * leaking one SDK's wording into a cross-language contract.
17
+ */
18
+ import type { CryptoOps } from "./crypto.js";
19
+ import type { KeyEntry } from "./keys.js";
20
+ import { type PublicKeyInfo } from "./verify.js";
21
+ import { type RunRecord, type RunRecordResult } from "./run-record.js";
22
+ export declare const AUDIT_PACK_FORMAT = "burnledger.audit_pack.v1";
23
+ export type AuditPackVerdict = "VERIFIED" | "INCOMPLETE" | "INVALID" | "UNREADABLE";
24
+ export type AuditPackLogHead = "VALID" | "ABSENT" | "INVALID_SIGNATURE" | "UNREADABLE";
25
+ export interface AuditPackFilters {
26
+ status: string | null;
27
+ issuedAfter: string | null;
28
+ issuedBefore: string | null;
29
+ /** Limits the pack to one run (ADR-031). A pack filtered by a closed run
30
+ * carries the run record in its header. */
31
+ runId: string | null;
32
+ }
33
+ /** The log head as the header carries it: GET /v1/log/head's hex document. */
34
+ export interface SignedTreeHeadDocument {
35
+ tree_size: number;
36
+ root_hash: string;
37
+ timestamp: string;
38
+ signature: string;
39
+ log_id?: string;
40
+ }
41
+ export interface AuditPackHeader {
42
+ format: string;
43
+ /** Whole-second UTC, as Go's time.Time prints it: the server stamps a
44
+ * nanosecond clock, and the three CLIs print one Generated line. */
45
+ generatedAt: string;
46
+ filters: AuditPackFilters;
47
+ /** The cursor this page resumed from; null on a first page. */
48
+ cursor: string | null;
49
+ issuerKeys: KeyEntry[];
50
+ /** Absent when the issuer had none to give. */
51
+ logHead?: SignedTreeHeadDocument;
52
+ /** The signed run record (ADR-031) when the pack is filtered by a CLOSED
53
+ * run: the document GET /v1/runs/{id} serves as `record`, proof included,
54
+ * as it arrived. Absent for an open or lost run, or no run filter. */
55
+ runRecord?: Record<string, unknown>;
56
+ }
57
+ /** The wire form of the footer's signed statement (core.AuditPackFooterSigned):
58
+ * the fields the header and footer do not already carry, as the file prints
59
+ * them. */
60
+ export interface AuditPackFooterSigned {
61
+ statement_issued_at: string;
62
+ sth_tree_size: number;
63
+ sth_root_hash: string;
64
+ signature: string;
65
+ key_id: string;
66
+ }
67
+ export interface AuditPackFooter {
68
+ recordCount: number;
69
+ nextCursor: string | null;
70
+ recordsSha256: string;
71
+ /** Absent when the issuer could not sign; the count and digest are then the
72
+ * issuer's unsigned word, and the reader is told so. */
73
+ signed?: AuditPackFooterSigned;
74
+ }
75
+ export declare const PAYLOAD_TYPE_AUDIT_PACK_FOOTER = "burnledger.audit_pack_footer.v1";
76
+ /** What a reader learns about a footer's signature (core.AuditPackFooterResult).
77
+ * Not a record verdict: it answers whether the issuer attested to the count
78
+ * and digest, never whether a record may be relied on. */
79
+ export type AuditPackFooterResult = "VALID" | "UNSIGNED" | "UNKNOWN_KEY" | "KEY_UNUSABLE" | "INVALID_SIGNATURE";
80
+ /** The enclave's signed word on one page (core.AuditPackFooterStatement): for
81
+ * THIS query, resumed from THIS cursor, the issuer wrote THIS many records with
82
+ * THIS digest, with THIS log head in front of it, at THIS instant. The filters
83
+ * and cursor are the header's, so the signature binds the footer to the query
84
+ * its header names. It says nothing about completeness: the enclave signs what
85
+ * the host tells it. */
86
+ export interface AuditPackFooterStatement {
87
+ filters: AuditPackFilters;
88
+ cursor: string | null;
89
+ nextCursor: string | null;
90
+ recordCount: number;
91
+ /** 32 bytes. */
92
+ recordsSha256: Uint8Array;
93
+ /** The header's log head; zero when the header carries none. */
94
+ sthTreeSize: number;
95
+ /** 32 bytes. */
96
+ sthRootHash: Uint8Array;
97
+ /** RFC 3339. Signed in whole-second UTC, whatever offset it arrived with. */
98
+ statementIssuedAt: string;
99
+ /** 64 bytes. */
100
+ signature: Uint8Array;
101
+ keyId: string;
102
+ }
103
+ export interface AuditPackRecordFailure {
104
+ /** 1-based position in the file, for a record so broken it has no id. */
105
+ index: number;
106
+ certificateId: string;
107
+ /** Go's VerificationResult name; "" when the record never reached the verifier. */
108
+ offline: string;
109
+ /** Go's TransparencyResult name; "" when the record never reached the verifier. */
110
+ transparency: string;
111
+ reason: string;
112
+ }
113
+ /** Mirrors core.AuditPackResult. */
114
+ export interface AuditPackResult {
115
+ verdict: AuditPackVerdict;
116
+ /** Empty on VERIFIED; every finding otherwise, joined with "; ". */
117
+ reason: string;
118
+ header: AuditPackHeader | null;
119
+ footer: AuditPackFooter | null;
120
+ /** Record lines the file carries, refused ones included. */
121
+ records: number;
122
+ /** Records whose envelope label is REVOKED. The label is unsigned. */
123
+ revoked: number;
124
+ /** Records with no transparency proof yet. Not a failure. */
125
+ notIncluded: number;
126
+ failed: AuditPackRecordFailure[];
127
+ logHead: AuditPackLogHead;
128
+ /** The key that verified the head, when one did. */
129
+ logHeadKeyId: string;
130
+ /** No key set was supplied, so the pack's own issuer_keys were used. */
131
+ keysFromPack: boolean;
132
+ digest: string;
133
+ /** Records a signed status statement was obtained for, and those whose
134
+ * statement said REVOKED. Neither refuses the pack. */
135
+ statusChecked: number;
136
+ statusRevoked: number;
137
+ revokedIds: string[];
138
+ /** What the footer's signature established, UNSIGNED when it carries none.
139
+ * Only VALID means the issuer attested to the count and digest; any other
140
+ * refusal is INVALID for the page. */
141
+ footerStatement: AuditPackFooterResult;
142
+ footerKeyId: string;
143
+ /** The parsed run record when the header carries one; runResult its
144
+ * signature verdict and runInclusion its own proof's, both "" without one.
145
+ * runSubjects and runRecordIds are what this page contributes to
146
+ * reproducing the record's roots — a reader holding every page of the run's
147
+ * chain checks them with checkRunAgainstRecords. runMislabelled counts
148
+ * records whose own signed run_id names another run; each is also refused. */
149
+ run: RunRecord | null;
150
+ runResult: RunRecordResult | "";
151
+ runInclusion: string;
152
+ runSubjects: Uint8Array[];
153
+ runRecordIds: string[];
154
+ runMislabelled: number;
155
+ }
156
+ export interface AuditPackOptions {
157
+ /** Step 8, per record. null means no statement could be had, which leaves
158
+ * the record at VALID_REVOCATION_UNKNOWN exactly as offline. */
159
+ status?: (certificateId: string) => Promise<Record<string, unknown> | null>;
160
+ }
161
+ /** The one definition of the footer's records_sha256: SHA-256 over every
162
+ * record line followed by a newline, in file order, with a trailing carriage
163
+ * return stripped. Mirrors core.AuditPackDigest. */
164
+ export declare function auditPackDigest(crypto: CryptoOps, lines: Uint8Array[]): Promise<string>;
165
+ /** Verify one page offline, exactly as core.VerifyAuditPackWith does.
166
+ *
167
+ * `keys` null means the pack's own issuer_keys are used and the result says so
168
+ * (trust on first use). A supplied map — even an empty one — outranks them.
169
+ * `now` is the reader's clock, used to read a status statement's window.
170
+ */
171
+ export declare function verifyAuditPack(crypto: CryptoOps, source: string | Uint8Array, keys: Map<string, PublicKeyInfo> | null, now: Date, opts?: AuditPackOptions): Promise<AuditPackResult>;
172
+ /** The canonical signing payload of a footer statement. Optional fields are
173
+ * omitted rather than encoded as null, as in every other statement: a page
174
+ * with no filter must sign the same bytes a verifier rebuilds from it. Mirrors
175
+ * core.BuildAuditPackFooterPayload. */
176
+ export declare function buildAuditPackFooterPayload(s: AuditPackFooterStatement): Uint8Array;
177
+ /** Checks a footer statement against the reader's keys, in the order every
178
+ * other verifier uses: the key's authority first, then the signature. Mirrors
179
+ * core.VerifyAuditPackFooter. A statement whose payload cannot be built is
180
+ * INVALID_SIGNATURE, as there. */
181
+ export declare function verifyAuditPackFooter(crypto: CryptoOps, s: AuditPackFooterStatement, keys: Map<string, PublicKeyInfo>): Promise<AuditPackFooterResult>;
182
+ /** Rebuilds the signed statement from a page's header and footer, as
183
+ * core.AuditPackFooter.Statement does. Throws for an unsigned footer, and for
184
+ * signed fields that do not parse, rather than returning a statement that
185
+ * would verify against nothing. */
186
+ export declare function auditPackFooterStatement(header: AuditPackHeader, footer: AuditPackFooter): AuditPackFooterStatement;
187
+ export interface AuditPackPage {
188
+ name: string;
189
+ cursor: string | null;
190
+ nextCursor: string | null;
191
+ }
192
+ /** Orders a set of pages by their cursors and says whether they are one
193
+ * complete answer: exactly one first page, each next_cursor met by a page that
194
+ * resumes from it, every file used, and a last page with no next cursor. The
195
+ * returned order is as far as the chain could be followed. */
196
+ export declare function chainAuditPackPages(pages: AuditPackPage[]): {
197
+ order: AuditPackPage[];
198
+ complete: boolean;
199
+ reason: string;
200
+ };
201
+ //# sourceMappingURL=audit-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-pack.d.ts","sourceRoot":"","sources":["../../src/audit-pack.ts"],"names":[],"mappings":"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"}