node-opcua-pki 6.7.0 → 6.7.2

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/dist/index.mjs CHANGED
@@ -1175,10 +1175,28 @@ var configurationFileSimpleTemplate = simple_config_template_cnf_default;
1175
1175
  var fsWriteFile = fs9.promises.writeFile;
1176
1176
  function getOrComputeInfo(entry) {
1177
1177
  if (!entry.info) {
1178
- entry.info = exploreCertificate(entry.certificate);
1178
+ entry.info = exploreCertificateCached(entry.certificate);
1179
1179
  }
1180
1180
  return entry.info;
1181
1181
  }
1182
+ var EXPLORE_CACHE_MAX = 8;
1183
+ var _exploreCache = /* @__PURE__ */ new Map();
1184
+ function exploreCertificateCached(certificate) {
1185
+ const key = makeSHA1Thumbprint(certificate).toString("hex");
1186
+ const cached = _exploreCache.get(key);
1187
+ if (cached) {
1188
+ _exploreCache.delete(key);
1189
+ _exploreCache.set(key, cached);
1190
+ return cached;
1191
+ }
1192
+ const info = exploreCertificate(certificate);
1193
+ _exploreCache.set(key, info);
1194
+ if (_exploreCache.size > EXPLORE_CACHE_MAX) {
1195
+ const oldest = _exploreCache.keys().next().value;
1196
+ if (oldest) _exploreCache.delete(oldest);
1197
+ }
1198
+ return info;
1199
+ }
1182
1200
  var VerificationStatus = /* @__PURE__ */ ((VerificationStatus2) => {
1183
1201
  VerificationStatus2["BadCertificateInvalid"] = "BadCertificateInvalid";
1184
1202
  VerificationStatus2["BadSecurityChecksFailed"] = "BadSecurityChecksFailed";
@@ -1209,7 +1227,7 @@ var forbiddenChars = /[\x00-\x1F<>:"/\\|?*]/g;
1209
1227
  function buildIdealCertificateName(certificate) {
1210
1228
  const fingerprint = makeFingerprint(certificate);
1211
1229
  try {
1212
- const commonName = exploreCertificate(certificate).tbsCertificate.subject.commonName || "";
1230
+ const commonName = exploreCertificateCached(certificate).tbsCertificate.subject.commonName || "";
1213
1231
  const sanitizedCommonName = commonName.replace(forbiddenChars, "_");
1214
1232
  return `${sanitizedCommonName}[${fingerprint}]`;
1215
1233
  } catch (_err) {
@@ -1226,14 +1244,14 @@ function isSelfSigned2(info) {
1226
1244
  return info.tbsCertificate.extensions?.subjectKeyIdentifier === info.tbsCertificate.extensions?.authorityKeyIdentifier?.keyIdentifier;
1227
1245
  }
1228
1246
  function isSelfSigned3(certificate) {
1229
- const info = exploreCertificate(certificate);
1247
+ const info = exploreCertificateCached(certificate);
1230
1248
  return isSelfSigned2(info);
1231
1249
  }
1232
1250
  function findIssuerCertificateInChain(certificate, chain) {
1233
1251
  if (!certificate) {
1234
1252
  return null;
1235
1253
  }
1236
- const certInfo = exploreCertificate(certificate);
1254
+ const certInfo = exploreCertificateCached(certificate);
1237
1255
  if (isSelfSigned2(certInfo)) {
1238
1256
  return certificate;
1239
1257
  }
@@ -1243,7 +1261,7 @@ function findIssuerCertificateInChain(certificate, chain) {
1243
1261
  return null;
1244
1262
  }
1245
1263
  const potentialIssuers = chain.filter((c) => {
1246
- const info = exploreCertificate(c);
1264
+ const info = exploreCertificateCached(c);
1247
1265
  return info.tbsCertificate.extensions && info.tbsCertificate.extensions.subjectKeyIdentifier === wantedIssuerKey;
1248
1266
  });
1249
1267
  if (potentialIssuers.length === 1) {
@@ -1479,7 +1497,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
1479
1497
  }
1480
1498
  const chain = split_der(certificate);
1481
1499
  debugLog("NB CERTIFICATE IN CHAIN = ", chain.length);
1482
- const info = exploreCertificate(chain[0]);
1500
+ const info = exploreCertificateCached(chain[0]);
1483
1501
  let hasValidIssuer = false;
1484
1502
  let hasTrustedIssuer = false;
1485
1503
  const hasIssuerKey = info.tbsCertificate.extensions?.authorityKeyIdentifier?.keyIdentifier;
@@ -1756,7 +1774,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
1756
1774
  await this.#readCertificates();
1757
1775
  }
1758
1776
  async withLock2(action) {
1759
- const lockFileName = path6.join(this.rootDir, "mutex.lock");
1777
+ const lockFileName = path6.join(this.rootDir, "mutex");
1760
1778
  return withLock({ fileToLock: lockFileName }, async () => {
1761
1779
  return await action();
1762
1780
  });
@@ -1967,7 +1985,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
1967
1985
  * @param target - "issuers", "trusted", or "all" (default "all")
1968
1986
  */
1969
1987
  async removeRevocationListsForIssuer(issuerCertificate, target = "all") {
1970
- const issuerInfo = exploreCertificate(issuerCertificate);
1988
+ const issuerInfo = exploreCertificateCached(issuerCertificate);
1971
1989
  const issuerFingerprint = issuerInfo.tbsCertificate.subjectFingerPrint;
1972
1990
  const processIndex = async (index) => {
1973
1991
  const crlData = index.get(issuerFingerprint);
@@ -2013,7 +2031,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2013
2031
  const certificates = split_der(certificateChain);
2014
2032
  const leafCertificate = certificates[0];
2015
2033
  try {
2016
- exploreCertificate(leafCertificate);
2034
+ exploreCertificateCached(leafCertificate);
2017
2035
  } catch (_err) {
2018
2036
  return "BadCertificateInvalid" /* BadCertificateInvalid */;
2019
2037
  }
@@ -2073,7 +2091,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2073
2091
  *
2074
2092
  */
2075
2093
  async findIssuerCertificate(certificate) {
2076
- const certInfo = exploreCertificate(certificate);
2094
+ const certInfo = exploreCertificateCached(certificate);
2077
2095
  if (isSelfSigned2(certInfo)) {
2078
2096
  return certificate;
2079
2097
  }
@@ -2154,7 +2172,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2154
2172
  });
2155
2173
  }
2156
2174
  #findAssociatedCRLs(issuerCertificate) {
2157
- const issuerCertificateInfo = exploreCertificate(issuerCertificate);
2175
+ const issuerCertificateInfo = exploreCertificateCached(issuerCertificate);
2158
2176
  const key = issuerCertificateInfo.tbsCertificate.subjectFingerPrint;
2159
2177
  return this.#thumbs.issuersCrl.get(key) ?? this.#thumbs.crl.get(key) ?? null;
2160
2178
  }
@@ -2188,7 +2206,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2188
2206
  if (!crls) {
2189
2207
  return "BadCertificateRevocationUnknown" /* BadCertificateRevocationUnknown */;
2190
2208
  }
2191
- const certInfo = exploreCertificate(certificate);
2209
+ const certInfo = exploreCertificateCached(certificate);
2192
2210
  const serialNumber = certInfo.tbsCertificate.serialNumber || certInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.serial || "";
2193
2211
  const key = certInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.authorityCertIssuerFingerPrint || "<unknown>";
2194
2212
  const crl2 = this.#thumbs.crl.get(key) ?? null;
@@ -2255,22 +2273,31 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2255
2273
  ...usePolling ? { interval: pollingInterval } : {},
2256
2274
  persistent: false
2257
2275
  };
2258
- const createUnreffedWatcher = (folder) => {
2259
- const capturedHandles = [];
2260
- const origWatch = fs9.watch;
2261
- fs9.watch = ((...args) => {
2262
- const handle = origWatch.apply(fs9, args);
2263
- capturedHandles.push(handle);
2264
- return handle;
2276
+ const allCapturedHandles = [];
2277
+ const origWatch = fs9.watch;
2278
+ let watcherReadyCount = 0;
2279
+ const totalWatchers = 5;
2280
+ fs9.watch = ((...args) => {
2281
+ const handle = origWatch.apply(fs9, args);
2282
+ handle.setMaxListeners(handle.getMaxListeners() + 1);
2283
+ handle.on("error", () => {
2265
2284
  });
2285
+ allCapturedHandles.push(handle);
2286
+ return handle;
2287
+ });
2288
+ const createUnreffedWatcher = (folder) => {
2289
+ const startIdx = allCapturedHandles.length;
2266
2290
  const w = chokidar.watch(folder, chokidarOptions);
2267
2291
  const unreffAll = () => {
2268
- fs9.watch = origWatch;
2269
- for (const h of capturedHandles) {
2270
- h.unref();
2292
+ for (let i = startIdx; i < allCapturedHandles.length; i++) {
2293
+ allCapturedHandles[i].unref();
2294
+ }
2295
+ watcherReadyCount++;
2296
+ if (watcherReadyCount >= totalWatchers) {
2297
+ fs9.watch = origWatch;
2271
2298
  }
2272
2299
  };
2273
- return { w, capturedHandles, unreffAll };
2300
+ return { w, capturedHandles: allCapturedHandles.slice(startIdx), unreffAll };
2274
2301
  };
2275
2302
  await Promise.all([
2276
2303
  this.#scanCertFolder(this.trustedFolder, this.#thumbs.trusted),
@@ -2299,7 +2326,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2299
2326
  const stat = await fs9.promises.stat(filename);
2300
2327
  if (!stat.isFile()) continue;
2301
2328
  const certificate = await readCertificateAsync(filename);
2302
- const info = exploreCertificate(certificate);
2329
+ const info = exploreCertificateCached(certificate);
2303
2330
  const fingerprint = makeFingerprint(certificate);
2304
2331
  index.set(fingerprint, { certificate, filename, info });
2305
2332
  this.#filenameToHash.set(filename, fingerprint);
@@ -2332,6 +2359,9 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2332
2359
  */
2333
2360
  #startCrlWatcher(folder, index, createUnreffedWatcher, store) {
2334
2361
  const { w, unreffAll } = createUnreffedWatcher(folder);
2362
+ w.on("error", (err) => {
2363
+ debugLog(`chokidar CRL watcher error on ${folder}:`, err);
2364
+ });
2335
2365
  let ready = false;
2336
2366
  w.on("unlink", (filename) => {
2337
2367
  for (const [key, data] of index.entries()) {
@@ -2367,6 +2397,9 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2367
2397
  */
2368
2398
  #startWatcher(folder, index, createUnreffedWatcher, store) {
2369
2399
  const { w, unreffAll } = createUnreffedWatcher(folder);
2400
+ w.on("error", (err) => {
2401
+ debugLog(`chokidar cert watcher error on ${folder}:`, err);
2402
+ });
2370
2403
  let ready = false;
2371
2404
  w.on("unlink", (filename) => {
2372
2405
  debugLog(chalk6.cyan(`unlink in folder ${folder}`), filename);
@@ -2380,7 +2413,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2380
2413
  debugLog(chalk6.cyan(`add in folder ${folder}`), filename);
2381
2414
  try {
2382
2415
  const certificate = readCertificate(filename);
2383
- const info = exploreCertificate(certificate);
2416
+ const info = exploreCertificateCached(certificate);
2384
2417
  const fingerprint = makeFingerprint(certificate);
2385
2418
  const isNew = !index.has(fingerprint);
2386
2419
  index.set(fingerprint, { certificate, filename, info });
@@ -2408,7 +2441,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
2408
2441
  if (oldHash && oldHash !== newFingerprint) {
2409
2442
  index.delete(oldHash);
2410
2443
  }
2411
- index.set(newFingerprint, { certificate, filename: changedPath, info: exploreCertificate(certificate) });
2444
+ index.set(newFingerprint, { certificate, filename: changedPath, info: exploreCertificateCached(certificate) });
2412
2445
  this.#filenameToHash.set(changedPath, newFingerprint);
2413
2446
  this.emit("certificateChange", { store, certificate, fingerprint: newFingerprint, filename: changedPath });
2414
2447
  } catch (err) {