@wavehouse/chtypes 0.5.2 → 1.0.2

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 (195) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +34 -38
  3. package/dist/abi1/buildinfo.d.ts +40 -0
  4. package/dist/abi1/buildinfo.d.ts.map +1 -0
  5. package/dist/abi1/buildinfo.js +83 -0
  6. package/dist/abi1/buildinfo.js.map +1 -0
  7. package/dist/abi1/calls.gen.d.ts +55 -0
  8. package/dist/abi1/calls.gen.d.ts.map +1 -0
  9. package/dist/abi1/calls.gen.js +110 -0
  10. package/dist/abi1/calls.gen.js.map +1 -0
  11. package/dist/abi1/decls.gen.d.ts +115 -0
  12. package/dist/abi1/decls.gen.d.ts.map +1 -0
  13. package/dist/abi1/decls.gen.js +1613 -0
  14. package/dist/abi1/decls.gen.js.map +1 -0
  15. package/dist/abi1/errmap.gen.d.ts +18 -0
  16. package/dist/abi1/errmap.gen.d.ts.map +1 -0
  17. package/dist/abi1/errmap.gen.js +66 -0
  18. package/dist/abi1/errmap.gen.js.map +1 -0
  19. package/dist/abi1/errors.d.ts +107 -0
  20. package/dist/abi1/errors.d.ts.map +1 -0
  21. package/dist/abi1/errors.js +134 -0
  22. package/dist/abi1/errors.js.map +1 -0
  23. package/dist/abi1/handles.d.ts +31 -0
  24. package/dist/abi1/handles.d.ts.map +1 -0
  25. package/dist/abi1/handles.js +76 -0
  26. package/dist/abi1/handles.js.map +1 -0
  27. package/dist/abi1/index.d.ts +17 -0
  28. package/dist/abi1/index.d.ts.map +1 -0
  29. package/dist/abi1/index.js +17 -0
  30. package/dist/abi1/index.js.map +1 -0
  31. package/dist/abi1/libc.d.ts +54 -0
  32. package/dist/abi1/libc.d.ts.map +1 -0
  33. package/dist/abi1/libc.gen.d.ts +12 -0
  34. package/dist/abi1/libc.gen.d.ts.map +1 -0
  35. package/dist/abi1/libc.gen.js +75 -0
  36. package/dist/abi1/libc.gen.js.map +1 -0
  37. package/dist/abi1/libc.js +109 -0
  38. package/dist/abi1/libc.js.map +1 -0
  39. package/dist/abi1/loader.d.ts +101 -0
  40. package/dist/abi1/loader.d.ts.map +1 -0
  41. package/dist/abi1/loader.js +274 -0
  42. package/dist/abi1/loader.js.map +1 -0
  43. package/dist/abi1/raw.d.ts +104 -0
  44. package/dist/abi1/raw.d.ts.map +1 -0
  45. package/dist/abi1/raw.js +296 -0
  46. package/dist/abi1/raw.js.map +1 -0
  47. package/dist/abi1/strictjson.d.ts +19 -0
  48. package/dist/abi1/strictjson.d.ts.map +1 -0
  49. package/dist/abi1/strictjson.js +78 -0
  50. package/dist/abi1/strictjson.js.map +1 -0
  51. package/dist/abi1/vocab.gen.d.ts +169 -0
  52. package/dist/abi1/vocab.gen.d.ts.map +1 -0
  53. package/dist/abi1/vocab.gen.js +306 -0
  54. package/dist/abi1/vocab.gen.js.map +1 -0
  55. package/dist/cli.d.ts +25 -26
  56. package/dist/cli.d.ts.map +1 -1
  57. package/dist/cli.js +206 -218
  58. package/dist/cli.js.map +1 -1
  59. package/dist/documents.d.ts +195 -0
  60. package/dist/documents.d.ts.map +1 -0
  61. package/dist/documents.js +389 -0
  62. package/dist/documents.js.map +1 -0
  63. package/dist/env.d.ts +16 -0
  64. package/dist/env.d.ts.map +1 -0
  65. package/dist/env.js +57 -0
  66. package/dist/env.js.map +1 -0
  67. package/dist/index.d.ts +19 -24
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +17 -23
  70. package/dist/index.js.map +1 -1
  71. package/dist/json.d.ts +11 -89
  72. package/dist/json.d.ts.map +1 -1
  73. package/dist/json.js +16 -180
  74. package/dist/json.js.map +1 -1
  75. package/dist/library.d.ts +53 -309
  76. package/dist/library.d.ts.map +1 -1
  77. package/dist/library.js +77 -315
  78. package/dist/library.js.map +1 -1
  79. package/dist/ocifetch/constants.gen.d.ts +84 -0
  80. package/dist/ocifetch/constants.gen.d.ts.map +1 -0
  81. package/dist/ocifetch/constants.gen.js +92 -0
  82. package/dist/ocifetch/constants.gen.js.map +1 -0
  83. package/dist/ocifetch/dsse.d.ts +114 -0
  84. package/dist/ocifetch/dsse.d.ts.map +1 -0
  85. package/dist/ocifetch/dsse.js +331 -0
  86. package/dist/ocifetch/dsse.js.map +1 -0
  87. package/dist/ocifetch/ensure.d.ts +65 -0
  88. package/dist/ocifetch/ensure.d.ts.map +1 -0
  89. package/dist/ocifetch/ensure.js +775 -0
  90. package/dist/ocifetch/ensure.js.map +1 -0
  91. package/dist/ocifetch/errors.d.ts +92 -0
  92. package/dist/ocifetch/errors.d.ts.map +1 -0
  93. package/dist/ocifetch/errors.js +101 -0
  94. package/dist/ocifetch/errors.js.map +1 -0
  95. package/dist/ocifetch/goldens.d.ts +44 -0
  96. package/dist/ocifetch/goldens.d.ts.map +1 -0
  97. package/dist/ocifetch/goldens.js +62 -0
  98. package/dist/ocifetch/goldens.js.map +1 -0
  99. package/dist/ocifetch/http.d.ts +124 -0
  100. package/dist/ocifetch/http.d.ts.map +1 -0
  101. package/dist/ocifetch/http.js +549 -0
  102. package/dist/ocifetch/http.js.map +1 -0
  103. package/dist/ocifetch/index.d.ts +17 -0
  104. package/dist/ocifetch/index.d.ts.map +1 -0
  105. package/dist/ocifetch/index.js +14 -0
  106. package/dist/ocifetch/index.js.map +1 -0
  107. package/dist/ocifetch/layout.d.ts +126 -0
  108. package/dist/ocifetch/layout.d.ts.map +1 -0
  109. package/dist/ocifetch/layout.js +375 -0
  110. package/dist/ocifetch/layout.js.map +1 -0
  111. package/dist/ocifetch/localverify.d.ts +43 -0
  112. package/dist/ocifetch/localverify.d.ts.map +1 -0
  113. package/dist/ocifetch/localverify.js +164 -0
  114. package/dist/ocifetch/localverify.js.map +1 -0
  115. package/dist/ocifetch/lock.d.ts +39 -0
  116. package/dist/ocifetch/lock.d.ts.map +1 -0
  117. package/dist/ocifetch/lock.js +140 -0
  118. package/dist/ocifetch/lock.js.map +1 -0
  119. package/dist/ocifetch/oci.d.ts +100 -0
  120. package/dist/ocifetch/oci.d.ts.map +1 -0
  121. package/dist/ocifetch/oci.js +323 -0
  122. package/dist/ocifetch/oci.js.map +1 -0
  123. package/dist/ocifetch/referrers.d.ts +55 -0
  124. package/dist/ocifetch/referrers.d.ts.map +1 -0
  125. package/dist/ocifetch/referrers.js +132 -0
  126. package/dist/ocifetch/referrers.js.map +1 -0
  127. package/dist/ocifetch/types.d.ts +167 -0
  128. package/dist/ocifetch/types.d.ts.map +1 -0
  129. package/dist/ocifetch/types.js +88 -0
  130. package/dist/ocifetch/types.js.map +1 -0
  131. package/dist/ocifetch/unpack.d.ts +55 -0
  132. package/dist/ocifetch/unpack.d.ts.map +1 -0
  133. package/dist/ocifetch/unpack.js +205 -0
  134. package/dist/ocifetch/unpack.js.map +1 -0
  135. package/dist/registry.d.ts +38 -387
  136. package/dist/registry.d.ts.map +1 -1
  137. package/dist/registry.js +95 -819
  138. package/dist/registry.js.map +1 -1
  139. package/dist/schema.d.ts +77 -588
  140. package/dist/schema.d.ts.map +1 -1
  141. package/dist/schema.js +87 -549
  142. package/dist/schema.js.map +1 -1
  143. package/dist/settings.d.ts +27 -36
  144. package/dist/settings.d.ts.map +1 -1
  145. package/dist/settings.js +75 -25
  146. package/dist/settings.js.map +1 -1
  147. package/dist/setup.d.ts +46 -0
  148. package/dist/setup.d.ts.map +1 -0
  149. package/dist/setup.js +79 -0
  150. package/dist/setup.js.map +1 -0
  151. package/dist/tar.d.ts +27 -11
  152. package/dist/tar.d.ts.map +1 -1
  153. package/dist/tar.js +54 -32
  154. package/dist/tar.js.map +1 -1
  155. package/package.json +2 -2
  156. package/dist/discover.d.ts +0 -142
  157. package/dist/discover.d.ts.map +0 -1
  158. package/dist/discover.js +0 -288
  159. package/dist/discover.js.map +0 -1
  160. package/dist/error-codes.d.ts +0 -80
  161. package/dist/error-codes.d.ts.map +0 -1
  162. package/dist/error-codes.js +0 -139
  163. package/dist/error-codes.js.map +0 -1
  164. package/dist/errors.d.ts +0 -284
  165. package/dist/errors.d.ts.map +0 -1
  166. package/dist/errors.js +0 -321
  167. package/dist/errors.js.map +0 -1
  168. package/dist/fetch.d.ts +0 -382
  169. package/dist/fetch.d.ts.map +0 -1
  170. package/dist/fetch.js +0 -1498
  171. package/dist/fetch.js.map +0 -1
  172. package/dist/ffi.d.ts +0 -410
  173. package/dist/ffi.d.ts.map +0 -1
  174. package/dist/ffi.js +0 -1154
  175. package/dist/ffi.js.map +0 -1
  176. package/dist/format.d.ts +0 -128
  177. package/dist/format.d.ts.map +0 -1
  178. package/dist/format.js +0 -132
  179. package/dist/format.js.map +0 -1
  180. package/dist/numeric.d.ts +0 -20
  181. package/dist/numeric.d.ts.map +0 -1
  182. package/dist/numeric.js +0 -107
  183. package/dist/numeric.js.map +0 -1
  184. package/dist/paths.d.ts +0 -55
  185. package/dist/paths.d.ts.map +0 -1
  186. package/dist/paths.js +0 -87
  187. package/dist/paths.js.map +0 -1
  188. package/dist/results.d.ts +0 -495
  189. package/dist/results.d.ts.map +0 -1
  190. package/dist/results.js +0 -406
  191. package/dist/results.js.map +0 -1
  192. package/dist/transform.d.ts +0 -73
  193. package/dist/transform.d.ts.map +0 -1
  194. package/dist/transform.js +0 -533
  195. package/dist/transform.js.map +0 -1
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Trust (`docs/guides/fetch-v1.md` §4): verifying one Sigstore bundle v0.3 by
3
+ * hand — never a Sigstore client library, which cannot verify a key-only
4
+ * bundle at all (`layout-v2.md` §4.3). `node:crypto`'s `verify(null, …)` is
5
+ * ed25519 (no digest algorithm to name), matching Go `crypto/ed25519`,
6
+ * Python's own RFC 8032 verifier and Rust's `ed25519-dalek` — the primitive
7
+ * every binding already ships for v0.
8
+ *
9
+ * The split this module enforces (guide §4): a bundle whose SIGNATURE does
10
+ * not verify under any trusted key is simply "not this one" — a caller tries
11
+ * the next referrer and only reports `UNTRUSTED` once every candidate has
12
+ * failed this way. A bundle whose signature DOES verify but whose STATEMENT
13
+ * fails a content check (wrong predicateType, wrong subject, wrong platform,
14
+ * wrong version, a duplicate JSON key) is `CORRUPT` **immediately** — an
15
+ * authentically-signed statement that asserts the wrong thing is a real
16
+ * inconsistency, never something to paper over by trying another referrer.
17
+ */
18
+ import type { RequestOptions } from './http.js';
19
+ import type { ArtifactPredicate, Statement, TrustedKey } from './types.js';
20
+ /**
21
+ * `bytes` as a plain JS value, refusing a duplicate key **anywhere** in the
22
+ * document (guide §4's "a duplicate key anywhere in the statement's JSON is
23
+ * CORRUPT") — `../json.ts`'s parser keeps every key/value pair, duplicates
24
+ * included, specifically so a caller can detect this; `JSON.parse` would
25
+ * silently keep only the last and could never see it.
26
+ */
27
+ export declare function parseJsonNoDuplicates(bytes: Buffer): unknown;
28
+ /** DSSE's pre-authentication encoding (PAE): `DSSEv1 LEN(type) SP type LEN(body) SP body`. */
29
+ /** A key's id: `sha256-first16hex`, the first 16 hex characters of sha256 over the raw 32-byte public key (`spec/fetch-v1/constants.json`, `trust.keyid_algorithm`). */
30
+ export declare function keyIdOfRawKey(publicKeyHex: string): string;
31
+ export declare function dssePAE(payloadType: string, payload: Buffer): Buffer;
32
+ /** Verifies one ed25519 signature over `message` against a raw 32-byte public key given as hex. */
33
+ export declare function verifyEd25519(publicKeyHex: string, message: Buffer, signature: Buffer): boolean;
34
+ /**
35
+ * Attempts to verify one bundle's DSSE signature against `trustedKeys`.
36
+ * Returns the trusted key id that verified it, or `undefined` when none did
37
+ * (including an unparseable bundle) — callers try the next candidate.
38
+ *
39
+ * This checks the SIGNATURE only. The caller parses and checks the
40
+ * statement's content afterward, using the authenticated `payload` bytes.
41
+ */
42
+ export declare function verifyBundleSignature(bundleBytes: Buffer, trustedKeys: readonly TrustedKey[]): {
43
+ readonly signedBy: string;
44
+ readonly payload: Buffer;
45
+ } | undefined;
46
+ /**
47
+ * Parses an already-authenticated DSSE payload into a `Statement`, refusing
48
+ * a duplicate key anywhere (guide §4). Call this only after
49
+ * `verifyBundleSignature` has returned a `signedBy` for these exact bytes —
50
+ * parsing content checks are meaningless, and must never run, on bytes no
51
+ * signature has covered.
52
+ */
53
+ export declare function parseStatement(payload: Buffer): Statement;
54
+ /** `clickhouse_version`'s relationship to the original request spelling (guide §4). */
55
+ export declare function versionWithinRequest(actualVersion: string, requestedSpelling: string): boolean;
56
+ export interface ArtifactStatementCheck {
57
+ readonly os: string;
58
+ readonly arch: string;
59
+ /**
60
+ * Omit only when there is no one request to check against yet —
61
+ * `localverify.ts`'s local-blob scan verifies a pre-seeded entry on its
62
+ * own terms first, and the caller checks the resulting predicate's own
63
+ * `clickhouse_version` against whatever request prompted the scan
64
+ * afterward. Every other caller always supplies this.
65
+ */
66
+ readonly requestedSpelling?: string;
67
+ }
68
+ /**
69
+ * The full statement check for a **platform artifact** manifest (guide §4):
70
+ * predicateType, subject digest, `abi` (never `abi_revision`), os/arch and
71
+ * — when `check.requestedSpelling` is given — the version-within-request
72
+ * rule. Throws `ArtifactCorruptError` naming the first failing check.
73
+ */
74
+ export declare function checkArtifactStatement(statement: Statement, expectedPredicateType: string, expectedLayerDigest: string, check: ArtifactStatementCheck): ArtifactPredicate;
75
+ /**
76
+ * The reduced statement check `fetchSigned` uses for goldens and fixtures
77
+ * (guide §9): predicateType and subject digest only. These objects' own
78
+ * predicate shapes are not yet specified (blocked on the producer, plan
79
+ * §1.2), so `fetchSigned`'s caller reads `statement.predicate` itself.
80
+ */
81
+ export declare function checkGenericStatement(statement: Statement, expectedPredicateType: string, expectedLayerDigest: string): void;
82
+ export interface TrustResult {
83
+ readonly statement: Statement;
84
+ /** The trusted key id that verified it, or the fixture test key's id under `trust: "test"`. */
85
+ readonly signedBy: string;
86
+ /** The digest of the verified bundle blob itself (the referrer manifest's layer), as a lock pin's `bundle` records it. */
87
+ readonly bundleDigest: string;
88
+ /** The digest of the referrer manifest that carried the bundle. */
89
+ readonly bundleManifestDigest: string;
90
+ }
91
+ /**
92
+ * Finds, fetches and verifies a signature for `subjectDigest` within
93
+ * `repositoryRoot`: every referrer-API-or-fallback-tag candidate of
94
+ * `bundleArtifactType` (`referrers.ts`), each one's own manifest-then-layer
95
+ * hop (a referrer is itself a small OCI artifact; its layer blob holds the
96
+ * actual bundle JSON), tried in order until one verifies.
97
+ *
98
+ * `checkContent` is the caller's statement check (`checkArtifactStatement`
99
+ * for the main artifact, `checkGenericStatement` for `fetchSigned`) — it
100
+ * throws `ArtifactCorruptError` on a content mismatch, and that throw
101
+ * propagates immediately, out of this function, without trying further
102
+ * candidates (this module's header explains why).
103
+ *
104
+ * A candidate whose manifest or layer cannot even be fetched is skipped
105
+ * (treated the same as a signature that failed to verify) rather than
106
+ * aborting the whole search — a dangling or unreachable referrer on one
107
+ * mirror should not prevent trying another.
108
+ *
109
+ * Returns `undefined` when no candidate's signature verified under any
110
+ * trusted key at all — the caller raises `ArtifactUntrustedError` (or
111
+ * honors allow-unsigned).
112
+ */
113
+ export declare function verifyAnyReferrerBundle(repositoryRoot: string, subjectDigest: string, bundleArtifactType: string, trustedKeys: readonly TrustedKey[], checkContent: (statement: Statement) => void, options: RequestOptions): Promise<TrustResult | undefined>;
114
+ //# sourceMappingURL=dsse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsse.d.ts","sourceRoot":"","sources":["../../src/ocifetch/dsse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK3E;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI5D;AAkCD,8FAA8F;AAC9F,wKAAwK;AACxK,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAYpE;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAiB/F;AAqDD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,SAAS,UAAU,EAAE,GACjC;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAarE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAmCzD;AAID,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAQ9F;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,EACpB,qBAAqB,EAAE,MAAM,EAC7B,mBAAmB,EAAE,MAAM,EAC3B,KAAK,EAAE,sBAAsB,GAC5B,iBAAiB,CA+BnB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAU5H;AAID,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0HAA0H;IAC1H,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,uBAAuB,CAC3C,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,EAC1B,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,YAAY,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,EAC5C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAkBlC"}
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Trust (`docs/guides/fetch-v1.md` §4): verifying one Sigstore bundle v0.3 by
3
+ * hand — never a Sigstore client library, which cannot verify a key-only
4
+ * bundle at all (`layout-v2.md` §4.3). `node:crypto`'s `verify(null, …)` is
5
+ * ed25519 (no digest algorithm to name), matching Go `crypto/ed25519`,
6
+ * Python's own RFC 8032 verifier and Rust's `ed25519-dalek` — the primitive
7
+ * every binding already ships for v0.
8
+ *
9
+ * The split this module enforces (guide §4): a bundle whose SIGNATURE does
10
+ * not verify under any trusted key is simply "not this one" — a caller tries
11
+ * the next referrer and only reports `UNTRUSTED` once every candidate has
12
+ * failed this way. A bundle whose signature DOES verify but whose STATEMENT
13
+ * fails a content check (wrong predicateType, wrong subject, wrong platform,
14
+ * wrong version, a duplicate JSON key) is `CORRUPT` **immediately** — an
15
+ * authentically-signed statement that asserts the wrong thing is a real
16
+ * inconsistency, never something to paper over by trying another referrer.
17
+ */
18
+ import { createHash, createPublicKey, verify as cryptoVerify } from 'node:crypto';
19
+ import { items, parseJsonValue } from '../json.js';
20
+ import { ABI_GENERATION, DSSE_MAX_SIGNATURES, DSSE_PAYLOAD_TYPE, SPELLING_REGEX } from './constants.gen.js';
21
+ import { ArtifactCorruptError } from './errors.js';
22
+ import { fetchBlobBytesByDigest, fetchManifestByDigest } from './oci.js';
23
+ import { discoverSignatureCandidates } from './referrers.js';
24
+ import { hexOfDigest } from './types.js';
25
+ // -------------------------------------------------------------- strict JSON
26
+ /**
27
+ * `bytes` as a plain JS value, refusing a duplicate key **anywhere** in the
28
+ * document (guide §4's "a duplicate key anywhere in the statement's JSON is
29
+ * CORRUPT") — `../json.ts`'s parser keeps every key/value pair, duplicates
30
+ * included, specifically so a caller can detect this; `JSON.parse` would
31
+ * silently keep only the last and could never see it.
32
+ */
33
+ export function parseJsonNoDuplicates(bytes) {
34
+ const parsed = parseJsonValue(bytes);
35
+ if (parsed === null)
36
+ throw new ArtifactCorruptError('chtypes: not a single valid JSON value');
37
+ return toPlain(parsed);
38
+ }
39
+ function toPlain(json) {
40
+ switch (json.kind) {
41
+ case 'null':
42
+ return null;
43
+ case 'bool':
44
+ return json.raw[0] === 0x74;
45
+ case 'number': {
46
+ const n = Number(json.raw.toString('utf8'));
47
+ return Number.isFinite(n) ? n : json.raw.toString('utf8');
48
+ }
49
+ case 'string':
50
+ return json.bytes.toString('utf8');
51
+ case 'array':
52
+ return items(json).map(toPlain);
53
+ case 'object': {
54
+ const seen = new Set();
55
+ const obj = {};
56
+ for (let i = 0; i < json.keys.length; i++) {
57
+ const key = json.keys[i].toString('utf8');
58
+ if (seen.has(key))
59
+ throw new ArtifactCorruptError(`chtypes: duplicate JSON key ${JSON.stringify(key)}`);
60
+ seen.add(key);
61
+ obj[key] = toPlain(json.items[i]);
62
+ }
63
+ return obj;
64
+ }
65
+ default:
66
+ return null;
67
+ }
68
+ }
69
+ // ------------------------------------------------------------------- ed25519
70
+ /** DSSE's pre-authentication encoding (PAE): `DSSEv1 LEN(type) SP type LEN(body) SP body`. */
71
+ /** A key's id: `sha256-first16hex`, the first 16 hex characters of sha256 over the raw 32-byte public key (`spec/fetch-v1/constants.json`, `trust.keyid_algorithm`). */
72
+ export function keyIdOfRawKey(publicKeyHex) {
73
+ return createHash('sha256').update(Buffer.from(publicKeyHex, 'hex')).digest('hex').slice(0, 16);
74
+ }
75
+ export function dssePAE(payloadType, payload) {
76
+ const typeBytes = Buffer.from(payloadType, 'utf8');
77
+ return Buffer.concat([
78
+ Buffer.from('DSSEv1 ', 'ascii'),
79
+ Buffer.from(String(typeBytes.length), 'ascii'),
80
+ Buffer.from(' ', 'ascii'),
81
+ typeBytes,
82
+ Buffer.from(' ', 'ascii'),
83
+ Buffer.from(String(payload.length), 'ascii'),
84
+ Buffer.from(' ', 'ascii'),
85
+ payload,
86
+ ]);
87
+ }
88
+ /** Verifies one ed25519 signature over `message` against a raw 32-byte public key given as hex. */
89
+ export function verifyEd25519(publicKeyHex, message, signature) {
90
+ const keyBytes = Buffer.from(publicKeyHex, 'hex');
91
+ if (keyBytes.length !== 32)
92
+ return false;
93
+ let keyObject;
94
+ try {
95
+ keyObject = createPublicKey({
96
+ key: { kty: 'OKP', crv: 'Ed25519', x: keyBytes.toString('base64url') },
97
+ format: 'jwk',
98
+ });
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ try {
104
+ return cryptoVerify(null, message, keyObject, signature);
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
110
+ /**
111
+ * Parses a Sigstore bundle v0.3's DSSE envelope. Lenient on purpose: a
112
+ * malformed or unexpectedly-shaped bundle among several referrer candidates
113
+ * is "not usable", not a hard failure — `null` lets the caller move on to
114
+ * the next candidate instead of raising `CORRUPT` for bytes nothing has
115
+ * authenticated yet.
116
+ */
117
+ function parseEnvelope(bundleBytes) {
118
+ let bundle;
119
+ try {
120
+ bundle = JSON.parse(bundleBytes.toString('utf8'));
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ if (bundle === null || typeof bundle !== 'object')
126
+ return null;
127
+ const envelope = bundle['dsseEnvelope'];
128
+ if (envelope === null || typeof envelope !== 'object')
129
+ return null;
130
+ const e = envelope;
131
+ const payloadType = e['payloadType'];
132
+ const payloadB64 = e['payload'];
133
+ const signaturesRaw = e['signatures'];
134
+ if (typeof payloadType !== 'string' || typeof payloadB64 !== 'string' || !Array.isArray(signaturesRaw))
135
+ return null;
136
+ let payload;
137
+ try {
138
+ payload = Buffer.from(payloadB64, 'base64');
139
+ }
140
+ catch {
141
+ return null;
142
+ }
143
+ const signatures = [];
144
+ for (const row of signaturesRaw.slice(0, DSSE_MAX_SIGNATURES)) {
145
+ if (row === null || typeof row !== 'object')
146
+ continue;
147
+ const sigB64 = row['sig'];
148
+ const keyid = row['keyid'];
149
+ if (typeof sigB64 !== 'string')
150
+ continue;
151
+ try {
152
+ signatures.push({ sig: Buffer.from(sigB64, 'base64'), keyid: typeof keyid === 'string' ? keyid : undefined });
153
+ }
154
+ catch {
155
+ // Not valid base64 — skip this one signature, not the whole bundle.
156
+ }
157
+ }
158
+ return { payloadType, payload, signatures };
159
+ }
160
+ /**
161
+ * Attempts to verify one bundle's DSSE signature against `trustedKeys`.
162
+ * Returns the trusted key id that verified it, or `undefined` when none did
163
+ * (including an unparseable bundle) — callers try the next candidate.
164
+ *
165
+ * This checks the SIGNATURE only. The caller parses and checks the
166
+ * statement's content afterward, using the authenticated `payload` bytes.
167
+ */
168
+ export function verifyBundleSignature(bundleBytes, trustedKeys) {
169
+ const envelope = parseEnvelope(bundleBytes);
170
+ if (envelope === null)
171
+ return undefined;
172
+ if (envelope.payloadType !== DSSE_PAYLOAD_TYPE)
173
+ return undefined;
174
+ const pae = dssePAE(envelope.payloadType, envelope.payload);
175
+ for (const sig of envelope.signatures) {
176
+ for (const key of trustedKeys) {
177
+ if (verifyEd25519(key.ed25519Hex, pae, sig.sig)) {
178
+ return { signedBy: key.keyid, payload: envelope.payload };
179
+ }
180
+ }
181
+ }
182
+ return undefined;
183
+ }
184
+ /**
185
+ * Parses an already-authenticated DSSE payload into a `Statement`, refusing
186
+ * a duplicate key anywhere (guide §4). Call this only after
187
+ * `verifyBundleSignature` has returned a `signedBy` for these exact bytes —
188
+ * parsing content checks are meaningless, and must never run, on bytes no
189
+ * signature has covered.
190
+ */
191
+ export function parseStatement(payload) {
192
+ const value = parseJsonNoDuplicates(payload);
193
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
194
+ throw new ArtifactCorruptError('chtypes: the DSSE payload is not a JSON object');
195
+ }
196
+ const v = value;
197
+ const type = v['_type'];
198
+ const predicateType = v['predicateType'];
199
+ const predicate = v['predicate'];
200
+ const subject = v['subject'];
201
+ if (typeof type !== 'string' || typeof predicateType !== 'string') {
202
+ throw new ArtifactCorruptError('chtypes: the statement is missing _type or predicateType');
203
+ }
204
+ if (predicate === null || typeof predicate !== 'object' || Array.isArray(predicate)) {
205
+ throw new ArtifactCorruptError('chtypes: the statement predicate is not an object');
206
+ }
207
+ if (!Array.isArray(subject) || subject.length === 0) {
208
+ throw new ArtifactCorruptError('chtypes: the statement names no subject');
209
+ }
210
+ const parsedSubjects = subject.map((s) => {
211
+ if (s === null || typeof s !== 'object')
212
+ throw new ArtifactCorruptError('chtypes: a statement subject is not an object');
213
+ const row = s;
214
+ const digest = row['digest'];
215
+ const name = row['name'];
216
+ if (digest === null || typeof digest !== 'object')
217
+ throw new ArtifactCorruptError('chtypes: a subject has no digest');
218
+ const sha256 = digest['sha256'];
219
+ if (typeof sha256 !== 'string')
220
+ throw new ArtifactCorruptError('chtypes: a subject digest has no sha256');
221
+ return { name: typeof name === 'string' ? name : '', digest: { sha256 } };
222
+ });
223
+ return {
224
+ _type: type,
225
+ predicateType,
226
+ predicate: predicate,
227
+ subject: parsedSubjects,
228
+ };
229
+ }
230
+ // --------------------------------------------------------- content checking
231
+ /** `clickhouse_version`'s relationship to the original request spelling (guide §4). */
232
+ export function versionWithinRequest(actualVersion, requestedSpelling) {
233
+ const actual = actualVersion.split('.');
234
+ const requested = requestedSpelling.split('.');
235
+ if (requested.length > actual.length)
236
+ return false;
237
+ for (let i = 0; i < requested.length; i++) {
238
+ if (requested[i] !== actual[i])
239
+ return false;
240
+ }
241
+ return true;
242
+ }
243
+ /**
244
+ * The full statement check for a **platform artifact** manifest (guide §4):
245
+ * predicateType, subject digest, `abi` (never `abi_revision`), os/arch and
246
+ * — when `check.requestedSpelling` is given — the version-within-request
247
+ * rule. Throws `ArtifactCorruptError` naming the first failing check.
248
+ */
249
+ export function checkArtifactStatement(statement, expectedPredicateType, expectedLayerDigest, check) {
250
+ if (statement.predicateType !== expectedPredicateType) {
251
+ throw new ArtifactCorruptError(`chtypes: statement predicateType ${JSON.stringify(statement.predicateType)} != expected ${JSON.stringify(expectedPredicateType)}`);
252
+ }
253
+ const expectedHex = hexOfDigest(expectedLayerDigest);
254
+ if (statement.subject[0]?.digest.sha256 !== expectedHex) {
255
+ throw new ArtifactCorruptError(`chtypes: statement subject digest does not match the manifest's own layer digest`);
256
+ }
257
+ const p = statement.predicate;
258
+ if (p['abi'] !== ABI_GENERATION) {
259
+ throw new ArtifactCorruptError(`chtypes: statement predicate.abi is ${JSON.stringify(p['abi'])}, not ${ABI_GENERATION}`);
260
+ }
261
+ if (p['os'] !== check.os || p['arch'] !== check.arch) {
262
+ throw new ArtifactCorruptError(`chtypes: statement predicate is for ${JSON.stringify(p['os'])}-${JSON.stringify(p['arch'])}, not ${check.os}-${check.arch}`);
263
+ }
264
+ const version = p['clickhouse_version'];
265
+ if (typeof version !== 'string') {
266
+ throw new ArtifactCorruptError(`chtypes: statement predicate.clickhouse_version ${JSON.stringify(version)} is not a string`);
267
+ }
268
+ if (check.requestedSpelling !== undefined && new RegExp(SPELLING_REGEX).test(check.requestedSpelling) && !versionWithinRequest(version, check.requestedSpelling)) {
269
+ throw new ArtifactCorruptError(`chtypes: statement predicate.clickhouse_version ${JSON.stringify(version)} does not lie within requested ${JSON.stringify(check.requestedSpelling)}`);
270
+ }
271
+ return p;
272
+ }
273
+ /**
274
+ * The reduced statement check `fetchSigned` uses for goldens and fixtures
275
+ * (guide §9): predicateType and subject digest only. These objects' own
276
+ * predicate shapes are not yet specified (blocked on the producer, plan
277
+ * §1.2), so `fetchSigned`'s caller reads `statement.predicate` itself.
278
+ */
279
+ export function checkGenericStatement(statement, expectedPredicateType, expectedLayerDigest) {
280
+ if (statement.predicateType !== expectedPredicateType) {
281
+ throw new ArtifactCorruptError(`chtypes: statement predicateType ${JSON.stringify(statement.predicateType)} != expected ${JSON.stringify(expectedPredicateType)}`);
282
+ }
283
+ const expectedHex = hexOfDigest(expectedLayerDigest);
284
+ if (statement.subject[0]?.digest.sha256 !== expectedHex) {
285
+ throw new ArtifactCorruptError("chtypes: statement subject digest does not match the fetched object's own layer digest");
286
+ }
287
+ }
288
+ /**
289
+ * Finds, fetches and verifies a signature for `subjectDigest` within
290
+ * `repositoryRoot`: every referrer-API-or-fallback-tag candidate of
291
+ * `bundleArtifactType` (`referrers.ts`), each one's own manifest-then-layer
292
+ * hop (a referrer is itself a small OCI artifact; its layer blob holds the
293
+ * actual bundle JSON), tried in order until one verifies.
294
+ *
295
+ * `checkContent` is the caller's statement check (`checkArtifactStatement`
296
+ * for the main artifact, `checkGenericStatement` for `fetchSigned`) — it
297
+ * throws `ArtifactCorruptError` on a content mismatch, and that throw
298
+ * propagates immediately, out of this function, without trying further
299
+ * candidates (this module's header explains why).
300
+ *
301
+ * A candidate whose manifest or layer cannot even be fetched is skipped
302
+ * (treated the same as a signature that failed to verify) rather than
303
+ * aborting the whole search — a dangling or unreachable referrer on one
304
+ * mirror should not prevent trying another.
305
+ *
306
+ * Returns `undefined` when no candidate's signature verified under any
307
+ * trusted key at all — the caller raises `ArtifactUntrustedError` (or
308
+ * honors allow-unsigned).
309
+ */
310
+ export async function verifyAnyReferrerBundle(repositoryRoot, subjectDigest, bundleArtifactType, trustedKeys, checkContent, options) {
311
+ const candidates = await discoverSignatureCandidates(repositoryRoot, subjectDigest, bundleArtifactType, options);
312
+ for (const candidate of candidates) {
313
+ let bundleBytes;
314
+ let referrerManifest;
315
+ try {
316
+ referrerManifest = await fetchManifestByDigest([repositoryRoot], candidate.digest, options);
317
+ bundleBytes = await fetchBlobBytesByDigest([repositoryRoot], referrerManifest.layer, options);
318
+ }
319
+ catch {
320
+ continue;
321
+ }
322
+ const verified = verifyBundleSignature(bundleBytes, trustedKeys);
323
+ if (verified === undefined)
324
+ continue;
325
+ const statement = parseStatement(verified.payload);
326
+ checkContent(statement);
327
+ return { statement, signedBy: verified.signedBy, bundleDigest: referrerManifest.layer.digest, bundleManifestDigest: referrerManifest.digest };
328
+ }
329
+ return undefined;
330
+ }
331
+ //# sourceMappingURL=dsse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsse.js","sourceRoot":"","sources":["../../src/ocifetch/dsse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The seam (`docs/guides/fetch-v1.md` §9): `ensure`, `resolveInstalled`,
3
+ * `listInstalled`, `verifyInstalled`, `fetchSigned`. This is the only file
4
+ * that wires resolve (`oci.ts`), trust (`dsse.ts`), bytes (`unpack.ts`), the
5
+ * cache (`layout.ts`) and the lock (`lock.ts`) together; nothing outside
6
+ * `index.ts` calls into those modules directly.
7
+ */
8
+ import type { FetchV1Options, PlatformKey, Resolved, VerifyResult } from './types.js';
9
+ /**
10
+ * Never touches the network (guide §9). The source of truth is the
11
+ * immutable `unpacked/sha256/*\/verified.json` records (guide §6) — never
12
+ * `index.json` directly, though a pre-seeded `index.json` entry with no
13
+ * `verified.json` of its own yet is verified and unpacked from local blobs
14
+ * first (guide §1), exactly once, so every call after the first reads the
15
+ * same way `verified.json`-backed entries always have. Picks the newest
16
+ * match (version, then build, both compared as fixed-width strings per the
17
+ * guide's monotonicity rule) among records whose platform matches and whose
18
+ * `clickhouse_version` lies within `request`.
19
+ */
20
+ export declare function resolveInstalled(request: string, platform: PlatformKey, options?: FetchV1Options): Promise<Resolved | undefined>;
21
+ export declare function listInstalled(options?: FetchV1Options): Promise<readonly Resolved[]>;
22
+ /** Re-checks every installed library's bytes against its own `verified.json` record (guide §9). */
23
+ export declare function verifyInstalled(options?: FetchV1Options): Promise<readonly VerifyResult[]>;
24
+ /**
25
+ * `ensure(request, options)`: resolve unless `frozen` or `offline`, verify
26
+ * trust, download and unpack bytes, install into the cache, optionally write
27
+ * a lock entry. See `docs/guides/fetch-v1.md` §9 for the full contract.
28
+ */
29
+ export declare function ensure(request: string, options?: FetchV1Options): Promise<Resolved>;
30
+ export interface FetchSignedResult {
31
+ readonly path: string;
32
+ readonly statement: unknown;
33
+ readonly digests: {
34
+ readonly manifest: string;
35
+ readonly layer: string;
36
+ };
37
+ }
38
+ /**
39
+ * The generic signed-artifact fetch (guide §9): `repository` is a full
40
+ * repository root (like a base — see `types.ts`'s `endpointUrl`), `ref` a
41
+ * tag or digest. Resolves the manifest, downloads and verifies its single
42
+ * layer, and verifies a referrer bundle of `predicateType` against it —
43
+ * `predicateType` and subject digest only (`checkGenericStatement`): these
44
+ * objects' predicate shapes are not yet specified (blocked on the producer,
45
+ * plan §1.2), so the caller reads `statement.predicate` itself. Returns the
46
+ * verified blob's path on disk (written into this layout's `blobs/`, not
47
+ * unpacked — unpacking is this fetch's caller's job, since goldens and
48
+ * fixtures are not necessarily tarballs).
49
+ *
50
+ * For `predicateType` = `PREDICATE_TYPE_GOLDENS`, `ref` is instead a
51
+ * PLATFORM manifest digest: the registry is append-only, so a corrected
52
+ * goldens set is a second goldens referrer of it, and the result is the
53
+ * highest-`revision` verified one (`goldens.ts`, guide §9).
54
+ */
55
+ export declare function fetchSigned(repository: string, ref: string, predicateType: string, options?: FetchV1Options): Promise<FetchSignedResult>;
56
+ /**
57
+ * The version spellings a repository publishes: `GET tags/list` from the first
58
+ * base that has the repository, every tag that is not a version spelling
59
+ * (`SPELLING_REGEX`: the `sha256-<hex>` referrers fallback tags, symbolic tags)
60
+ * dropped, the rest in ascending numeric order. A tag names a version, not a
61
+ * platform: whether a platform is offered is that tag's index, which only a
62
+ * resolve reads. A next page is followed through the `Link` header.
63
+ */
64
+ export declare function listTags(options?: FetchV1Options): Promise<readonly string[]>;
65
+ //# sourceMappingURL=ensure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure.d.ts","sourceRoot":"","sources":["../../src/ocifetch/ensure.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAyDH,OAAO,KAAK,EAAqB,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAc,YAAY,EAAE,MAAM,YAAY,CAAC;AA6ErH;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAkB/B;AAmFD,wBAAsB,aAAa,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAQ9F;AAID,mGAAmG;AACnG,wBAAsB,eAAe,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAapG;AAID;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0I7F;AAgQD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACzE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA+B5B;AA4HD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CA2CvF"}