@blamejs/pki 0.7.2 → 0.7.4

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.7.4 — 2026-09-10
8
+
9
+ Two authoring inputs that were accepted quietly are now refused by name.
10
+
11
+ ### Fixed
12
+
13
+ - pki.csr.sign refuses an option it does not recognize. It reads the same three options its sibling pki.x509.sign reads, and that verb already refused anything else, so a name outside the set was accepted and dropped here alone: a caller asking for PEM output and misspelling the option received DER and no error. A name every object inherits, such as toString, is not a recognized option either. The three it does read are unchanged.
14
+ - A distinguished name given as an array with a missing element is refused with this toolkit's own typed error. Encoding walks the array per element, and a gap left the element absent all the way to the encoder, which then failed on it as an untyped read of undefined rather than as a verdict naming the input. It affected the subject of a certificate and of a certification request, and an explicitly supplied issuer name. Every other authoring list already refused a gap, and this now answers the same way, in the domain of the verb that was called.
15
+
16
+ ## v0.7.3 — 2026-09-10
17
+
18
+ A timestamp verification takes its options once, so every pass reads the same answer.
19
+
20
+ ### Changed
21
+
22
+ - pki.tsp.verify reads each option once. A token is examined in more than one pass, and opts.certs was consulted again by each of them, so an option reached through an accessor could hand one set of certificates to the signature check and another to the chain the signer is traced through. No route was found that turns this into a wrong verdict, and a caller passing options as plain values was never affected; the change makes the verdict describe one set of inputs rather than relying on a caller object to answer consistently. It follows the same read-once shape applied to the PKCS#12 verbs in 0.7.2.
23
+
7
24
  ## v0.7.2 — 2026-09-10
8
25
 
9
26
  A PKCS#12 iteration cap is read once, so it cannot be answered with a value that is not a number.
package/lib/csr-sign.js CHANGED
@@ -30,6 +30,10 @@ var csrVerify = require("./csr-verify");
30
30
 
31
31
  var CsrError = frameworkError.CsrError;
32
32
  var KNOWN_SPEC_KEYS = Object.assign(Object.create(null), { subject: 1, subjectPublicKey: 1, extensionRequest: 1, challengePassword: 1, attributes: 1 });
33
+ /** @internal The three this verb reads, which are the three `pki.x509.sign` reads. A name outside
34
+ * them was accepted and dropped, so asking for PEM and misspelling the option returned DER and
35
+ * reported nothing. */
36
+ var KNOWN_SIGN_OPTS = Object.assign(Object.create(null), { digestAlgorithm: 1, pem: 1, pss: 1 });
33
37
  var b = asn1.build;
34
38
  function _err(code, message, cause) { return new CsrError(code, message, cause); }
35
39
  function _signE(kind, message, cause) { return new CsrError("csr/" + kind, message, cause); }
@@ -99,6 +103,7 @@ function _sign(spec, key, opts) {
99
103
  opts = opts || {};
100
104
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("csr/bad-input", "the certification-request spec must be an object");
101
105
  guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "csr/bad-input", "unknown spec field ");
106
+ guard.identifier.assertKnownKeys(opts, KNOWN_SIGN_OPTS, _err, "csr/bad-input", "pki.csr.sign has an unknown option ");
102
107
  var signingKey = (key && typeof key === "object" && !Buffer.isBuffer(key) && !(key instanceof Uint8Array) && key.type == null && "key" in key) ? key.key : key;
103
108
  if (signingKey == null) throw _err("csr/bad-input", "a signing key (the subject's private key) is required");
104
109
 
package/lib/pki-build.js CHANGED
@@ -300,7 +300,10 @@ function makeBuilder(ctx) {
300
300
  if (guard.bytes.isByteSource(spec)) { var _nd = guard.bytes.snapshotSource(spec, ErrorClass, ctx.prefix + "/bad-name", "raw Name DER"); assertValidNameDer(_nd); return _nd; }
301
301
  if (typeof spec === "string") spec = [{ commonName: spec }];
302
302
  if (!_isArray(spec)) throw E("bad-name", "a name must be a string, an array of RDNs, or raw Name DER");
303
- return b.sequence(spec.map(encodeRdn));
303
+ /** @internal Held to the same density every other authoring list is held to. Mapping over a
304
+ * sparse array leaves the hole in place, so an absent element reached the encoder and surfaced
305
+ * as an untyped read of undefined rather than as a refusal a caller can act on. */
306
+ return b.sequence(reqDenseArray(spec, "a name's RDN array").map(encodeRdn));
304
307
  }
305
308
  function assertValidNameDer(der) {
306
309
  var node;
package/lib/tsp-sign.js CHANGED
@@ -596,6 +596,12 @@ async function verify(token, data, opts) {
596
596
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.verify options must be an object");
597
597
  guard.identifier.assertKnownKeys(opts, _VERIFY_OPTS, _err, "tsp/bad-input",
598
598
  "pki.tsp.verify has an unknown option (the anchor option is `trustAnchors`) ");
599
+ /** @internal Every option is taken once, here, and each pass below reads that copy. A token is
600
+ * examined in several passes: the signature over it, then the chain from the signer to the
601
+ * caller's anchors. An option left on the caller's object is read again by each, and an option
602
+ * reached through an accessor answers each read separately, so the certificates that verified the
603
+ * signature need not be the certificates the chain was built from. */
604
+ opts = guard.identifier.snapshotOptions(opts, _VERIFY_OPTS);
599
605
  if (opts.certs != null && (!Array.isArray(opts.certs) || !guard.list.allMatch(opts.certs, function (c) { return guard.bytes.isByteSource(c); }))) {
600
606
  throw _err("tsp/bad-input", "pki.tsp.verify opts.certs must be an array of DER certificate Buffers");
601
607
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
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:3b58cd3c-2ea1-4d00-9d93-8181e4a421b2",
5
+ "serialNumber": "urn:uuid:f78d7d30-68ed-48a9-905f-3e46577f4005",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-09-10T07:33:50.131Z",
8
+ "timestamp": "2026-09-10T10:14:34.771Z",
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.7.2",
22
+ "bom-ref": "@blamejs/pki@0.7.4",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.7.2",
25
+ "version": "0.7.4",
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.7.2",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.7.4",
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.7.2",
57
+ "ref": "@blamejs/pki@0.7.4",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]