@blamejs/blamejs-shop 0.1.0 → 0.1.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 (33) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +2 -2
  3. package/lib/admin.js +299 -7
  4. package/lib/payment.js +27 -0
  5. package/lib/storefront.js +25 -6
  6. package/lib/vendor/MANIFEST.json +2 -2
  7. package/lib/vendor/blamejs/CHANGELOG.md +14 -0
  8. package/lib/vendor/blamejs/README.md +6 -5
  9. package/lib/vendor/blamejs/SECURITY.md +2 -0
  10. package/lib/vendor/blamejs/api-snapshot.json +166 -3
  11. package/lib/vendor/blamejs/lib/cose.js +284 -10
  12. package/lib/vendor/blamejs/lib/crypto.js +119 -0
  13. package/lib/vendor/blamejs/lib/did.js +69 -20
  14. package/lib/vendor/blamejs/lib/mdoc.js +122 -0
  15. package/lib/vendor/blamejs/lib/network-dnssec.js +328 -0
  16. package/lib/vendor/blamejs/lib/network.js +1 -0
  17. package/lib/vendor/blamejs/lib/vc.js +231 -33
  18. package/lib/vendor/blamejs/package.json +1 -1
  19. package/lib/vendor/blamejs/release-notes/v0.12.42.json +18 -0
  20. package/lib/vendor/blamejs/release-notes/v0.12.43.json +18 -0
  21. package/lib/vendor/blamejs/release-notes/v0.12.44.json +18 -0
  22. package/lib/vendor/blamejs/release-notes/v0.12.45.json +18 -0
  23. package/lib/vendor/blamejs/release-notes/v0.12.46.json +18 -0
  24. package/lib/vendor/blamejs/release-notes/v0.12.47.json +18 -0
  25. package/lib/vendor/blamejs/release-notes/v0.12.48.json +22 -0
  26. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +38 -1
  27. package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +101 -2
  28. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-self-test.test.js +74 -0
  29. package/lib/vendor/blamejs/test/layer-0-primitives/did.test.js +29 -0
  30. package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +130 -0
  31. package/lib/vendor/blamejs/test/layer-0-primitives/mdoc.test.js +52 -0
  32. package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +63 -0
  33. package/package.json +1 -1
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+ /**
3
+ * @module b.network.dns.dnssec
4
+ * @nav Network
5
+ * @title DNSSEC validation
6
+ *
7
+ * @intro
8
+ * Local DNSSEC signature verification (RFC 4033–4035 / 6605 / 8080) —
9
+ * the cryptographic core that lets a resolver client verify a DNS
10
+ * answer itself instead of trusting the upstream resolver's AD bit.
11
+ * <code>b.network.dns.resolver</code> checks the AD flag; this module
12
+ * verifies the actual RRSIG signature over the canonicalised RRset,
13
+ * defending against a compromised or on-path resolver.
14
+ *
15
+ * <code>verifyRrset</code> reconstructs the RFC 4034 §3.1.8.1 signed
16
+ * data (the RRSIG RDATA without the signature, followed by the RRset
17
+ * in canonical form — owner names lowercased, RRs ordered by canonical
18
+ * RDATA, the RRSIG's Original TTL) and verifies it with the DNSKEY,
19
+ * enforcing the signature's inception / expiration window. The DNSKEY
20
+ * algorithms are RSA/SHA-256 (8), ECDSA P-256/SHA-256 (13), ECDSA
21
+ * P-384/SHA-384 (14), and Ed25519 (15) — the modern, deployed set.
22
+ * <code>verifyDs</code> checks a delegation-signer digest against a
23
+ * DNSKEY (SHA-256 / SHA-384), and <code>keyTag</code> computes the
24
+ * RFC 4034 Appendix B key tag.
25
+ *
26
+ * <strong>Scope.</strong> This is the verification core. RR types that
27
+ * carry domain names in their RDATA (NS, CNAME, SOA, MX, SRV, …) need
28
+ * name-lowercasing inside the RDATA (RFC 4034 §6.2) that this version
29
+ * does not perform, so they are refused with
30
+ * <code>dnssec/uncanonicalizable-type</code> rather than mis-validated
31
+ * — the security-critical DNSKEY / DS and the name-free address /
32
+ * text types (A, AAAA, TXT, …) are fully supported. The recursive
33
+ * chain-walk (root → TLD → zone), NSEC / NSEC3 denial-of-existence,
34
+ * and the IANA root trust-anchor bundle are deferred: these primitives
35
+ * are the per-RRset building blocks a chain-walker composes.
36
+ *
37
+ * @card
38
+ * Local DNSSEC verification (RFC 4035) — verify an RRSIG over a
39
+ * canonicalised RRset against a DNSKEY (RSA / ECDSA P-256·P-384 /
40
+ * Ed25519), plus DS-digest + key-tag. Don't trust the upstream AD bit;
41
+ * verify the signature. Name-bearing RR types are refused, not
42
+ * mis-validated; chain-walk + NSEC3 deferred.
43
+ */
44
+
45
+ var nodeCrypto = require("node:crypto");
46
+ var bCrypto = require("./crypto");
47
+ var validateOpts = require("./validate-opts");
48
+ var { defineClass } = require("./framework-error");
49
+
50
+ var DnssecError = defineClass("DnssecError", { alwaysPermanent: true });
51
+
52
+ // DNSSEC algorithm numbers (IANA DNSSEC Algorithm Numbers) → verify params.
53
+ var ALGS = {
54
+ 8: { name: "RSASHA256", kind: "rsa", hash: "sha256" }, // allow:raw-byte-literal — IANA DNSSEC algorithm number
55
+ 13: { name: "ECDSAP256SHA256", kind: "ec", hash: "sha256", crv: "P-256", coord: 32 }, // allow:raw-byte-literal — P-256 coordinate size
56
+ 14: { name: "ECDSAP384SHA384", kind: "ec", hash: "sha384", crv: "P-384", coord: 48 }, // allow:raw-byte-literal — P-384 coordinate size
57
+ 15: { name: "ED25519", kind: "okp", hash: null, crv: "Ed25519" },
58
+ };
59
+
60
+ // DS digest algorithms (IANA) → node hash.
61
+ var DS_DIGESTS = { 2: "sha256", 4: "sha384" };
62
+
63
+ // RR types whose RDATA contains NO embedded domain name, so the wire
64
+ // RDATA is already in canonical form (RFC 4034 §6.2 needs no rewrite).
65
+ // Name-bearing types are refused rather than silently mis-canonicalised.
66
+ // (type numbers IANA): A 1, AAAA 28, TXT 16, DNSKEY 48, DS 43, CAA 257,
67
+ // TLSA 52, SSHFP 44, HINFO 13, CDS 59, CDNSKEY 60, OPENPGPKEY 61, SMIMEA 53.
68
+ var NAME_FREE_TYPE_NUMS = [1, 28, 16, 48, 43, 257, 52, 44, 13, 59, 60, 61, 53]; // allow:raw-byte-literal allow:raw-time-literal — IANA DNS type numbers (no embedded names)
69
+ var TYPE_NUM = {
70
+ A: 1, NS: 2, CNAME: 5, SOA: 6, PTR: 12, MX: 15, TXT: 16, AAAA: 28, SRV: 33,
71
+ DS: 43, SSHFP: 44, RRSIG: 46, DNSKEY: 48, TLSA: 52, SMIMEA: 53, CDS: 59, CDNSKEY: 60, // allow:raw-byte-literal allow:raw-time-literal — IANA DNS type numbers
72
+ OPENPGPKEY: 61, CAA: 257, HINFO: 13,
73
+ };
74
+
75
+ function _bytes(x, what) {
76
+ if (Buffer.isBuffer(x)) return x;
77
+ if (x instanceof Uint8Array) return Buffer.from(x);
78
+ throw new DnssecError("dnssec/bad-bytes", "dnssec: " + what + " must be a Buffer");
79
+ }
80
+
81
+ // Canonical wire form of a domain name (RFC 4034 §6.2): each label
82
+ // length-prefixed, ASCII lowercased, terminated by the root label.
83
+ function _canonicalName(name) {
84
+ if (typeof name !== "string") throw new DnssecError("dnssec/bad-name", "dnssec: name must be a string");
85
+ var n = name.replace(/\.$/, "");
86
+ if (n === "") return Buffer.from([0]);
87
+ var labels = n.split(".");
88
+ var parts = [];
89
+ for (var i = 0; i < labels.length; i++) {
90
+ var lab = Buffer.from(labels[i].toLowerCase(), "ascii");
91
+ if (lab.length === 0 || lab.length > 63) { // allow:raw-byte-literal — DNS label length cap (RFC 1035)
92
+ throw new DnssecError("dnssec/bad-name", "dnssec: invalid label in '" + name + "'");
93
+ }
94
+ parts.push(Buffer.from([lab.length]), lab);
95
+ }
96
+ parts.push(Buffer.from([0]));
97
+ return Buffer.concat(parts);
98
+ }
99
+
100
+ function _u16(n) { return Buffer.from([(n >> 8) & 0xff, n & 0xff]); } // allow:raw-byte-literal — 16-bit big-endian split
101
+ function _u32(n) {
102
+ var b = Buffer.alloc(4);
103
+ b.writeUInt32BE(n >>> 0, 0);
104
+ return b;
105
+ }
106
+ function _typeNumber(type) {
107
+ if (typeof type === "number") return type;
108
+ var t = TYPE_NUM[String(type).toUpperCase()];
109
+ if (t === undefined) throw new DnssecError("dnssec/unknown-type", "dnssec: unknown RR type '" + type + "'");
110
+ return t;
111
+ }
112
+
113
+ // DNSKEY public-key RDATA → JWK (kty/crv allowlisted; RFC 3110 RSA,
114
+ // RFC 6605 ECDSA, RFC 8080 Ed25519). publicKey is the key bytes after
115
+ // the DNSKEY flags/protocol/algorithm fields.
116
+ function _dnskeyToKey(algId, publicKey) {
117
+ var alg = ALGS[algId];
118
+ if (!alg) throw new DnssecError("dnssec/unsupported-alg", "dnssec: unsupported DNSKEY algorithm " + algId);
119
+ var pk = _bytes(publicKey, "dnskey publicKey");
120
+ if (alg.kind === "rsa") {
121
+ // RFC 3110: exponent length is 1 byte, or (if that byte is 0) the
122
+ // next 2 bytes; then exponent, then modulus.
123
+ var off = 0, explen = pk[0];
124
+ off = 1;
125
+ if (explen === 0) { explen = (pk[1] << 8) | pk[2]; off = 3; } // allow:raw-byte-literal — RFC 3110 3-byte exponent length
126
+ if (explen === 0 || off + explen >= pk.length) {
127
+ throw new DnssecError("dnssec/bad-key", "dnssec: malformed RSA DNSKEY public key");
128
+ }
129
+ var exponent = pk.slice(off, off + explen);
130
+ var modulus = pk.slice(off + explen);
131
+ return _jwkKey({ kty: "RSA", n: modulus.toString("base64url"), e: exponent.toString("base64url") });
132
+ }
133
+ if (alg.kind === "ec") {
134
+ if (pk.length !== alg.coord * 2) {
135
+ throw new DnssecError("dnssec/bad-key", "dnssec: " + alg.crv + " key must be " + (alg.coord * 2) + " bytes (x||y)");
136
+ }
137
+ return _jwkKey({ kty: "EC", crv: alg.crv, x: pk.slice(0, alg.coord).toString("base64url"), y: pk.slice(alg.coord).toString("base64url") });
138
+ }
139
+ // Ed25519
140
+ if (pk.length !== 32) throw new DnssecError("dnssec/bad-key", "dnssec: Ed25519 key must be 32 bytes"); // allow:raw-byte-literal — Ed25519 key size
141
+ return _jwkKey({ kty: "OKP", crv: "Ed25519", x: pk.toString("base64url") });
142
+ }
143
+ function _jwkKey(jwk) {
144
+ try { return nodeCrypto.createPublicKey({ key: jwk, format: "jwk" }); }
145
+ catch (e) { throw new DnssecError("dnssec/bad-key", "dnssec: could not import DNSKEY: " + ((e && e.message) || e)); }
146
+ }
147
+
148
+ /**
149
+ * @primitive b.network.dns.dnssec.keyTag
150
+ * @signature b.network.dns.dnssec.keyTag(dnskeyRdata)
151
+ * @since 0.12.48
152
+ * @status stable
153
+ * @related b.network.dns.dnssec.verifyDs, b.network.dns.dnssec.verifyRrset
154
+ *
155
+ * Compute the RFC 4034 Appendix B key tag of a DNSKEY from its full
156
+ * RDATA (flags || protocol || algorithm || public key) — the 16-bit
157
+ * identifier an RRSIG / DS references to select the signing key.
158
+ *
159
+ * @example
160
+ * var tag = b.network.dns.dnssec.keyTag(dnskeyRdata);
161
+ */
162
+ function keyTag(dnskeyRdata) {
163
+ var rd = _bytes(dnskeyRdata, "dnskeyRdata");
164
+ var acc = 0;
165
+ for (var i = 0; i < rd.length; i++) {
166
+ acc += (i & 1) ? rd[i] : (rd[i] << 8); // allow:raw-byte-literal — RFC 4034 App B key-tag accumulation
167
+ }
168
+ acc += (acc >> 16) & 0xffff; // allow:raw-byte-literal — App B fold
169
+ return acc & 0xffff; // allow:raw-byte-literal — App B 16-bit tag
170
+ }
171
+
172
+ /**
173
+ * @primitive b.network.dns.dnssec.verifyDs
174
+ * @signature b.network.dns.dnssec.verifyDs(opts)
175
+ * @since 0.12.48
176
+ * @status stable
177
+ * @related b.network.dns.dnssec.verifyRrset
178
+ *
179
+ * Verify a DS (Delegation Signer) record against a child DNSKEY — the
180
+ * link that lets a parent zone vouch for a child's key. The DS digest
181
+ * (SHA-256 / SHA-384) is recomputed over the owner name plus the DNSKEY
182
+ * RDATA and compared to the DS, with the key tag and algorithm checked.
183
+ *
184
+ * @opts
185
+ * {
186
+ * ownerName: string, // the child zone name (the DNSKEY owner)
187
+ * dnskeyRdata: Buffer, // full DNSKEY RDATA (flags||protocol||alg||publicKey)
188
+ * ds: { keyTag, algorithm, digestType, digest: Buffer }, // the parent DS
189
+ * }
190
+ *
191
+ * @example
192
+ * b.network.dns.dnssec.verifyDs({ ownerName: "example.com", dnskeyRdata: ksk, ds: parentDs });
193
+ */
194
+ function verifyDs(opts) {
195
+ validateOpts.requireObject(opts, "dnssec.verifyDs", DnssecError);
196
+ validateOpts(opts, ["ownerName", "dnskeyRdata", "ds"], "dnssec.verifyDs");
197
+ var ds = opts.ds;
198
+ if (!ds || typeof ds !== "object") throw new DnssecError("dnssec/bad-ds", "dnssec.verifyDs: opts.ds is required");
199
+ var hashName = DS_DIGESTS[ds.digestType];
200
+ if (!hashName) throw new DnssecError("dnssec/unsupported-digest", "dnssec.verifyDs: unsupported DS digest type " + ds.digestType);
201
+ var rd = _bytes(opts.dnskeyRdata, "dnskeyRdata");
202
+ if (keyTag(rd) !== ds.keyTag) {
203
+ throw new DnssecError("dnssec/keytag-mismatch", "dnssec.verifyDs: DNSKEY key tag does not match the DS");
204
+ }
205
+ var digestInput = Buffer.concat([_canonicalName(opts.ownerName), rd]);
206
+ var expected = nodeCrypto.createHash(hashName).update(digestInput).digest();
207
+ var actual = _bytes(ds.digest, "ds.digest");
208
+ if (!bCrypto.timingSafeEqual(expected, actual)) {
209
+ throw new DnssecError("dnssec/ds-mismatch", "dnssec.verifyDs: DS digest does not match the DNSKEY");
210
+ }
211
+ return { ok: true, keyTag: ds.keyTag, digestType: ds.digestType };
212
+ }
213
+
214
+ /**
215
+ * @primitive b.network.dns.dnssec.verifyRrset
216
+ * @signature b.network.dns.dnssec.verifyRrset(opts)
217
+ * @since 0.12.48
218
+ * @status stable
219
+ * @compliance soc2
220
+ * @related b.network.dns.dnssec.verifyDs, b.network.dns.resolver.create
221
+ *
222
+ * Verify an RRSIG over an RRset against a DNSKEY (RFC 4035 §5.3). The
223
+ * signed data is reconstructed in canonical form — the RRSIG RDATA
224
+ * without the signature, then the RRset's records ordered by canonical
225
+ * RDATA with the RRSIG Original TTL — and the signature is verified with
226
+ * the DNSKEY (RSA/SHA-256, ECDSA P-256/384, Ed25519). The signature's
227
+ * inception / expiration window is enforced against <code>opts.at</code>.
228
+ * RR types carrying embedded domain names are refused
229
+ * (<code>dnssec/uncanonicalizable-type</code>) rather than mis-validated.
230
+ *
231
+ * @opts
232
+ * {
233
+ * name: string, // owner name of the RRset
234
+ * type: string|number, // RR type (e.g. "DNSKEY", "A")
235
+ * class?: number, // default 1 (IN)
236
+ * rdatas: Buffer[], // each record's wire-format RDATA
237
+ * rrsig: { // the RRSIG covering the RRset
238
+ * algorithm, labels, originalTtl, expiration, inception, keyTag,
239
+ * signerName: string, signature: Buffer,
240
+ * },
241
+ * dnskey: { algorithm, publicKey: Buffer }, // the signing DNSKEY (publicKey = bytes after flags/proto/alg)
242
+ * at?: Date, // validity instant (default now); must be a valid Date
243
+ * }
244
+ *
245
+ * @example
246
+ * b.network.dns.dnssec.verifyRrset({ name: "example.com", type: "DNSKEY", rdatas: keys, rrsig: sig, dnskey: ksk });
247
+ */
248
+ function verifyRrset(opts) {
249
+ validateOpts.requireObject(opts, "dnssec.verifyRrset", DnssecError);
250
+ validateOpts(opts, ["name", "type", "class", "rdatas", "rrsig", "dnskey", "at"], "dnssec.verifyRrset");
251
+ var rrsig = opts.rrsig;
252
+ var dnskey = opts.dnskey;
253
+ if (!rrsig || typeof rrsig !== "object") throw new DnssecError("dnssec/bad-rrsig", "dnssec.verifyRrset: opts.rrsig is required");
254
+ if (!dnskey || typeof dnskey !== "object") throw new DnssecError("dnssec/bad-key", "dnssec.verifyRrset: opts.dnskey is required");
255
+ if (!Array.isArray(opts.rdatas) || opts.rdatas.length === 0) {
256
+ throw new DnssecError("dnssec/empty-rrset", "dnssec.verifyRrset: opts.rdatas must be a non-empty array");
257
+ }
258
+ var alg = ALGS[rrsig.algorithm];
259
+ if (!alg) throw new DnssecError("dnssec/unsupported-alg", "dnssec.verifyRrset: unsupported algorithm " + rrsig.algorithm);
260
+ if (dnskey.algorithm !== rrsig.algorithm) {
261
+ throw new DnssecError("dnssec/alg-mismatch", "dnssec.verifyRrset: DNSKEY algorithm does not match the RRSIG");
262
+ }
263
+
264
+ var typeNum = _typeNumber(opts.type);
265
+ if (NAME_FREE_TYPE_NUMS.indexOf(typeNum) === -1) {
266
+ throw new DnssecError("dnssec/uncanonicalizable-type",
267
+ "dnssec.verifyRrset: RR type " + typeNum + " carries embedded names; RDATA-name canonicalisation is not supported (refused, not mis-validated)");
268
+ }
269
+
270
+ // Validity window (fail closed on a bad opts.at).
271
+ var atMs;
272
+ if (opts.at !== undefined && opts.at !== null) {
273
+ if (!(opts.at instanceof Date) || !isFinite(opts.at.getTime())) {
274
+ throw new DnssecError("dnssec/bad-at", "dnssec.verifyRrset: opts.at must be a valid Date");
275
+ }
276
+ atMs = opts.at.getTime();
277
+ } else {
278
+ atMs = Date.now();
279
+ }
280
+ var nowSec = Math.floor(atMs / 1000); // allow:raw-time-literal — ms→NumericDate seconds (RRSIG inception/expiration are seconds since epoch, RFC 4034 §3.1.5)
281
+ if (nowSec < (rrsig.inception >>> 0)) throw new DnssecError("dnssec/not-yet-valid", "dnssec.verifyRrset: RRSIG inception is in the future");
282
+ if (nowSec > (rrsig.expiration >>> 0)) throw new DnssecError("dnssec/expired", "dnssec.verifyRrset: RRSIG has expired");
283
+
284
+ var klass = typeof opts.class === "number" ? opts.class : 1;
285
+ var ownerWire = _canonicalName(opts.name);
286
+ var ttl = _u32(rrsig.originalTtl);
287
+
288
+ // Canonical RRset (RFC 4034 §6.3): order records by canonical RDATA.
289
+ var rdatas = opts.rdatas.map(function (r, i) { return _bytes(r, "rdatas[" + i + "]"); });
290
+ var sorted = rdatas.slice().sort(Buffer.compare);
291
+ var rrParts = [];
292
+ for (var i = 0; i < sorted.length; i++) {
293
+ rrParts.push(ownerWire, _u16(typeNum), _u16(klass), ttl, _u16(sorted[i].length), sorted[i]);
294
+ }
295
+
296
+ // RRSIG RDATA without the signature (RFC 4034 §3.1.8.1).
297
+ var rrsigPrefix = Buffer.concat([
298
+ _u16(typeNum), Buffer.from([rrsig.algorithm & 0xff, rrsig.labels & 0xff]), // allow:raw-byte-literal — single-octet alg + labels fields
299
+ _u32(rrsig.originalTtl), _u32(rrsig.expiration), _u32(rrsig.inception),
300
+ _u16(rrsig.keyTag), _canonicalName(rrsig.signerName),
301
+ ]);
302
+ var signedData = Buffer.concat([rrsigPrefix].concat(rrParts));
303
+
304
+ var key = _dnskeyToKey(dnskey.algorithm, dnskey.publicKey);
305
+ var signature = _bytes(rrsig.signature, "rrsig.signature");
306
+ var ok;
307
+ try {
308
+ if (alg.kind === "okp") {
309
+ ok = nodeCrypto.verify(null, signedData, key, signature);
310
+ } else if (alg.kind === "ec") {
311
+ ok = nodeCrypto.verify(alg.hash, signedData, { key: key, dsaEncoding: "ieee-p1363" }, signature);
312
+ } else {
313
+ ok = nodeCrypto.verify(alg.hash, signedData, key, signature);
314
+ }
315
+ } catch (e) {
316
+ throw new DnssecError("dnssec/verify-threw", "dnssec.verifyRrset: signature verification threw: " + ((e && e.message) || e));
317
+ }
318
+ if (!ok) throw new DnssecError("dnssec/bad-signature", "dnssec.verifyRrset: RRSIG signature did not verify");
319
+ return { ok: true, algorithm: alg.name, keyTag: rrsig.keyTag, signerName: rrsig.signerName };
320
+ }
321
+
322
+ module.exports = {
323
+ verifyRrset: verifyRrset,
324
+ verifyDs: verifyDs,
325
+ keyTag: keyTag,
326
+ ALGORITHMS: ALGS,
327
+ DnssecError: DnssecError,
328
+ };
@@ -35,6 +35,7 @@ var ntpCheck = require("./ntp-check");
35
35
  var nts = require("./network-nts");
36
36
  var networkDns = require("./network-dns");
37
37
  networkDns.resolver = require("./network-dns-resolver");
38
+ networkDns.dnssec = require("./network-dnssec");
38
39
  var networkProxy = require("./network-proxy");
39
40
  var networkTls = require("./network-tls");
40
41
  var heartbeat = require("./network-heartbeat");