@xfuel/verify 0.2.1 → 0.3.1

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 (46) hide show
  1. package/README.md +41 -3
  2. package/dist/anchor-witness.d.ts +155 -0
  3. package/dist/anchor-witness.d.ts.map +1 -0
  4. package/dist/anchor-witness.js +431 -0
  5. package/dist/anchor-witness.js.map +1 -0
  6. package/dist/canonical-preimage.d.ts +9 -0
  7. package/dist/canonical-preimage.d.ts.map +1 -0
  8. package/dist/canonical-preimage.js +25 -0
  9. package/dist/canonical-preimage.js.map +1 -0
  10. package/dist/cli.d.ts +1 -0
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +527 -15
  13. package/dist/cli.js.map +1 -1
  14. package/dist/epoch.d.ts +109 -0
  15. package/dist/epoch.d.ts.map +1 -0
  16. package/dist/epoch.js +209 -0
  17. package/dist/epoch.js.map +1 -0
  18. package/dist/head-binding.d.ts +24 -0
  19. package/dist/head-binding.d.ts.map +1 -0
  20. package/dist/head-binding.js +61 -0
  21. package/dist/head-binding.js.map +1 -0
  22. package/dist/index.d.ts +146 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +305 -24
  25. package/dist/index.js.map +1 -1
  26. package/dist/issuer-history.d.ts +91 -0
  27. package/dist/issuer-history.d.ts.map +1 -0
  28. package/dist/issuer-history.js +292 -0
  29. package/dist/issuer-history.js.map +1 -0
  30. package/dist/jcs.d.ts +8 -0
  31. package/dist/jcs.d.ts.map +1 -0
  32. package/dist/jcs.js +64 -0
  33. package/dist/jcs.js.map +1 -0
  34. package/dist/preimage.d.ts +49 -0
  35. package/dist/preimage.d.ts.map +1 -0
  36. package/dist/preimage.js +203 -0
  37. package/dist/preimage.js.map +1 -0
  38. package/dist/receipt-lane.d.ts +234 -0
  39. package/dist/receipt-lane.d.ts.map +1 -0
  40. package/dist/receipt-lane.js +443 -0
  41. package/dist/receipt-lane.js.map +1 -0
  42. package/dist/refusal.d.ts +90 -0
  43. package/dist/refusal.d.ts.map +1 -0
  44. package/dist/refusal.js +226 -0
  45. package/dist/refusal.js.map +1 -0
  46. package/package.json +6 -4
@@ -0,0 +1,91 @@
1
+ import { type Es256Jwk } from './jws.js';
2
+ interface HistoryJwks {
3
+ keys: Es256Jwk[];
4
+ }
5
+ export declare const ISSUER_HISTORY_SCHEMA = "chit402.issuer_history.v1";
6
+ export interface IssuerHistoryEntry {
7
+ kid: string;
8
+ jwk: Es256Jwk;
9
+ alg: string;
10
+ not_before: string;
11
+ not_after?: string | null;
12
+ status: 'active' | 'retired' | 'revoked' | string;
13
+ revoked_at?: string | null;
14
+ reason?: string | null;
15
+ custody?: string;
16
+ prev_hash?: string | null;
17
+ entry_hash?: string;
18
+ }
19
+ export interface IssuerHistoryPin {
20
+ hash: string;
21
+ version: number;
22
+ seq: number;
23
+ }
24
+ export interface IssuerHistoryDocument {
25
+ schema?: string;
26
+ version?: number;
27
+ seq?: number;
28
+ entries?: IssuerHistoryEntry[];
29
+ head_hash?: string;
30
+ issuer_signature?: {
31
+ jws?: string;
32
+ kid?: string;
33
+ issuer_jwk?: Es256Jwk;
34
+ };
35
+ }
36
+ export interface IssuerHistoryCheck {
37
+ checked: boolean;
38
+ ok: boolean;
39
+ unreachable: boolean;
40
+ warning: string | null;
41
+ reason: string | null;
42
+ kid: string | null;
43
+ }
44
+ export declare function issuerHistoryEntryBody(entry: IssuerHistoryEntry): Record<string, unknown>;
45
+ export declare function issuerHistoryEntryHash(entry: IssuerHistoryEntry): string;
46
+ export declare function verifyIssuerHistoryDocument(doc: IssuerHistoryDocument, { jwks, trustedKids }?: {
47
+ jwks?: HistoryJwks;
48
+ trustedKids?: readonly string[];
49
+ }): {
50
+ valid: boolean;
51
+ reason?: string;
52
+ };
53
+ export declare function issuerKeyWindow(doc: IssuerHistoryDocument, kid: string, issuedAt: unknown): {
54
+ ok: boolean;
55
+ reason: string | null;
56
+ };
57
+ export declare function issuerHistoryDocumentHash(doc: unknown): string;
58
+ /** Pin from verified JWS claims. An unsigned outer copy is not a pin. */
59
+ export declare function readIssuerHistoryPin(claims: Record<string, unknown> | null | undefined): IssuerHistoryPin | null;
60
+ export declare function checkReceiptIssuerHistory(receipt: {
61
+ verification?: {
62
+ jwks_uri?: string;
63
+ };
64
+ verify_url?: string;
65
+ created_at?: unknown;
66
+ }, { document, fetchHistory, strict, historyUrl, jwks, trustedKids, fetchImpl, trustedHosts, issuedAt, kid, pin, requirePin, documentBytes, }?: {
67
+ document?: IssuerHistoryDocument | null;
68
+ fetchHistory?: boolean;
69
+ strict?: boolean;
70
+ historyUrl?: string | null;
71
+ jwks?: HistoryJwks;
72
+ trustedKids?: readonly string[];
73
+ fetchImpl?: typeof fetch;
74
+ trustedHosts?: readonly string[];
75
+ issuedAt?: unknown;
76
+ kid?: string | null;
77
+ /** From verified claims. When set, the fetched snapshot must match. */
78
+ pin?: IssuerHistoryPin | null;
79
+ /** Payload versions that sign a pin fail when the pin is absent. */
80
+ requirePin?: boolean;
81
+ /** Exact response or file bytes. SHA-256 of these must equal the pin. */
82
+ documentBytes?: string | null;
83
+ }): Promise<IssuerHistoryCheck>;
84
+ export declare function historyUrlFromReceipt(receipt: {
85
+ verification?: {
86
+ jwks_uri?: string;
87
+ };
88
+ verify_url?: string;
89
+ }): string | null;
90
+ export {};
91
+ //# sourceMappingURL=issuer-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer-history.d.ts","sourceRoot":"","sources":["../src/issuer-history.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,UAAU,CAAC;AAElB,UAAU,WAAW;IACnB,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED,eAAO,MAAM,qBAAqB,8BAA8B,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,QAAQ,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAClD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;CAC1E;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBzF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAExE;AASD,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,qBAAqB,EAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,GAAE;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAO,GAClF;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA+CrC;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,qBAAqB,EAC1B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,OAAO,GAChB;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAiBxC;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE9D;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,gBAAgB,GAAG,IAAI,CAUhH;AASD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE;IAAE,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5F,EACE,QAAe,EACf,YAAoB,EACpB,MAAc,EACd,UAAiB,EACjB,IAAI,EACJ,WAAW,EACX,SAA4B,EAC5B,YAAkC,EAClC,QAAe,EACf,GAAU,EACV,GAAU,EACV,UAAkB,EAClB,aAAoB,GACrB,GAAE;IACD,QAAQ,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uEAAuE;IACvE,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC9B,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACL,OAAO,CAAC,kBAAkB,CAAC,CA4F7B;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAAE,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAe3H"}
@@ -0,0 +1,292 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ISSUER_HISTORY_SCHEMA = void 0;
4
+ exports.issuerHistoryEntryBody = issuerHistoryEntryBody;
5
+ exports.issuerHistoryEntryHash = issuerHistoryEntryHash;
6
+ exports.verifyIssuerHistoryDocument = verifyIssuerHistoryDocument;
7
+ exports.issuerKeyWindow = issuerKeyWindow;
8
+ exports.issuerHistoryDocumentHash = issuerHistoryDocumentHash;
9
+ exports.readIssuerHistoryPin = readIssuerHistoryPin;
10
+ exports.checkReceiptIssuerHistory = checkReceiptIssuerHistory;
11
+ exports.historyUrlFromReceipt = historyUrlFromReceipt;
12
+ /**
13
+ * Public issuer key history.
14
+ * The document is signed by the current issuer key. Entries chain by
15
+ * SHA-256(JCS(entry without entry_hash)).
16
+ */
17
+ const node_crypto_1 = require("node:crypto");
18
+ const jcs_js_1 = require("./jcs.js");
19
+ const jws_js_1 = require("./jws.js");
20
+ exports.ISSUER_HISTORY_SCHEMA = 'chit402.issuer_history.v1';
21
+ function sha256Hex(text) {
22
+ return (0, node_crypto_1.createHash)('sha256').update(text, 'utf8').digest('hex');
23
+ }
24
+ function issuerHistoryEntryBody(entry) {
25
+ return {
26
+ kid: entry.kid,
27
+ jwk: entry.jwk ? {
28
+ kty: entry.jwk.kty,
29
+ crv: entry.jwk.crv,
30
+ x: entry.jwk.x,
31
+ y: entry.jwk.y,
32
+ kid: entry.jwk.kid,
33
+ alg: entry.jwk.alg || 'ES256',
34
+ use: entry.jwk.use || 'sig',
35
+ } : null,
36
+ alg: entry.alg || 'ES256',
37
+ not_before: entry.not_before,
38
+ not_after: entry.not_after ?? null,
39
+ status: entry.status,
40
+ revoked_at: entry.revoked_at ?? null,
41
+ reason: entry.reason ?? null,
42
+ custody: entry.custody,
43
+ prev_hash: entry.prev_hash ?? null,
44
+ };
45
+ }
46
+ function issuerHistoryEntryHash(entry) {
47
+ return sha256Hex((0, jcs_js_1.jcsCanonicalize)(issuerHistoryEntryBody(entry)));
48
+ }
49
+ function parseTime(value) {
50
+ if (value == null || value === '')
51
+ return null;
52
+ if (typeof value === 'number' && Number.isFinite(value))
53
+ return value > 1e12 ? value : value * 1000;
54
+ const ms = Date.parse(String(value));
55
+ return Number.isFinite(ms) ? ms : null;
56
+ }
57
+ function verifyIssuerHistoryDocument(doc, { jwks, trustedKids } = {}) {
58
+ if (!doc || doc.schema !== exports.ISSUER_HISTORY_SCHEMA || !Array.isArray(doc.entries) || !doc.entries.length) {
59
+ return { valid: false, reason: 'not_issuer_history' };
60
+ }
61
+ let prev = null;
62
+ for (const entry of doc.entries) {
63
+ if ((entry.prev_hash ?? null) !== prev)
64
+ return { valid: false, reason: 'prev_hash_mismatch' };
65
+ if (issuerHistoryEntryHash(entry) !== entry.entry_hash)
66
+ return { valid: false, reason: 'entry_hash_mismatch' };
67
+ if (!['active', 'retired', 'revoked'].includes(entry.status))
68
+ return { valid: false, reason: 'bad_status' };
69
+ prev = entry.entry_hash || null;
70
+ }
71
+ const head = doc.entries[doc.entries.length - 1].entry_hash;
72
+ if (doc.head_hash !== head)
73
+ return { valid: false, reason: 'head_hash_mismatch' };
74
+ const jws = doc.issuer_signature?.jws;
75
+ if (!jws)
76
+ return { valid: false, reason: 'no_signature' };
77
+ const headerKid = doc.issuer_signature?.kid || null;
78
+ // Undefined matches verifyReceipt / verifyRefusal: the production pin.
79
+ // An explicit empty list (--no-trusted-kid) does not.
80
+ const pins = trustedKids ?? jws_js_1.DEFAULT_TRUSTED_ISSUER_KIDS;
81
+ const candidates = [];
82
+ if (jwks?.keys) {
83
+ for (const key of jwks.keys) {
84
+ if (!headerKid || key.kid === headerKid)
85
+ candidates.push(key);
86
+ }
87
+ }
88
+ const embedded = doc.issuer_signature?.issuer_jwk;
89
+ if (embedded && (0, jws_js_1.isPinnedTrustedJwk)(embedded, pins))
90
+ candidates.push(embedded);
91
+ if (!candidates.length && embedded && headerKid && pins.includes(headerKid)) {
92
+ if ((0, jws_js_1.jwkThumbprint)(embedded) === headerKid)
93
+ candidates.push(embedded);
94
+ }
95
+ if (!candidates.length)
96
+ return { valid: false, reason: 'key untrusted' };
97
+ for (const jwk of candidates) {
98
+ const result = (0, jws_js_1.verifyIssuerJws)(jws, jwk);
99
+ if (!result.valid)
100
+ continue;
101
+ const payload = result.payload || {};
102
+ if (payload.schema !== exports.ISSUER_HISTORY_SCHEMA)
103
+ return { valid: false, reason: 'schema_mismatch' };
104
+ if (Number(payload.entry_count) !== doc.entries.length)
105
+ return { valid: false, reason: 'entry_count_mismatch' };
106
+ if (payload.head_hash !== head)
107
+ return { valid: false, reason: 'signed_head_mismatch' };
108
+ if (payload.version != null && Number(payload.version) !== Number(doc.version)) {
109
+ return { valid: false, reason: 'version_mismatch' };
110
+ }
111
+ if (payload.seq != null && Number(payload.seq) !== Number(doc.seq)) {
112
+ return { valid: false, reason: 'seq_mismatch' };
113
+ }
114
+ return { valid: true };
115
+ }
116
+ return { valid: false, reason: 'signature_invalid' };
117
+ }
118
+ function issuerKeyWindow(doc, kid, issuedAt) {
119
+ const entry = (doc.entries || []).find((row) => row.kid === kid);
120
+ if (!entry)
121
+ return { ok: false, reason: 'kid_not_in_history' };
122
+ const issued = parseTime(issuedAt);
123
+ if (issued == null)
124
+ return { ok: false, reason: 'issued_at_missing' };
125
+ const notBefore = parseTime(entry.not_before);
126
+ if (notBefore == null)
127
+ return { ok: false, reason: 'not_before_missing' };
128
+ if (issued < notBefore)
129
+ return { ok: false, reason: 'issued_before_not_before' };
130
+ const notAfter = parseTime(entry.not_after);
131
+ if (entry.not_after != null && notAfter == null)
132
+ return { ok: false, reason: 'not_after_invalid' };
133
+ if (notAfter != null && issued > notAfter)
134
+ return { ok: false, reason: 'issued_after_not_after' };
135
+ if (entry.status === 'revoked') {
136
+ const revoked = parseTime(entry.revoked_at);
137
+ if (revoked == null)
138
+ return { ok: false, reason: 'revoked_at_missing' };
139
+ if (issued >= revoked)
140
+ return { ok: false, reason: 'kid_revoked_before_issuance' };
141
+ }
142
+ return { ok: true, reason: null };
143
+ }
144
+ function issuerHistoryDocumentHash(doc) {
145
+ return sha256Hex((0, jcs_js_1.jcsCanonicalize)(doc));
146
+ }
147
+ /** Pin from verified JWS claims. An unsigned outer copy is not a pin. */
148
+ function readIssuerHistoryPin(claims) {
149
+ const pin = claims?.issuer_history;
150
+ if (!pin || typeof pin !== 'object')
151
+ return null;
152
+ const row = pin;
153
+ if (typeof row.hash !== 'string' || !/^[0-9a-f]{64}$/.test(row.hash))
154
+ return null;
155
+ const version = Number(row.version);
156
+ const seq = Number(row.seq);
157
+ if (!Number.isInteger(version) || version < 1)
158
+ return null;
159
+ if (!Number.isInteger(seq) || seq < 1)
160
+ return null;
161
+ return { hash: row.hash, version, seq };
162
+ }
163
+ function historyUrlWithPin(url, pin) {
164
+ if (!pin)
165
+ return url;
166
+ const parsed = new URL(url);
167
+ parsed.searchParams.set('version', String(pin.version));
168
+ return parsed.toString();
169
+ }
170
+ async function checkReceiptIssuerHistory(receipt, { document = null, fetchHistory = false, strict = false, historyUrl = null, jwks, trustedKids, fetchImpl = globalThis.fetch, trustedHosts = ['api.chit402.com'], issuedAt = null, kid = null, pin = null, requirePin = false, documentBytes = null, } = {}) {
171
+ const base = {
172
+ checked: false,
173
+ ok: true,
174
+ unreachable: false,
175
+ warning: null,
176
+ reason: null,
177
+ kid,
178
+ };
179
+ const pinned = !!(pin && pin.hash);
180
+ const failClosed = strict || pinned || requirePin;
181
+ if (requirePin && !pinned) {
182
+ return { ...base, checked: true, ok: false, reason: 'issuer_history_pin_missing' };
183
+ }
184
+ if (!kid) {
185
+ const warning = 'issuer history not checked: receipt has no kid';
186
+ if (failClosed)
187
+ return { ...base, checked: true, ok: false, reason: warning };
188
+ return { ...base, warning };
189
+ }
190
+ let doc = document;
191
+ let raw = documentBytes;
192
+ if (!doc && (fetchHistory || historyUrl || strict || pinned)) {
193
+ const baseUrl = historyUrl || historyUrlFromReceipt(receipt);
194
+ if (!baseUrl) {
195
+ const warning = 'issuer history unreachable: no history url on the receipt';
196
+ if (failClosed)
197
+ return { ...base, checked: true, ok: false, unreachable: true, reason: warning, warning };
198
+ return { ...base, unreachable: true, warning };
199
+ }
200
+ let url = baseUrl;
201
+ try {
202
+ url = historyUrlWithPin(baseUrl, pin);
203
+ }
204
+ catch {
205
+ const warning = 'issuer history unreachable: bad history url';
206
+ if (failClosed)
207
+ return { ...base, checked: true, ok: false, unreachable: true, reason: warning, warning };
208
+ return { ...base, unreachable: true, warning };
209
+ }
210
+ let parsed;
211
+ try {
212
+ parsed = new URL(url);
213
+ }
214
+ catch {
215
+ const warning = 'issuer history unreachable: bad history url';
216
+ if (failClosed)
217
+ return { ...base, checked: true, ok: false, unreachable: true, reason: warning, warning };
218
+ return { ...base, unreachable: true, warning };
219
+ }
220
+ const explicit = !!historyUrl;
221
+ const hostOk = explicit
222
+ ? parsed.protocol === 'https:'
223
+ : parsed.protocol === 'https:' && trustedHosts.some((host) => host.toLowerCase() === parsed.hostname.toLowerCase());
224
+ if (!hostOk) {
225
+ const warning = 'issuer history unreachable: history host is not allowed';
226
+ if (failClosed)
227
+ return { ...base, checked: true, ok: false, unreachable: true, reason: warning, warning };
228
+ return { ...base, unreachable: true, warning };
229
+ }
230
+ try {
231
+ const res = await fetchImpl(url, { signal: AbortSignal.timeout(4000) });
232
+ if (!res.ok)
233
+ throw new Error(`HTTP ${res.status}`);
234
+ raw = await res.text();
235
+ doc = JSON.parse(raw);
236
+ }
237
+ catch (err) {
238
+ const warning = `issuer history unreachable: ${err instanceof Error ? err.message : String(err)}`;
239
+ if (failClosed)
240
+ return { ...base, checked: true, ok: false, unreachable: true, reason: warning, warning };
241
+ return { ...base, unreachable: true, warning };
242
+ }
243
+ }
244
+ if (!doc) {
245
+ const warning = 'issuer history not checked';
246
+ if (failClosed)
247
+ return { ...base, checked: true, ok: false, unreachable: true, reason: warning, warning };
248
+ return { ...base, warning };
249
+ }
250
+ if (pinned && pin) {
251
+ if (raw != null && sha256Hex(raw) !== pin.hash) {
252
+ return { ...base, checked: true, ok: false, reason: 'issuer_history_pin_mismatch' };
253
+ }
254
+ if (issuerHistoryDocumentHash(doc) !== pin.hash) {
255
+ return { ...base, checked: true, ok: false, reason: 'issuer_history_pin_mismatch' };
256
+ }
257
+ if (Number(doc.version) !== pin.version) {
258
+ return { ...base, checked: true, ok: false, reason: 'issuer_history_version_mismatch' };
259
+ }
260
+ if (Number(doc.seq) !== pin.seq) {
261
+ return { ...base, checked: true, ok: false, reason: 'issuer_history_seq_mismatch' };
262
+ }
263
+ }
264
+ const signed = verifyIssuerHistoryDocument(doc, { jwks, trustedKids });
265
+ if (!signed.valid) {
266
+ return { ...base, checked: true, ok: false, reason: signed.reason || 'issuer_history_invalid' };
267
+ }
268
+ const window = issuerKeyWindow(doc, kid, issuedAt);
269
+ if (!window.ok) {
270
+ return { ...base, checked: true, ok: false, reason: window.reason };
271
+ }
272
+ return { ...base, checked: true, ok: true };
273
+ }
274
+ function historyUrlFromReceipt(receipt) {
275
+ const jwks = receipt.verification?.jwks_uri;
276
+ if (jwks && jwks.includes('/.well-known/jwks.json')) {
277
+ return jwks.replace('/.well-known/jwks.json', '/.well-known/issuer-history.json');
278
+ }
279
+ if (receipt.verify_url) {
280
+ try {
281
+ const url = new URL(receipt.verify_url);
282
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
283
+ return null;
284
+ return `${url.origin}/.well-known/issuer-history.json`;
285
+ }
286
+ catch {
287
+ return null;
288
+ }
289
+ }
290
+ return null;
291
+ }
292
+ //# sourceMappingURL=issuer-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer-history.js","sourceRoot":"","sources":["../src/issuer-history.ts"],"names":[],"mappings":"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"}
package/dist/jcs.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * RFC 8785 JSON Canonicalization.
3
+ * Same rules as `jcsCanonicalize` in services/gateway/src/offer-receipt.js.
4
+ * Issuer-history entry hashes and the receipt canonical object use this form.
5
+ * Per-field receipt hashes keep the encoding they were signed with.
6
+ */
7
+ export declare function jcsCanonicalize(value: unknown): string;
8
+ //# sourceMappingURL=jcs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jcs.d.ts","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD"}
package/dist/jcs.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * RFC 8785 JSON Canonicalization.
4
+ * Same rules as `jcsCanonicalize` in services/gateway/src/offer-receipt.js.
5
+ * Issuer-history entry hashes and the receipt canonical object use this form.
6
+ * Per-field receipt hashes keep the encoding they were signed with.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.jcsCanonicalize = jcsCanonicalize;
10
+ function jcsCanonicalize(value) {
11
+ return jcsValue(value);
12
+ }
13
+ function jcsValue(value) {
14
+ if (value === null || value === undefined)
15
+ return 'null';
16
+ const type = typeof value;
17
+ if (type === 'boolean')
18
+ return value ? 'true' : 'false';
19
+ if (type === 'number') {
20
+ if (!Number.isFinite(value))
21
+ throw new Error('Cannot canonicalize Infinity or NaN');
22
+ if (Object.is(value, -0))
23
+ return '0';
24
+ return String(value);
25
+ }
26
+ if (type === 'string')
27
+ return jcsString(value);
28
+ if (Array.isArray(value))
29
+ return `[${value.map(jcsValue).join(',')}]`;
30
+ if (type === 'object')
31
+ return jcsObject(value);
32
+ throw new Error(`Cannot canonicalize value of type ${type}`);
33
+ }
34
+ function jcsString(str) {
35
+ let result = '"';
36
+ for (let i = 0; i < str.length; i += 1) {
37
+ const char = str[i];
38
+ const code = str.charCodeAt(i);
39
+ if (code < 32) {
40
+ result += `\\u${code.toString(16).padStart(4, '0')}`;
41
+ }
42
+ else if (char === '"') {
43
+ result += '\\"';
44
+ }
45
+ else if (char === '\\') {
46
+ result += '\\\\';
47
+ }
48
+ else {
49
+ result += char;
50
+ }
51
+ }
52
+ return `${result}"`;
53
+ }
54
+ function jcsObject(obj) {
55
+ const keys = Object.keys(obj).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
56
+ const pairs = [];
57
+ for (const key of keys) {
58
+ const value = obj[key];
59
+ if (value !== undefined)
60
+ pairs.push(`${jcsString(key)}:${jcsValue(value)}`);
61
+ }
62
+ return `{${pairs.join(',')}}`;
63
+ }
64
+ //# sourceMappingURL=jcs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jcs.js","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAEH,0CAEC;AAFD,SAAgB,eAAe,CAAC,KAAc;IAC5C,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACzD,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC;IAC1B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACxD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAe,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC9F,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACrC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC,KAAe,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACtE,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC,KAAgC,CAAC,CAAC;IAC1E,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC;YACd,MAAM,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACvD,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC;QAClB,CAAC;aAAM,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,MAAM,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,MAAM,GAAG,CAAC;AACtB,CAAC;AAED,SAAS,SAAS,CAAC,GAA4B;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAChC,CAAC"}
@@ -0,0 +1,49 @@
1
+ export interface PreimageLeaf {
2
+ preimage_utf8?: string;
3
+ preimage_hex?: string;
4
+ }
5
+ export interface PreimageEntry {
6
+ field?: string;
7
+ alg?: string;
8
+ recomputable?: boolean;
9
+ preimage_utf8?: string;
10
+ preimage_hex?: string;
11
+ hash?: string;
12
+ merkle?: string;
13
+ leaves?: PreimageLeaf[];
14
+ url?: string;
15
+ }
16
+ export interface PreimageBlock {
17
+ schema?: string;
18
+ fields?: Record<string, PreimageEntry>;
19
+ not_recomputable?: {
20
+ field?: string;
21
+ hash?: string | null;
22
+ reason?: string;
23
+ }[];
24
+ links?: {
25
+ preimage?: string;
26
+ };
27
+ }
28
+ export interface PreimageCheck {
29
+ checked: boolean;
30
+ ok: boolean;
31
+ errors: string[];
32
+ fields: {
33
+ field: string;
34
+ ok: boolean;
35
+ reason?: string;
36
+ }[];
37
+ }
38
+ /**
39
+ * Fields a stranger is expected to recompute when they are present.
40
+ * Coverage and tree_head_hash count only when the issuer published a preimage.
41
+ * Output, HMAC, and book-row universe hashes do not.
42
+ */
43
+ export declare function requiredPreimageFields(receipt: Record<string, unknown>): string[];
44
+ export declare function verifyPublishedPreimages(receipt: Record<string, unknown>, { requirePreimages, fetchImpl, trustedHosts, }?: {
45
+ requirePreimages?: boolean;
46
+ fetchImpl?: typeof fetch;
47
+ trustedHosts?: readonly string[];
48
+ }): Promise<PreimageCheck>;
49
+ //# sourceMappingURL=preimage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preimage.d.ts","sourceRoot":"","sources":["../src/preimage.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,gBAAgB,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/E,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3D;AAkGD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAUjF;AAmBD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,EACE,gBAAwB,EACxB,SAA4B,EAC5B,YAAkC,GACnC,GAAE;IACD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,GACL,OAAO,CAAC,aAAa,CAAC,CAoDxB"}