@blamejs/pki 0.8.60 → 0.9.0

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 (59) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +7 -0
  3. package/index.js +55 -26
  4. package/lib/acme.js +5 -5
  5. package/lib/asn1-der.js +1 -1
  6. package/lib/attrcert-sign.js +2 -2
  7. package/lib/cbor-det.js +4 -1
  8. package/lib/cmc-build.js +15 -10
  9. package/lib/cmp-build.js +5 -5
  10. package/lib/cmp-session.js +6 -3
  11. package/lib/cmp-verify.js +1 -1
  12. package/lib/cms-compress.js +5 -2
  13. package/lib/cms-decrypt.js +17 -17
  14. package/lib/cms-digest.js +2 -3
  15. package/lib/cms-encrypt.js +17 -18
  16. package/lib/cms-sign.js +2 -2
  17. package/lib/composite-kem.js +28 -29
  18. package/lib/crl-sign.js +3 -3
  19. package/lib/crmf-sign.js +12 -18
  20. package/lib/csr-sign.js +1 -1
  21. package/lib/ct.js +25 -22
  22. package/lib/est.js +12 -12
  23. package/lib/framework-error.js +1 -1
  24. package/lib/guard-bytes.js +1 -1
  25. package/lib/guard-crypto.js +506 -14
  26. package/lib/guard-limits.js +3 -2
  27. package/lib/guard-secret.js +3 -2
  28. package/lib/hpke.js +26 -26
  29. package/lib/http-digest.js +5 -7
  30. package/lib/http-retry-after.js +4 -1
  31. package/lib/http-transport.js +6 -6
  32. package/lib/inspect.js +9 -4
  33. package/lib/jose.js +3 -3
  34. package/lib/key.js +41 -29
  35. package/lib/merkle.js +4 -4
  36. package/lib/ocsp.js +3 -4
  37. package/lib/path-validate.js +3 -3
  38. package/lib/pbes2.js +14 -11
  39. package/lib/pkcs12-build.js +10 -11
  40. package/lib/pki-build.js +3 -3
  41. package/lib/scep.js +8 -9
  42. package/lib/schema-engine.js +12 -12
  43. package/lib/schema-pkix.js +12 -12
  44. package/lib/schema-tsp.js +3 -3
  45. package/lib/shbs.js +3 -6
  46. package/lib/sign-scheme.js +4 -4
  47. package/lib/sigstore.js +10 -10
  48. package/lib/smime.js +12 -9
  49. package/lib/tlog.js +5 -4
  50. package/lib/tls-cert-compress.js +3 -3
  51. package/lib/tsp-sign.js +6 -6
  52. package/lib/tuf.js +6 -5
  53. package/lib/validator-cose.js +2 -2
  54. package/lib/webauthn-mds.js +4 -8
  55. package/lib/webauthn.js +5 -12
  56. package/lib/webcrypto.js +61 -46
  57. package/lib/x509-sign.js +3 -3
  58. package/package.json +1 -1
  59. package/sbom.cdx.json +6 -6
package/lib/pbes2.js CHANGED
@@ -3,8 +3,10 @@
3
3
  "use strict";
4
4
  // @internal
5
5
 
6
- var nodeCrypto = require("crypto");
7
6
  var asn1 = require("./asn1-der");
7
+ /** @internal The record constructor, captured at load, for the reason the same capture in
8
+ * `lib/inspect.js` gives: arming this module counts 25 live runtime reads. */
9
+ var _create = Object.create;
8
10
  var oid = require("./oid");
9
11
  var webcrypto = require("./webcrypto");
10
12
  var guard = require("./guard-all");
@@ -102,25 +104,25 @@ function parsePbkdf2Params(paramsDer, opts, E, prefix, strictPrf) {
102
104
  }
103
105
 
104
106
  function cbcEncrypt(key, iv, plaintext, keyBits, E, code) {
105
- var c = nodeCrypto.createCipheriv("aes-" + keyBits + "-cbc", key, iv);
107
+ var c = guard.crypto.cipher("aes-" + keyBits + "-cbc", key, iv);
106
108
  return guard.secret.cipherFinish(c, plaintext, E, code, "a content-encryption intermediate");
107
109
  }
108
110
  function cbcDecrypt(key, iv, ct, keyBits, E, code) {
109
- var d = nodeCrypto.createDecipheriv("aes-" + keyBits + "-cbc", key, iv);
111
+ var d = guard.crypto.decipher("aes-" + keyBits + "-cbc", key, iv);
110
112
  return guard.secret.cipherFinish(d, ct, E, code, "the partially recovered plaintext");
111
113
  }
112
114
 
113
115
  function pbes2Encrypt(pwBytes, plaintext, opts, E, prefix) {
114
- opts = opts || {};
116
+ opts = opts || _create(null);
115
117
  var cipherName = opts.cipher || "aes256-CBC";
116
118
  var keyBits = CONTENT_KEYBITS[O(cipherName)];
117
119
  if (!keyBits || cipherName.indexOf("CBC") === -1) throw E(prefix + "/bad-input", "unsupported PBES2 cipher " + cipherName + " (AES-CBC only)");
118
120
  var prf = opts.prf || "hmacWithSHA256";
119
121
  var prfNode = prfNodeByName(prf, E, prefix);
120
122
  var iterations = assertIterations(opts.iterations == null ? 2048 : opts.iterations, E, prefix);
121
- var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) : nodeCrypto.randomBytes(16);
122
- var iv = opts.iv != null ? opts.iv : nodeCrypto.randomBytes(16);
123
- var key = nodeCrypto.pbkdf2Sync(pwBytes, salt, iterations, keyBits / 8, prfNode);
123
+ var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) : guard.crypto.randomBytes(16);
124
+ var iv = opts.iv != null ? opts.iv : guard.crypto.randomBytes(16);
125
+ var key = guard.crypto.pbkdf2(pwBytes, salt, iterations, keyBits / 8, prfNode);
124
126
  try {
125
127
  return { algId: pbes2AlgId(salt, iterations, prf, cipherName, iv), ct: cbcEncrypt(key, iv, plaintext, keyBits, E, prefix + "/bad-input") };
126
128
  } finally {
@@ -152,7 +154,7 @@ function pbes2Decrypt(pwBytes, params, ciphertext, opts, E, prefix, budget) {
152
154
  budget.rounds -= pb.iterations;
153
155
  if (budget.rounds < 0) throw E(prefix + "/iteration-limit", "the aggregate PBKDF2 key-derivation work exceeds the budget (a hostile many-element input)");
154
156
  }
155
- var dk = nodeCrypto.pbkdf2Sync(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
157
+ var dk = guard.crypto.pbkdf2(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
156
158
  try { return cbcDecrypt(dk, iv, ciphertext, keyBits, E, prefix + "/decrypt-failed"); }
157
159
  catch (_e) { throw E(prefix + "/decrypt-failed", "decryption failed"); }
158
160
  finally { guard.secret.zeroize(dk, E, prefix + "/bad-input", "the password-derived decryption key"); }
@@ -169,9 +171,10 @@ function pbmac1AlgId(desc) {
169
171
 
170
172
  function pbmac1(pwBytes, salt, iterationCount, keyLength, prfHash, macHash, message) {
171
173
  var subtle = webcrypto.webcrypto.subtle;
172
- /** @internal Every step is continued through the capture, and the wipe is attached on BOTH outcomes
173
- * rather than through `finally`, which calls the receiver's own `then`. These steps derive the key
174
- * a PBMAC1 integrity tag is computed under, so a replacement settling one hands back a tag computed
174
+ /** @internal Every step is continued through the capture, and the wipe is attached on the success
175
+ * outcome and the failure outcome separately, not through `finally`, which calls the receiver's own
176
+ * `then`. These steps derive the key a PBMAC1 integrity tag is computed under, so a replacement
177
+ * settling one hands back a tag computed
175
178
  * under bytes nobody derived, and skips the wipe that keeps the derived key from outliving it. */
176
179
  var base = guard.async.chain(subtle.importKey("raw", pwBytes, { name: "PBKDF2" }, false, ["deriveBits"]),
177
180
  function (baseKey) {
@@ -17,7 +17,6 @@
17
17
  * @card Build a password-integrity PKCS#12 store (RFC 7292 / RFC 9579) and verify its MAC.
18
18
  */
19
19
 
20
- var nodeCrypto = require("crypto");
21
20
  var asn1 = require("./asn1-der");
22
21
  var rc2 = require("./rc2");
23
22
  var oid = require("./oid");
@@ -150,7 +149,7 @@ function _p12Kdf(hashName, id, pwBytes, salt, iterations, nBytes) {
150
149
  var A = Buffer.concat([D, I]);
151
150
  for (var r = 0; r < iterations; r++) {
152
151
  var prev = A;
153
- A = nodeCrypto.createHash(hashName).update(A).digest();
152
+ A = guard.crypto.digest(hashName, A);
154
153
  guard.secret.zeroize(prev, Pkcs12Error, "pkcs12/bad-input", "a key-derivation intermediate");
155
154
  }
156
155
  A.copy(out, i * u);
@@ -238,7 +237,7 @@ function _buildBag(bag, opts, depth) {
238
237
  case "shroudedKey": {
239
238
  var kDer = _coerceDer(bag.key, "shroudedKey key");
240
239
  try { pkcs8.parse(kDer); } catch (e2) { throw _err("pkcs12/bad-input", "shroudedKey key is not a well-formed PKCS#8 PrivateKeyInfo", e2); }
241
- var enc = bag.encrypt || {};
240
+ var enc = bag.encrypt || intrinsic.create(null);
242
241
  var bagPbe = _pbeOpts(enc);
243
242
  var pw = _pbePasswordOwned(enc.password != null ? enc.password : opts.password);
244
243
  var r;
@@ -351,7 +350,7 @@ async function _buildMacData(macOpts, sharedPassword, authSafeDer) {
351
350
  var password = macOpts.password != null ? macOpts.password : sharedPassword;
352
351
  var algorithm = macOpts.algorithm || "hmac";
353
352
  var hash = macOpts.hash || "sha256";
354
- var salt = macOpts.salt != null ? _bytes(macOpts.salt, "mac salt") : nodeCrypto.randomBytes(MAC_SALT_BYTES);
353
+ var salt = macOpts.salt != null ? _bytes(macOpts.salt, "mac salt") : guard.crypto.randomBytes(MAC_SALT_BYTES);
355
354
  if (salt.length === 0) throw _err("pkcs12/bad-input", "the MAC salt must be non-empty (RFC 9579 sec. 4c)");
356
355
  if (salt.length > C.LIMITS.PBKDF2_MAX_SALT) throw _err("pkcs12/bad-input", "the MAC salt exceeds the " + C.LIMITS.PBKDF2_MAX_SALT + "-octet cap");
357
356
 
@@ -363,7 +362,7 @@ async function _buildMacData(macOpts, sharedPassword, authSafeDer) {
363
362
  var macKey = _p12Kdf(node, 3, macPw.bytes, salt, iter, P12_KDF_UV[node].u);
364
363
  if (macPw.owned) guard.secret.zeroize(macPw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
365
364
  try {
366
- var digest = nodeCrypto.createHmac(node, macKey).update(authSafeDer).digest();
365
+ var digest = guard.crypto.hmac(node, macKey, authSafeDer);
367
366
  var digestInfo = b.sequence([b.sequence([b.oid(O(node)), b.nullValue()]), b.octetString(digest)]);
368
367
  return b.sequence([digestInfo, b.octetString(salt), b.integer(BigInt(iter))]);
369
368
  } finally {
@@ -553,7 +552,7 @@ function build(spec, opts) {
553
552
  }
554
553
 
555
554
  async function _build(spec, opts) {
556
- opts = opts || {};
555
+ opts = opts || intrinsic.create(null);
557
556
  var form = _specForm(spec);
558
557
  if (form.isObject) {
559
558
  guard.identifier.assertKnownKeys(spec, form.full ? _BUILD_SPEC_FULL_KEYS : _BUILD_SPEC_SHORTHAND_KEYS,
@@ -622,7 +621,7 @@ async function _build(spec, opts) {
622
621
  : "");
623
622
  });
624
623
  }
625
- if (opts.mac !== false) _push(pfxChildren,await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
624
+ if (opts.mac !== false) _push(pfxChildren,await _buildMacData(opts.mac || intrinsic.create(null), opts.password, authSafeDer));
626
625
  pfx = b.sequence(pfxChildren);
627
626
  }
628
627
 
@@ -677,7 +676,7 @@ async function verifyMac(pfx, password, opts) {
677
676
  }
678
677
 
679
678
  async function _verifyMacOfStore(m, password, opts) {
680
- opts = opts || {};
679
+ opts = opts || intrinsic.create(null);
681
680
  if (m.integrityMode !== "password" || !m.mac) throw _err("pkcs12/bad-input", "the store carries no password MAC (integrityMode " + m.integrityMode + ")");
682
681
  var expected = m.mac.macValue;
683
682
  var computed;
@@ -688,7 +687,7 @@ async function _verifyMacOfStore(m, password, opts) {
688
687
  var vMacPw = _p12PasswordOwned(password);
689
688
  var macKey = _p12Kdf(node, 3, vMacPw.bytes, m.mac.macSalt, m.mac.iterations, P12_KDF_UV[node].u);
690
689
  if (vMacPw.owned) guard.secret.zeroize(vMacPw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
691
- try { computed = nodeCrypto.createHmac(node, macKey).update(m.macedBytes).digest(); }
690
+ try { computed = guard.crypto.hmac(node, macKey, m.macedBytes); }
692
691
  finally { guard.secret.zeroize(macKey, Pkcs12Error, "pkcs12/bad-input", "the password-derived MAC key"); }
693
692
  } else {
694
693
  var kdf = m.mac.pbmac1.kdf;
@@ -768,7 +767,7 @@ function _capWork(iterations, salt, opts, keyLength, hardCap) {
768
767
  * var keyDer = store.keys[0].pkcs8, certDer = store.certs[0].cert;
769
768
  */
770
769
  async function open(pfx, password, opts) {
771
- opts = opts || {};
770
+ opts = opts || intrinsic.create(null);
772
771
  guard.identifier.assertKnownKeys(opts, _OPEN_OPTS, _err, "pkcs12/bad-input", "pki.pkcs12.open has an unknown option ");
773
772
  /** @internal Every option is taken once, here, and everything below reads the snapshot. A store
774
773
  * is opened in many passes, the MAC and then each bag, so an option left on the caller's object is
@@ -868,7 +867,7 @@ function _decryptLegacyPbe(ea, ct, password, opts, budget) {
868
867
  if (p12pw.owned) guard.secret.zeroize(p12pw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
869
868
  try {
870
869
  if (scheme.rc2) return rc2.cbcDecrypt(keyM, scheme.rc2, iv, ct, _err, "pkcs12/decrypt-failed");
871
- var d = nodeCrypto.createDecipheriv(scheme.cipher, keyM, iv);
870
+ var d = guard.crypto.decipher(scheme.cipher, keyM, iv);
872
871
  return guard.secret.cipherFinish(d, ct, Pkcs12Error, "pkcs12/bad-input", "the recovered safe contents");
873
872
  } catch (_e) { throw _err("pkcs12/decrypt-failed", "decryption failed"); }
874
873
  finally { guard.secret.zeroize(keyM, Pkcs12Error, "pkcs12/bad-input", "the password-derived decryption key"); }
package/lib/pki-build.js CHANGED
@@ -418,7 +418,7 @@ var DP_KEYS = intrinsic.assign(intrinsic.create(null), { fullName: 1, reasons: 1
418
418
  * others, so the loop keeps the leading octet uniform over 1 to 127. */
419
419
  function randomSerial() {
420
420
  for (;;) {
421
- var rnd = nodeCrypto.randomBytes(20);
421
+ var rnd = guard.crypto.randomBytes(20);
422
422
  rnd[0] &= 0x7f;
423
423
  if (rnd[0] !== 0) return BigInt("0x" + rnd.toString("hex"));
424
424
  }
@@ -1249,7 +1249,7 @@ function makeBuilder(ctx) {
1249
1249
 
1250
1250
  function spkiKeyId(spkiDer) {
1251
1251
  var keyBytes = asn1.read.bitString(asn1.decode(spkiDer).children[1]).bytes;
1252
- return nodeCrypto.createHash("sha1").update(keyBytes).digest();
1252
+ return guard.crypto.digest("sha1", keyBytes);
1253
1253
  }
1254
1254
  function skiKeyId(val, spkiDer) {
1255
1255
  if (guard.bytes.isByteSource(val)) return guard.bytes.snapshotSource(val, ErrorClass, ctx.prefix + "/bad-input", "subjectKeyIdentifier");
@@ -1517,7 +1517,7 @@ function samePublicKey(spkiA, spkiB) {
1517
1517
  /** @internal Two keys of different types are never the same key, and comparing them through
1518
1518
  * the runtime's equality leaves a fault queued in the crypto library that surfaces on the
1519
1519
  * next unrelated key import in the process, so the type decides that case first. */
1520
- if (ka.asymmetricKeyType !== kb.asymmetricKeyType) return false;
1520
+ if (guard.crypto.keyType(ka) !== guard.crypto.keyType(kb)) return false;
1521
1521
  return _keyEquals(ka, kb) === true;
1522
1522
  }
1523
1523
 
package/lib/scep.js CHANGED
@@ -77,7 +77,6 @@ var C = require("./constants");
77
77
  var httpTransport = require("./http-transport");
78
78
  var retryAfter = require("./http-retry-after");
79
79
  var _defaultSleep = require("./sleep").sleep;
80
- var nodeCrypto = require("node:crypto");
81
80
 
82
81
  function _err(code, msg, cause) { return new ScepError(code, msg, cause); }
83
82
  function _showValue(v) { return guard.text.showValue(v); }
@@ -103,7 +102,7 @@ var ENVELOPE_CIPHER = "aes-128-cbc";
103
102
  var EMPTY_CONTENT = Buffer.alloc(0);
104
103
 
105
104
  function _nonce(v, label) {
106
- if (v == null) return nodeCrypto.randomBytes(16);
105
+ if (v == null) return guard.crypto.randomBytes(16);
107
106
  var buf = guard.bytes.snapshotSource(v, ScepError, "scep/bad-nonce", label);
108
107
  if (buf.length !== 16) throw _err("scep/bad-nonce", label + " must be exactly 16 bytes (RFC 8894 sec. 3.2.1.5), got " + buf.length);
109
108
  return buf;
@@ -746,7 +745,7 @@ function _drive(method, url, body, headers, opts, transport, budgets) {
746
745
  if (proxySnap != null) req.proxy = proxySnap;
747
746
  if (curBody != null) req.body = curBody;
748
747
  return guard.async.invoked(transport, [req], _err, "scep/bad-input", "opts.transport").then(function (res) {
749
- res = res || {};
748
+ res = res || intrinsic.create(null);
750
749
  var blen = _responseLen(res.body);
751
750
  if (blen > budgets.maxResponseBytes) throw _err("scep/response-too-large", "the response body (" + blen + " bytes) exceeds the " + budgets.maxResponseBytes + "-byte cap");
752
751
  var status = res.status;
@@ -903,7 +902,7 @@ function findIssuedCert(certs, wantSpki) {
903
902
  }
904
903
  function _normalizeFingerprint(fp, algName) {
905
904
  var algorithm = _foldLower(String(algName == null ? "sha256" : algName));
906
- try { nodeCrypto.createHash(algorithm); }
905
+ try { guard.crypto.hash(algorithm); }
907
906
  catch (_e) { throw _err("scep/bad-input", "fingerprintAlgorithm " + _showValue(algorithm) + " is not an available hash"); }
908
907
  var value;
909
908
  if (Buffer.isBuffer(fp)) value = Buffer.from(fp);
@@ -968,7 +967,7 @@ async function getCACert(baseUrl, opts) {
968
967
  if (fp != null) {
969
968
  var matched = null, j;
970
969
  for (j = 0; j < certs.length; j++) {
971
- var got = nodeCrypto.createHash(fp.algorithm).update(certs[j]).digest();
970
+ var got = guard.crypto.digest(fp.algorithm, certs[j]);
972
971
  if (got.length === fp.value.length && got.equals(fp.value)) { matched = certs[j]; break; }
973
972
  }
974
973
  if (!matched) throw _err("scep/fingerprint-mismatch", "no GetCACert certificate matched the expected " + fp.algorithm + " fingerprint (RFC 8894 sec. 2.2)");
@@ -1030,7 +1029,7 @@ async function getNextCACert(baseUrl, opts) {
1030
1029
  }
1031
1030
 
1032
1031
  function _defaultTransactionId() {
1033
- return nodeCrypto.randomBytes(16).toString("hex");
1032
+ return guard.crypto.randomBytes(16).toString("hex");
1034
1033
  }
1035
1034
  var POLL_COUNT_MAX = 1000;
1036
1035
 
@@ -1078,7 +1077,7 @@ async function _pollForIssuance(ctx) {
1078
1077
  if (waitedMs > ctx.maxTotalWait * C.TIME.seconds(1)) throw _pollExhausted("the total wait budget", ctx.transactionId, lastNonce);
1079
1078
  if (ctx.onRetryAfter) ctx.onRetryAfter(delaySec);
1080
1079
  await ctx.sleep(delaySec * C.TIME.seconds(1));
1081
- var sn = nodeCrypto.randomBytes(16);
1080
+ var sn = guard.crypto.randomBytes(16);
1082
1081
  lastNonce = sn;
1083
1082
  var certPoll = await build({ messageType: "CertPoll", requestSubject: ctx.csrSubject, issuer: issuerName, recipient: ctx.caCert, signer: ctx.signer, transactionId: ctx.transactionId, senderNonce: sn });
1084
1083
  res = await _pkiRequest(ctx.httpMethod, ctx.postUrl, certPoll, ctx.clientOpts);
@@ -1125,7 +1124,7 @@ async function _pkiOperation(messageType, baseUrl, opts, verbName) {
1125
1124
  var maxTotalWait = guard.limits.cap(opts.maxTotalWait, "maxTotalWait", retryAfter.MAX_RETRY_AFTER_SECONDS, { E: _err, code: "scep/bad-input", min: 0, max: retryAfter.MAX_RETRY_AFTER_SECONDS });
1126
1125
  var sleep = typeof opts.sleep === "function" ? opts.sleep : _defaultSleep;
1127
1126
  var onRetryAfter = typeof opts.onRetryAfter === "function" ? opts.onRetryAfter : null;
1128
- var senderNonce = nodeCrypto.randomBytes(16);
1127
+ var senderNonce = guard.crypto.randomBytes(16);
1129
1128
  var transactionId = opts.transactionId != null ? opts.transactionId : _defaultTransactionId();
1130
1129
  var reqMsg = await build({ messageType: messageType, messageData: csrView, recipient: caCert, signer: signer, transactionId: transactionId, senderNonce: senderNonce });
1131
1130
  var res = await _pkiRequest(httpMethod, postUrl, reqMsg, clientOpts);
@@ -1258,7 +1257,7 @@ async function _queryOperation(messageType, baseUrl, opts, verbName) {
1258
1257
  var want = _resolveQueryTarget(opts);
1259
1258
  var clientOpts = { tls: opts.tls != null ? guard.identifier.ownOptions(opts.tls) : opts.tls, maxRedirects: opts.maxRedirects, allowCrossOriginRedirect: opts.allowCrossOriginRedirect, timeout: opts.timeout, maxResponseBytes: opts.maxResponseBytes, proxy: _snapshotProxy(opts.proxy) };
1260
1259
  if (checkedTransport !== undefined) clientOpts.transport = checkedTransport;
1261
- var senderNonce = nodeCrypto.randomBytes(16);
1260
+ var senderNonce = guard.crypto.randomBytes(16);
1262
1261
  var transactionId = opts.transactionId != null ? opts.transactionId : _defaultTransactionId();
1263
1262
  var httpMethod = _pkiMethod(opts);
1264
1263
  var reqMsg = await build(Object.assign({ messageType: messageType, recipient: caCert, signer: signer, transactionId: transactionId, senderNonce: senderNonce }, want.buildSpec));
@@ -169,7 +169,7 @@ function time(ns) {
169
169
 
170
170
  function field(name, schema) { return { fkind: "required", name: name, schema: schema }; }
171
171
  function optional(name, schema, opts) {
172
- opts = opts || {};
172
+ opts = opts || intrinsic.create(null);
173
173
  var match = opts.whenAny
174
174
  ? function () { return true; }
175
175
  : opts.whenUniversal
@@ -182,51 +182,51 @@ function optional(name, schema, opts) {
182
182
  defaultCode: opts.defaultCode };
183
183
  }
184
184
  function trailing(members, opts) {
185
- opts = opts || {};
185
+ opts = opts || intrinsic.create(null);
186
186
  return { fkind: "trailing", members: members, minTag: opts.minTag, maxTag: opts.maxTag,
187
187
  unexpectedCode: opts.unexpectedCode, orderCode: opts.orderCode };
188
188
  }
189
189
 
190
190
 
191
191
  function seq(fields, opts) {
192
- opts = opts || {};
192
+ opts = opts || intrinsic.create(null);
193
193
  return { kind: "seq", fields: fields, assert: opts.assert || "sequence", implicitTag: opts.implicitTag, arity: opts.arity,
194
194
  code: opts.code, what: opts.what, build: opts.build, checks: opts.checks || [] };
195
195
  }
196
196
 
197
197
  function explicit(tag, schema, opts) {
198
- opts = opts || {};
198
+ opts = opts || intrinsic.create(null);
199
199
  return { kind: "explicit", tag: tag, schema: schema, emptyCode: opts.emptyCode, code: opts.code, what: opts.what };
200
200
  }
201
201
 
202
202
  function choice(alts, opts) {
203
- opts = opts || {};
203
+ opts = opts || intrinsic.create(null);
204
204
  return { kind: "choice", alts: alts, code: opts.code, what: opts.what };
205
205
  }
206
206
 
207
207
  function seqOf(item, opts) {
208
- opts = opts || {};
208
+ opts = opts || intrinsic.create(null);
209
209
  return { kind: "repeat", item: item, assert: opts.assert || "sequence", code: opts.code, what: opts.what,
210
210
  min: opts.min, max: opts.max, maxCode: opts.maxCode,
211
211
  unique: opts.unique, dupCode: opts.dupCode, build: opts.build };
212
212
  }
213
213
  function setOf(item, opts) {
214
- opts = opts || {};
214
+ opts = opts || intrinsic.create(null);
215
215
  return { kind: "repeat", item: item, assert: opts.assert || "set", derSetOrder: true, code: opts.code, what: opts.what,
216
216
  min: opts.min, max: opts.max, maxCode: opts.maxCode,
217
217
  unique: opts.unique, dupCode: opts.dupCode, build: opts.build };
218
218
  }
219
219
  function setOfUnique(item, keyFn, opts) {
220
- return setOf(item, Object.assign({ unique: keyFn }, opts || {}));
220
+ return setOf(item, Object.assign({ unique: keyFn }, opts || intrinsic.create(null)));
221
221
  }
222
222
  function implicitSetOf(tag, item, opts) {
223
- opts = opts || {};
223
+ opts = opts || intrinsic.create(null);
224
224
  return { kind: "repeat", item: item, assert: "implicit", implicitTag: tag, derSetOrder: true, code: opts.code, what: opts.what,
225
225
  min: opts.min, max: opts.max, maxCode: opts.maxCode,
226
226
  unique: opts.unique, dupCode: opts.dupCode, build: opts.build };
227
227
  }
228
228
  function implicitSeqOf(tag, item, opts) {
229
- opts = opts || {};
229
+ opts = opts || intrinsic.create(null);
230
230
  return { kind: "repeat", item: item, assert: "implicit", implicitTag: tag, code: opts.code, what: opts.what,
231
231
  min: opts.min, max: opts.max, maxCode: opts.maxCode,
232
232
  unique: opts.unique, dupCode: opts.dupCode, build: opts.build };
@@ -471,7 +471,7 @@ function _wrapConstructed(schema, parts) {
471
471
  function _present(v) { return v !== undefined && v !== null; }
472
472
 
473
473
  function _encodeSeq(schema, value, ctx) {
474
- value = value || {};
474
+ value = value || intrinsic.create(null);
475
475
  var parts = [];
476
476
  for (var f = 0; f < schema.fields.length; f++) {
477
477
  var fld = schema.fields[f];
@@ -578,7 +578,7 @@ function _encodeChoice(schema, value, ctx) {
578
578
  * { code: "app/bad-der", what: "the embedded structure" });
579
579
  */
580
580
  function embeddedDer(schema, bytes, ctx, opts) {
581
- opts = opts || {};
581
+ opts = opts || intrinsic.create(null);
582
582
  if (opts.budget) {
583
583
  if (!(opts.budget.remaining > 0)) {
584
584
  throw ctx.E(opts.budgetCode || opts.code, (opts.what || "embedded DER") +
@@ -330,7 +330,7 @@ function _blockCap(given, ceiling, what, PemError) {
330
330
  * label is the only thing separating a CERTIFICATE from a TRUSTED CERTIFICATE or a PRIVATE KEY, and
331
331
  * the byte offset it started at, so a fault in a file of hundreds names the one object it is about. */
332
332
  function pemDecodeBundle(text, opts, PemError, detect) {
333
- opts = opts || {};
333
+ opts = opts || _create(null);
334
334
  var maxBlocks = _blockCap(opts.maxBlocks, constants.LIMITS.PEM_MAX_BLOCKS, "maxBlocks", PemError);
335
335
  var maxDecoded = _blockCap(opts.maxDecodedBytes, constants.LIMITS.PEM_MAX_DECODED_BYTES, "maxDecodedBytes", PemError);
336
336
  var route = opts.route === true;
@@ -739,7 +739,7 @@ function versionReader(ns, accept) {
739
739
  }
740
740
 
741
741
  function algorithmIdentifier(ns, opts) {
742
- opts = opts || {};
742
+ opts = opts || _create(null);
743
743
  return schema.seq([
744
744
  schema.field("algorithm", schema.oidLeaf()),
745
745
  schema.optional("parameters", schema.any(), { whenAny: true }),
@@ -761,7 +761,7 @@ function algorithmIdentifier(ns, opts) {
761
761
  * (RFC 5652 sec. 10.2.4). CMS names the type and RFC 9763 sec. 3.1 reuses it inside a CSR attribute,
762
762
  * so the shape is defined once and each caller supplies its own code and name for the refusal. */
763
763
  function issuerAndSerialNumber(ns, opts) {
764
- opts = opts || {};
764
+ opts = opts || _create(null);
765
765
  return schema.seq([
766
766
  schema.field("issuer", name(ns)),
767
767
  schema.field("serialNumber", schema.integerLeaf()),
@@ -952,7 +952,7 @@ function relativeDistinguishedName(ns) {
952
952
  return schema.setOf(attributeTypeAndValue(ns), { assert: "set", min: 1, code: ns.prefix + "/bad-rdn", what: "RelativeDistinguishedName" });
953
953
  }
954
954
  function name(ns, opts) {
955
- opts = opts || {};
955
+ opts = opts || _create(null);
956
956
  function nameBuild(m) {
957
957
  var rdns = [], parts = [];
958
958
  _forEach(m.items, function (rdnItem) {
@@ -978,7 +978,7 @@ function name(ns, opts) {
978
978
  }
979
979
 
980
980
  function generalizedTime(ns, opts) {
981
- opts = opts || {};
981
+ opts = opts || _create(null);
982
982
  var code = opts.code || (ns.prefix + "/bad-time");
983
983
  var message = opts.message || "the time must be a GeneralizedTime";
984
984
  var readOpts = opts.allowFractional ? { allowFractional: true } : undefined;
@@ -991,7 +991,7 @@ function generalizedTime(ns, opts) {
991
991
  }
992
992
 
993
993
  function utf8Text(ns, opts) {
994
- opts = opts || {};
994
+ opts = opts || _create(null);
995
995
  var code = opts.code || (ns.prefix + "/bad-freetext");
996
996
  var message = opts.message || "the element must be a UTF8String";
997
997
  return schema.decode(function (n, ctx) {
@@ -1003,7 +1003,7 @@ function utf8Text(ns, opts) {
1003
1003
  }
1004
1004
 
1005
1005
  function rawNonEmptySequence(ns, opts) {
1006
- opts = opts || {};
1006
+ opts = opts || _create(null);
1007
1007
  var code = opts.code || (ns.prefix + "/bad-sequence");
1008
1008
  var message = opts.message || "expected a non-empty universal SEQUENCE";
1009
1009
  return schema.decode(function (n, ctx) {
@@ -1069,7 +1069,7 @@ var GN_IA5 = _assign(_create(null), { 1: 1, 2: 1, 6: 1 });
1069
1069
  var DIRECTORY_STRING_TAGS = [asn1.TAGS.UTF8_STRING, asn1.TAGS.PRINTABLE_STRING, asn1.TAGS.TELETEX_STRING,
1070
1070
  asn1.TAGS.UNIVERSAL_STRING, asn1.TAGS.BMP_STRING];
1071
1071
  function generalName(ns, opts) {
1072
- opts = opts || {};
1072
+ opts = opts || _create(null);
1073
1073
  var code = opts.code || (ns.prefix + "/bad-general-name");
1074
1074
  var decodeValue = opts.decodeValue === true;
1075
1075
  var subtreeBase = opts.subtreeBase === true;
@@ -1165,7 +1165,7 @@ function generalName(ns, opts) {
1165
1165
  }
1166
1166
 
1167
1167
  function generalNames(ns, opts) {
1168
- opts = opts || {};
1168
+ opts = opts || _create(null);
1169
1169
  var code = opts.code || (ns.prefix + "/bad-general-names");
1170
1170
  var gn = generalName(ns, { code: code, decodeValue: opts.decodeValue === true, subtreeBase: opts.subtreeBase === true });
1171
1171
  function build(m) { return { names: _map(m.items, function (it) { return it.value; }), bytes: m.node.bytes }; }
@@ -2528,7 +2528,7 @@ function extension(ns) {
2528
2528
  });
2529
2529
  }
2530
2530
  function extensions(ns, opts) {
2531
- opts = opts || {};
2531
+ opts = opts || _create(null);
2532
2532
  var EXT = extension(ns);
2533
2533
  var extOpts = {
2534
2534
  min: 1, code: ns.prefix + "/bad-extensions", what: "Extensions",
@@ -2540,7 +2540,7 @@ function extensions(ns, opts) {
2540
2540
  }
2541
2541
 
2542
2542
  function spki(ns, opts) {
2543
- opts = opts || {};
2543
+ opts = opts || _create(null);
2544
2544
  return schema.seq([
2545
2545
  schema.field("algorithm", algorithmIdentifier(ns)),
2546
2546
  schema.field("subjectPublicKey", schema.bitString()),
@@ -2558,7 +2558,7 @@ function spki(ns, opts) {
2558
2558
  }
2559
2559
 
2560
2560
  function attribute(ns, opts) {
2561
- opts = opts || {};
2561
+ opts = opts || _create(null);
2562
2562
  var minValues = opts.minValues === undefined ? 1 : opts.minValues;
2563
2563
  return schema.seq([
2564
2564
  schema.field("type", schema.oidLeaf()),
package/lib/schema-tsp.js CHANGED
@@ -528,8 +528,8 @@ function essDigest(name) {
528
528
  var xof = ESS_XOF_BYTES[name];
529
529
  /** @internal One read of the name answers both whether the digest can be computed and how to
530
530
  * compute it, so the hash every candidate is put through is the one that read settled. */
531
- return function () {
532
- return xof ? nodeCrypto.createHash(name, { outputLength: xof }) : nodeCrypto.createHash(name);
531
+ return function (bytes) {
532
+ return xof ? guard.crypto.xof(name, bytes, xof) : guard.crypto.digest(name, bytes);
533
533
  };
534
534
  }
535
535
 
@@ -579,7 +579,7 @@ function _essNamedCertificate(token, attr) {
579
579
  for (var j = 0; j < certs.length; j++) {
580
580
  var element = certs[j];
581
581
  if (!element || element.tagClass !== "universal" || !Buffer.isBuffer(element.bytes)) continue;
582
- var actual = digest().update(element.bytes).digest();
582
+ var actual = digest(element.bytes);
583
583
  if (actual.length === want.length && guard.bytes.compare(actual, want) === 0) return element.bytes;
584
584
  }
585
585
  return null;
package/lib/shbs.js CHANGED
@@ -21,7 +21,6 @@
21
21
  * @card Verify HSS/LMS signatures (post-quantum, CNSA 2.0 firmware signing).
22
22
  */
23
23
 
24
- var nodeCrypto = require("crypto");
25
24
  var frameworkError = require("./framework-error");
26
25
  var guard = require("./guard-all");
27
26
  /** @internal The append every list here is built with: `push` stores at the index and a store
@@ -82,11 +81,9 @@ function _lmotsSet(code) {
82
81
  }
83
82
 
84
83
  function _hash(family, n, parts) {
85
- var h;
86
- if (family === "shake256") h = nodeCrypto.createHash("shake256", { outputLength: n });
87
- else h = nodeCrypto.createHash("sha256");
88
- for (var i = 0; i < parts.length; i++) h.update(parts[i]);
89
- var d = h.digest();
84
+ var d = family === "shake256"
85
+ ? guard.crypto.digestParts("shake256", parts, n)
86
+ : guard.crypto.digestParts("sha256", parts);
90
87
  return (family === "shake256" || n === 32) ? d : d.subarray(0, n);
91
88
  }
92
89
 
@@ -124,7 +124,7 @@ function resolveSignScheme(cert, so, noSignedAttrs, E) {
124
124
  }
125
125
 
126
126
  function _resolveSignScheme(cert, so, noSignedAttrs, E) {
127
- so = so || {};
127
+ so = so || intrinsic.create(null);
128
128
  var alg = cert.subjectPublicKeyInfo.algorithm;
129
129
  var keyOid = alg.oid;
130
130
  var comp = compositeSig.COMPOSITE_ALGS[keyOid];
@@ -180,7 +180,7 @@ function _resolveSignScheme(cert, so, noSignedAttrs, E) {
180
180
  }
181
181
 
182
182
  function _assertKeyMatchesScheme(key, imp, E, what) {
183
- var ka = key.algorithm || {};
183
+ var ka = key.algorithm || intrinsic.create(null);
184
184
  var subject = what || "CryptoKey";
185
185
  if (_toUpperCase(_String(ka.name)) !== _toUpperCase(_String(imp.name))) {
186
186
  var hint = (_toUpperCase(_String(ka.name)) === "RSA-PSS" && _toUpperCase(_String(imp.name)) === "RSASSA-PKCS1-V1_5")
@@ -359,14 +359,14 @@ function _keyTypeAccepts(reported, wanted) {
359
359
  }
360
360
 
361
361
  function _assertKeyObjectMatchesScheme(key, scheme, E) {
362
- var reported = key.asymmetricKeyType;
362
+ var reported = guard.crypto.keyType(key);
363
363
  var wanted = NODE_KEY_TYPE[scheme.imp.name] || _toLowerCase(_String(scheme.imp.name));
364
364
  if (!_keyTypeAccepts(reported, wanted)) {
365
365
  throw E("bad-input", "the signer KeyObject algorithm (" + reported +
366
366
  ") does not match the certificate's key algorithm (" + scheme.imp.name + ")");
367
367
  }
368
368
  if (scheme.imp.namedCurve) {
369
- var details = key.asymmetricKeyDetails;
369
+ var details = guard.crypto.keyDetails(key);
370
370
  var curve = details && details.namedCurve;
371
371
  if (curve !== NODE_CURVE[scheme.imp.namedCurve]) {
372
372
  throw E("bad-input", "the signer KeyObject curve (" + curve +
package/lib/sigstore.js CHANGED
@@ -28,7 +28,6 @@
28
28
  * @card Verify an npm --provenance Sigstore bundle offline (DSSE + Fulcio + Rekor + SLSA).
29
29
  */
30
30
 
31
- var nodeCrypto = require("crypto");
32
31
  var frameworkError = require("./framework-error");
33
32
  var constants = require("./constants");
34
33
  var asn1 = require("./asn1-der");
@@ -227,8 +226,8 @@ function _assertKeyDetailsParameters(want, leafSpki, declared) {
227
226
  if (want.bits !== undefined) {
228
227
  var bits;
229
228
  try {
230
- bits = guard.crypto.publicKey({ key: leafSpki.bytes, format: "der", type: "spki" })
231
- .asymmetricKeyDetails.modulusLength;
229
+ bits = guard.crypto.keyDetails(
230
+ guard.crypto.publicKey({ key: leafSpki.bytes, format: "der", type: "spki" })).modulusLength;
232
231
  } catch (_e) { bits = null; } // allow:swallow-unverified -- a key that will not import has no modulus size to match, and the mismatch below is the verdict
233
232
  if (bits !== want.bits) {
234
233
  throw _err("sigstore/entry-mismatch", "the Rekor entry states the signing key is " +
@@ -709,13 +708,14 @@ function _chainDers(vm) {
709
708
  }
710
709
 
711
710
  function _rawVerify(keyObj, data, derSig) {
712
- var t = keyObj.asymmetricKeyType;
711
+ var t = guard.crypto.keyType(keyObj);
713
712
  if (t === "ed25519" || t === "ed448") {
714
713
  var edSpki = guard.crypto.exportKey(keyObj, { type: "spki", format: "der" });
715
714
  edwardsPoint.validateSpki(edSpki, t === "ed25519" ? 6 : 7, SigstoreError, "sigstore/bad-key");
716
715
  return guard.crypto.verify(null, data, keyObj, derSig);
717
716
  }
718
- var crv = keyObj.asymmetricKeyDetails && keyObj.asymmetricKeyDetails.namedCurve;
717
+ var keyObjDetails = guard.crypto.keyDetails(keyObj);
718
+ var crv = keyObjDetails && keyObjDetails.namedCurve;
719
719
  var hash = crv === "secp384r1" ? "sha384" : (crv === "secp521r1" ? "sha512" : "sha256");
720
720
  return guard.crypto.verify(hash, data, { key: keyObj, dsaEncoding: "der" }, derSig);
721
721
  }
@@ -723,7 +723,7 @@ function _pubFromSpki(spkiDer, label) {
723
723
  var key;
724
724
  try { key = guard.crypto.publicKey({ key: spkiDer, format: "der", type: "spki" }); }
725
725
  catch (e) { throw _err("sigstore/bad-key", "invalid " + label + " public key", e); }
726
- var t = key.asymmetricKeyType;
726
+ var t = guard.crypto.keyType(key);
727
727
  if (t === "ed25519" || t === "ed448") {
728
728
  edwardsPoint.validateSpki(spkiDer, t === "ed25519" ? 6 : 7, SigstoreError, "sigstore/bad-key");
729
729
  }
@@ -735,7 +735,7 @@ function _parseCert(der, label) {
735
735
  }
736
736
 
737
737
 
738
- function _sha256(buf) { return nodeCrypto.createHash("sha256").update(buf).digest(); }
738
+ function _sha256(buf) { return guard.crypto.digest("sha256", buf); }
739
739
 
740
740
  function _toMs(x) {
741
741
  if (x == null) return null;
@@ -1109,7 +1109,7 @@ function _bindHashedRekordV002Entry(body, arm, leafDer, contentType, payloadType
1109
1109
  }
1110
1110
  var digest = _b64(data.digest, "hashedRekordV002.data.digest");
1111
1111
  if (contentType === "dsseEnvelope") {
1112
- var computed = nodeCrypto.createHash(alg.node).update(pae(payloadType, payload)).digest();
1112
+ var computed = guard.crypto.digest(alg.node, pae(payloadType, payload));
1113
1113
  if (!guard.crypto.constantTimeEqual(computed, digest)) {
1114
1114
  throw _err("sigstore/entry-mismatch", "the Rekor entry digest is not the hash of this envelope's " +
1115
1115
  "signing preimage, so the entry records a different signature than the bundle carries");
@@ -1715,7 +1715,7 @@ async function verifyBundle(bundle, opts) {
1715
1715
  if (bundle === null || typeof bundle !== "object" && typeof bundle !== "string" && !_isBuffer(bundle)) {
1716
1716
  throw new TypeError("verifyBundle: bundle must be an object, JSON string, or Buffer");
1717
1717
  }
1718
- opts = opts || {};
1718
+ opts = opts || _create(null);
1719
1719
  guard.identifier.assertKnownKeys(opts, _VERIFY_BUNDLE_OPTS, _err, "sigstore/bad-input", "pki.sigstore.verifyBundle has an unknown option ");
1720
1720
  /** @internal parseBundle takes the copy, so every check below runs on plain data that cannot change
1721
1721
  * under it, whichever field it reads and however many times. */
@@ -1831,7 +1831,7 @@ async function verifyBundle(bundle, opts) {
1831
1831
  var artifactDigests = intrinsic.create(null);
1832
1832
  function _artifactDigest(nodeName) {
1833
1833
  if (!intrinsic.hasOwn(artifactDigests, nodeName)) {
1834
- artifactDigests[nodeName] = nodeCrypto.createHash(nodeName).update(artifact).digest();
1834
+ artifactDigests[nodeName] = guard.crypto.digest(nodeName, artifact);
1835
1835
  }
1836
1836
  return artifactDigests[nodeName];
1837
1837
  }