@blamejs/pki 0.9.1 → 0.9.3

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.
@@ -293,7 +293,7 @@ var ATTRIBUTE_CERTIFICATE = pkix.signedEnvelope(NS, ACINFO, {
293
293
  * var aaCert = await pki.x509.sign({ subject: "Attribute Authority", subjectPublicKey: await pki.key.export(pair.publicKey),
294
294
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
295
295
  * var der = await pki.attrcert.sign(
296
- * { holder: { entityName: { directoryName: "CN=Alice" } },
296
+ * { holder: { entityName: { directoryName: "Alice" } },
297
297
  * notBeforeTime: new Date("2026-01-01T00:00:00Z"), notAfterTime: new Date("2027-01-01T00:00:00Z"),
298
298
  * attributes: { role: { roleName: { uniformResourceIdentifier: "urn:role:admin" } } } },
299
299
  * { cert: aaCert, key: key });
@@ -350,7 +350,7 @@ function parseV1(input, callerOpts) {
350
350
  * var aaCert = await pki.x509.sign({ subject: "Attribute Authority", subjectPublicKey: await pki.key.export(pair.publicKey),
351
351
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
352
352
  * var pemText = await pki.attrcert.sign(
353
- * { holder: { entityName: { directoryName: "CN=Alice" } },
353
+ * { holder: { entityName: { directoryName: "Alice" } },
354
354
  * notBeforeTime: new Date("2026-01-01T00:00:00Z"), notAfterTime: new Date("2027-01-01T00:00:00Z"),
355
355
  * attributes: { role: { roleName: { uniformResourceIdentifier: "urn:role:admin" } } } },
356
356
  * { cert: aaCert, key: key }, { pem: true });
@@ -375,7 +375,7 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label === null ? n
375
375
  * var aaCert = await pki.x509.sign({ subject: "Attribute Authority", subjectPublicKey: await pki.key.export(pair.publicKey),
376
376
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
377
377
  * var der = await pki.attrcert.sign(
378
- * { holder: { entityName: { directoryName: "CN=Alice" } },
378
+ * { holder: { entityName: { directoryName: "Alice" } },
379
379
  * notBeforeTime: new Date("2026-01-01T00:00:00Z"), notAfterTime: new Date("2027-01-01T00:00:00Z"),
380
380
  * attributes: { role: { roleName: { uniformResourceIdentifier: "urn:role:admin" } } } },
381
381
  * { cert: aaCert, key: key });
@@ -700,7 +700,7 @@ var DOOR = pkix.extensionDoor({
700
700
  * var key = await pki.key.export(pair.privateKey);
701
701
  * var aaCert = await pki.x509.sign({ subject: "Example AA", subjectPublicKey: await pki.key.export(pair.publicKey),
702
702
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
703
- * var acDer = await pki.attrcert.sign({ holder: { entityName: [{ directoryName: "CN=Holder" }] },
703
+ * var acDer = await pki.attrcert.sign({ holder: { entityName: [{ directoryName: "Holder" }] },
704
704
  * attributes: { role: { roleName: "https://example.test/role/admin" } }, serialNumber: 1n,
705
705
  * notBeforeTime: new Date("2026-01-01T00:00:00Z"), notAfterTime: new Date("2027-01-01T00:00:00Z"),
706
706
  * extensions: { noRevAvail: true } }, { cert: aaCert, key: key });
@@ -729,7 +729,7 @@ var decodeExtensions = DOOR.decodeExtensions;
729
729
  * var key = await pki.key.export(pair.privateKey);
730
730
  * var aaCert = await pki.x509.sign({ subject: "Example AA", subjectPublicKey: await pki.key.export(pair.publicKey),
731
731
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
732
- * var acDer = await pki.attrcert.sign({ holder: { entityName: [{ directoryName: "CN=Holder" }] },
732
+ * var acDer = await pki.attrcert.sign({ holder: { entityName: [{ directoryName: "Holder" }] },
733
733
  * attributes: { role: { roleName: "https://example.test/role/admin" } }, serialNumber: 1n,
734
734
  * notBeforeTime: new Date("2026-01-01T00:00:00Z"), notAfterTime: new Date("2027-01-01T00:00:00Z"),
735
735
  * extensions: { noRevAvail: true } }, { cert: aaCert, key: key });
@@ -1590,6 +1590,12 @@ function _reconstructDer(r, sigNode) {
1590
1590
  * reached by an explicit call and is not auto-routed by pki.schema.parse. The type-2 signedData and the
1591
1591
  * raw signature are surfaced as-is (a native verifier hashes them without re-serialization).
1592
1592
  *
1593
+ * A type-3 ECDSA signature is a fixed-width `r || s` that names no curve, so the same pair padded to a
1594
+ * wider accepted width reconstructs byte-identical DER: 64, 96 and 132 are three spellings of one
1595
+ * certificate. `signatureValueMinimalWidth` reports the narrowest width that represents the value, and
1596
+ * does not fail the parse. A reader that deduplicates, caches or blocklists by encoded form compares it
1597
+ * against `signatureValue.length`, and re-narrows to it for a key that is the same for every spelling.
1598
+ *
1593
1599
  * @example
1594
1600
  * // the RFC 7925 profiled certificate from draft-ietf-cose-cbor-encoded-cert Appendix A.1 (type 3)
1595
1601
  * var bytes = Buffer.from(
@@ -1703,7 +1709,10 @@ function _finishParse(f, root, nested, fields) {
1703
1709
  result._fieldBytes = root.bytes.subarray(1, root.bytes.length - f[10].bytes.length);
1704
1710
  if (type === 2) result.signedData = result._fieldBytes;
1705
1711
 
1706
- if (type === 3) result.reconstructedDer = _reconstructDer(result, f[10]);
1712
+ if (type === 3) {
1713
+ result.reconstructedDer = _reconstructDer(result, f[10]);
1714
+ result.signatureValueMinimalWidth = _minimalSigWidth(signatureValue);
1715
+ }
1707
1716
  return result;
1708
1717
  }
1709
1718
 
@@ -1960,11 +1969,37 @@ function _keyUsageBitsFromDer(extnValue, ctx) {
1960
1969
  var _NO_EXPIRY = C.TIME.seconds(Number(NO_EXPIRY_SECONDS));
1961
1970
  var NODE_TO_WEBCRYPTO = Object.assign(Object.create(null), { "prime256v1": "P-256", "secp384r1": "P-384", "secp521r1": "P-521" });
1962
1971
  var WEBCRYPTO_FIELD_BYTES = Object.assign(Object.create(null), { "P-256": 32, "P-384": 48, "P-521": 66 });
1972
+ /** @internal The accepted fixed-width `r || s` lengths, derived from the field sizes above rather
1973
+ * than written a fourth time. */
1974
+ var EC_SIG_WIDTHS = Object.keys(WEBCRYPTO_FIELD_BYTES).map(function (n) { return WEBCRYPTO_FIELD_BYTES[n] * 2; });
1963
1975
  var SIG_ALG_TO_CURVE = Object.assign(Object.create(null), { "ecdsaWithSHA256": "P-256", "ecdsaWithSHA384": "P-384", "ecdsaWithSHA512": "P-521" });
1964
- function _magBytes(intNode) {
1965
- var c = intNode.content, i = 0;
1966
- while (i < c.length - 1 && c[i] === 0x00) i++;
1967
- return c.length - i;
1976
+ /** @internal The significant byte count of a big-endian magnitude in `buf[from, to)`: the leading
1977
+ * zero bytes do not change the value they encode. Taken as a range so the fixed-width halves of an
1978
+ * r||s signature and a decoded INTEGER's content are measured by the one scan. */
1979
+ function _magBytes(buf, from, to) {
1980
+ var i = from;
1981
+ while (i < to - 1 && buf[i] === 0x00) i++;
1982
+ return to - i;
1983
+ }
1984
+
1985
+ /** @internal The narrowest accepted r||s width that encodes the same (r, s) as `sig`. A fixed-width
1986
+ * r||s carries no curve, so padding each half of a 64-byte signature to 32 more bytes reconstructs
1987
+ * byte-identical DER: 64, 96 and 132 are three spellings of one certificate, which makes a C509 byte
1988
+ * string something other than a unique identifier for what it encodes. Neither the width nor the
1989
+ * issuer's curve is recoverable from the bytes, and `parse` takes no option to be told, so this is
1990
+ * reported and the caller judges. The widths come from the field-size table rather than a fourth
1991
+ * copy of 32/48/66. */
1992
+ function _minimalSigWidth(sig) {
1993
+ var half = sig.length / 2;
1994
+ var need = _magBytes(sig, 0, half);
1995
+ var other = _magBytes(sig, half, sig.length);
1996
+ if (other > need) need = other;
1997
+ var narrowest = sig.length;
1998
+ for (var i = 0; i < EC_SIG_WIDTHS.length; i++) {
1999
+ var width = EC_SIG_WIDTHS[i];
2000
+ if (width >= need * 2 && width <= sig.length && width < narrowest) narrowest = width;
2001
+ }
2002
+ return narrowest;
1968
2003
  }
1969
2004
  function _sigMagWidth(derSig) {
1970
2005
  var n;
@@ -1975,7 +2010,8 @@ function _sigMagWidth(derSig) {
1975
2010
  var ch = n.children[i];
1976
2011
  if (ch.tagNumber !== asn1.TAGS.INTEGER || ch.tagClass !== "universal" || ch.constructed) throw _err("c509/bad-signature", "the ECDSA issuer signature r and s must be universal INTEGERs");
1977
2012
  }
1978
- return Math.max(_magBytes(n.children[0]), _magBytes(n.children[1]));
2013
+ var r0 = n.children[0].content, s0 = n.children[1].content;
2014
+ return Math.max(_magBytes(r0, 0, r0.length), _magBytes(s0, 0, s0.length));
1979
2015
  }
1980
2016
  var CURVE_ORDER = ["P-256", "P-384", "P-521"];
1981
2017
  function _minCurveForMag(mag) {
package/lib/schema-cmp.js CHANGED
@@ -803,7 +803,7 @@ var readName = _valueParser("Name", pkix.name(NS));
803
803
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
804
804
  * var csrDer = await pki.csr.sign({ subject: "client", subjectPublicKey: await pki.key.export(pair.publicKey) }, { key: key });
805
805
  * var der = await pki.cmp.build(
806
- * { header: { sender: { directoryName: "CN=client" }, recipient: { directoryName: "CN=CA" } },
806
+ * { header: { sender: { directoryName: "client" }, recipient: { directoryName: "CA" } },
807
807
  * body: { p10cr: csrDer } }, { key: key, cert: cert });
808
808
  * var m = pki.schema.cmp.parse(der);
809
809
  * m.body.arm; // "ir", "ip", "error", ...
@@ -837,7 +837,7 @@ var parse = pkix.makeParser({
837
837
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
838
838
  * var csrDer = await pki.csr.sign({ subject: "client", subjectPublicKey: await pki.key.export(pair.publicKey) }, { key: key });
839
839
  * var msg = await pki.cmp.build(
840
- * { header: { sender: { directoryName: "CN=client" }, recipient: { directoryName: "CN=CA" } },
840
+ * { header: { sender: { directoryName: "client" }, recipient: { directoryName: "CA" } },
841
841
  * body: { p10cr: csrDer } }, { key: key, cert: cert });
842
842
  * var pemText = pki.schema.cmp.pemEncode(msg);
843
843
  * var der = pki.schema.cmp.pemDecode(pemText);
@@ -861,7 +861,7 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label || "CMP", Pe
861
861
  * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: key });
862
862
  * var csrDer = await pki.csr.sign({ subject: "client", subjectPublicKey: await pki.key.export(pair.publicKey) }, { key: key });
863
863
  * var der = await pki.cmp.build(
864
- * { header: { sender: { directoryName: "CN=client" }, recipient: { directoryName: "CN=CA" } },
864
+ * { header: { sender: { directoryName: "client" }, recipient: { directoryName: "CA" } },
865
865
  * body: { p10cr: csrDer } }, { key: key, cert: cert });
866
866
  * var pem = pki.schema.cmp.pemEncode(der);
867
867
  */
@@ -1811,6 +1811,12 @@ function _acceptExtensionRecord(ext, E, code, key) {
1811
1811
  function keyUsagePermits(ns, allowed) {
1812
1812
  var kuOid = ns.oid.byName("keyUsage");
1813
1813
  var decoders = certExtensionDecoders(ns).byOid;
1814
+ /** @internal `allowed` may be a FUNCTION of the certificate, for a caller whose permitted set
1815
+ * depends on the subject key: an establishment bit authorizes nothing where the key's own family
1816
+ * cannot perform that establishment mechanism, and the certificate is the only place that says
1817
+ * which family it is. Every name the set names must be one the KeyUsage decoder defines, since
1818
+ * the record it answers from inherits nothing. */
1819
+ var perCert = typeof allowed === "function";
1814
1820
  return function (parsedCert) {
1815
1821
  var exts = (parsedCert && parsedCert.extensions) || [];
1816
1822
  for (var i = 0; i < exts.length; i++) {
@@ -1818,13 +1824,60 @@ function keyUsagePermits(ns, allowed) {
1818
1824
  var ku;
1819
1825
  try { ku = decoders[kuOid](exts[i].value); }
1820
1826
  catch (e) { void e; return false; }
1821
- for (var a = 0; a < allowed.length; a++) if (ku[allowed[a]] === true) return true;
1827
+ var names = perCert ? allowed(parsedCert) : allowed;
1828
+ for (var a = 0; a < names.length; a++) if (ku[names[a]] === true) return true;
1822
1829
  return false;
1823
1830
  }
1824
1831
  return true;
1825
1832
  };
1826
1833
  }
1827
1834
 
1835
+ /** @internal Which key-establishment bit a subject key's own family can carry, as one table the
1836
+ * callers that read an establishment usage share. The governing documents state it per family:
1837
+ * RFC 3279 sec. 2.3.1 lists keyEncipherment for an RSA key and does not list keyAgreement; RFC 5480
1838
+ * sec. 3 lists keyAgreement for id-ecPublicKey, id-ecDH and id-ecMQV, and RFC 8813 sec. 3 makes
1839
+ * keyEncipherment and dataEncipherment a MUST NOT for all three; RFC 8410 sec. 5 makes keyAgreement
1840
+ * a MUST for id-X25519 and id-X448; and RFC 9935 sec. 5 has an ML-KEM certificate assert
1841
+ * keyEncipherment as its only usage.
1842
+ *
1843
+ * A family in NEITHER column answers null, which is the refusing direction: an establishment bit
1844
+ * then authorizes nothing, and a signature bit is what the certificate has to assert. */
1845
+ var KEY_TRANSPORT_KEY_NAMES = ["rsaEncryption", "rsaesOaep"];
1846
+ /** @internal The three FIPS 203 sets and the composite KEM arms, matched by the prefix the registry
1847
+ * files them under rather than listed one at a time, so a set the registry gains later belongs to
1848
+ * this rule without a second edit. */
1849
+ var KEY_TRANSPORT_KEY_PREFIXES = ["id-ml-kem-", "id-MLKEM"];
1850
+ var KEY_AGREEMENT_KEY_NAMES = ["ecPublicKey", "X25519", "X448", "dhpublicnumber"];
1851
+
1852
+ var _estabBitByNs = new _WeakMapI();
1853
+
1854
+ function keyEstablishmentBit(ns) {
1855
+ var table = _weakGet(_estabBitByNs, ns.oid);
1856
+ if (table === undefined) {
1857
+ table = _assign(_create(null), {});
1858
+ var put = function (bit) {
1859
+ return function (n) {
1860
+ var dotted = ns.oid.byName(n);
1861
+ if (dotted !== undefined && dotted !== null) table[dotted] = bit;
1862
+ };
1863
+ };
1864
+ _forEach(KEY_TRANSPORT_KEY_NAMES, put("keyEncipherment"));
1865
+ _forEach(KEY_AGREEMENT_KEY_NAMES, put("keyAgreement"));
1866
+ var registry = ns.oid.all();
1867
+ _forEach(intrinsic.keys(registry), function (dotted) {
1868
+ var n = registry[dotted];
1869
+ if (typeof n !== "string") return;
1870
+ _forEach(KEY_TRANSPORT_KEY_PREFIXES, function (p) {
1871
+ if (_strIndexOf(n, p) === 0) table[dotted] = "keyEncipherment";
1872
+ });
1873
+ });
1874
+ _weakSet(_estabBitByNs, ns.oid, table);
1875
+ }
1876
+ return function (dotted) {
1877
+ return typeof dotted === "string" && _hasOwn(table, dotted) ? table[dotted] : null;
1878
+ };
1879
+ }
1880
+
1828
1881
  /** @internal The subject-key algorithms that can only ever SIGN, as one table the linter and the verifier
1829
1882
  * share. RFC 9883 sec. 6 states "The privateKeyPossessionStatement attribute MUST NOT be used to obtain a
1830
1883
  * signature certificate", and sec. 4 states the same requirement as a property of the request: "the
@@ -1912,8 +1965,13 @@ function certExtensionDecoders(ns) {
1912
1965
  for (var z = 0; z < bs.bytes.length; z++) { if (bs.bytes[z] !== 0) { anyBit = true; break; } }
1913
1966
  if (!anyBit) throw ns.E(C, "KeyUsage must assert at least one bit (RFC 5280 sec. 4.2.1.3)");
1914
1967
  schema.assertMinimalNamedBits(bs.unusedBits, bs.bytes, function (m) { throw ns.E(C, m); });
1915
- // allow:registry-table-inherits-object-prototype -- the decoded KeyUsage record, whose keys are the fixed KU_BITS names the schema declares; the certificate supplies none of them
1916
- var out = {};
1968
+ /** @internal The record inherits nothing. The exemption this carried rested on its keys being
1969
+ * the fixed KU_BITS names, and `keyUsagePermits` is called with a name that is NOT one of them:
1970
+ * `contentCommitment` is the X.509 spelling of the nonRepudiation bit and the BUILDER accepts
1971
+ * it, so an authorization gate asked for a name this decoder never defines and whatever
1972
+ * answered for it decided. Measured: a certificate confined to cRLSign went from maySign=false
1973
+ * to maySign=true under one assignment to `Object.prototype.contentCommitment`. */
1974
+ var out = _create(null);
1917
1975
  _forEach(KU_BITS, function (nm, bit) {
1918
1976
  var byte = bit >> 3, mask = 0x80 >> (bit & 7);
1919
1977
  out[nm] = byte < bs.bytes.length && (bs.bytes[byte] & mask) !== 0;
@@ -2725,6 +2783,7 @@ module.exports = intrinsic.freeze({
2725
2783
  crlEntryFixedCriticality: crlEntryFixedCriticality,
2726
2784
  certExtensionDecoders: certExtensionDecoders,
2727
2785
  keyUsagePermits: keyUsagePermits,
2786
+ keyEstablishmentBit: keyEstablishmentBit,
2728
2787
  signatureOnlyKeyOid: signatureOnlyKeyOid,
2729
2788
  scopedCertDecoder: scopedCertDecoder,
2730
2789
  crlExtensionDecoders: crlExtensionDecoders,
@@ -359,7 +359,7 @@ var TRUST_ANCHOR_LIST = schema.seqOf(TRUST_ANCHOR_CHOICE, {
359
359
  * var pair = await pki.key.generate("Ed25519");
360
360
  * var spki = await pki.key.export(pair.publicKey);
361
361
  * var der = pki.trustanchor.build({ anchors: [{ taInfo: {
362
- * pubKey: spki, keyId: Buffer.alloc(20, 1), certPath: { taName: "CN=Example Root" } } }] });
362
+ * pubKey: spki, keyId: Buffer.alloc(20, 1), certPath: { taName: "Example Root" } } }] });
363
363
  * pki.schema.trustanchor.parse(der).anchors[0].kind; // -> "taInfo"
364
364
  */
365
365
  var parse = pkix.makeParser({
@@ -385,7 +385,7 @@ var parse = pkix.makeParser({
385
385
  * var pair = await pki.key.generate("Ed25519");
386
386
  * var spki = await pki.key.export(pair.publicKey);
387
387
  * var list = pki.schema.trustanchor.parse(pki.trustanchor.build({ anchors: [{ taInfo: {
388
- * pubKey: spki, keyId: Buffer.alloc(20, 1), certPath: { taName: "CN=Example Root" } } }] }));
388
+ * pubKey: spki, keyId: Buffer.alloc(20, 1), certPath: { taName: "Example Root" } } }] }));
389
389
  * list.anchors[0].taInfo.certPath.taName.dn; // -> "CN=Example Root"
390
390
  */
391
391
  var parseInfo = pkix.makeParser({
@@ -407,7 +407,7 @@ var parseInfo = pkix.makeParser({
407
407
  * var pair = await pki.key.generate("Ed25519");
408
408
  * var der = pki.trustanchor.build({ anchors: [{ taInfo: {
409
409
  * pubKey: await pki.key.export(pair.publicKey), keyId: Buffer.alloc(20, 1),
410
- * certPath: { taName: "CN=Example Root" } } }] });
410
+ * certPath: { taName: "Example Root" } } }] });
411
411
  * pki.schema.trustanchor.pemDecode(pki.schema.trustanchor.pemEncode(der)).equals(der); // -> true
412
412
  */
413
413
  function pemDecode(text, label) { return pkix.pemDecode(text, label || "TRUST ANCHOR LIST", PemError); }
@@ -426,7 +426,7 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label || "TRUST AN
426
426
  * var pair = await pki.key.generate("Ed25519");
427
427
  * var der = pki.trustanchor.build({ anchors: [{ taInfo: {
428
428
  * pubKey: await pki.key.export(pair.publicKey), keyId: Buffer.alloc(20, 1),
429
- * certPath: { taName: "CN=Example Root" } } }] });
429
+ * certPath: { taName: "Example Root" } } }] });
430
430
  * pki.schema.trustanchor.pemEncode(der).indexOf("-----BEGIN TRUST ANCHOR LIST-----"); // -> 0
431
431
  */
432
432
  function pemEncode(der, label) { return pkix.pemEncode(der, label || "TRUST ANCHOR LIST", PemError); }
package/lib/sigstore.js CHANGED
@@ -1383,7 +1383,7 @@ async function _verifyEmbeddedScts(leaf, leafDer, issuer, logs, timeMs, atMs) {
1383
1383
  /** @internal A receipt the verifier refuses structurally counted as verified would be the whole leg
1384
1384
  * lost, so a fault is an unverified receipt and the next one is still tried. */
1385
1385
  function _sctVerifies(entry, sct, spki) {
1386
- return _ctVerifySct(entry, sct, spki).then(function (ok) { return ok === true; }, function () { return false; });
1386
+ return intrinsic.chain(_ctVerifySct(entry, sct, spki), function (ok) { return ok === true; }, function () { return false; });
1387
1387
  }
1388
1388
 
1389
1389
  /** @internal A receipt's own instant, in milliseconds. The parser's `timestampMs` is this same value
package/lib/smime.js CHANGED
@@ -457,8 +457,24 @@ function _readDescriptor(s, position) {
457
457
  var names = Object.getOwnPropertyNames(proto);
458
458
  for (var n = 0; n < names.length; n++) {
459
459
  var name = names[n];
460
- if ((name === "constructor" && proto !== s) || seen[name] === 1) continue;
461
- if (proto !== s && _isMethod(proto, name)) continue;
460
+ if (seen[name] === 1) continue;
461
+ /** @internal The three names this walk declines: a prototype level's `constructor`, which is
462
+ * the class rather than a field; a prototype level's method, likewise; and a callable
463
+ * descriptor's own function machinery, which `guard.identifier` knows the names of and which
464
+ * copying turned a legitimate callable into a descriptor `pki.cms.sign`'s own unknown-field
465
+ * door then refused.
466
+ *
467
+ * A declined name is marked SEEN, because the value `s[name]` reads is the one the NEAREST
468
+ * level holds and a deeper property of that name is shadowed and unreadable. Measured before
469
+ * the marking: a derived class's own `length` was declined and then read off the base class
470
+ * as a field; a generator's own `prototype` was declined and then its generator-prototype
471
+ * OBJECT was walked, which read as a signer nested too deeply to copy; and a prototype-level
472
+ * method was declined and then a data property of the same name one level up was copied,
473
+ * which set the field to the method shadowing it and reached the digest resolver as
474
+ * `unsupported RSA digest algorithm undefined`. */
475
+ if ((name === "constructor" && proto !== s) ||
476
+ (proto !== s && _isMethod(proto, name)) ||
477
+ (proto === s && guard.identifier.isOwnMachineryName(s, name))) { seen[name] = 1; continue; }
462
478
  seen[name] = 1;
463
479
  if (++fields > DESCRIPTOR_MAX_FIELDS) throw _err("smime/bad-input", "signer " + position + " carries more than " + DESCRIPTOR_MAX_FIELDS + " fields");
464
480
  copy[name] = s[name];
package/lib/trust.js CHANGED
@@ -1156,7 +1156,7 @@ function _subtreeOf(st) { return { tag: st.base.tagNumber, base: st.base.value }
1156
1156
  * var pair = await pki.key.generate("Ed25519");
1157
1157
  * var der = pki.trustanchor.build({ anchors: [{ taInfo: {
1158
1158
  * pubKey: await pki.key.export(pair.publicKey), keyId: Buffer.alloc(20, 1),
1159
- * certPath: { taName: "CN=Example Root" } } }] });
1159
+ * certPath: { taName: "Example Root" } } }] });
1160
1160
  * pki.trust.parseTrustAnchorList(der).anchors.length; // -> 1
1161
1161
  */
1162
1162
  function parseTrustAnchorList(input, opts) {
@@ -249,7 +249,7 @@ function _anchorDer(spec, i) {
249
249
  * pubKey: await pki.key.export(pair.publicKey),
250
250
  * keyId: Buffer.alloc(20, 1),
251
251
  * taTitle: "Example Root CA",
252
- * certPath: { taName: "CN=Example Root", pathLenConstraint: 2 } } }] });
252
+ * certPath: { taName: "Example Root", pathLenConstraint: 2 } } }] });
253
253
  * pki.schema.trustanchor.parse(der).anchors[0].taInfo.certPath.pathLenConstraint; // -> 2
254
254
  */
255
255
  function build(spec, opts) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
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:c9865553-89a9-487f-aef1-fe53df25b0ea",
5
+ "serialNumber": "urn:uuid:a3e510f1-a551-49fe-aabf-02db532556c6",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-10-08T04:38:54.565Z",
8
+ "timestamp": "2026-10-09T01:08:02.322Z",
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.9.1",
22
+ "bom-ref": "@blamejs/pki@0.9.3",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.9.1",
25
+ "version": "0.9.3",
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.9.1",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.9.3",
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.9.1",
57
+ "ref": "@blamejs/pki@0.9.3",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]