@blamejs/pki 0.5.37 → 0.5.38
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.
- package/CHANGELOG.md +9 -1
- package/lib/cmc-build.js +6 -3
- package/lib/cms-encrypt.js +12 -4
- package/lib/crl-sign.js +8 -6
- package/lib/crmf-sign.js +2 -1
- package/lib/ocsp.js +5 -2
- package/lib/pkcs12-build.js +8 -3
- package/lib/pki-build.js +38 -18
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,15 @@ All notable changes to `@blamejs/pki` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## v0.5.
|
|
7
|
+
## v0.5.38 — 2026-08-30
|
|
8
|
+
|
|
9
|
+
Builder verbs reject a sparse or nullish array argument with a typed error instead of a native one.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- The array arguments of pki.pkcs12.build (SafeContents bags), pki.ocsp.buildRequest and pki.ocsp.sign (the query and response batches), pki.cmc.build (requests and the CMS and other-message sequences), pki.crl.sign (revoked entries and the issuing-distribution-point and freshest-CRL general names), pki.crmf.build (controls and registration info), and pki.cms.encrypt (authenticated attributes) are checked for holes and nullish entries up front. A sparse or nullish array is now the verb's own typed `<domain>/bad-input` error naming the index, in place of the native `TypeError` the hole previously produced at the encoder. A valid (dense) array is unaffected and its emitted structure is byte-for-byte identical.
|
|
14
|
+
|
|
15
|
+
## v0.5.37 — 2026-08-29
|
|
8
16
|
|
|
9
17
|
pki.cms.decrypt can return the recovered content as an async iterable of plaintext chunks.
|
|
10
18
|
|
package/lib/cmc-build.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
var nodeCrypto = require("node:crypto");
|
|
29
29
|
var asn1 = require("./asn1-der");
|
|
30
|
+
var pkiBuild = require("./pki-build"); // reqDenseArray: reject a sparse/nullish caller array as a typed cmc/bad-input
|
|
30
31
|
var csr = require("./schema-csr"); // to read the Subject Key Identifier a tcr request declares
|
|
31
32
|
var crmf = require("./schema-crmf"); // ... and the one a crm request declares
|
|
32
33
|
var cmcFmt = require("./schema-cmc"); // to read the assembled message back before signing it
|
|
@@ -510,7 +511,9 @@ function _build(spec, signer, opts) {
|
|
|
510
511
|
// them has no replay defense, and pki.cmc.verify cannot enforce a binding the
|
|
511
512
|
// client never sent, so the omission is invisible from both ends.
|
|
512
513
|
guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, E, "cmc/bad-input", "unknown spec field ");
|
|
513
|
-
|
|
514
|
+
// Density up front: requests is iterated by both the forEach below and the map that encodes it, and a
|
|
515
|
+
// hole would survive either (map/forEach skip it) to reach b.sequence as a native error.
|
|
516
|
+
var requests = spec.requests != null ? pkiBuild.reqDenseArray(spec.requests, "requests", E, "cmc/bad-input") : [];
|
|
514
517
|
if (!Array.isArray(requests)) throw E("cmc/bad-input", "spec.requests must be an array");
|
|
515
518
|
var callerControls = spec.controls || [];
|
|
516
519
|
if (!Array.isArray(callerControls)) throw E("cmc/bad-input", "spec.controls must be an array");
|
|
@@ -532,10 +535,10 @@ function _build(spec, signer, opts) {
|
|
|
532
535
|
var fixed = fixedRequestId(r, i);
|
|
533
536
|
if (fixed != null) ids.reserve(fixed, "request " + i);
|
|
534
537
|
});
|
|
535
|
-
var cmsSequence = (spec.cmsSequence
|
|
538
|
+
var cmsSequence = (spec.cmsSequence != null ? pkiBuild.reqDenseArray(spec.cmsSequence, "cmsSequence", E, "cmc/bad-input") : []).map(function (el, i) {
|
|
536
539
|
return _claimRawElement(el, ids, "a cmsSequence element (index " + i + ")");
|
|
537
540
|
});
|
|
538
|
-
var otherMsgSequence = (spec.otherMsgSequence
|
|
541
|
+
var otherMsgSequence = (spec.otherMsgSequence != null ? pkiBuild.reqDenseArray(spec.otherMsgSequence, "otherMsgSequence", E, "cmc/bad-input") : []).map(function (el, i) {
|
|
539
542
|
return _claimRawElement(el, ids, "an otherMsgSequence element (index " + i + ")");
|
|
540
543
|
});
|
|
541
544
|
|
package/lib/cms-encrypt.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
var nodeCrypto = require("crypto");
|
|
19
19
|
var asn1 = require("./asn1-der");
|
|
20
|
+
var pkiBuild = require("./pki-build"); // reqDenseArray: reject a sparse/nullish caller array as a typed cms/bad-input
|
|
20
21
|
var oid = require("./oid");
|
|
21
22
|
var x509 = require("./schema-x509");
|
|
22
23
|
var schemaCms = require("./schema-cms");
|
|
@@ -589,8 +590,14 @@ async function _envelopedData(contentBytes, contentStream, cek, ca, contentType,
|
|
|
589
590
|
// design (RFC 5652 sec. 9.2), while for AuthEnvelopedData that value is the unencrypted hash of a
|
|
590
591
|
// plaintext the message exists to conceal (RFC 5083 sec. 2.1 / sec. 5).
|
|
591
592
|
function _assertAuthAttrs(pairs, forbidden) {
|
|
593
|
+
// Reject a sparse/nullish attribute array as a typed error before b.setOf reaches it as a native one.
|
|
594
|
+
// This gate runs before the setOf on both the AuthEnveloped and AuthenticatedData paths.
|
|
595
|
+
// Validate AND SNAPSHOT: reqDenseArray returns a fresh dense copy, and it is that copy the caller must
|
|
596
|
+
// iterate and encode. Iterating the original `pairs` would let an indexed getter that sparsified it
|
|
597
|
+
// during validation slip a hole into b.setOf as a native error; the returned snapshot cannot.
|
|
598
|
+
var dense = pkiBuild.reqDenseArray(pairs, "authAttrs", _err, "cms/bad-input");
|
|
592
599
|
var seenTypes = {};
|
|
593
|
-
|
|
600
|
+
dense.forEach(function (p) {
|
|
594
601
|
var node;
|
|
595
602
|
try { node = asn1.decode(p); } catch (e) { throw _err("cms/bad-input", "an authenticated attribute is not well-formed DER", e); }
|
|
596
603
|
if (node.tagClass !== "universal" || node.tagNumber !== asn1.TAGS.SEQUENCE || !node.children || node.children.length !== 2 ||
|
|
@@ -604,6 +611,7 @@ function _assertAuthAttrs(pairs, forbidden) {
|
|
|
604
611
|
seenTypes[t] = 1;
|
|
605
612
|
if (forbidden && t === forbidden.oid) throw _err("cms/bad-input", forbidden.why);
|
|
606
613
|
});
|
|
614
|
+
return dense;
|
|
607
615
|
}
|
|
608
616
|
|
|
609
617
|
// The one attribute AuthEnvelopedData declines to emit. Its value is the unencrypted one-way hash of
|
|
@@ -623,9 +631,9 @@ async function _authEnvelopedData(contentBytes, contentStream, cek, ca, contentT
|
|
|
623
631
|
throw _err("cms/bad-input", "AuthEnvelopedData with a non-data contentType requires authAttrs (RFC 5083 sec. 2.1)");
|
|
624
632
|
}
|
|
625
633
|
if (opts.authAttrs && opts.authAttrs.length) {
|
|
626
|
-
_assertAuthAttrs(opts.authAttrs, AUTH_ENVELOPED_FORBIDDEN);
|
|
634
|
+
var denseAttrs = _assertAuthAttrs(opts.authAttrs, AUTH_ENVELOPED_FORBIDDEN);
|
|
627
635
|
// authAttrs are transmitted [1] IMPLICIT but MACed under the EXPLICIT SET OF tag (RFC 5083 sec. 2.2).
|
|
628
|
-
var setOf = b.setOf(
|
|
636
|
+
var setOf = b.setOf(denseAttrs);
|
|
629
637
|
aad = setOf; authAttrsDer = b.contextConstructed(1, setOf.subarray(_tlvHeaderLen(setOf)));
|
|
630
638
|
}
|
|
631
639
|
// A 16-octet (128-bit) GCM tag, the strongest ICV and what OpenSSL emits, so the message
|
|
@@ -799,7 +807,7 @@ async function authenticate(content, recipients, opts) {
|
|
|
799
807
|
b.sequence([b.oid(O("messageDigest")), b.setOf([b.octetString(mdDigest)])]),
|
|
800
808
|
];
|
|
801
809
|
if (opts.authAttrs && opts.authAttrs.length) pairs = pairs.concat(opts.authAttrs);
|
|
802
|
-
_assertAuthAttrs(pairs, null);
|
|
810
|
+
pairs = _assertAuthAttrs(pairs, null);
|
|
803
811
|
var setOf = b.setOf(pairs);
|
|
804
812
|
preimage = setOf; // MAC over the 0x31 SET OF
|
|
805
813
|
authAttrsDer = b.contextConstructed(2, setOf.subarray(_tlvHeaderLen(setOf))); // [2] IMPLICIT on the wire
|
package/lib/crl-sign.js
CHANGED
|
@@ -203,7 +203,7 @@ function _idpValue(idp) {
|
|
|
203
203
|
if (idp.onlyContainsAttributeCerts === true) throw _err("crl/bad-idp", "onlyContainsAttributeCerts=TRUE is not permitted for a conforming CRL issuer (RFC 5280 sec. 5.2.5)");
|
|
204
204
|
var children = [];
|
|
205
205
|
if (idp.fullName != null) {
|
|
206
|
-
var entries = Array.isArray(idp.fullName) ? idp.fullName : [idp.fullName];
|
|
206
|
+
var entries = Array.isArray(idp.fullName) ? pkiBuild.reqDenseArray(idp.fullName, "issuingDistributionPoint.fullName", _err, "crl/bad-idp") : [idp.fullName];
|
|
207
207
|
if (!entries.length) throw _err("crl/bad-idp", "issuingDistributionPoint fullName must carry at least one GeneralName");
|
|
208
208
|
// distributionPoint [0] { fullName [0] IMPLICIT GeneralNames }
|
|
209
209
|
children.push(b.contextConstructed(0, b.contextConstructed(0, Buffer.concat(entries.map(_encodeGeneralName)))));
|
|
@@ -243,11 +243,12 @@ function _validatePreEncodedIdp(inner) {
|
|
|
243
243
|
// fullName) or an array of { fullName } distribution points.
|
|
244
244
|
function _freshestValue(spec) {
|
|
245
245
|
if (!Array.isArray(spec) || !spec.length) throw _err("crl/bad-input", "freshestCRL must be a non-empty array of GeneralNames (or { fullName } distribution points)");
|
|
246
|
-
var
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
var dense = _b.reqDenseArray(spec, "freshestCRL"); // density before every()/map() skip a hole into b.sequence
|
|
247
|
+
var dps = dense.every(function (e) { return e && typeof e === "object" && !Buffer.isBuffer(e) && Object.keys(e).length === 1 && e.fullName != null; })
|
|
248
|
+
? dense.map(function (dp) { return dp.fullName; })
|
|
249
|
+
: [dense];
|
|
249
250
|
return b.sequence(dps.map(function (fullName) {
|
|
250
|
-
var entries = Array.isArray(fullName) ? fullName : [fullName];
|
|
251
|
+
var entries = Array.isArray(fullName) ? _b.reqDenseArray(fullName, "a freshestCRL distribution point fullName") : [fullName];
|
|
251
252
|
if (!entries.length) throw _err("crl/bad-input", "a freshestCRL distribution point must carry at least one GeneralName (GeneralNames is SIZE(1..MAX), RFC 5280 sec. 4.2.1.13)");
|
|
252
253
|
return b.sequence([b.contextConstructed(0, b.contextConstructed(0, Buffer.concat(entries.map(_encodeGeneralName))))]);
|
|
253
254
|
}));
|
|
@@ -345,7 +346,8 @@ function _buildCrlExtensions(spec, ctx) {
|
|
|
345
346
|
function _buildRevoked(entryList, isDelta) {
|
|
346
347
|
if (!Array.isArray(entryList)) throw _err("crl/bad-input", "revoked must be an array of revoked-certificate entries");
|
|
347
348
|
var anyExt = false, seenSerials = {};
|
|
348
|
-
|
|
349
|
+
// Density before the map, which would otherwise skip a hole into b.sequence as a native error.
|
|
350
|
+
var entries = _b.reqDenseArray(entryList, "revoked").map(function (e, idx) {
|
|
349
351
|
if (!e || typeof e !== "object" || Buffer.isBuffer(e)) throw _err("crl/bad-input", "each revoked entry must be an object");
|
|
350
352
|
// Before any field of the entry is encoded, so an unrecognized name is a refusal rather than an
|
|
351
353
|
// entry signed without what it asked for.
|
package/lib/crmf-sign.js
CHANGED
|
@@ -148,7 +148,8 @@ function _buildAttrTypeAndValues(spec, code, label, valueMap) {
|
|
|
148
148
|
if (Array.isArray(spec)) {
|
|
149
149
|
if (!spec.length) throw _err(code, label + " must carry at least one entry");
|
|
150
150
|
var seenA = {};
|
|
151
|
-
|
|
151
|
+
// Density before the map, which would otherwise skip a hole into b.sequence as a native error.
|
|
152
|
+
return b.sequence(pkiBuild.reqDenseArray(spec, label, _err, code).map(function (e, i) {
|
|
152
153
|
var der = _b.reqDer(e, label + " [" + i + "]");
|
|
153
154
|
var n;
|
|
154
155
|
try { n = asn1.decode(der); } catch (err) { throw _err("crmf/bad-input", "pre-encoded " + label + " [" + i + "] is not valid DER", err); }
|
package/lib/ocsp.js
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
var nodeCrypto = require("crypto");
|
|
27
27
|
var asn1 = require("./asn1-der");
|
|
28
|
+
var pkiBuild = require("./pki-build"); // reqDenseArray: reject a sparse/nullish caller array as a typed ocsp/bad-input
|
|
28
29
|
var oid = require("./oid");
|
|
29
30
|
var x509 = require("./schema-x509");
|
|
30
31
|
var ocspSchema = require("./schema-ocsp");
|
|
@@ -176,7 +177,9 @@ function _buildRequest(query, opts) {
|
|
|
176
177
|
var lightweight = opts.profile === "lightweight";
|
|
177
178
|
var hashName = opts.hashAlgorithm || "sha1";
|
|
178
179
|
if (lightweight && hashName !== "sha1") throw _err("ocsp/bad-input", "the lightweight profile requires a SHA-1 CertID (RFC 5019 sec. 2.1.1)");
|
|
179
|
-
|
|
180
|
+
// A batch array is density-checked before the map below (which would otherwise skip a hole and reach
|
|
181
|
+
// Promise.all/b.sequence with an undefined); a single {cert,issuer} wraps to a dense one-element array.
|
|
182
|
+
var queries = Array.isArray(query) ? pkiBuild.reqDenseArray(query, "queries", _err, "ocsp/bad-input") : [query];
|
|
180
183
|
if (!queries.length) throw _err("ocsp/bad-input", "buildRequest needs at least one { cert, issuer } query");
|
|
181
184
|
if (lightweight && queries.length !== 1) throw _err("ocsp/bad-input", "the lightweight profile permits exactly one Request (RFC 5019 sec. 2.1.1)");
|
|
182
185
|
if (opts.signer && !opts.requestorName) throw _err("ocsp/bad-input", "a signed OCSP request MUST carry requestorName (RFC 6960 sec. 4.1.2)");
|
|
@@ -335,7 +338,7 @@ function _sign(responseData, responder, opts) {
|
|
|
335
338
|
// exit -- sync throw and async rejection alike -- rather than each fallible step needing to
|
|
336
339
|
// remember. `responderKey` is the private copy; it is never the caller's object.
|
|
337
340
|
function _signResponse(responseData, responder, respCert, respCertDer, responderKey, opts) {
|
|
338
|
-
var responses = responseData.responses
|
|
341
|
+
var responses = responseData.responses != null ? pkiBuild.reqDenseArray(responseData.responses, "responses", _err, "ocsp/bad-input") : [];
|
|
339
342
|
if (!responses.length) throw _err("ocsp/bad-input", "a response MUST include at least one SingleResponse (RFC 6960 sec. 4.2.1)");
|
|
340
343
|
|
|
341
344
|
return _responderID(responseData.responderID, respCert).then(function (ridNode) {
|
package/lib/pkcs12-build.js
CHANGED
|
@@ -47,6 +47,7 @@ var cmsSign = require("./cms-sign"); // the signer-descriptor field tables, fo
|
|
|
47
47
|
var cmsDecrypt = require("./cms-decrypt"); // the @internal decryptEnvelopedData seam -- opens a privacy safe off the pkcs12 parser's already-walked (BER-capable) EnvelopedData node
|
|
48
48
|
var schemaPkcs12 = require("./schema-pkcs12");
|
|
49
49
|
var pkix = require("./schema-pkix");
|
|
50
|
+
var pkiBuild = require("./pki-build"); // reqDenseArray: reject a sparse/nullish caller array as a typed pkcs12/bad-input
|
|
50
51
|
var guard = require("./guard-all");
|
|
51
52
|
var intrinsic = require("./guard-intrinsic");
|
|
52
53
|
var frameworkError = require("./framework-error");
|
|
@@ -463,9 +464,13 @@ function _pbeOpts(enc) {
|
|
|
463
464
|
|
|
464
465
|
// SafeContents ::= SEQUENCE OF SafeBag (ordered, and not a SET OF).
|
|
465
466
|
function _buildSafeContents(bags, opts, depth) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
467
|
+
// The element cap is enforced BEFORE the density scan, so a huge dense array is rejected in O(1) rather
|
|
468
|
+
// than walked. reqDenseArray then rejects a non-array, or a sparse hole / nullish entry that
|
|
469
|
+
// Array.prototype.map would skip into Buffer.concat as a native error, testing own-property presence
|
|
470
|
+
// and failing at the first bad index.
|
|
471
|
+
if (intrinsic.isArray(bags) && bags.length > C.LIMITS.PKCS12_MAX_ELEMENTS) throw _err("pkcs12/bad-input", "a SafeContents exceeds the element cap " + C.LIMITS.PKCS12_MAX_ELEMENTS);
|
|
472
|
+
var dense = pkiBuild.reqDenseArray(bags, "bags", _err, "pkcs12/bad-input");
|
|
473
|
+
return b.sequence(dense.map(function (bag) { return _buildBag(bag, opts, depth); }));
|
|
469
474
|
}
|
|
470
475
|
|
|
471
476
|
// One AuthenticatedSafe element: a plaintext id-data ContentInfo, an id-encryptedData ContentInfo whose
|
package/lib/pki-build.js
CHANGED
|
@@ -329,6 +329,34 @@ var KU_BIT = {
|
|
|
329
329
|
dataEncipherment: 3, keyAgreement: 4, keyCertSign: 5, cRLSign: 6, encipherOnly: 7, decipherOnly: 8,
|
|
330
330
|
};
|
|
331
331
|
|
|
332
|
+
// A caller-supplied array a builder is about to map over: reject a sparse hole or a nullish entry as a
|
|
333
|
+
// typed error. Array.prototype.map SKIPS a hole, which would otherwise reach Buffer.concat as a native
|
|
334
|
+
// ERR_INVALID_ARG_TYPE and, on a huge sparse length, traverse the empty slots. Tests OWN-property presence
|
|
335
|
+
// (intrinsic.hasOwn) at each index BEFORE reading it, so a polluted Array.prototype[i] cannot slip a hole
|
|
336
|
+
// past the check, and fails fast at the first bad index so the length alone can never force a walk. Takes
|
|
337
|
+
// the caller's error factory E (invoked E(fullCode, msg)) so a builder WITHOUT a makeBuilder instance
|
|
338
|
+
// routes its caller arrays through the same choke point; makeBuilder's own reqDenseArray delegates here.
|
|
339
|
+
function reqDenseArrayImpl(list, what, E, code) {
|
|
340
|
+
if (!_isArray(list)) throw E(code, what + " must be an array");
|
|
341
|
+
var n = list.length;
|
|
342
|
+
// Snapshot each own index into a FRESH dense array and return THAT, never `list`. Reading list[i] can
|
|
343
|
+
// fire a caller-defined indexed accessor that mutates `list` (extending it with holes past the captured
|
|
344
|
+
// n, or deleting an already-checked index); returning `list` would then hand the caller's map a
|
|
345
|
+
// newly-sparse array and the native error this guard exists to prevent. The copy captures the value as
|
|
346
|
+
// read, so a later mutation of `list` cannot reintroduce a hole into what the caller iterates.
|
|
347
|
+
var out = [];
|
|
348
|
+
for (var i = 0; i < n; i++) {
|
|
349
|
+
if (!intrinsic.hasOwn(list, i)) throw E(code, what + "[" + i + "] is missing (a sparse array is not allowed)");
|
|
350
|
+
var v = list[i];
|
|
351
|
+
if (v === undefined || v === null) throw E(code, what + "[" + i + "] is missing (a nullish array entry is not allowed)");
|
|
352
|
+
// defineProperty, not `out[i] = v`: a plain assignment invokes an inherited Array.prototype[i] SETTER
|
|
353
|
+
// ([[Set]]) if one is polluted in, which could leave `out` sparse; [[DefineOwnProperty]] always makes
|
|
354
|
+
// an own data property, so the snapshot is dense regardless of prototype pollution.
|
|
355
|
+
intrinsic.defineProperty(out, i, { value: v, writable: true, enumerable: true, configurable: true });
|
|
356
|
+
}
|
|
357
|
+
return out;
|
|
358
|
+
}
|
|
359
|
+
|
|
332
360
|
// makeBuilder(ctx) -> the bound producing primitives. ctx = { ErrorClass, prefix, O, NS, NAME_SCHEMA,
|
|
333
361
|
// SPKI_SCHEMA, EXT_DECODERS }. `E(kind, msg, cause)` builds a `<prefix>/<kind>` typed error.
|
|
334
362
|
function makeBuilder(ctx) {
|
|
@@ -593,23 +621,9 @@ function makeBuilder(ctx) {
|
|
|
593
621
|
if (guard.bytes.isByteSource(v)) return guard.bytes.snapshotSource(v, ErrorClass, ctx.prefix + "/bad-input", what);
|
|
594
622
|
throw E("bad-input", what + " must be a DER Buffer");
|
|
595
623
|
}
|
|
596
|
-
//
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
// presence at each index BEFORE reading it: a bare `list[i]` on a hole walks the prototype chain, so a
|
|
600
|
-
// polluted `Array.prototype[i]` would read as a value and slip a hole past the check while map still
|
|
601
|
-
// skips it. Fails fast at the first bad index, so the length alone can never force a walk. Returns the
|
|
602
|
-
// validated dense array for the caller to map normally.
|
|
603
|
-
function reqDenseArray(list, what) {
|
|
604
|
-
if (!_isArray(list)) throw E("bad-input", what + " must be an array");
|
|
605
|
-
var n = list.length;
|
|
606
|
-
for (var i = 0; i < n; i++) {
|
|
607
|
-
if (!intrinsic.hasOwn(list, i)) throw E("bad-input", what + "[" + i + "] is missing (a sparse array is not allowed)");
|
|
608
|
-
var v = list[i];
|
|
609
|
-
if (v === undefined || v === null) throw E("bad-input", what + "[" + i + "] is missing (a nullish array entry is not allowed)");
|
|
610
|
-
}
|
|
611
|
-
return list;
|
|
612
|
-
}
|
|
624
|
+
// The bound 2-arg form every makeBuilder consumer calls (`_b.reqDenseArray(list, what)`); it delegates
|
|
625
|
+
// to the standalone guard above with this builder's namespace, so the density rule lives in ONE place.
|
|
626
|
+
function reqDenseArray(list, what) { return reqDenseArrayImpl(list, what, rawErr, ctx.prefix + "/bad-input"); }
|
|
613
627
|
// A caller-supplied DER a builder validates with a PEM-accepting parser and then embeds verbatim with
|
|
614
628
|
// b.raw. Those parsers unwrap PEM from a byte source, so a PEM-armored input (a Buffer straight from
|
|
615
629
|
// fs.readFileSync) passes the parse, but b.raw embeds the raw ASCII armor -- which the enclosing
|
|
@@ -817,4 +831,10 @@ function tbsSerialNumber(cert) {
|
|
|
817
831
|
return asn1.read.integer(tbs.children[hasVersion ? 1 : 0]);
|
|
818
832
|
}
|
|
819
833
|
|
|
820
|
-
|
|
834
|
+
// Frozen so a co-resident cannot reassign an exported guard (e.g. reqDenseArray) to bypass it: the
|
|
835
|
+
// standalone consumers read reqDenseArray off this object at call time, so the object holding it must be
|
|
836
|
+
// immutable, the way the guard-* modules freeze their surfaces.
|
|
837
|
+
// Frozen so a co-resident cannot reassign an exported guard (e.g. reqDenseArray) to bypass it: the
|
|
838
|
+
// standalone consumers read reqDenseArray off this object at call time, so the object holding it must be
|
|
839
|
+
// immutable, the way the guard-* modules freeze their surfaces.
|
|
840
|
+
module.exports = intrinsic.freeze({ makeBuilder: makeBuilder, reqDenseArray: reqDenseArrayImpl, KU_BIT: KU_BIT, tbsNameField: tbsNameField, tbsSerialNumber: tbsSerialNumber });
|
package/package.json
CHANGED
package/sbom.cdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:fe024f86-e1b5-48d0-97ee-173c19cc63b0",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-08-
|
|
8
|
+
"timestamp": "2026-08-30T02:10:51.770Z",
|
|
9
9
|
"lifecycles": [
|
|
10
10
|
{
|
|
11
11
|
"phase": "build"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"component": {
|
|
22
|
-
"bom-ref": "@blamejs/pki@0.5.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.5.38",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.5.
|
|
25
|
+
"version": "0.5.38",
|
|
26
26
|
"scope": "required",
|
|
27
27
|
"author": "blamejs contributors",
|
|
28
28
|
"description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
|
|
29
|
-
"purl": "pkg:npm/%40blamejs/pki@0.5.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.5.38",
|
|
30
30
|
"properties": [],
|
|
31
31
|
"externalReferences": [
|
|
32
32
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"components": [],
|
|
55
55
|
"dependencies": [
|
|
56
56
|
{
|
|
57
|
-
"ref": "@blamejs/pki@0.5.
|
|
57
|
+
"ref": "@blamejs/pki@0.5.38",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|