@blamejs/pki 0.8.60 → 0.8.61

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/lib/hpke.js CHANGED
@@ -250,10 +250,10 @@ function _importPublic(kem, raw) {
250
250
  if (raw[0] !== 0x04) throw _err("hpke/bad-key", "EC public key must be an uncompressed 0x04 point (RFC 9180 sec. 7.1.4)");
251
251
  var half = (raw.length - 1) / 2;
252
252
  var jwk = { kty: "EC", crv: kem.curve, x: raw.subarray(1, 1 + half).toString("base64url"), y: raw.subarray(1 + half).toString("base64url") };
253
- return nodeCrypto.createPublicKey({ key: jwk, format: "jwk" });
253
+ return guard.crypto.publicKey({ key: jwk, format: "jwk" });
254
254
  }
255
255
  var prefix = kem.kind === "mlkem" ? ML_KEM_SPKI[kem.name] : OKP_SPKI[kem.curve];
256
- return nodeCrypto.createPublicKey({ key: _bufferConcat([_hex(prefix), raw]), format: "der", type: "spki" });
256
+ return guard.crypto.publicKey({ key: _bufferConcat([_hex(prefix), raw]), format: "der", type: "spki" });
257
257
  } catch (e) {
258
258
  if (e instanceof HpkeError) throw e;
259
259
  throw _err("hpke/bad-key", "invalid " + kem.name + " public key" +
@@ -261,15 +261,15 @@ function _importPublic(kem, raw) {
261
261
  }
262
262
  }
263
263
  function _exportPublic(kem, keyObject) {
264
- var pub = keyObject.type === "public" ? keyObject : nodeCrypto.createPublicKey(keyObject);
264
+ var pub = keyObject.type === "public" ? keyObject : guard.crypto.publicKey(keyObject);
265
265
  if (kem.kind === "mlkem") {
266
- var der = pub.export({ format: "der", type: "spki" }), prefix = _hex(ML_KEM_SPKI[kem.name]);
266
+ var der = guard.crypto.exportKey(pub, { format: "der", type: "spki" }), prefix = _hex(ML_KEM_SPKI[kem.name]);
267
267
  if (der.length !== prefix.length + kem.Npub || !_bufferEquals(_subarray(der, 0, prefix.length), prefix)) {
268
268
  throw _err("hpke/bad-key", "the KeyObject is not an " + kem.name + " key");
269
269
  }
270
270
  return _subarray(der, prefix.length);
271
271
  }
272
- var jwk = pub.export({ format: "jwk" });
272
+ var jwk = guard.crypto.exportKey(pub, { format: "jwk" });
273
273
  if (jwk.crv !== kem.curve) throw _err("hpke/bad-key", "the KeyObject is not a " + kem.name + " key");
274
274
  if (kem.kind === "ec") return concat([Buffer.from([0x04]), _b64u(jwk.x), _b64u(jwk.y)]);
275
275
  return _b64u(jwk.x);
@@ -293,7 +293,7 @@ function _importPrivate(kem, rawSk) {
293
293
  der = _bufferConcat([_hex(kem.kind === "mlkem" ? ML_KEM_PKCS8[kem.name] : OKP_PKCS8[kem.curve]), rawSk]);
294
294
  }
295
295
  try {
296
- return nodeCrypto.createPrivateKey({ key: der, format: "der", type: kem.kind === "ec" ? "sec1" : "pkcs8" });
296
+ return guard.crypto.privateKey({ key: der, format: "der", type: kem.kind === "ec" ? "sec1" : "pkcs8" });
297
297
  } catch (e) {
298
298
  throw _err("hpke/bad-key", "invalid " + kem.name + " private key", e);
299
299
  } finally {
@@ -301,7 +301,7 @@ function _importPrivate(kem, rawSk) {
301
301
  }
302
302
  }
303
303
  function _boundPublic(kem, privateKey, pkm) {
304
- var derived = _exportPublic(kem, nodeCrypto.createPublicKey(privateKey));
304
+ var derived = _exportPublic(kem, guard.crypto.publicKey(privateKey));
305
305
  if (pkm === undefined) return derived;
306
306
  if (!_isBuffer(pkm) || !_bufferEquals(derived, pkm)) {
307
307
  throw _err("hpke/bad-key", "pkm is not the " + kem.name + " public key derived from skm");
@@ -310,7 +310,7 @@ function _boundPublic(kem, privateKey, pkm) {
310
310
  }
311
311
  function _dh(privateKey, publicKey) {
312
312
  try {
313
- return nodeCrypto.diffieHellman({ privateKey: privateKey, publicKey: publicKey });
313
+ return guard.crypto.diffieHellman({ privateKey: privateKey, publicKey: publicKey });
314
314
  } catch (e) {
315
315
  throw _err("hpke/bad-key", "KEM Diffie-Hellman failed: invalid or low-order public key", e);
316
316
  }
@@ -319,8 +319,8 @@ function _dh(privateKey, publicKey) {
319
319
  * drawn and expanded by generateKeyPair, and an ML-KEM encapsulation takes its randomness from the
320
320
  * runtime rather than from an ephemeral key pair. */
321
321
  function _generate(kem) {
322
- if (kem.kind === "ec") return nodeCrypto.generateKeyPairSync("ec", { namedCurve: kem.nodeCurve });
323
- return nodeCrypto.generateKeyPairSync(kem.curve.toLowerCase());
322
+ if (kem.kind === "ec") return guard.crypto.generateKeyPair("ec", { namedCurve: kem.nodeCurve });
323
+ return guard.crypto.generateKeyPair(intrinsic.toLowerCase(kem.curve));
324
324
  }
325
325
 
326
326
 
@@ -385,8 +385,8 @@ function _hybridExpand(kem, seed) {
385
385
  var skT = _importPrivate(_groupRow(kem), _randomScalar(kem, _subarray(full, kem.pq.Nsk)));
386
386
  return {
387
387
  skPQ: skPQ, skT: skT,
388
- ekPQ: _exportPublic(kem.pq, nodeCrypto.createPublicKey(skPQ)),
389
- ekT: _exportPublic(_groupRow(kem), nodeCrypto.createPublicKey(skT)),
388
+ ekPQ: _exportPublic(kem.pq, guard.crypto.publicKey(skPQ)),
389
+ ekT: _exportPublic(_groupRow(kem), guard.crypto.publicKey(skT)),
390
390
  };
391
391
  } finally {
392
392
  guard.secret.zeroize(full, HpkeError, "hpke/bad-input", "the hybrid seed expansion");
@@ -491,7 +491,7 @@ function _refuseEph(kem, eph) {
491
491
  function _mlKemEncap(kem, pkR, eph) {
492
492
  _refuseEph(kem, eph);
493
493
  var r;
494
- try { r = nodeCrypto.encapsulate(pkR); }
494
+ try { r = guard.crypto.encapsulate(pkR); }
495
495
  catch (e) { throw _err("hpke/bad-key", kem.name + " encapsulation failed", e); }
496
496
  return { sharedSecret: r.sharedKey, enc: r.ciphertext };
497
497
  }
@@ -499,7 +499,7 @@ function _mlKemDecap(kem, enc, skR) {
499
499
  if (enc.length !== kem.Nenc) {
500
500
  throw _err("hpke/bad-key", kem.name + " encapsulated key must be " + kem.Nenc + " bytes (FIPS 203 sec. 7.3 ciphertext check)");
501
501
  }
502
- try { return nodeCrypto.decapsulate(skR, enc); }
502
+ try { return guard.crypto.decapsulate(skR, enc); }
503
503
  catch (e) { throw _err("hpke/bad-key", kem.name + " decapsulation failed", e); }
504
504
  }
505
505
  function _encap(kem, pkR, pkRm, eph) {
@@ -648,10 +648,10 @@ Context.prototype.seal = function (aad, pt) {
648
648
  * which is what RFC 9180 sec. 5.2 uses. */
649
649
  var aadBytes = _buf(aad);
650
650
  var nonce = this._nonce();
651
- var c = nodeCrypto.createCipheriv(aead.cipher, this._key, nonce, { authTagLength: aead.Nt });
652
- if (aadBytes.length) c.setAAD(aadBytes);
651
+ var c = guard.crypto.cipher(aead.cipher, this._key, nonce, { authTagLength: aead.Nt });
652
+ if (aadBytes.length) guard.crypto.transformSetAAD(c, aadBytes);
653
653
  var body = guard.secret.cipherFinish(c, _buf(pt), HpkeError, "hpke/bad-input", "a seal intermediate");
654
- var ct = concat([body, c.getAuthTag()]);
654
+ var ct = concat([body, guard.crypto.cipherAuthTag(c)]);
655
655
  this._inc();
656
656
  return ct;
657
657
  };
@@ -665,9 +665,9 @@ Context.prototype.open = function (aad, ct) {
665
665
  * so the AAD was dropped on this side too and the pair round-tripped with nothing bound. */
666
666
  var aadBytes = _buf(aad);
667
667
  var nonce = this._nonce();
668
- var d = nodeCrypto.createDecipheriv(aead.cipher, this._key, nonce, { authTagLength: aead.Nt });
669
- if (aadBytes.length) d.setAAD(aadBytes);
670
- d.setAuthTag(ct.subarray(ct.length - aead.Nt));
668
+ var d = guard.crypto.decipher(aead.cipher, this._key, nonce, { authTagLength: aead.Nt });
669
+ if (aadBytes.length) guard.crypto.transformSetAAD(d, aadBytes);
670
+ guard.crypto.decipherSetAuthTag(d, ct.subarray(ct.length - aead.Nt));
671
671
  var pt;
672
672
  try { pt = guard.secret.cipherFinish(d, ct.subarray(0, ct.length - aead.Nt), HpkeError, "hpke/bad-input", "the recovered plaintext"); }
673
673
  catch (e) { throw _err("hpke/open-failed", "AEAD authentication failed (RFC 9180 sec. 5.2)", e); }
@@ -814,7 +814,7 @@ function _recipPrivate(suite, sk) {
814
814
  }
815
815
  try {
816
816
  if (sk.type !== "private") throw _err("hpke/bad-key", "the private key must be a private KeyObject or { skm, pkm }, got a " + guard.text.showValue(sk.type) + " KeyObject");
817
- var pkm = _exportPublic(kem, nodeCrypto.createPublicKey(sk));
817
+ var pkm = _exportPublic(kem, guard.crypto.publicKey(sk));
818
818
  return { key: sk, pkm: pkm };
819
819
  } catch (e) {
820
820
  if (e instanceof HpkeError) throw e;
@@ -1118,11 +1118,11 @@ function deriveKeyPair(kemId, ikm) {
1118
1118
  * and the decapsulation key returned is that 64-byte value. */
1119
1119
  var dk = _labeledDerive("shake256", _kemSuiteId(_kemId(kem)), input, "DeriveKeyPair", _EMPTY, kem.Nsk);
1120
1120
  var mlSk = _importPrivate(kem, dk);
1121
- return { publicKey: _exportPublic(kem, nodeCrypto.createPublicKey(mlSk)), privateKey: dk };
1121
+ return { publicKey: _exportPublic(kem, guard.crypto.publicKey(mlSk)), privateKey: dk };
1122
1122
  }
1123
1123
  var raw = _deriveKeyPairDhkem(kem, input);
1124
1124
  var sk = _importPrivate(kem, raw);
1125
- return { publicKey: _exportPublic(kem, nodeCrypto.createPublicKey(sk)), privateKey: raw };
1125
+ return { publicKey: _exportPublic(kem, guard.crypto.publicKey(sk)), privateKey: raw };
1126
1126
  }
1127
1127
 
1128
1128
  /** @internal DeriveKeyPair for a DHKEM (RFC 9180 sec. 7.1.3). X25519 and X448 expand the extract output
@@ -1258,7 +1258,7 @@ function decap(kemId, enc, recipientPrivateKey) {
1258
1258
  * Nsk rather than trusted. An ML-KEM or hybrid key never reaches here, its private half being a seed
1259
1259
  * that generateKeyPair draws. */
1260
1260
  function _exportPrivateRaw(kem, privateKey) {
1261
- var raw = _b64u(privateKey.export({ format: "jwk" }).d);
1261
+ var raw = _b64u(guard.crypto.exportKey(privateKey, { format: "jwk" }).d);
1262
1262
  if (!_isBuffer(raw) || raw.length !== kem.Nsk) {
1263
1263
  throw _err("hpke/bad-key", "the generated " + kem.name + " private key is not the " +
1264
1264
  kem.Nsk + "-byte scalar this verb returns");
@@ -6,6 +6,7 @@
6
6
  var crypto = require("crypto");
7
7
  var constants = require("./constants");
8
8
  var intrinsic = require("./guard-intrinsic");
9
+ var guard = require("./guard-all");
9
10
  var guardIdentifier = require("./guard-identifier");
10
11
  var _hasOwn = intrinsic.hasOwn;
11
12
  /** @internal The URL parser, taken at load: the origin it reports is what a challenge is bound to.
@@ -46,14 +47,11 @@ var DEFAULT_CODES = intrinsic.assign(intrinsic.create(null), {
46
47
  noQop: "digest/no-qop", badChallenge: "digest/bad-challenge",
47
48
  });
48
49
 
49
- /** @internal The hash the credential is computed with, taken at load along with the methods of the
50
- * object it returns. Every Digest response value is this function's output, so a replacement chooses
51
- * what is sent in place of the password-derived proof. */
52
- var _createHash = crypto.createHash;
50
+ /** @internal Every Digest response value is this function's output, so whatever computes it chooses
51
+ * what is sent in place of the password-derived proof. RFC 7616 sec. 3 computes over the octets of
52
+ * the latin1 encoding, which is why the input encoding is named rather than defaulted. */
53
53
  var _randomBytes = crypto.randomBytes;
54
- var _hashUpdate = intrinsic.uncurry(crypto.createHash("sha256").update);
55
- var _hashDigest = intrinsic.uncurry(crypto.createHash("sha256").digest);
56
- function H(hash, s) { return _hashDigest(_hashUpdate(_createHash(hash), s, "latin1"), "hex"); }
54
+ function H(hash, s) { return guard.crypto.digest(hash, s, { input: "latin1", output: "hex" }); }
57
55
  function KD(hash, secret, data) { return H(hash, secret + ":" + data); }
58
56
  function _qstr(v) {
59
57
  var s = intrinsic.String(v), out = "";
package/lib/key.js CHANGED
@@ -183,11 +183,11 @@ async function encrypt(privateKey, password, opts) {
183
183
  var prf = opts.prf || "hmacWithSHA256";
184
184
  var prfNode = pbes2.prfNodeByName(prf, _err, "key");
185
185
  var iterations = pbes2.assertIterations(opts.iterations == null ? 600000 : opts.iterations, _err, "key");
186
- var salt = opts.salt != null ? pbes2.assertSalt(guard.bytes.view(opts.salt, KeyError, "key/bad-input", "salt"), _err, "key") : nodeCrypto.randomBytes(16);
187
- var iv = nodeCrypto.randomBytes(16);
186
+ var salt = opts.salt != null ? pbes2.assertSalt(guard.bytes.view(opts.salt, KeyError, "key/bad-input", "salt"), _err, "key") : guard.crypto.randomBytes(16);
187
+ var iv = guard.crypto.randomBytes(16);
188
188
  var pwK = pbes2.passwordBytesOwned(password, _err, "key");
189
189
  var dk;
190
- try { dk = nodeCrypto.pbkdf2Sync(pwK.bytes, salt, iterations, keyBits / 8, prfNode); }
190
+ try { dk = guard.crypto.pbkdf2(pwK.bytes, salt, iterations, keyBits / 8, prfNode); }
191
191
  finally { if (pwK.owned) guard.secret.zeroize(pwK.bytes, KeyError, "key/bad-input", "the password encoding"); }
192
192
  try {
193
193
  var ciphertext = pbes2.cbcEncrypt(dk, iv, der, keyBits, KeyError, "key/bad-input");
@@ -290,6 +290,10 @@ function _decryptPbes2(encAlg, ciphertext, password, opts) {
290
290
  * var spkiPem = await pki.key.export(pair.publicKey, { format: "pem" });
291
291
  */
292
292
  var _EXPORT_OPTS = _assign(_create(null), { format: 1, label: 1 });
293
+ /** @internal The WebCrypto export format each key type calls for, named here so the ONE read of the
294
+ * key's type below settles the encoding as well as the PEM label. Passing the format explicitly is
295
+ * what keeps the engine from reading the type a second time. */
296
+ var _EXPORT_WANT_BY_TYPE = _assign(_create(null), { "private": "pkcs8", "public": "spki", "secret": "raw" });
293
297
 
294
298
  async function export_(key, opts) {
295
299
  opts = guard.identifier.optionsObject(opts, _err, "key/bad-input", "pki.key.export options");
@@ -297,9 +301,14 @@ async function export_(key, opts) {
297
301
  "pki.key.export has an unknown option. It serializes only. To protect a private key, call " +
298
302
  "pki.key.encrypt(key, password) first and export its result. The unknown option was: ");
299
303
  if (!_isCryptoKey(key)) throw _err("key/bad-input", "export expects a WebCrypto CryptoKey");
304
+ /** @internal ONE read of the key's type, which both the PEM label and every encoding decision
305
+ * below come from. On node's own CryptoKey it is a getter, so reading it per question let a
306
+ * replacement answer "private" where the label was chosen and "public" where the bytes were, and
307
+ * a public key came back inside a `PRIVATE KEY` block. */
308
+ var keyType = key.type;
300
309
  var defaultLabel;
301
- if (key.type === "private") defaultLabel = "PRIVATE KEY";
302
- else if (key.type === "public") defaultLabel = "PUBLIC KEY";
310
+ if (keyType === "private") defaultLabel = "PRIVATE KEY";
311
+ else if (keyType === "public") defaultLabel = "PUBLIC KEY";
303
312
  else throw _err("key/bad-input", "export supports asymmetric (private / public) CryptoKeys only");
304
313
  var fmt = opts.format || "der";
305
314
  if (fmt === "jwk") {
@@ -310,11 +319,11 @@ async function export_(key, opts) {
310
319
  throw _err("key/bad-input", "exporting the key as a JWK failed", e);
311
320
  }
312
321
  }
313
- var der = await _exportAnyKey(key, _err, "key/bad-input");
322
+ var der = await _exportAnyKey(key, _err, "key/bad-input", _EXPORT_WANT_BY_TYPE[keyType]);
314
323
  if (fmt === "der") return der;
315
324
  if (fmt === "pem") return pkix.pemEncode(der, opts.label || defaultLabel, PemError);
316
- if (fmt === "pkcs1") return _toPkcs1(der, key);
317
- if (fmt === "sec1") return _toSec1(der, key);
325
+ if (fmt === "pkcs1") return _toPkcs1(der, key, keyType);
326
+ if (fmt === "sec1") return _toSec1(der, key, keyType);
318
327
  throw _err("key/bad-input", "unsupported format " + guard.text.showValue(opts.format) + " (der / pem / pkcs1 / sec1 / jwk)");
319
328
  }
320
329
 
@@ -923,18 +932,19 @@ var _PAIR_RSA = _assign(_create(null), { rsa: 1, "rsa-pss": 1 });
923
932
  var _PAIR_PROBE = _bufferFrom("pki.js key pair correspondence", "utf8");
924
933
 
925
934
  function _sameKeyFamily(priv, pub) {
926
- if (priv.asymmetricKeyType === pub.asymmetricKeyType) return true;
927
- return !!(_PAIR_RSA[guard.text.keyOf(priv.asymmetricKeyType)] &&
928
- _PAIR_RSA[guard.text.keyOf(pub.asymmetricKeyType)]);
935
+ var privType = guard.crypto.keyType(priv), pubType = guard.crypto.keyType(pub);
936
+ if (privType === pubType) return true;
937
+ return !!(_PAIR_RSA[guard.text.keyOf(privType)] && _PAIR_RSA[guard.text.keyOf(pubType)]);
929
938
  }
930
939
 
931
940
  /** @internal How to exercise a signing pair: the digest, and any padding the encoding requires. An
932
941
  * `id-RSASSA-PSS` key may pin the hash and salt length it is usable with, and the engine refuses any
933
942
  * other, so a pinned value from either half is what proves the pair. */
934
943
  function _pairSignOptions(priv, pub) {
935
- var privPss = priv.asymmetricKeyType === "rsa-pss", pubPss = pub.asymmetricKeyType === "rsa-pss";
944
+ var privType = guard.crypto.keyType(priv);
945
+ var privPss = privType === "rsa-pss", pubPss = guard.crypto.keyType(pub) === "rsa-pss";
936
946
  if (!privPss && !pubPss) {
937
- return { digest: _PAIR_DIGEST[guard.text.keyOf(priv.asymmetricKeyType)] || null, options: null };
947
+ return { digest: _PAIR_DIGEST[guard.text.keyOf(privType)] || null, options: null };
938
948
  }
939
949
  var privDetails = _pssRestrictionOf(priv, privPss);
940
950
  var pubDetails = _pssRestrictionOf(pub, pubPss);
@@ -969,7 +979,7 @@ var _PSS_PINS = ["hashAlgorithm", "mgf1HashAlgorithm", "saltLength"];
969
979
  * carried, and refuse a genuine pair. */
970
980
  function _pssRestrictionOf(key, isPss) {
971
981
  var out = _create(null);
972
- var details = isPss ? key.asymmetricKeyDetails : null;
982
+ var details = isPss ? guard.crypto.keyDetails(key) : null;
973
983
  if (details == null) return out;
974
984
  for (var i = 0; i < _PSS_PINS.length; i++) {
975
985
  var name = _PSS_PINS[i];
@@ -1026,7 +1036,7 @@ async function correspondsTo(privateKey, spkiDer) {
1026
1036
  try { pub = guard.crypto.publicKey({ key: pubAsPkcs3, format: "der", type: "spki" }); }
1027
1037
  catch (e) { throw _err("key/bad-input", "the public key could not be read", e); }
1028
1038
  if (!_sameKeyFamily(priv, pub)) return false;
1029
- var kind = guard.text.keyOf(priv.asymmetricKeyType);
1039
+ var kind = guard.text.keyOf(guard.crypto.keyType(priv));
1030
1040
  /** @internal Every secret a probe makes, wiped once the verdict is decided, on every way out. */
1031
1041
  var secrets = [];
1032
1042
  try {
@@ -1041,17 +1051,17 @@ async function correspondsTo(privateKey, spkiDer) {
1041
1051
  return _keyEquals(guard.crypto.publicKey(priv), pub) === true;
1042
1052
  }
1043
1053
  if (_PAIR_KEM[kind]) {
1044
- var sealed = nodeCrypto.encapsulate(pub);
1054
+ var sealed = guard.crypto.encapsulate(pub);
1045
1055
  guard.list.append(secrets, sealed.sharedKey);
1046
- var opened = nodeCrypto.decapsulate(priv, sealed.ciphertext);
1056
+ var opened = guard.crypto.decapsulate(priv, sealed.ciphertext);
1047
1057
  guard.list.append(secrets, opened);
1048
1058
  return guard.crypto.constantTimeEqual(opened, sealed.sharedKey);
1049
1059
  }
1050
1060
  if (_PAIR_AGREE[kind]) {
1051
- var ephemeral = nodeCrypto.generateKeyPairSync(priv.asymmetricKeyType);
1052
- var ours = nodeCrypto.diffieHellman({ privateKey: priv, publicKey: ephemeral.publicKey });
1061
+ var ephemeral = guard.crypto.generateKeyPair(guard.crypto.keyType(priv));
1062
+ var ours = guard.crypto.diffieHellman({ privateKey: priv, publicKey: ephemeral.publicKey });
1053
1063
  guard.list.append(secrets, ours);
1054
- var theirs = nodeCrypto.diffieHellman({ privateKey: ephemeral.privateKey, publicKey: pub });
1064
+ var theirs = guard.crypto.diffieHellman({ privateKey: ephemeral.privateKey, publicKey: pub });
1055
1065
  guard.list.append(secrets, theirs);
1056
1066
  if (!guard.crypto.constantTimeEqual(ours, theirs)) return false;
1057
1067
  /** @internal The agreement proves the SCALAR, not the encoding it was handed. RFC 7748 masks the
@@ -1194,13 +1204,13 @@ async function _importNamedFormat(input, opts) {
1194
1204
  /** @internal The inverse of the wrap: pull the inner key out of the PKCS#8 or SPKI the engine
1195
1205
  * wrote. The bytes come back as they went in, since the engine carries the inner structure
1196
1206
  * unchanged and this reads it rather than re-encoding it. */
1197
- function _toPkcs1(der, key) {
1198
- var algOid = _wrappedAlgorithmOid(der, key);
1207
+ function _toPkcs1(der, key, keyType) {
1208
+ var algOid = _wrappedAlgorithmOid(der, keyType);
1199
1209
  if (algOid !== O("rsaEncryption")) {
1200
1210
  throw _err("key/bad-input", "PKCS#1 is an RSA encoding (RFC 8017 App. A.1) and this key is " + _algName(key.algorithm));
1201
1211
  }
1202
1212
  var node = asn1.decode(der);
1203
- if (key.type === "public") {
1213
+ if (keyType === "public") {
1204
1214
  var bits = asn1.read.bitString(node.children[1]);
1205
1215
  if (bits.unusedBits !== 0) throw _err("key/bad-input", "the exported public key does not hold whole octets");
1206
1216
  schemaPkcs1.parsePublic(bits.bytes);
@@ -1210,12 +1220,12 @@ function _toPkcs1(der, key) {
1210
1220
  schemaPkcs1.parse(inner);
1211
1221
  return inner;
1212
1222
  }
1213
- function _toSec1(der, key) {
1214
- var algOid = _wrappedAlgorithmOid(der, key);
1223
+ function _toSec1(der, key, keyType) {
1224
+ var algOid = _wrappedAlgorithmOid(der, keyType);
1215
1225
  if (algOid !== O("ecPublicKey")) {
1216
1226
  throw _err("key/bad-input", "SEC1 is an elliptic-curve private-key encoding (RFC 5915 sec. 3) and this key is " + _algName(key.algorithm));
1217
1227
  }
1218
- if (key.type !== "private") {
1228
+ if (keyType !== "private") {
1219
1229
  throw _err("key/bad-input", "SEC1 encodes a private key; export the public half as SubjectPublicKeyInfo");
1220
1230
  }
1221
1231
  var node = asn1.decode(der);
@@ -1248,11 +1258,13 @@ function _toSec1(der, key) {
1248
1258
  }
1249
1259
 
1250
1260
  /** @internal The algorithm the wrapper names, read from whichever wrapper the key type produced:
1251
- * a PrivateKeyInfo names it second, a SubjectPublicKeyInfo first. */
1252
- function _wrappedAlgorithmOid(der, key) {
1261
+ * a PrivateKeyInfo names it second, a SubjectPublicKeyInfo first. `keyType` is the one read the
1262
+ * caller took, rather than a fresh one off the key, so every decision in an export comes from the
1263
+ * same answer. */
1264
+ function _wrappedAlgorithmOid(der, keyType) {
1253
1265
  var node;
1254
1266
  try { node = asn1.decode(der); } catch (e) { throw _err("key/bad-input", "the exported key is not DER", e); }
1255
- var algSeq = key.type === "public" ? node.children[0] : node.children[1];
1267
+ var algSeq = keyType === "public" ? node.children[0] : node.children[1];
1256
1268
  if (!algSeq || !algSeq.children || algSeq.children.length === 0) {
1257
1269
  throw _err("key/bad-input", "the exported key names no algorithm");
1258
1270
  }
package/lib/ocsp.js CHANGED
@@ -23,7 +23,6 @@
23
23
  * @card Build, sign, and verify RFC 6960 OCSP requests + responses (a responder + a relying party).
24
24
  */
25
25
 
26
- var nodeCrypto = require("crypto");
27
26
  var asn1 = require("./asn1-der");
28
27
  var pkiBuild = require("./pki-build");
29
28
  var _ocspIntrinsic = require("./guard-intrinsic");
@@ -245,7 +244,7 @@ function _buildRequest(query, opts) {
245
244
  _push(tbsChildren,b.sequence(requests));
246
245
  var reqExts = [];
247
246
  if (opts.nonce) {
248
- var nonceBytes = opts.nonce === true ? nodeCrypto.randomBytes(32) : opts.nonce;
247
+ var nonceBytes = opts.nonce === true ? guard.crypto.randomBytes(32) : opts.nonce;
249
248
  _assertNonce(nonceBytes, REQUESTER_NONCE_FLOOR);
250
249
  _push(reqExts,_nonceExt(nonceBytes));
251
250
  }
package/lib/pbes2.js CHANGED
@@ -3,7 +3,6 @@
3
3
  "use strict";
4
4
  // @internal
5
5
 
6
- var nodeCrypto = require("crypto");
7
6
  var asn1 = require("./asn1-der");
8
7
  var oid = require("./oid");
9
8
  var webcrypto = require("./webcrypto");
@@ -102,11 +101,11 @@ function parsePbkdf2Params(paramsDer, opts, E, prefix, strictPrf) {
102
101
  }
103
102
 
104
103
  function cbcEncrypt(key, iv, plaintext, keyBits, E, code) {
105
- var c = nodeCrypto.createCipheriv("aes-" + keyBits + "-cbc", key, iv);
104
+ var c = guard.crypto.cipher("aes-" + keyBits + "-cbc", key, iv);
106
105
  return guard.secret.cipherFinish(c, plaintext, E, code, "a content-encryption intermediate");
107
106
  }
108
107
  function cbcDecrypt(key, iv, ct, keyBits, E, code) {
109
- var d = nodeCrypto.createDecipheriv("aes-" + keyBits + "-cbc", key, iv);
108
+ var d = guard.crypto.decipher("aes-" + keyBits + "-cbc", key, iv);
110
109
  return guard.secret.cipherFinish(d, ct, E, code, "the partially recovered plaintext");
111
110
  }
112
111
 
@@ -118,9 +117,9 @@ function pbes2Encrypt(pwBytes, plaintext, opts, E, prefix) {
118
117
  var prf = opts.prf || "hmacWithSHA256";
119
118
  var prfNode = prfNodeByName(prf, E, prefix);
120
119
  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);
120
+ var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) : guard.crypto.randomBytes(16);
121
+ var iv = opts.iv != null ? opts.iv : guard.crypto.randomBytes(16);
122
+ var key = guard.crypto.pbkdf2(pwBytes, salt, iterations, keyBits / 8, prfNode);
124
123
  try {
125
124
  return { algId: pbes2AlgId(salt, iterations, prf, cipherName, iv), ct: cbcEncrypt(key, iv, plaintext, keyBits, E, prefix + "/bad-input") };
126
125
  } finally {
@@ -152,7 +151,7 @@ function pbes2Decrypt(pwBytes, params, ciphertext, opts, E, prefix, budget) {
152
151
  budget.rounds -= pb.iterations;
153
152
  if (budget.rounds < 0) throw E(prefix + "/iteration-limit", "the aggregate PBKDF2 key-derivation work exceeds the budget (a hostile many-element input)");
154
153
  }
155
- var dk = nodeCrypto.pbkdf2Sync(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
154
+ var dk = guard.crypto.pbkdf2(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
156
155
  try { return cbcDecrypt(dk, iv, ciphertext, keyBits, E, prefix + "/decrypt-failed"); }
157
156
  catch (_e) { throw E(prefix + "/decrypt-failed", "decryption failed"); }
158
157
  finally { guard.secret.zeroize(dk, E, prefix + "/bad-input", "the password-derived decryption key"); }
@@ -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);
@@ -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 {
@@ -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;
@@ -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;
@@ -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));
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
 
@@ -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 +