@blamejs/pki 0.8.61 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/MIGRATING.md +46 -0
  3. package/README.md +8 -1
  4. package/index.js +55 -26
  5. package/lib/acme.js +5 -5
  6. package/lib/asn1-der.js +1 -1
  7. package/lib/attrcert-sign.js +2 -2
  8. package/lib/cbor-det.js +4 -1
  9. package/lib/cmc-build.js +1 -1
  10. package/lib/cmp-build.js +5 -5
  11. package/lib/cmp-session.js +6 -3
  12. package/lib/cmp-verify.js +1 -1
  13. package/lib/cms-compress.js +5 -2
  14. package/lib/cms-decrypt.js +2 -2
  15. package/lib/cms-encrypt.js +2 -2
  16. package/lib/cms-sign.js +2 -2
  17. package/lib/constants.js +3 -0
  18. package/lib/crl-sign.js +3 -3
  19. package/lib/crmf-sign.js +1 -1
  20. package/lib/csr-sign.js +1 -1
  21. package/lib/ct.js +14 -13
  22. package/lib/est.js +101 -29
  23. package/lib/framework-error.js +1 -1
  24. package/lib/guard-bytes.js +1 -1
  25. package/lib/guard-limits.js +3 -2
  26. package/lib/hpke.js +2 -2
  27. package/lib/http-retry-after.js +4 -1
  28. package/lib/http-transport.js +6 -6
  29. package/lib/inspect.js +9 -4
  30. package/lib/jose.js +3 -3
  31. package/lib/merkle.js +4 -4
  32. package/lib/mime.js +124 -17
  33. package/lib/ocsp.js +2 -2
  34. package/lib/path-validate.js +3 -3
  35. package/lib/pbes2.js +8 -4
  36. package/lib/pkcs12-build.js +5 -5
  37. package/lib/scep.js +1 -1
  38. package/lib/schema-engine.js +12 -12
  39. package/lib/schema-pkix.js +12 -12
  40. package/lib/sign-scheme.js +2 -2
  41. package/lib/sigstore.js +1 -1
  42. package/lib/smime.js +11 -12
  43. package/lib/tlog.js +2 -2
  44. package/lib/tls-cert-compress.js +3 -3
  45. package/lib/tsp-sign.js +6 -6
  46. package/lib/tuf.js +3 -3
  47. package/lib/webauthn-mds.js +1 -1
  48. package/lib/webauthn.js +1 -1
  49. package/lib/x509-sign.js +3 -3
  50. package/package.json +1 -1
  51. package/sbom.cdx.json +6 -6
package/lib/smime.js CHANGED
@@ -33,6 +33,10 @@
33
33
  * algorithm-agnostic.
34
34
  */
35
35
 
36
+ /** @internal The record constructor, captured at load, for the reason the same capture in
37
+ * `lib/inspect.js` gives: requiring the guard-intrinsic captures arms the module whole, which counts
38
+ * 176 live runtime reads here. */
39
+ var _create = Object.create;
36
40
  var frameworkError = require("./framework-error.js");
37
41
  var mime = require("./mime.js");
38
42
  var cms = require("./cms-verify.js");
@@ -265,7 +269,6 @@ function _declaresHp(content) {
265
269
 
266
270
  function _noneSurface() { return { protectedHeaders: null, headerProtection: { present: false, mode: null, fromMismatch: null, confidential: [], legacy: null } }; }
267
271
 
268
- function _contentTypeCount(headers) { var n = 0; headers.forEach(function (h) { if (h.lname === "content-type") n++; }); return n; }
269
272
 
270
273
  var RFC5322_SINGLETON = new Set(["date", "from", "sender", "reply-to", "to", "cc", "bcc", "message-id", "in-reply-to", "references", "subject", "return-path"]);
271
274
 
@@ -330,7 +333,6 @@ function _legacyHpSurface(canon, outerEnt, mode, enabled) {
330
333
  if (partC.contentType.type !== "message/rfc822") return _noneSurface();
331
334
  partD = mime.parse(partC.body, SmimeError, "smime/bad-header-protection");
332
335
  } catch (_e) { return _noneSurface(); }
333
- if (_contentTypeCount(partC.headers) > 1 || _contentTypeCount(partD.headers) > 1) return _noneSurface();
334
336
  if (mime.hasParam(partD.contentType.value, "hp")) return _noneSurface();
335
337
  if (_isCryptoLayer(partD.contentType.type)) return _noneSurface();
336
338
  var ex = _extractProtected(partD.headers);
@@ -549,9 +551,6 @@ function _hpSurface(content, outerEnt, expectedMode, authenticated, legacyEnable
549
551
  var canon = mime.canonicalizeText(content);
550
552
  if (!_declaresHp(canon)) return _legacyHpSurface(canon, outerEnt, expectedMode, legacyEnabled);
551
553
  var inner = mime.parse(canon, SmimeError, "smime/bad-header-protection");
552
- var ctCount = _contentTypeCount(inner.headers);
553
- if (ctCount > 1) throw _err("smime/bad-header-protection", "a header-protected payload must carry exactly one Content-Type field (found " + ctCount + ")");
554
- if (mime.paramNameCount(inner.contentType.value, "hp") > 1) throw _err("smime/bad-header-protection", "a header-protected payload declares the hp parameter more than once");
555
554
  var raw = inner.contentType.params.hp;
556
555
  if (raw === undefined) throw _err("smime/bad-header-protection", "a header-protected payload declares a bare hp parameter with no value (expected hp=\"clear\" or hp=\"cipher\")");
557
556
  var hp = raw.toLowerCase();
@@ -654,7 +653,7 @@ function _base64Body(der) {
654
653
  */
655
654
  async function sign(content, signers, opts) {
656
655
  content = _fixedContent(content);
657
- opts = opts || {};
656
+ opts = opts || _create(null);
658
657
  opts = _knownOpts(opts, SIGN_OPTS, "sign");
659
658
  signers = _snapshotSignersFitForMail(signers);
660
659
  var hp = opts.protectHeaders === true;
@@ -767,7 +766,7 @@ function _capped(msg) {
767
766
  * if (res.valid) { res.content; res.signers[0].sid; }
768
767
  */
769
768
  async function verify(message, opts) {
770
- opts = opts || {};
769
+ opts = opts || _create(null);
771
770
  opts = _knownOpts(opts, VERIFY_OPTS, "verify");
772
771
  var ent = mime.parse(message, SmimeError, "smime/bad-mime");
773
772
  var ct = ent.contentType;
@@ -877,7 +876,7 @@ function _cmsEncryptOpts(opts) {
877
876
  */
878
877
  async function encrypt(content, recipients, opts) {
879
878
  content = _fixedContent(content);
880
- opts = opts || {};
879
+ opts = opts || _create(null);
881
880
  opts = _knownOpts(opts, ENCRYPT_OPTS, "encrypt");
882
881
  var hp = opts.protectHeaders === true;
883
882
  var hpList = hp ? _hpHeaderList(opts.headers) : null;
@@ -934,7 +933,7 @@ async function encrypt(content, recipients, opts) {
934
933
  * res.authenticated; // true here (an AEAD content cipher); false for an enveloped-only CBC message, which carries no integrity
935
934
  */
936
935
  async function decrypt(message, keyMaterial, opts) {
937
- opts = opts || {};
936
+ opts = opts || _create(null);
938
937
  opts = _knownOpts(opts, DECRYPT_OPTS, "decrypt");
939
938
  var ent = mime.parse(message, SmimeError, "smime/bad-mime");
940
939
  var ct = ent.contentType;
@@ -984,7 +983,7 @@ async function decrypt(message, keyMaterial, opts) {
984
983
  */
985
984
  async function compress(content, opts) {
986
985
  content = _fixedContent(content);
987
- opts = opts || {};
986
+ opts = opts || _create(null);
988
987
  opts = _knownOpts(opts, COMPRESS_OPTS, "compress");
989
988
  var entity = _entityBytes(content, opts);
990
989
  var cOpts = {};
@@ -1018,7 +1017,7 @@ async function compress(content, opts) {
1018
1017
  * res.content; // the recovered inner MIME entity
1019
1018
  */
1020
1019
  async function decompress(message, opts) {
1021
- opts = opts || {};
1020
+ opts = opts || _create(null);
1022
1021
  opts = _knownOpts(opts, DECOMPRESS_OPTS, "decompress");
1023
1022
  var ent = mime.parse(message, SmimeError, "smime/bad-mime");
1024
1023
  var ct = ent.contentType;
@@ -1064,7 +1063,7 @@ var CERTS_ONLY_OPTS = Object.assign(Object.create(null), { crls: 1 });
1064
1063
  * var p7c = pki.smime.buildCertsOnly([leafDer]);
1065
1064
  */
1066
1065
  function buildCertsOnly(certs, opts) {
1067
- opts = opts || {};
1066
+ opts = opts || _create(null);
1068
1067
  opts = _knownOpts(opts, CERTS_ONLY_OPTS, "buildCertsOnly");
1069
1068
  var der = _toBuf(cms.certsOnly(certs, { crls: opts.crls }));
1070
1069
  return _capped(Buffer.concat([_pkcs7MimeHead("certs-only", "smime.p7c"), _base64Body(der), mime.CRLF]));
package/lib/tlog.js CHANGED
@@ -671,7 +671,7 @@ function parseCheckpoint(input) {
671
671
  */
672
672
  var _CHECKPOINT_OPTS = _assign(_create(null), { origin: 1 });
673
673
  async function verifyCheckpoint(input, keys, opts) {
674
- opts = opts || {};
674
+ opts = opts || _create(null);
675
675
  guard.identifier.assertKnownKeys(opts, _CHECKPOINT_OPTS, _err,
676
676
  "tlog/bad-input", "unknown verifyCheckpoint option ");
677
677
  /** @internal ONE read of the caller's input, shared by the decode and the verification below. Reading
@@ -1209,7 +1209,7 @@ async function _tilePath(lo, hi, m, size, unitAt) {
1209
1209
  */
1210
1210
  var _INCLUSION_PROOF_KEYS = _assign(_create(null), { index: 1, size: 1, read: 1 });
1211
1211
  async function inclusionProof(opts) {
1212
- opts = opts || {};
1212
+ opts = opts || _create(null);
1213
1213
  guard.identifier.assertKnownKeys(opts, _INCLUSION_PROOF_KEYS, _err,
1214
1214
  "tlog/bad-input", "unknown inclusionProof option ");
1215
1215
  var size = guard.range.uint64(opts.size, _err, "tlog/bad-input", "size");
@@ -167,7 +167,7 @@ function _resolveAllowed(opts) {
167
167
  * pki.schema.x509.parse(out.certificate.entries[0].certData).subject;
168
168
  */
169
169
  function decompressCertificate(bytes, opts) {
170
- opts = opts || {};
170
+ opts = opts || intrinsic.create(null);
171
171
  /** @internal Viewed, CAPPED, then COPIED, and only then are the options read. A view stays a window
172
172
  * onto the caller's buffer, and `_resolveCap` reads `opts`, which is caller code when it is an
173
173
  * accessor: a `maxOutputBytes` getter that wrote another valid message of the same length over the
@@ -262,7 +262,7 @@ function decompressCertificate(bytes, opts) {
262
262
  * pki.schema.x509.parse(msg.entries[0].certData).subject;
263
263
  */
264
264
  function parseCertificateMessage(bytes, opts) {
265
- opts = opts || {};
265
+ opts = opts || intrinsic.create(null);
266
266
  var type = opts.certificateType === undefined ? "X509" : opts.certificateType;
267
267
  if (type !== "X509" && type !== "RawPublicKey") {
268
268
  throw _err("tls/bad-input", "opts.certificateType must be \"X509\" or \"RawPublicKey\"");
@@ -315,7 +315,7 @@ function parseCertificateMessage(bytes, opts) {
315
315
  * wire.length < message.length; // true
316
316
  */
317
317
  function compressCertificate(certificateMessage, opts) {
318
- opts = opts || {};
318
+ opts = opts || intrinsic.create(null);
319
319
  /** @internal Copied, not viewed. `opts.algorithm` is read below, and reading an option is caller code
320
320
  * when it is an accessor, so over a view it would run between the message being looked at and being
321
321
  * compressed and replace what this verb compresses, after it had accepted the message it was handed.
package/lib/tsp-sign.js CHANGED
@@ -155,7 +155,7 @@ var _SIGN_OPTS = intrinsic.assign(intrinsic.create(null), {
155
155
  });
156
156
 
157
157
  function _sign(messageImprint, tsa, opts) {
158
- opts = opts || {};
158
+ opts = opts || intrinsic.create(null);
159
159
  if (messageImprint && typeof messageImprint === "object" && !Buffer.isBuffer(messageImprint)) {
160
160
  guard.identifier.assertKnownKeys(messageImprint, _IMPRINT_KEYS, _err, "tsp/bad-input", function (k) {
161
161
  return "unknown messageImprint field " + JSON.stringify(k) + " (the imprint is { hashAlgorithm, hashedMessage })";
@@ -169,7 +169,7 @@ function _sign(messageImprint, tsa, opts) {
169
169
  " (the TSA is { cert, key }; a signing option belongs in the third argument)";
170
170
  });
171
171
  }
172
- var mi = messageImprint || {};
172
+ var mi = messageImprint || intrinsic.create(null);
173
173
  if (!mi.hashAlgorithm || !NODE_DIGEST[guard.text.keyOf(mi.hashAlgorithm)]) throw _err("tsp/unsupported-algorithm", "messageImprint.hashAlgorithm must be a supported hash name");
174
174
  if (!guard.bytes.isByteSource(mi.hashedMessage)) throw _err("tsp/bad-input", "messageImprint.hashedMessage must be a BufferSource");
175
175
  var _signHmLen = guard.bytes.source(mi.hashedMessage, TspError, "tsp/bad-input", "messageImprint.hashedMessage").length;
@@ -292,10 +292,10 @@ function _assertImprint(mi) {
292
292
  var _REQUEST_OPTS = intrinsic.assign(intrinsic.create(null), { reqPolicy: 1, nonce: 1, certReq: 1, extensions: 1, pem: 1 });
293
293
 
294
294
  function request(messageImprint, opts) {
295
- opts = opts || {};
295
+ opts = opts || intrinsic.create(null);
296
296
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.request options must be an object");
297
297
  guard.identifier.assertKnownKeys(opts, _REQUEST_OPTS, _err, "tsp/bad-input", "pki.tsp.request has an unknown option ");
298
- var mi = messageImprint || {};
298
+ var mi = messageImprint || intrinsic.create(null);
299
299
  if (mi && typeof mi === "object" && !Buffer.isBuffer(mi)) {
300
300
  guard.identifier.assertKnownKeys(mi, _IMPRINT_KEYS, _err, "tsp/bad-input", function (k) {
301
301
  return "unknown messageImprint field " + JSON.stringify(k) +
@@ -379,7 +379,7 @@ function parseRequest(input) { return schemaTsp.parseRequest(input); }
379
379
  var _RESPONSE_OPTS = intrinsic.assign(intrinsic.create(null), { status: 1, statusString: 1, failInfo: 1, pem: 1 });
380
380
 
381
381
  function response(token, opts) {
382
- opts = opts || {};
382
+ opts = opts || intrinsic.create(null);
383
383
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.response options must be an object");
384
384
  guard.identifier.assertKnownKeys(opts, _RESPONSE_OPTS, _err, "tsp/bad-input", "pki.tsp.response has an unknown option ");
385
385
  var st = opts.status;
@@ -664,7 +664,7 @@ function _anyCritical(extensions) {
664
664
  }
665
665
 
666
666
  async function verify(token, data, opts) {
667
- opts = opts || {};
667
+ opts = opts || intrinsic.create(null);
668
668
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.verify options must be an object");
669
669
  guard.identifier.assertKnownKeys(opts, _VERIFY_OPTS, _err, "tsp/bad-input",
670
670
  "pki.tsp.verify has an unknown option (the anchor option is `trustAnchors`) ");
package/lib/tuf.js CHANGED
@@ -804,7 +804,7 @@ function _checkedPublicKey(key, d) {
804
804
  guard.text.showValue(importedType) + " public key, so the signature would be checked " +
805
805
  "under an algorithm the metadata does not name");
806
806
  }
807
- var details = guard.crypto.keyDetails(imported) || {};
807
+ var details = guard.crypto.keyDetails(imported) || _create(null);
808
808
  if (d.curve !== null && details.namedCurve !== d.curve) {
809
809
  throw _err("tuf/bad-key", "the scheme " + key.scheme + " names the " + d.curve +
810
810
  " curve; the key is on " + guard.text.showValue(details.namedCurve));
@@ -889,7 +889,7 @@ function _publicFromPem(pem, label) {
889
889
  */
890
890
  var _VERIFY_KEYS = intrinsic.assign(_create(null), { metadata: 1, keys: 1, role: 1 });
891
891
  async function verifySignatures(opts) {
892
- opts = opts || {};
892
+ opts = opts || _create(null);
893
893
  guard.identifier.assertKnownKeys(opts, _VERIFY_KEYS, _err, "tuf/bad-input", "unknown verifySignatures option ");
894
894
  /** @internal Every caller-owned input is taken ONCE, at the top, and everything below reads the copy.
895
895
  * Validating the caller's object and then reading it again is two reads, and a member reached through an
@@ -1297,7 +1297,7 @@ function _asRoot(input, label) {
1297
1297
  */
1298
1298
  var _UPDATE_KEYS = intrinsic.assign(_create(null), { trustedRoot: 1, candidates: 1, now: 1 });
1299
1299
  async function updateRoot(opts) {
1300
- opts = opts || {};
1300
+ opts = opts || _create(null);
1301
1301
  guard.identifier.assertKnownKeys(opts, _UPDATE_KEYS, _err, "tuf/bad-input", "unknown updateRoot option ");
1302
1302
  /** @internal The instant is CAPTURED here, at the call, into a Date this function owns. A Date is
1303
1303
  * mutable and the caller keeps theirs, and the freeze-attack check runs at the END, after a signature
@@ -318,7 +318,7 @@ function _verifyMetadataBlob(blob, opts) {
318
318
  });
319
319
  var leaf = chain[0];
320
320
  _assertLeafSigns(leaf);
321
- var leafAlg = (leaf.subjectPublicKeyInfo.algorithm || {}).name;
321
+ var leafAlg = (leaf.subjectPublicKeyInfo.algorithm || intrinsic.create(null)).name;
322
322
  var leafSchemes = typeof leafAlg === "string" ? LEAF_SCHEMES_BY_SPKI_ALG[leafAlg] : undefined;
323
323
  if (!leafSchemes || !leafSchemes[algRow.scheme]) {
324
324
  throw _err("webauthn/unsupported-algorithm", "the metadata BLOB alg " + header.alg + " does not match the x5c leaf key type " + intrinsic.stringify(leafAlg));
package/lib/webauthn.js CHANGED
@@ -268,7 +268,7 @@ function _certKeyAlgNames(cose) {
268
268
  return [];
269
269
  }
270
270
  function _assertCertKeyAlgorithm(cert, cose, E) {
271
- var alg = (cert.subjectPublicKeyInfo && cert.subjectPublicKeyInfo.algorithm) || {};
271
+ var alg = (cert.subjectPublicKeyInfo && cert.subjectPublicKeyInfo.algorithm) || intrinsic.create(null);
272
272
  var want = _certKeyAlgNames(cose);
273
273
  if (!want.length || intrinsic.indexOf(want, alg.name) < 0) {
274
274
  throw E("webauthn/key-mismatch", "the attestation certificate carries a " + intrinsic.stringify(alg.name) +
package/lib/x509-sign.js CHANGED
@@ -166,7 +166,7 @@ var RESERVED_ALT_EXTS = intrinsic.assign(intrinsic.create(null), (function () {
166
166
  })());
167
167
 
168
168
  function _buildExtensions(extSpec, ctx) {
169
- if (extSpec == null) extSpec = {};
169
+ if (extSpec == null) extSpec = intrinsic.create(null);
170
170
  if (_isArray(extSpec)) {
171
171
  var seenExt = intrinsic.create(null), arrCa = false, arrKeyCertSign = false, arrPathLen = false, arrNameConstraints = false;
172
172
  var oidBc = O("basicConstraints"), oidKu = O("keyUsage"), oidNc = O("nameConstraints"), oidPm = O("policyMappings");
@@ -708,9 +708,9 @@ function sign(spec, issuer, opts) {
708
708
  }
709
709
 
710
710
  function _sign(spec, issuer, opts) {
711
- opts = opts || {};
711
+ opts = opts || intrinsic.create(null);
712
712
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("x509/bad-input", "the certificate spec must be an object");
713
- issuer = issuer || {};
713
+ issuer = issuer || intrinsic.create(null);
714
714
  guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "x509/bad-input", function (k) {
715
715
  return "unknown certificate spec field " + JSON.stringify(k) +
716
716
  (k === "issuer" ? "; the issuer is the SECOND argument to pki.x509.sign, not a spec field" : "") +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.8.61",
3
+ "version": "0.9.1",
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:dc638a09-3eb3-4620-b84b-f3edd3453ec6",
5
+ "serialNumber": "urn:uuid:c9865553-89a9-487f-aef1-fe53df25b0ea",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-10-07T23:02:52.146Z",
8
+ "timestamp": "2026-10-08T04:38:54.565Z",
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.61",
22
+ "bom-ref": "@blamejs/pki@0.9.1",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.8.61",
25
+ "version": "0.9.1",
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.61",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.9.1",
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.61",
57
+ "ref": "@blamejs/pki@0.9.1",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]