@blamejs/pki 0.8.58 → 0.8.59

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 CHANGED
@@ -4,6 +4,23 @@ 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.8.59 — 2026-10-07
8
+
9
+ Render an object identifier, match a header name and read a media type through operations a replacement cannot answer.
10
+
11
+ ### Changed
12
+
13
+ - The check that holds these modules to captured operations now counts a method reached through an index, not only one reached through a call. It is the same receiver one bracket over, and the earlier form could not see it: two live copies in the RFC 5280 policy-mapping walk, where the copy becomes a node's expected policy set, were found by other means.
14
+
15
+ ### Fixed
16
+
17
+ - An object identifier is rendered to its dotted form through operations bound when the module loaded, and its arcs are collected by defining each index rather than by appending to the array. Three different replacements each decided that string, which is the value `pki.oid` resolves, which selects a signature algorithm and which names an extension: a replaced integer conversion made the content octets of `1.2.3` render as `1.3.4`, and an accessor inherited at the first index of every array took each arc as it was collected and made the same octets render as `0.1.3`. Appending stores at an index, and a store consults the prototype chain for a setter, so a list this build assembles is now built by defining its indexes.
18
+ - A media type is read on the delimiter character and folded through a captured conversion, in `pki.acme`, `pki.cmp` and `pki.ct`. The token decides which parser a response body is handed to, and it was produced by splitting, trimming and folding through live operations. Splitting is now a character scan, which this toolkit requires in its libraries because a separator's own split hook is part of that operation.
19
+ - `pki.est` reads a content-type parameter through captured operations, and collects the segments it searches by defining each index. That is where the RFC 7030 multipart boundary comes from, so the value decides where a multi-part response is divided: measured, a header declaring `boundary=wire` yielded `forged`, both through a replaced append and through an accessor inherited at an array index. The name comparison that selects a parameter, the slicing that extracts it and the quote stripping around it were each live, as were the name and value of every header on a part, which is where a part's own content type comes from: measured, a part declaring `application/pkcs8` was read as `application/pkcs7-mime` carrying `smime-type=certs-only`. Its two case-insensitive header lookups are folded through the capture on both sides of the comparison.
20
+ - `pki.acme` parses a Link header through captured operations: the header is divided into links, each link into parameters, and the target cut out of its angle brackets, all through operations bound when the module loaded. The relation decides whether a header names a resource the client will follow and the target is the URL it would fetch, and both were produced by methods read off the live prototype: measured, a header stating one alternate chain resolved to a different URL.
21
+ - `pki.cmc.build` selects which request arm a message carries through a selection that reads each candidate once and builds its own result, rather than through a method that is both read off the prototype and specified to construct its result through a replaceable protocol.
22
+ - The algorithm, extension and criticality tables that `pki.path.validate`, `pki.cms`, `pki.crl`, `pki.key`, `pki.webcrypto`, `pki.x509` and the signature-scheme registry build when they load are built through captured walks, so a replacement installed before a module loads cannot decide which rows exist.
23
+
7
24
  ## v0.8.58 — 2026-10-07
8
25
 
9
26
  Connect under the trust anchors, the address and the identity check the request named, not the ones a second read answers with.
package/lib/acme.js CHANGED
@@ -88,6 +88,7 @@ var _sortI = intrinsic.sort;
88
88
  var _objectKeys = intrinsic.keys;
89
89
  var _lower = intrinsic.toLowerCase;
90
90
  var _StringI = intrinsic.String;
91
+ var _acmeTrim = intrinsic.uncurry(String.prototype.trim);
91
92
  var _stringify = intrinsic.stringify;
92
93
  var _push = intrinsic.push;
93
94
  var _pop = intrinsic.pop;
@@ -98,6 +99,7 @@ var _split = intrinsic.uncurry(String.prototype.split);
98
99
  var _parseIntI = intrinsic.parseInt;
99
100
  var _numToString = intrinsic.numberToString;
100
101
  var _strSlice = intrinsic.uncurry(String.prototype.slice);
102
+ var _charAtA = intrinsic.uncurry(String.prototype.charAt);
101
103
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
102
104
  var _charAt = intrinsic.uncurry(String.prototype.charAt);
103
105
  var pkgVersion = require("../package.json").version;
@@ -1707,61 +1709,71 @@ function _hasCtlOctet(s) {
1707
1709
  }
1708
1710
 
1709
1711
  function _splitLinkValues(s) {
1712
+ /** @internal The header is cut through the captured operations, the same as the parameters below:
1713
+ * each piece becomes a link whose relation decides whether this client follows it. */
1710
1714
  var out = [], start = 0, inAngle = false, inQuote = false;
1711
1715
  for (var i = 0; i < s.length; i++) {
1712
- var ch = s.charAt(i);
1716
+ var ch = _charAtA(s, i);
1713
1717
  if (inQuote) { if (ch === "\\") { i++; continue; } if (ch === "\"") inQuote = false; continue; }
1714
1718
  if (ch === "\"") { inQuote = true; continue; }
1715
1719
  if (ch === "<") inAngle = true;
1716
1720
  else if (ch === ">") inAngle = false;
1717
- else if (ch === "," && !inAngle) { out.push(s.slice(start, i)); start = i + 1; }
1721
+ else if (ch === "," && !inAngle) { intrinsic.append(out, _strSlice(s, start, i)); start = i + 1; }
1718
1722
  }
1719
1723
  if (inQuote || inAngle) throw E("acme/bad-link", "the Link header has an unterminated quote or angle bracket (RFC 8288)");
1720
- out.push(s.slice(start));
1724
+ intrinsic.append(out, _strSlice(s, start));
1721
1725
  return out;
1722
1726
  }
1723
1727
  function _splitLinkParams(rest) {
1724
1728
  var parts = [], start = 0, inQuote = false;
1725
1729
  for (var i = 0; i < rest.length; i++) {
1726
- var ch = rest.charAt(i);
1730
+ var ch = _charAtA(rest, i);
1727
1731
  if (inQuote) { if (ch === "\\") { i++; continue; } if (ch === "\"") inQuote = false; continue; }
1728
1732
  if (ch === "\"") inQuote = true;
1729
- else if (ch === ";") { parts.push(rest.slice(start, i)); start = i + 1; }
1733
+ else if (ch === ";") { intrinsic.append(parts, _strSlice(rest, start, i)); start = i + 1; }
1730
1734
  }
1731
- parts.push(rest.slice(start));
1735
+ intrinsic.append(parts, _strSlice(rest, start));
1732
1736
  var out = [];
1733
1737
  for (var j = 0; j < parts.length; j++) {
1734
1738
  var p = _trimOWS(parts[j]);
1735
1739
  if (p === "") { if (j === 0) continue; throw E("acme/bad-link", "an empty Link parameter (a ';' with no parameter) is malformed (RFC 8288): " + JSON.stringify(rest)); }
1736
- var eq = p.indexOf("=");
1737
- var name = (eq === -1 ? p : _trimOWS(p.slice(0, eq))).toLowerCase();
1740
+ /** @internal The parameter name and value are cut and folded through the captured operations.
1741
+ * A Link parameter is what names the relation this client follows, and read off the prototype a
1742
+ * replacement chose it: measured, a header stating `rel=next` parsed as `alternate`. */
1743
+ var eq = intrinsic.stringIndexOf(p, "=");
1744
+ var name = _lower(eq === -1 ? p : _trimOWS(_strSlice(p, 0, eq)));
1738
1745
  if (!pkix.allCharsIn(name, _LINK_TOKEN_TABLE)) throw E("acme/bad-link", "a Link parameter name must be a token (RFC 8288 / RFC 7230): " + JSON.stringify(p));
1739
- if (eq === -1) { out.push({ name: name, value: "", hasValue: false }); continue; }
1740
- var v = _trimOWS(p.slice(eq + 1));
1741
- if (v.length >= 2 && v.charAt(0) === "\"" && v.charAt(v.length - 1) === "\"") {
1742
- var inner = v.slice(1, -1);
1746
+ if (eq === -1) { intrinsic.append(out, { name: name, value: "", hasValue: false }); continue; }
1747
+ var v = _trimOWS(_strSlice(p, eq + 1));
1748
+ if (v.length >= 2 && _charAtA(v, 0) === "\"" && _charAtA(v, v.length - 1) === "\"") {
1749
+ var inner = _strSlice(v, 1, -1);
1743
1750
  if (!_isValidQuotedInterior(inner)) throw E("acme/bad-link", "a quoted Link parameter value is malformed (an unescaped quote or dangling backslash, RFC 7230): " + JSON.stringify(p));
1744
1751
  v = _unescapeQuotedPair(inner);
1745
1752
  } else if (!pkix.allCharsIn(v, _LINK_TOKEN_TABLE)) {
1746
1753
  throw E("acme/bad-link", "an unquoted Link parameter value must be a non-empty token (RFC 8288 / RFC 7230): " + JSON.stringify(p));
1747
1754
  }
1748
- out.push({ name: name, value: v, hasValue: true });
1755
+ intrinsic.append(out, { name: name, value: v, hasValue: true });
1749
1756
  }
1750
1757
  return out;
1751
1758
  }
1752
1759
  function _relHas(rel, relName) {
1753
- var toks = String(rel).split(" ");
1754
- for (var i = 0; i < toks.length; i++) { if (toks[i].toLowerCase() === relName) return true; }
1760
+ /** @internal The relation names are scanned on the delimiter CHARACTER, which hard rule 11 requires
1761
+ * in lib/, and each token is folded through the captured conversion: the match decides whether a
1762
+ * Link header names the resource this client then follows. */
1763
+ var toks = intrinsic.splitChar(_StringI(rel), 32);
1764
+ for (var i = 0; i < toks.length; i++) { if (_lower(toks[i]) === relName) return true; }
1755
1765
  return false;
1756
1766
  }
1757
1767
  function _parseLinkValue(raw) {
1758
1768
  var s = _trimOWS(raw);
1759
1769
  if (s === "") return null;
1760
- var gt = s.indexOf(">");
1761
- if (s.charAt(0) !== "<" || gt === -1) throw E("acme/bad-link", "a Link value must be <URI-Reference> with parameters (RFC 8288): " + JSON.stringify(raw));
1770
+ var gt = intrinsic.stringIndexOf(s, ">");
1771
+ if (_charAtA(s, 0) !== "<" || gt === -1) throw E("acme/bad-link", "a Link value must be <URI-Reference> with parameters (RFC 8288): " + JSON.stringify(raw));
1762
1772
  var rest = _stripLeadingOWS(s, gt + 1);
1763
- if (rest !== "" && rest.charAt(0) !== ";") throw E("acme/bad-link", "a Link value's parameters must be introduced by ';' (RFC 8288): " + JSON.stringify(raw));
1764
- var uri = s.slice(1, gt);
1773
+ if (rest !== "" && _charAtA(rest, 0) !== ";") throw E("acme/bad-link", "a Link value's parameters must be introduced by ';' (RFC 8288): " + JSON.stringify(raw));
1774
+ /** @internal The target this client may follow is cut through the captured operation: read off the
1775
+ * prototype, a replacement decided the URL a Link header resolves to. */
1776
+ var uri = _strSlice(s, 1, gt);
1765
1777
  if (_linkUriInvalid(uri)) throw E("acme/bad-link", "a Link URI-Reference contains a character, percent-escape, or encoded dot-segment not permitted by RFC 3986: " + JSON.stringify(raw));
1766
1778
  var params = _splitLinkParams(rest), rel = "", relSeen = false, anchor = null, anchorSeen = false;
1767
1779
  for (var i = 0; i < params.length; i++) {
@@ -1780,14 +1792,16 @@ function _parseLinkRelation(headers, base, relName, opts) {
1780
1792
  var raw = null;
1781
1793
  var hNames = guard.identifier.optionNames(headers);
1782
1794
  for (var hi = 0; hi < hNames.length; hi++) {
1783
- if (hNames[hi].toLowerCase() === "link") { raw = headers[hNames[hi]]; break; }
1795
+ if (_lower(hNames[hi]) === "link") { raw = headers[hNames[hi]]; break; }
1784
1796
  }
1785
1797
  if (raw == null) return [];
1786
1798
  var baseUrl = new _URL(base), baseOrigin = _urlOrigin(baseUrl), baseHref = _urlHref(baseUrl);
1787
1799
  var baseKey = _dedupKey(baseHref);
1788
- var fields = Array.isArray(raw) ? raw : [raw], out = [], seen = Object.create(null), distinctCount = 0, totalBytes = 0;
1800
+ var fields = intrinsic.isArray(raw) ? raw : [raw], out = [], seen = intrinsic.create(null), distinctCount = 0, totalBytes = 0;
1789
1801
  for (var fi = 0; fi < fields.length; fi++) {
1790
- var field = String(fields[fi]);
1802
+ /** @internal The header field is converted through the capture: read through the live global, a
1803
+ * replacement supplied the whole Link header and with it the target this client resolves. */
1804
+ var field = _StringI(fields[fi]);
1791
1805
  totalBytes += field.length + 1;
1792
1806
  if (totalBytes > LINK_HEADER_MAX_BYTES) throw E("acme/bad-link", "the Link header(s) exceed the " + LINK_HEADER_MAX_BYTES + "-byte aggregate cap (RFC 8288, CWE-770)");
1793
1807
  if (_hasCtlOctet(field)) throw E("acme/bad-link", "a Link header must not contain control octets (RFC 9110 field-value)");
@@ -2202,7 +2216,8 @@ function client(directoryUrl, opts) {
2202
2216
  function _pollAuthorization(url, budget) { return _poll("authorization", url, budget); }
2203
2217
 
2204
2218
  function _readCertChain(res) {
2205
- var ctToken = String(res.headers["content-type"] || "").split(";")[0].trim().toLowerCase();
2219
+ var ctParts = intrinsic.splitChar(_StringI(res.headers["content-type"] || ""), 59);
2220
+ var ctToken = _lower(_acmeTrim(ctParts.length ? ctParts[0] : ""));
2206
2221
  if (ctToken !== "application/pem-certificate-chain") throw E("acme/bad-certificate-chain", "the certificate download returned an unexpected media type " + JSON.stringify(ctToken) + " (expected application/pem-certificate-chain, RFC 8555 sec. 7.4.2)");
2207
2222
  var chain = _splitPemChain(_bodyText(res));
2208
2223
  return { certificate: chain[0], chain: chain.slice(1), certificates: chain };
package/lib/asn1-der.js CHANGED
@@ -566,8 +566,16 @@ function decodeOidContent(buf) {
566
566
  "OBJECT IDENTIFIER carries more than " + constants.LIMITS.OID_MAX_SUBIDENTIFIERS + " sub-identifiers");
567
567
  }
568
568
  var value = 0n;
569
- for (var k = arcStart; k <= i; k++) value = value * 128n + BigInt(buf[k] & 0x7f);
570
- arcs.push(value);
569
+ /** @internal The arc is accumulated through the captured conversion. Read off the global, a
570
+ * replacement decides the sub-identifier, and therefore the dotted string every algorithm and
571
+ * extension decision in this toolkit is made on: measured, the same two bytes rendered as
572
+ * `1.2.3` and as `1.2.4`. */
573
+ for (var k = arcStart; k <= i; k++) value = value * 128n + intrinsic.BigInt(buf[k] & 0x7f);
574
+ /** @internal `append`, not a captured `push`: appending with `push` STORES at the index, and a
575
+ * store walks the prototype chain for a setter, so an accessor installed at
576
+ * `Array.prototype[0]` took the arc and answered with another. `append` defines the index on
577
+ * the array itself. */
578
+ intrinsic.append(arcs, value);
571
579
  arcStart = i + 1;
572
580
  }
573
581
  }
@@ -577,9 +585,12 @@ function decodeOidContent(buf) {
577
585
  if (first < 40n) { a1 = 0n; a2 = first; }
578
586
  else if (first < 80n) { a1 = 1n; a2 = first - 40n; }
579
587
  else { a1 = 2n; a2 = first - 80n; }
580
- var out = [a1.toString(), a2.toString()];
581
- for (var j = 1; j < arcs.length; j++) out.push(arcs[j].toString());
582
- return out.join(".");
588
+ /** @internal Each arc is rendered through the captured conversion. Read off the prototype, the
589
+ * value that becomes the dotted identifier is whatever a replacement returns, and the identifier
590
+ * is what every algorithm and extension decision in this toolkit is made on. */
591
+ var out = [intrinsic.bigIntToString(a1, 10), intrinsic.bigIntToString(a2, 10)];
592
+ for (var j = 1; j < arcs.length; j++) intrinsic.append(out, intrinsic.bigIntToString(arcs[j], 10));
593
+ return intrinsic.join(out, ".");
583
594
  }
584
595
 
585
596
  function _decodeText(buf, encoding) {
package/lib/cmc-build.js CHANGED
@@ -173,7 +173,10 @@ function fixedRequestId(req, index) {
173
173
  return "unknown field " + JSON.stringify(k) + " on request " + index +
174
174
  " -- a request names one of tcr / crm / orm, and optionally bodyPartID";
175
175
  });
176
- var arms = ["tcr", "crm", "orm"].filter(function (k) { return req[k] != null; });
176
+ /** @internal `selectList`, not the live `filter`: the selection decides which request arm this
177
+ * message carries, and `Array.prototype.filter` is both read off the prototype and specified to
178
+ * build its result through the species constructor. */
179
+ var arms = intrinsic.selectList(["tcr", "crm", "orm"], function (k) { return req[k] != null; });
177
180
  if (arms.length !== 1) {
178
181
  throw E("cmc/bad-input",
179
182
  "each request names exactly one of tcr / crm / orm, got " + (arms.length ? arms.join(" + ") : "none") +
package/lib/cmp-build.js CHANGED
@@ -29,6 +29,7 @@ var cmp = require("./schema-cmp");
29
29
  var crmf = require("./crmf-sign");
30
30
  var schemaCrmf = require("./schema-crmf");
31
31
  var intrinsic = require("./guard-intrinsic");
32
+ var _strTrim = intrinsic.uncurry(String.prototype.trim);
32
33
  /** @internal The promise a signature self-check is awaited through, built from the constructor captured
33
34
  * at load. `Promise.resolve` builds from its RECEIVER, so reading the global binding at the call hands
34
35
  * the construction to whatever that binding holds, and one settling without awaiting its argument runs
@@ -1012,7 +1013,15 @@ function _tlsForTransfer(opts) {
1012
1013
  return guard.identifier.pickSettings(opts.tls, TLS_SETTINGS);
1013
1014
  }
1014
1015
 
1015
- function _ctypeToken(headers) { return String((headers || {})["content-type"] || "").split(";")[0].trim().toLowerCase(); }
1016
+ /** @internal The media type is read through the captured operations, and on the delimiter CHARACTER
1017
+ * rather than through `split`, which hard rule 11 bans in lib/ because the separator's own
1018
+ * `Symbol.split` is part of that operation. The token decides which parser a response body is
1019
+ * handed to. */
1020
+ function _ctypeToken(headers) {
1021
+ var raw = intrinsic.String((headers || {})["content-type"] || "");
1022
+ var parts = intrinsic.splitChar(raw, 59);
1023
+ return intrinsic.toLowerCase(_strTrim(parts.length ? parts[0] : ""));
1024
+ }
1016
1025
  function _isPkixcmp(headers) { var t = _ctypeToken(headers); return t === PKIXCMP || t === PKIXCMP_POLL; }
1017
1026
 
1018
1027
  /** @internal The sentinel is added at the one exit rather than at each `return`, so a branch added
@@ -631,9 +631,13 @@ var HASH_W3C = intrinsic.create(null); HASH_W3C[O("sha1")] = "SHA-1"; HASH_W3C[O
631
631
  function _hashW3c(o) { if (!HASH_W3C[o]) throw _err("cms/unsupported-algorithm", "unsupported OAEP hash " + o); return HASH_W3C[o]; }
632
632
 
633
633
  var X963_HASH = intrinsic.create(null);
634
- [["dhSinglePass-stdDH-sha1kdf-scheme", "SHA-1"], ["dhSinglePass-stdDH-sha224kdf-scheme", "SHA-224"], ["dhSinglePass-stdDH-sha256kdf-scheme", "SHA-256"], ["dhSinglePass-stdDH-sha384kdf-scheme", "SHA-384"], ["dhSinglePass-stdDH-sha512kdf-scheme", "SHA-512"],
634
+ var _X963_ROWS = [["dhSinglePass-stdDH-sha1kdf-scheme", "SHA-1"], ["dhSinglePass-stdDH-sha224kdf-scheme", "SHA-224"], ["dhSinglePass-stdDH-sha256kdf-scheme", "SHA-256"], ["dhSinglePass-stdDH-sha384kdf-scheme", "SHA-384"], ["dhSinglePass-stdDH-sha512kdf-scheme", "SHA-512"],
635
635
  ["dhSinglePass-cofactorDH-sha1kdf-scheme", "SHA-1"], ["dhSinglePass-cofactorDH-sha224kdf-scheme", "SHA-224"], ["dhSinglePass-cofactorDH-sha256kdf-scheme", "SHA-256"], ["dhSinglePass-cofactorDH-sha384kdf-scheme", "SHA-384"], ["dhSinglePass-cofactorDH-sha512kdf-scheme", "SHA-512"]
636
- ].forEach(function (r) { X963_HASH[O(r[0])] = r[1]; });
636
+ ];
637
+ /** @internal The registry is built through the captured walk. The method is read off the live
638
+ * prototype at the moment it runs even where the receiver is a literal, and these rows decide which
639
+ * hash a key-agreement recipient's KDF uses. */
640
+ intrinsic.forEach(_X963_ROWS, function (r) { X963_HASH[O(r[0])] = r[1]; });
637
641
  function _x963Hash(scheme) { if (!X963_HASH[scheme]) throw _err("cms/unsupported-algorithm", "unsupported kari key-agreement scheme " + scheme); return X963_HASH[scheme]; }
638
642
  function _kariWrap(kea) {
639
643
  var params = asn1.decode(kea.parameters);
package/lib/cms-verify.js CHANGED
@@ -126,9 +126,9 @@ var SIG_SCHEME = intrinsic.assign(intrinsic.create(null), {
126
126
  ecdsaWithSHA384: { kind: "ec", hash: "SHA-384", params: "absent" },
127
127
  ecdsaWithSHA512: { kind: "ec", hash: "SHA-512", params: "absent" },
128
128
  });
129
- ["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
130
- "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
131
- ].forEach(function (s) { SIG_SCHEME["id-slh-dsa-" + s] = { kind: "slhdsa", name: "SLH-DSA-" + s.toUpperCase(), params: "absent", sameKeyOid: true, digest: SLHDSA_BY_OID[oid.byName("id-slh-dsa-" + s)].digest }; });
129
+ intrinsic.forEach(["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
130
+ "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
131
+ ], function (s) { SIG_SCHEME["id-slh-dsa-" + s] = { kind: "slhdsa", name: "SLH-DSA-" + intrinsic.toUpperCase(s), params: "absent", sameKeyOid: true, digest: SLHDSA_BY_OID[oid.byName("id-slh-dsa-" + s)].digest }; });
132
132
  function _isDerNull(p) { return guard.der.isNull(p); }
133
133
  function _algParamsOk(shape, p) { return shape === "null" ? _isDerNull(p) : (p === null || p === undefined); }
134
134
  var EC_CURVE = intrinsic.create(null);
package/lib/crl-sign.js CHANGED
@@ -108,8 +108,8 @@ var KNOWN_REVOKED_KEYS = intrinsic.assign(intrinsic.create(null), {
108
108
  });
109
109
 
110
110
  var REQUIRED_CRITICALITY = intrinsic.create(null);
111
- [["cRLNumber", false], ["authorityKeyIdentifier", false], ["freshestCRL", false], ["authorityInfoAccess", false],
112
- ["issuingDistributionPoint", true], ["deltaCRLIndicator", true]].forEach(function (r) { REQUIRED_CRITICALITY[O(r[0])] = r[1]; });
111
+ intrinsic.forEach([["cRLNumber", false], ["authorityKeyIdentifier", false], ["freshestCRL", false], ["authorityInfoAccess", false],
112
+ ["issuingDistributionPoint", true], ["deltaCRLIndicator", true]], function (r) { REQUIRED_CRITICALITY[O(r[0])] = r[1]; });
113
113
 
114
114
  var REQUIRED_ENTRY_CRITICALITY = intrinsic.create(null);
115
115
  (function () {
@@ -199,7 +199,7 @@ var _PRE_ENCODED_IDP_SCHEMA = pkix.issuingDistributionPoint("crl/bad-idp");
199
199
  function _validatePreEncodedIdp(inner) {
200
200
  if (!inner.children || !inner.children.length) throw _err("crl/bad-idp", "pre-encoded issuingDistributionPoint MUST NOT be empty (RFC 5280 sec. 5.2.5)");
201
201
  var f = schema.walk(_PRE_ENCODED_IDP_SCHEMA, inner, NS).fields;
202
- ["onlyContainsUserCerts", "onlyContainsCACerts", "onlyContainsAttributeCerts"].forEach(function (name) {
202
+ intrinsic.forEach(["onlyContainsUserCerts", "onlyContainsCACerts", "onlyContainsAttributeCerts"], function (name) {
203
203
  if (f[name].present && f[name].value !== true) throw _err("crl/bad-idp", "pre-encoded issuingDistributionPoint " + name + " encodes its DEFAULT FALSE, which DER omits (X.690 sec. 11.5)");
204
204
  });
205
205
  if (f.indirectCRL.present) throw _err("crl/bad-idp", _INDIRECT_IDP_DEFERRED);
package/lib/ct.js CHANGED
@@ -63,6 +63,7 @@ var _bufToString = intrinsic.bufToString;
63
63
  var _bufferCompare = intrinsic.compare;
64
64
  var _subarray = intrinsic.subarray;
65
65
  var _toLowerCase = intrinsic.toLowerCase;
66
+ var _ctTrim = intrinsic.uncurry(String.prototype.trim);
66
67
  var _bufCopy = intrinsic.uncurry(Buffer.prototype.copy);
67
68
  var _writeU64BE = intrinsic.uncurry(Buffer.prototype.writeBigUInt64BE);
68
69
  var _searchSet = intrinsic.uncurry(URLSearchParams.prototype.set);
@@ -1230,7 +1231,15 @@ function _assertTransport(opts) {
1230
1231
  "(request) => Promise<{ status, headers, body }>");
1231
1232
  }
1232
1233
 
1233
- function _fetchCtypeToken(headers) { return String((headers || {})["content-type"] || "").split(";")[0].trim().toLowerCase(); }
1234
+ /** @internal The media type is read through the captured operations, and on the delimiter CHARACTER
1235
+ * rather than through `split`, which hard rule 11 bans in lib/ because the separator's own
1236
+ * `Symbol.split` is part of that operation. The token decides which parser a log's response body is
1237
+ * handed to. */
1238
+ function _fetchCtypeToken(headers) {
1239
+ var raw = intrinsic.String((headers || {})["content-type"] || "");
1240
+ var parts = intrinsic.splitChar(raw, 59);
1241
+ return _toLowerCase(_ctTrim(parts.length ? parts[0] : ""));
1242
+ }
1234
1243
 
1235
1244
  function _parseHttpsUrl(u, label) {
1236
1245
  var parsed;
package/lib/est.js CHANGED
@@ -76,6 +76,9 @@ var intrinsic = require("./guard-intrinsic");
76
76
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
77
77
  var _strSlice = intrinsic.uncurry(String.prototype.slice);
78
78
  var _toLowerCase = intrinsic.uncurry(String.prototype.toLowerCase);
79
+ var _estTrim = intrinsic.uncurry(String.prototype.trim);
80
+ var _estCharAt = intrinsic.uncurry(String.prototype.charAt);
81
+ var _estIndexOf = intrinsic.stringIndexOf;
79
82
  /** @internal Each verb gates its body on a resolved promise and returns its refusals as rejected ones,
80
83
  * and both build from the RECEIVER, so reading the global binding at the call decides whether the body
81
84
  * runs and whether a refusal stays a refusal. Taken at load. */
@@ -250,7 +253,7 @@ function _isMultipartMixedPrefix(ct) {
250
253
  }
251
254
 
252
255
  function _multipartBoundary(contentType) {
253
- var ct = String(contentType || "");
256
+ var ct = _stringOf(contentType || "");
254
257
  if (!_isMultipartMixedPrefix(ct)) return null;
255
258
  var bp = _ctParam(ct, "boundary");
256
259
  if (bp.duplicated) {
@@ -356,12 +359,16 @@ function splitMultipartMixed(body, contentType) {
356
359
  var lines = _splitCrlf(_unfoldHeaders(rawHeaders));
357
360
  for (var li = 0; li < lines.length; li++) {
358
361
  var line = lines[li];
359
- var col = line.indexOf(":");
360
- if (col > 0) headers[line.slice(0, col).trim().toLowerCase()] = line.slice(col + 1).trim();
362
+ /** @internal A part's header name and value are cut, trimmed and folded through the captured
363
+ * operations. One of those headers is the part's own content type, which selects the reader
364
+ * its body goes to: measured, a part stating `application/pkcs8` was read as
365
+ * `application/pkcs7-mime` with a `smime-type` of `certs-only`. */
366
+ var col = _estIndexOf(line, ":");
367
+ if (col > 0) headers[_toLowerCase(_estTrim(_strSlice(line, 0, col)))] = _estTrim(_strSlice(line, col + 1));
361
368
  }
362
369
  var partCt = headers["content-type"] || "";
363
370
  if (_ciStartsWith(partCt, "MULTIPART/")) throw E("est/bad-multipart", "a nested multipart part is not permitted");
364
- parts.push({ headers: headers, contentType: partCt, body: partBody });
371
+ intrinsic.append(parts, { headers: headers, contentType: partCt, body: partBody });
365
372
  }
366
373
  return parts;
367
374
  }
@@ -457,29 +464,37 @@ function _recipientMatches(recipientInfos, opts) {
457
464
  return false;
458
465
  }
459
466
 
467
+ /** @internal The segments are collected through the captured append. Read off the prototype, a
468
+ * replacement decides which segments a parameter is then looked for in, and one of those parameters
469
+ * is the multipart boundary a response body is divided on: measured, a `boundary=wire` header
470
+ * yielded `forged`. */
460
471
  function _splitContentTypeParams(s) {
461
472
  var segs = [], cur = "", inQuote = false;
462
473
  for (var i = 0; i < s.length; i++) {
463
- var ch = s[i];
474
+ var ch = _estCharAt(s, i);
464
475
  if (ch === '"') { inQuote = !inQuote; cur += ch; }
465
- else if (ch === ";" && !inQuote) { segs.push(cur); cur = ""; }
476
+ else if (ch === ";" && !inQuote) { intrinsic.append(segs, cur); cur = ""; }
466
477
  else cur += ch;
467
478
  }
468
- segs.push(cur);
479
+ intrinsic.append(segs, cur);
469
480
  return segs;
470
481
  }
471
482
 
472
483
  function _ctParam(contentType, name) {
473
- var segs = _splitContentTypeParams(String(contentType || ""));
484
+ var segs = _splitContentTypeParams(_stringOf(contentType || ""));
474
485
  var value = null, count = 0;
486
+ /** @internal Each parameter is read through the captured operations. The name decides which
487
+ * parameter this is, and the value it returns is the one a caller acts on: for the RFC 7030
488
+ * multipart boundary, it is where a response body is split. */
475
489
  for (var i = 1; i < segs.length; i++) {
476
- var eq = segs[i].indexOf("=");
490
+ var seg = segs[i];
491
+ var eq = _estIndexOf(seg, "=");
477
492
  if (eq === -1) continue;
478
- if (segs[i].slice(0, eq).trim().toLowerCase() !== name) continue;
493
+ if (_toLowerCase(_estTrim(_strSlice(seg, 0, eq))) !== name) continue;
479
494
  count++;
480
495
  if (count > 1) continue;
481
- var val = segs[i].slice(eq + 1).trim();
482
- if (val.length >= 2 && val.charAt(0) === '"' && val.charAt(val.length - 1) === '"') val = val.slice(1, -1);
496
+ var val = _estTrim(_strSlice(seg, eq + 1));
497
+ if (val.length >= 2 && _estCharAt(val, 0) === '"' && _estCharAt(val, val.length - 1) === '"') val = _strSlice(val, 1, -1);
483
498
  value = val;
484
499
  }
485
500
  return { value: value, duplicated: count > 1 };
@@ -501,12 +516,15 @@ function _mediaType(seg) {
501
516
  return _toLowerCase(_strSlice(seg, a, b));
502
517
  }
503
518
 
519
+ /** @internal The media type and the S/MIME type are produced through the captured conversions. The
520
+ * media type selects which reader a part's body goes to, and read through the live global `String`
521
+ * a replacement chose it: measured, `text/plain` arrived as `application/pkcs8`. */
504
522
  function _partMediaType(contentType) {
505
- var segs = _splitContentTypeParams(String(contentType || ""));
523
+ var segs = _splitContentTypeParams(_stringOf(contentType || ""));
506
524
  var st = _ctParam(contentType, "smime-type");
507
525
  return {
508
526
  media: _mediaType(segs[0]),
509
- smimeType: st.value === null ? null : st.value.toLowerCase(),
527
+ smimeType: st.value === null ? null : _toLowerCase(st.value),
510
528
  ambiguous: st.duplicated,
511
529
  };
512
530
  }
@@ -1279,7 +1297,7 @@ function _requestBinding(der) {
1279
1297
  var body = cmcFmt.parse(der);
1280
1298
  var ids = [];
1281
1299
  var paths = [];
1282
- [body.requests, body.controls, body.cmsSequence, body.otherMsgs].forEach(function (list) {
1300
+ intrinsic.forEach([body.requests, body.controls, body.cmsSequence, body.otherMsgs], function (list) {
1283
1301
  (list || []).forEach(function (el) {
1284
1302
  if (el && el.bodyPartID != null) { ids.push(el.bodyPartID); paths.push([el.bodyPartID]); }
1285
1303
  });
@@ -1325,7 +1343,7 @@ function _collectNestedPaths(list, prefix, out, depth) {
1325
1343
  catch (_e) { /* allow:swallow-unverified the outer request must itself parse for this to run, which already rejects a malformed nested ContentInfo; a payload that survives that and still fails to read back lands on the same no-path refusal the non-pkiData route below takes, which the vectors drive */ return; }
1326
1344
  if (!inner || inner.kind !== "pkiData") return;
1327
1345
  var path = prefix.concat([el.bodyPartID]);
1328
- [inner.requests, inner.controls, inner.cmsSequence, inner.otherMsgs].forEach(function (l) {
1346
+ intrinsic.forEach([inner.requests, inner.controls, inner.cmsSequence, inner.otherMsgs], function (l) {
1329
1347
  (l || []).forEach(function (e2) { if (e2 && e2.bodyPartID != null) out.push(path.concat([e2.bodyPartID])); });
1330
1348
  });
1331
1349
  _collectNestedPaths(inner.cmsSequence, path, out, depth + 1);
@@ -1405,7 +1423,7 @@ function _fullcmcResult(res, opts, wanted, sent) {
1405
1423
  }
1406
1424
  var smimeType = pt200.smimeType;
1407
1425
  if (smimeType === "certs-only") {
1408
- var unecho = ["transactionId", "senderNonce", "dataReturn"].filter(function (k) {
1426
+ var unecho = intrinsic.selectList(["transactionId", "senderNonce", "dataReturn"], function (k) {
1409
1427
  return sent[k] != null;
1410
1428
  });
1411
1429
  if (unecho.length) {
@@ -1731,21 +1749,23 @@ function _assertConfidentialCipher(res) {
1731
1749
 
1732
1750
  function _ciHeaderList(headers, name) {
1733
1751
  headers = headers || {};
1734
- var lname = name.toLowerCase(), keys = guard.identifier.optionNames(headers), parts = [];
1752
+ /** @internal The header NAME a value is selected under is folded through the captured conversion on
1753
+ * both sides of the comparison: the match decides which header this response is read from. */
1754
+ var lname = _toLowerCase(name), keys = guard.identifier.optionNames(headers), parts = [];
1735
1755
  for (var i = 0; i < keys.length; i++) {
1736
- if (keys[i].toLowerCase() !== lname) continue;
1756
+ if (_toLowerCase(keys[i]) !== lname) continue;
1737
1757
  var v = headers[keys[i]];
1738
1758
  if (v == null) continue;
1739
- parts.push(Array.isArray(v) ? v.join(", ") : String(v));
1759
+ intrinsic.append(parts, intrinsic.isArray(v) ? intrinsic.join(v, ", ") : _stringOf(v));
1740
1760
  }
1741
- return parts.length ? parts.join(", ") : null;
1761
+ return parts.length ? intrinsic.join(parts, ", ") : null;
1742
1762
  }
1743
1763
 
1744
1764
  function _ciHeader(headers, name) {
1745
1765
  headers = headers || {};
1746
- var lname = name.toLowerCase(), keys = guard.identifier.optionNames(headers), found = null, n = 0;
1766
+ var lname = _toLowerCase(name), keys = guard.identifier.optionNames(headers), found = null, n = 0;
1747
1767
  for (var i = 0; i < keys.length; i++) {
1748
- if (keys[i].toLowerCase() !== lname) continue;
1768
+ if (_toLowerCase(keys[i]) !== lname) continue;
1749
1769
  n += 1;
1750
1770
  if (n === 1) found = headers[keys[i]];
1751
1771
  }
@@ -257,7 +257,7 @@ var _CONCRETE_TYPED_MEMBERS = ["BYTES_PER_ELEMENT"];
257
257
  var _BUFFER_PROTO_MEMBERS = ["parent", "offset"];
258
258
 
259
259
  var _ARRAY_MEMBERS = _ARRAY_PROTO_MEMBERS;
260
- var _REGEXP_MEMBERS = ["lastIndex"].concat(_REGEXP_PROTO_MEMBERS);
260
+ var _REGEXP_MEMBERS = intrinsic.concatList(["lastIndex"], _REGEXP_PROTO_MEMBERS);
261
261
  var _VIEW_MEMBERS = _TYPED_PROTO_MEMBERS.concat(_CONCRETE_TYPED_MEMBERS);
262
262
  var _BUFFER_KIND_MEMBERS = _VIEW_MEMBERS.concat(_BUFFER_PROTO_MEMBERS);
263
263
  var _DATAVIEW_MEMBERS = _DATAVIEW_PROTO_MEMBERS;
package/lib/key.js CHANGED
@@ -48,6 +48,10 @@ var _floor = intrinsic.floor;
48
48
  var _isFinite = intrinsic.isFinite;
49
49
  var _String = intrinsic.String;
50
50
  var _toUpperCase = intrinsic.toUpperCase;
51
+ /** @internal The walk over an array LITERAL is captured too. The receiver is the literal rather than
52
+ * a caller's value, but the method is still read off the live prototype at the moment it runs, and a
53
+ * replacement decides which rows of a registry this module builds. */
54
+ var _forEach = intrinsic.forEach;
51
55
  var _strIndexOf = intrinsic.stringIndexOf;
52
56
 
53
57
  var b = asn1.build;
@@ -60,13 +64,13 @@ function _err(code, msg, cause) { return new KeyError(code, msg, cause); }
60
64
  var CIPHER_NAME = _assign(_create(null), { "aes-128-cbc": "aes128-CBC", "aes-192-cbc": "aes192-CBC", "aes-256-cbc": "aes256-CBC" });
61
65
 
62
66
  var INFER_ALG = _create(null);
63
- ["Ed25519", "Ed448", "X25519", "X448"].forEach(function (n) { INFER_ALG[O(n)] = { name: n }; });
64
- [["id-ml-dsa-44", "ML-DSA-44"], ["id-ml-dsa-65", "ML-DSA-65"], ["id-ml-dsa-87", "ML-DSA-87"],
65
- ["id-ml-kem-512", "ML-KEM-512"], ["id-ml-kem-768", "ML-KEM-768"], ["id-ml-kem-1024", "ML-KEM-1024"]
66
- ].forEach(function (r) { INFER_ALG[O(r[0])] = { name: r[1] }; });
67
- ["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
68
- "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
69
- ].forEach(function (s) { INFER_ALG[O("id-slh-dsa-" + s)] = { name: _toUpperCase("SLH-DSA-" + s) }; });
67
+ _forEach(["Ed25519", "Ed448", "X25519", "X448"], function (n) { INFER_ALG[O(n)] = { name: n }; });
68
+ _forEach([["id-ml-dsa-44", "ML-DSA-44"], ["id-ml-dsa-65", "ML-DSA-65"], ["id-ml-dsa-87", "ML-DSA-87"],
69
+ ["id-ml-kem-512", "ML-KEM-512"], ["id-ml-kem-768", "ML-KEM-768"], ["id-ml-kem-1024", "ML-KEM-1024"]
70
+ ], function (r) { INFER_ALG[O(r[0])] = { name: r[1] }; });
71
+ _forEach(["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
72
+ "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
73
+ ], function (s) { INFER_ALG[O("id-slh-dsa-" + s)] = { name: _toUpperCase("SLH-DSA-" + s) }; });
70
74
 
71
75
  function _isCryptoKey(x) { return webcrypto.isCryptoKeyLike(x); }
72
76
  function _algName(a) { return typeof a === "string" ? a : (a && a.name); }
@@ -179,9 +179,9 @@ _sig("Ed448", { name: "Ed448" }, { name: "Ed448" }, "absent", false, true);
179
179
  _sig("id-ml-dsa-44", { name: "ML-DSA-44" }, { name: "ML-DSA-44" }, "absent", false, true);
180
180
  _sig("id-ml-dsa-65", { name: "ML-DSA-65" }, { name: "ML-DSA-65" }, "absent", false, true);
181
181
  _sig("id-ml-dsa-87", { name: "ML-DSA-87" }, { name: "ML-DSA-87" }, "absent", false, true);
182
- ["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
183
- "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
184
- ].forEach(function (set) {
182
+ intrinsic.forEach(["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
183
+ "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
184
+ ], function (set) {
185
185
  var wc = "SLH-DSA-" + set.toUpperCase();
186
186
  _sig("id-slh-dsa-" + set, { name: wc }, { name: wc }, "absent", false, true);
187
187
  });
@@ -304,7 +304,7 @@ function compositeKeyUsageCheck(cert) {
304
304
  }
305
305
 
306
306
  var STATEFUL_HBS_OIDS = intrinsic.create(null);
307
- ["id-alg-hss-lms-hashsig", "id-alg-xmss-hashsig", "id-alg-xmssmt-hashsig"].forEach(function (n) { STATEFUL_HBS_OIDS[oid.byName(n)] = true; });
307
+ intrinsic.forEach(["id-alg-hss-lms-hashsig", "id-alg-xmss-hashsig", "id-alg-xmssmt-hashsig"], function (n) { STATEFUL_HBS_OIDS[oid.byName(n)] = true; });
308
308
 
309
309
  /** @internal RFC 9802 sec. 6 states the rule twice, and the two differ: a certification authority's
310
310
  * certificate may assert keyCertSign, an end entity's may not. Both must assert at least one of the values
@@ -404,7 +404,7 @@ function statefulHbsKeyUsageCheck(cert, isCa) {
404
404
  }
405
405
 
406
406
  var ML_KEM_OIDS = intrinsic.create(null);
407
- ["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"].forEach(function (n) { ML_KEM_OIDS[oid.byName(n)] = true; });
407
+ intrinsic.forEach(["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"], function (n) { ML_KEM_OIDS[oid.byName(n)] = true; });
408
408
 
409
409
  function kemKeyUsageCheck(cert) {
410
410
  var ku;
package/lib/pki-build.js CHANGED
@@ -359,8 +359,8 @@ var ATV_TYPE = intrinsic.assign(intrinsic.create(null), {
359
359
  * pre-encoded value for one of them must be a member. An attribute with no published short
360
360
  * name has a syntax this toolkit does not claim to know, and its value stays opaque. */
361
361
  var DIRECTORY_STRING_TAGS = intrinsic.assign(intrinsic.create(null), {});
362
- [asn1.TAGS.TELETEX_STRING, asn1.TAGS.PRINTABLE_STRING, asn1.TAGS.UNIVERSAL_STRING,
363
- asn1.TAGS.UTF8_STRING, asn1.TAGS.BMP_STRING].forEach(function (t) { DIRECTORY_STRING_TAGS[t] = 1; });
362
+ intrinsic.forEach([asn1.TAGS.TELETEX_STRING, asn1.TAGS.PRINTABLE_STRING, asn1.TAGS.UNIVERSAL_STRING,
363
+ asn1.TAGS.UTF8_STRING, asn1.TAGS.BMP_STRING], function (t) { DIRECTORY_STRING_TAGS[t] = 1; });
364
364
 
365
365
  var KU_BIT = intrinsic.assign(intrinsic.create(null), {
366
366
  digitalSignature: 0, nonRepudiation: 1, contentCommitment: 1, keyEncipherment: 2,
@@ -396,12 +396,12 @@ var SDA_ATTR_KEYS = intrinsic.assign(intrinsic.create(null), { type: 1, values:
396
396
  * statement's set is refused rather than ignored: a misspelled field would otherwise be dropped and
397
397
  * the certificate would carry a statement the caller did not write. */
398
398
  var QC_INFO_KEYS = intrinsic.create(null);
399
- [["qcType", { types: 1 }], ["qcIdentMethod", { methods: 1 }],
399
+ intrinsic.forEach([["qcType", { types: 1 }], ["qcIdentMethod", { methods: 1 }],
400
400
  ["qcCClegislation", { countries: 1 }], ["qcQSCDlegislation", { countries: 1 }],
401
401
  ["qcRetentionPeriod", { years: 1 }], ["qcLimitValue", { currency: 1, amount: 1, exponent: 1 }],
402
402
  ["qcPDS", { locations: 1 }],
403
403
  ["qcsPkixQCSyntaxV1", { semanticsIdentifier: 1, nameRegistrationAuthorities: 1 }],
404
- ["qcsPkixQCSyntaxV2", { semanticsIdentifier: 1, nameRegistrationAuthorities: 1 }]].forEach(function (r) {
404
+ ["qcsPkixQCSyntaxV2", { semanticsIdentifier: 1, nameRegistrationAuthorities: 1 }]], function (r) {
405
405
  QC_INFO_KEYS[oid.byName(r[0])] = intrinsic.assign(intrinsic.create(null), r[1]);
406
406
  });
407
407
  var QC_PDS_LOCATION_KEYS = intrinsic.assign(intrinsic.create(null), { url: 1, language: 1 });
@@ -69,10 +69,10 @@ function mldsaDigestSuitable(mlName, md) {
69
69
  }
70
70
 
71
71
  var SLHDSA_BY_OID = intrinsic.create(null);
72
- [["sha2-128s", "sha256"], ["sha2-128f", "sha256"], ["sha2-192s", "sha512"], ["sha2-192f", "sha512"],
73
- ["sha2-256s", "sha512"], ["sha2-256f", "sha512"], ["shake-128s", "shake128"], ["shake-128f", "shake128"],
74
- ["shake-192s", "shake256"], ["shake-192f", "shake256"], ["shake-256s", "shake256"], ["shake-256f", "shake256"]
75
- ].forEach(function (r) { SLHDSA_BY_OID[O("id-slh-dsa-" + r[0])] = { wc: "SLH-DSA-" + r[0].toUpperCase(), digest: r[1] }; });
72
+ intrinsic.forEach([["sha2-128s", "sha256"], ["sha2-128f", "sha256"], ["sha2-192s", "sha512"], ["sha2-192f", "sha512"],
73
+ ["sha2-256s", "sha512"], ["sha2-256f", "sha512"], ["shake-128s", "shake128"], ["shake-128f", "shake128"],
74
+ ["shake-192s", "shake256"], ["shake-192f", "shake256"], ["shake-256s", "shake256"], ["shake-256f", "shake256"]
75
+ ], function (r) { SLHDSA_BY_OID[O("id-slh-dsa-" + r[0])] = { wc: "SLH-DSA-" + _toUpperCase(r[0]), digest: r[1] }; });
76
76
 
77
77
  function _algId(name, shape) { return shape === "null" ? b.sequence([b.oid(O(name)), b.nullValue()]) : b.sequence([b.oid(O(name))]); }
78
78
  function _pssAlgId(digestName) {
package/lib/webcrypto.js CHANGED
@@ -176,9 +176,9 @@ var ML_DSA_NODE = intrinsic.assign(intrinsic.create(null), { "ML-DSA-44": "ml-ds
176
176
  var ML_KEM_NODE = intrinsic.assign(intrinsic.create(null), { "ML-KEM-512": "ml-kem-512", "ML-KEM-768": "ml-kem-768", "ML-KEM-1024": "ml-kem-1024" });
177
177
 
178
178
  var SLH_DSA_NODE = intrinsic.create(null);
179
- ["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
180
- "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
181
- ].forEach(function (s) { SLH_DSA_NODE["SLH-DSA-" + _toUpperCase(s)] = "slh-dsa-" + s; });
179
+ _forEach(["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
180
+ "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
181
+ ], function (s) { SLH_DSA_NODE["SLH-DSA-" + _toUpperCase(s)] = "slh-dsa-" + s; });
182
182
 
183
183
  var SIGN_VERIFY_NAMES = intrinsic.create(null);
184
184
  ["RSASSA-PKCS1-V1_5", "RSA-PSS", "ECDSA", "ED25519", "ED448", "HMAC"]
@@ -868,7 +868,7 @@ function _nodeKey(fn, who) {
868
868
  }
869
869
 
870
870
  var ML_KEM_INNER = intrinsic.create(null);
871
- ["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"].forEach(function (n) {
871
+ _forEach(["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"], function (n) {
872
872
  var row = oid.kemParams(n);
873
873
  ML_KEM_INNER[oid.byName(n)] = { ek: row.ek, dk: row.dk };
874
874
  });
@@ -1010,7 +1010,7 @@ var IMPORT_KEY_TYPE = intrinsic.assign(intrinsic.create(null), {
1010
1010
  "ED25519": _typeSet(["ed25519"]), "ED448": _typeSet(["ed448"]),
1011
1011
  "X25519": _typeSet(["x25519"]), "X448": _typeSet(["x448"]),
1012
1012
  });
1013
- [ML_DSA_NODE, ML_KEM_NODE, SLH_DSA_NODE].forEach(function (m) {
1013
+ _forEach([ML_DSA_NODE, ML_KEM_NODE, SLH_DSA_NODE], function (m) {
1014
1014
  _forEach(_keys(m), function (webName) { IMPORT_KEY_TYPE[webName] = _typeSet([m[webName]]); });
1015
1015
  });
1016
1016
  function _algFromImport(name, alg, keyObject) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.8.58",
3
+ "version": "0.8.59",
4
4
  "description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
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:41653943-4244-48b6-acbe-1493b54bad90",
5
+ "serialNumber": "urn:uuid:2b5749b0-053a-41de-947c-63a7a8df8028",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-10-07T04:10:13.613Z",
8
+ "timestamp": "2026-10-07T05:12:27.182Z",
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.8.58",
22
+ "bom-ref": "@blamejs/pki@0.8.59",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.8.58",
25
+ "version": "0.8.59",
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.8.58",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.8.59",
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.8.58",
57
+ "ref": "@blamejs/pki@0.8.59",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]