@blamejs/blamejs-shop 0.0.127 → 0.0.129

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 (33) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -0
  3. package/lib/storefront.js +235 -6
  4. package/lib/vendor/MANIFEST.json +3 -3
  5. package/lib/vendor/blamejs/CHANGELOG.md +14 -0
  6. package/lib/vendor/blamejs/README.md +7 -1
  7. package/lib/vendor/blamejs/SECURITY.md +3 -0
  8. package/lib/vendor/blamejs/api-snapshot.json +408 -2
  9. package/lib/vendor/blamejs/index.js +6 -0
  10. package/lib/vendor/blamejs/lib/cose.js +212 -4
  11. package/lib/vendor/blamejs/lib/cwt.js +244 -0
  12. package/lib/vendor/blamejs/lib/eat.js +240 -0
  13. package/lib/vendor/blamejs/lib/mdoc.js +305 -0
  14. package/lib/vendor/blamejs/lib/scitt.js +243 -0
  15. package/lib/vendor/blamejs/lib/tsa.js +688 -0
  16. package/lib/vendor/blamejs/lib/vc.js +328 -0
  17. package/lib/vendor/blamejs/package.json +1 -1
  18. package/lib/vendor/blamejs/release-notes/v0.12.34.json +18 -0
  19. package/lib/vendor/blamejs/release-notes/v0.12.35.json +22 -0
  20. package/lib/vendor/blamejs/release-notes/v0.12.36.json +18 -0
  21. package/lib/vendor/blamejs/release-notes/v0.12.37.json +27 -0
  22. package/lib/vendor/blamejs/release-notes/v0.12.38.json +18 -0
  23. package/lib/vendor/blamejs/release-notes/v0.12.39.json +18 -0
  24. package/lib/vendor/blamejs/release-notes/v0.12.40.json +18 -0
  25. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +27 -0
  26. package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +84 -1
  27. package/lib/vendor/blamejs/test/layer-0-primitives/cwt.test.js +137 -0
  28. package/lib/vendor/blamejs/test/layer-0-primitives/eat.test.js +111 -0
  29. package/lib/vendor/blamejs/test/layer-0-primitives/mdoc.test.js +230 -0
  30. package/lib/vendor/blamejs/test/layer-0-primitives/scitt.test.js +158 -0
  31. package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +373 -0
  32. package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +188 -0
  33. package/package.json +1 -1
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /**
3
+ * @module b.scitt
4
+ * @nav Crypto
5
+ * @title SCITT signed statements
6
+ *
7
+ * @intro
8
+ * A SCITT (Supply Chain Integrity, Transparency, and Trust) signed
9
+ * statement is a <code>b.cose</code> COSE_Sign1 that makes a signed,
10
+ * attributable claim <em>about an artifact</em> — a signed SBOM, a
11
+ * build attestation, a release approval. The artifact (or a hash /
12
+ * reference to it) is the payload; the issuer and the subject are
13
+ * carried in the integrity-protected <strong>CWT_Claims</strong>
14
+ * header (label 15, RFC 9597): <code>iss</code> (label 1) is who
15
+ * makes the statement, <code>sub</code> (label 2) is the artifact the
16
+ * statement is about. This module builds and verifies that envelope
17
+ * over <code>b.cose</code> + <code>b.cbor</code>.
18
+ *
19
+ * <code>b.scitt.signStatement(payload, opts)</code> produces the
20
+ * COSE_Sign1, placing <code>iss</code> / <code>sub</code> (plus any
21
+ * extra CWT claims) in the protected CWT_Claims header and declaring
22
+ * the payload media type as the COSE content type.
23
+ * <code>b.scitt.verifyStatement(statement, opts)</code> verifies the
24
+ * signature (delegating the mandatory algorithm allowlist to
25
+ * <code>b.cose.verify</code>), then enforces that a CWT_Claims header
26
+ * with both <code>iss</code> and <code>sub</code> is present —
27
+ * refusing a statement that omits the issuer/subject binding — and
28
+ * optionally checks them against expected values.
29
+ *
30
+ * The signing algorithms are exactly <code>b.cose</code>'s: the
31
+ * classical ES256/384/512 + EdDSA (final COSE ids, interoperable
32
+ * today) and ML-DSA-87 (PQC-forward, draft COSE id). Because the
33
+ * identity binding lives in the protected header it is covered by the
34
+ * signature and cannot be substituted without detection.
35
+ *
36
+ * <strong>Scope.</strong> This is the <em>issuer half</em> of SCITT —
37
+ * producing and verifying signed statements, which is buildable today
38
+ * on finalized RFCs (RFC 9052 COSE, RFC 9597 CWT_Claims header, RFC
39
+ * 8392 iss/sub). The <em>transparency receipt</em> (an inclusion proof
40
+ * from an append-only transparency service, COSE Receipts /
41
+ * draft-ietf-cose-merkle-tree-proofs) and the transparency-service
42
+ * registration protocol (draft-ietf-scitt-*) are deferred until those
43
+ * drafts publish — a signed statement produced here is the input a
44
+ * transparency service registers, and the receipt format is the part
45
+ * still in flux. Re-open on COSE-Receipts publication.
46
+ *
47
+ * @card
48
+ * SCITT signed statements (RFC 9052 COSE + RFC 9597 CWT_Claims) — a
49
+ * signed, issuer/subject-bound claim about an artifact (SBOM /
50
+ * attestation / approval). Composes b.cose; transparency receipts
51
+ * deferred to the COSE-Receipts draft.
52
+ */
53
+
54
+ var cose = require("./cose");
55
+ var validateOpts = require("./validate-opts");
56
+ var { defineClass } = require("./framework-error");
57
+
58
+ var ScittError = defineClass("ScittError", { alwaysPermanent: true });
59
+
60
+ // CWT_Claims header label (RFC 9597) and the two SCITT-required claim
61
+ // labels inside it (RFC 8392 §3.1.1): iss = who states, sub = about what.
62
+ var HDR_CWT_CLAIMS = 15;
63
+ var CLAIM_ISS = 1;
64
+ var CLAIM_SUB = 2;
65
+
66
+ function _requireNonEmptyString(v, name) {
67
+ if (typeof v !== "string" || v.length === 0) {
68
+ throw new ScittError("scitt/bad-" + name,
69
+ "scitt.signStatement: opts." + name + " is required and must be a non-empty string");
70
+ }
71
+ }
72
+
73
+ /**
74
+ * @primitive b.scitt.signStatement
75
+ * @signature b.scitt.signStatement(payload, opts)
76
+ * @since 0.12.37
77
+ * @status experimental
78
+ * @compliance soc2, cra
79
+ * @related b.scitt.verifyStatement, b.cose.sign
80
+ *
81
+ * Produce a SCITT signed statement: a COSE_Sign1 over
82
+ * <code>payload</code> (the artifact bytes, or a hash / reference to
83
+ * it) whose integrity-protected CWT_Claims header (label 15) binds the
84
+ * issuer (<code>iss</code>) and subject (<code>sub</code>). Declare the
85
+ * payload media type via <code>contentType</code> so a consumer knows
86
+ * how to interpret it.
87
+ *
88
+ * @opts
89
+ * {
90
+ * alg: string, // b.cose alg: "ES256" | … | "ML-DSA-87"
91
+ * privateKey: object, // matching KeyObject or PEM
92
+ * issuer: string, // → CWT_Claims iss (label 1) — who makes the statement
93
+ * subject: string, // → CWT_Claims sub (label 2) — the artifact the statement is about
94
+ * contentType?: number|string, // payload media type (e.g. "application/spdx+json")
95
+ * claims?: object, // extra CWT claims by integer label, merged into CWT_Claims
96
+ * kid?: string, // → unprotected header label 4
97
+ * externalAad?: Buffer, // bound into the signature
98
+ * }
99
+ *
100
+ * @example
101
+ * var stmt = await b.scitt.signStatement(sbomBytes, {
102
+ * alg: "ES256", privateKey: issuerKey,
103
+ * issuer: "https://builder.example", subject: "pkg:npm/widget@1.2.3",
104
+ * contentType: "application/spdx+json",
105
+ * });
106
+ */
107
+ async function signStatement(payload, opts) {
108
+ validateOpts.requireObject(opts, "scitt.signStatement", ScittError);
109
+ validateOpts(opts,
110
+ ["alg", "privateKey", "issuer", "subject", "contentType", "claims", "kid", "externalAad"],
111
+ "scitt.signStatement");
112
+ _requireNonEmptyString(opts.issuer, "issuer");
113
+ _requireNonEmptyString(opts.subject, "subject");
114
+
115
+ var cwtClaims = new Map();
116
+ cwtClaims.set(CLAIM_ISS, opts.issuer);
117
+ cwtClaims.set(CLAIM_SUB, opts.subject);
118
+ // Extra CWT claims (e.g. iat = 6, a registration-policy claim) keyed
119
+ // by their integer label. iss / sub are managed via opts.issuer /
120
+ // opts.subject and cannot be overridden here.
121
+ if (opts.claims && typeof opts.claims === "object") {
122
+ var ck = opts.claims instanceof Map ? Array.from(opts.claims.keys()) : Object.keys(opts.claims);
123
+ for (var i = 0; i < ck.length; i++) {
124
+ var label = Number(ck[i]);
125
+ if (!Number.isInteger(label)) {
126
+ throw new ScittError("scitt/bad-claim-label",
127
+ "scitt.signStatement: claims keys must be integer CWT claim labels");
128
+ }
129
+ if (label === CLAIM_ISS || label === CLAIM_SUB) {
130
+ throw new ScittError("scitt/reserved-claim",
131
+ "scitt.signStatement: set iss / sub via opts.issuer / opts.subject, not opts.claims");
132
+ }
133
+ var val = opts.claims instanceof Map ? opts.claims.get(ck[i]) : opts.claims[ck[i]];
134
+ cwtClaims.set(label, val);
135
+ }
136
+ }
137
+
138
+ var protectedHeaders = {};
139
+ protectedHeaders[HDR_CWT_CLAIMS] = cwtClaims;
140
+
141
+ return cose.sign(payload, {
142
+ alg: opts.alg,
143
+ privateKey: opts.privateKey,
144
+ kid: opts.kid,
145
+ contentType: opts.contentType,
146
+ externalAad: opts.externalAad,
147
+ protectedHeaders: protectedHeaders,
148
+ });
149
+ }
150
+
151
+ /**
152
+ * @primitive b.scitt.verifyStatement
153
+ * @signature b.scitt.verifyStatement(statement, opts)
154
+ * @since 0.12.37
155
+ * @status experimental
156
+ * @compliance soc2, cra
157
+ * @related b.scitt.signStatement, b.cose.verify
158
+ *
159
+ * Verify a SCITT signed statement and return its payload + identity
160
+ * binding. The COSE signature is checked through
161
+ * <code>b.cose.verify</code> (the algorithm allowlist is mandatory); a
162
+ * statement that does not carry a CWT_Claims header with both
163
+ * <code>iss</code> and <code>sub</code> is refused — that binding is
164
+ * what makes it a SCITT statement rather than a bare COSE_Sign1.
165
+ * <code>expectedIssuer</code> / <code>expectedSubject</code>, when
166
+ * given, must match.
167
+ *
168
+ * @opts
169
+ * {
170
+ * algorithms: string[], // required — accepted alg names (allowlist)
171
+ * publicKey?: object, // verification key (KeyObject / PEM)
172
+ * keyResolver?: function, // (protectedHeaders, unprotectedHeaders) → key
173
+ * expectedIssuer?: string, // require iss === this
174
+ * expectedSubject?: string, // require sub === this
175
+ * externalAad?: Buffer, // must match what was signed
176
+ * maxBytes?: number, // forwarded to b.cose.verify → b.cbor.decode
177
+ * maxDepth?: number,
178
+ * }
179
+ *
180
+ * @example
181
+ * var out = await b.scitt.verifyStatement(stmt, {
182
+ * algorithms: ["ES256"], publicKey: issuerPub,
183
+ * expectedSubject: "pkg:npm/widget@1.2.3",
184
+ * });
185
+ * // → { payload: <Buffer>, issuer, subject, cwtClaims: Map, alg, protectedHeaders, unprotectedHeaders }
186
+ */
187
+ async function verifyStatement(statement, opts) {
188
+ validateOpts.requireObject(opts, "scitt.verifyStatement", ScittError);
189
+ validateOpts(opts,
190
+ ["algorithms", "publicKey", "keyResolver", "expectedIssuer", "expectedSubject",
191
+ "externalAad", "maxBytes", "maxDepth"],
192
+ "scitt.verifyStatement");
193
+
194
+ var out = await cose.verify(statement, {
195
+ algorithms: opts.algorithms,
196
+ publicKey: opts.publicKey,
197
+ keyResolver: opts.keyResolver,
198
+ externalAad: opts.externalAad,
199
+ maxBytes: opts.maxBytes,
200
+ maxDepth: opts.maxDepth,
201
+ });
202
+
203
+ var cwtClaims = out.protectedHeaders.get(HDR_CWT_CLAIMS);
204
+ if (!(cwtClaims instanceof Map)) {
205
+ throw new ScittError("scitt/missing-cwt-claims",
206
+ "scitt.verifyStatement: no CWT_Claims header (label 15) — not a SCITT signed statement");
207
+ }
208
+ var issuer = cwtClaims.get(CLAIM_ISS);
209
+ var subject = cwtClaims.get(CLAIM_SUB);
210
+ if (issuer === undefined || issuer === null) {
211
+ throw new ScittError("scitt/missing-issuer",
212
+ "scitt.verifyStatement: CWT_Claims has no iss (label 1)");
213
+ }
214
+ if (subject === undefined || subject === null) {
215
+ throw new ScittError("scitt/missing-subject",
216
+ "scitt.verifyStatement: CWT_Claims has no sub (label 2)");
217
+ }
218
+ if (opts.expectedIssuer !== undefined && issuer !== opts.expectedIssuer) {
219
+ throw new ScittError("scitt/issuer-mismatch",
220
+ "scitt.verifyStatement: iss does not match expectedIssuer");
221
+ }
222
+ if (opts.expectedSubject !== undefined && subject !== opts.expectedSubject) {
223
+ throw new ScittError("scitt/subject-mismatch",
224
+ "scitt.verifyStatement: sub does not match expectedSubject");
225
+ }
226
+
227
+ return {
228
+ payload: out.payload,
229
+ issuer: issuer,
230
+ subject: subject,
231
+ cwtClaims: cwtClaims,
232
+ alg: out.alg,
233
+ protectedHeaders: out.protectedHeaders,
234
+ unprotectedHeaders: out.unprotectedHeaders,
235
+ };
236
+ }
237
+
238
+ module.exports = {
239
+ signStatement: signStatement,
240
+ verifyStatement: verifyStatement,
241
+ CWT_CLAIMS_LABEL: HDR_CWT_CLAIMS,
242
+ ScittError: ScittError,
243
+ };