node-opcua-pki 6.6.0 → 6.7.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.
package/dist/bin/pki.mjs CHANGED
@@ -364,10 +364,26 @@ import {
364
364
  } from "node-opcua-crypto";
365
365
  function getOrComputeInfo(entry) {
366
366
  if (!entry.info) {
367
- entry.info = exploreCertificate(entry.certificate);
367
+ entry.info = exploreCertificateCached(entry.certificate);
368
368
  }
369
369
  return entry.info;
370
370
  }
371
+ function exploreCertificateCached(certificate) {
372
+ const key = makeSHA1Thumbprint(certificate).toString("hex");
373
+ const cached = _exploreCache.get(key);
374
+ if (cached) {
375
+ _exploreCache.delete(key);
376
+ _exploreCache.set(key, cached);
377
+ return cached;
378
+ }
379
+ const info = exploreCertificate(certificate);
380
+ _exploreCache.set(key, info);
381
+ if (_exploreCache.size > EXPLORE_CACHE_MAX) {
382
+ const oldest = _exploreCache.keys().next().value;
383
+ if (oldest) _exploreCache.delete(oldest);
384
+ }
385
+ return info;
386
+ }
371
387
  function makeFingerprint(certificate) {
372
388
  const chain = split_der(certificate);
373
389
  return makeSHA1Thumbprint(chain[0]).toString("hex");
@@ -378,7 +394,7 @@ function short(stringToShorten) {
378
394
  function buildIdealCertificateName(certificate) {
379
395
  const fingerprint2 = makeFingerprint(certificate);
380
396
  try {
381
- const commonName = exploreCertificate(certificate).tbsCertificate.subject.commonName || "";
397
+ const commonName = exploreCertificateCached(certificate).tbsCertificate.subject.commonName || "";
382
398
  const sanitizedCommonName = commonName.replace(forbiddenChars, "_");
383
399
  return `${sanitizedCommonName}[${fingerprint2}]`;
384
400
  } catch (_err) {
@@ -395,14 +411,14 @@ function isSelfSigned2(info) {
395
411
  return info.tbsCertificate.extensions?.subjectKeyIdentifier === info.tbsCertificate.extensions?.authorityKeyIdentifier?.keyIdentifier;
396
412
  }
397
413
  function isSelfSigned3(certificate) {
398
- const info = exploreCertificate(certificate);
414
+ const info = exploreCertificateCached(certificate);
399
415
  return isSelfSigned2(info);
400
416
  }
401
417
  function findIssuerCertificateInChain(certificate, chain) {
402
418
  if (!certificate) {
403
419
  return null;
404
420
  }
405
- const certInfo = exploreCertificate(certificate);
421
+ const certInfo = exploreCertificateCached(certificate);
406
422
  if (isSelfSigned2(certInfo)) {
407
423
  return certificate;
408
424
  }
@@ -412,7 +428,7 @@ function findIssuerCertificateInChain(certificate, chain) {
412
428
  return null;
413
429
  }
414
430
  const potentialIssuers = chain.filter((c) => {
415
- const info = exploreCertificate(c);
431
+ const info = exploreCertificateCached(c);
416
432
  return info.tbsCertificate.extensions && info.tbsCertificate.extensions.subjectKeyIdentifier === wantedIssuerKey;
417
433
  });
418
434
  if (potentialIssuers.length === 1) {
@@ -424,7 +440,7 @@ function findIssuerCertificateInChain(certificate, chain) {
424
440
  }
425
441
  return null;
426
442
  }
427
- var configurationFileSimpleTemplate, fsWriteFile, forbiddenChars, CertificateManager;
443
+ var configurationFileSimpleTemplate, fsWriteFile, EXPLORE_CACHE_MAX, _exploreCache, forbiddenChars, CertificateManager;
428
444
  var init_certificate_manager = __esm({
429
445
  "packages/node-opcua-pki/lib/pki/certificate_manager.ts"() {
430
446
  "use strict";
@@ -435,6 +451,8 @@ var init_certificate_manager = __esm({
435
451
  init_simple_config_template_cnf();
436
452
  configurationFileSimpleTemplate = simple_config_template_cnf_default;
437
453
  fsWriteFile = fs4.promises.writeFile;
454
+ EXPLORE_CACHE_MAX = 8;
455
+ _exploreCache = /* @__PURE__ */ new Map();
438
456
  forbiddenChars = /[\x00-\x1F<>:"/\\|?*]/g;
439
457
  CertificateManager = class _CertificateManager extends EventEmitter {
440
458
  // ── Global instance registry ─────────────────────────────────
@@ -652,7 +670,7 @@ var init_certificate_manager = __esm({
652
670
  }
653
671
  const chain = split_der(certificate);
654
672
  debugLog("NB CERTIFICATE IN CHAIN = ", chain.length);
655
- const info = exploreCertificate(chain[0]);
673
+ const info = exploreCertificateCached(chain[0]);
656
674
  let hasValidIssuer = false;
657
675
  let hasTrustedIssuer = false;
658
676
  const hasIssuerKey = info.tbsCertificate.extensions?.authorityKeyIdentifier?.keyIdentifier;
@@ -929,7 +947,7 @@ var init_certificate_manager = __esm({
929
947
  await this.#readCertificates();
930
948
  }
931
949
  async withLock2(action) {
932
- const lockFileName = path2.join(this.rootDir, "mutex.lock");
950
+ const lockFileName = path2.join(this.rootDir, "mutex");
933
951
  return withLock({ fileToLock: lockFileName }, async () => {
934
952
  return await action();
935
953
  });
@@ -1140,7 +1158,7 @@ var init_certificate_manager = __esm({
1140
1158
  * @param target - "issuers", "trusted", or "all" (default "all")
1141
1159
  */
1142
1160
  async removeRevocationListsForIssuer(issuerCertificate, target = "all") {
1143
- const issuerInfo = exploreCertificate(issuerCertificate);
1161
+ const issuerInfo = exploreCertificateCached(issuerCertificate);
1144
1162
  const issuerFingerprint = issuerInfo.tbsCertificate.subjectFingerPrint;
1145
1163
  const processIndex = async (index) => {
1146
1164
  const crlData = index.get(issuerFingerprint);
@@ -1186,7 +1204,7 @@ var init_certificate_manager = __esm({
1186
1204
  const certificates = split_der(certificateChain);
1187
1205
  const leafCertificate = certificates[0];
1188
1206
  try {
1189
- exploreCertificate(leafCertificate);
1207
+ exploreCertificateCached(leafCertificate);
1190
1208
  } catch (_err) {
1191
1209
  return "BadCertificateInvalid" /* BadCertificateInvalid */;
1192
1210
  }
@@ -1195,6 +1213,7 @@ var init_certificate_manager = __esm({
1195
1213
  return "BadCertificateInvalid" /* BadCertificateInvalid */;
1196
1214
  }
1197
1215
  if (certificates.length > 1) {
1216
+ await this.#scanCertFolder(this.issuersCertFolder, this.#thumbs.issuers.certs);
1198
1217
  for (const issuerCert of certificates.slice(1)) {
1199
1218
  const thumbprint = makeFingerprint(issuerCert);
1200
1219
  if (!await this.hasIssuer(thumbprint)) {
@@ -1245,7 +1264,7 @@ var init_certificate_manager = __esm({
1245
1264
  *
1246
1265
  */
1247
1266
  async findIssuerCertificate(certificate) {
1248
- const certInfo = exploreCertificate(certificate);
1267
+ const certInfo = exploreCertificateCached(certificate);
1249
1268
  if (isSelfSigned2(certInfo)) {
1250
1269
  return certificate;
1251
1270
  }
@@ -1326,7 +1345,7 @@ var init_certificate_manager = __esm({
1326
1345
  });
1327
1346
  }
1328
1347
  #findAssociatedCRLs(issuerCertificate) {
1329
- const issuerCertificateInfo = exploreCertificate(issuerCertificate);
1348
+ const issuerCertificateInfo = exploreCertificateCached(issuerCertificate);
1330
1349
  const key = issuerCertificateInfo.tbsCertificate.subjectFingerPrint;
1331
1350
  return this.#thumbs.issuersCrl.get(key) ?? this.#thumbs.crl.get(key) ?? null;
1332
1351
  }
@@ -1360,7 +1379,7 @@ var init_certificate_manager = __esm({
1360
1379
  if (!crls) {
1361
1380
  return "BadCertificateRevocationUnknown" /* BadCertificateRevocationUnknown */;
1362
1381
  }
1363
- const certInfo = exploreCertificate(certificate);
1382
+ const certInfo = exploreCertificateCached(certificate);
1364
1383
  const serialNumber = certInfo.tbsCertificate.serialNumber || certInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.serial || "";
1365
1384
  const key = certInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.authorityCertIssuerFingerPrint || "<unknown>";
1366
1385
  const crl2 = this.#thumbs.crl.get(key) ?? null;
@@ -1471,7 +1490,7 @@ var init_certificate_manager = __esm({
1471
1490
  const stat = await fs4.promises.stat(filename);
1472
1491
  if (!stat.isFile()) continue;
1473
1492
  const certificate = await readCertificateAsync(filename);
1474
- const info = exploreCertificate(certificate);
1493
+ const info = exploreCertificateCached(certificate);
1475
1494
  const fingerprint2 = makeFingerprint(certificate);
1476
1495
  index.set(fingerprint2, { certificate, filename, info });
1477
1496
  this.#filenameToHash.set(filename, fingerprint2);
@@ -1545,17 +1564,16 @@ var init_certificate_manager = __esm({
1545
1564
  const h = this.#filenameToHash.get(filename);
1546
1565
  if (h && index.has(h)) {
1547
1566
  index.delete(h);
1548
- if (ready) {
1549
- this.emit("certificateRemoved", { store, fingerprint: h, filename });
1550
- }
1567
+ this.emit("certificateRemoved", { store, fingerprint: h, filename });
1551
1568
  }
1552
1569
  });
1553
1570
  w.on("add", (filename) => {
1554
1571
  debugLog(chalk3.cyan(`add in folder ${folder}`), filename);
1555
1572
  try {
1556
1573
  const certificate = readCertificate(filename);
1557
- const info = exploreCertificate(certificate);
1574
+ const info = exploreCertificateCached(certificate);
1558
1575
  const fingerprint2 = makeFingerprint(certificate);
1576
+ const isNew = !index.has(fingerprint2);
1559
1577
  index.set(fingerprint2, { certificate, filename, info });
1560
1578
  this.#filenameToHash.set(filename, fingerprint2);
1561
1579
  debugLog(
@@ -1564,7 +1582,7 @@ var init_certificate_manager = __esm({
1564
1582
  info.tbsCertificate.serialNumber,
1565
1583
  info.tbsCertificate.extensions?.authorityKeyIdentifier?.authorityCertIssuerFingerPrint
1566
1584
  );
1567
- if (ready) {
1585
+ if (ready || isNew) {
1568
1586
  this.emit("certificateAdded", { store, certificate, fingerprint: fingerprint2, filename });
1569
1587
  }
1570
1588
  } catch (err) {
@@ -1581,11 +1599,9 @@ var init_certificate_manager = __esm({
1581
1599
  if (oldHash && oldHash !== newFingerprint) {
1582
1600
  index.delete(oldHash);
1583
1601
  }
1584
- index.set(newFingerprint, { certificate, filename: changedPath, info: exploreCertificate(certificate) });
1602
+ index.set(newFingerprint, { certificate, filename: changedPath, info: exploreCertificateCached(certificate) });
1585
1603
  this.#filenameToHash.set(changedPath, newFingerprint);
1586
- if (ready) {
1587
- this.emit("certificateChange", { store, certificate, fingerprint: newFingerprint, filename: changedPath });
1588
- }
1604
+ this.emit("certificateChange", { store, certificate, fingerprint: newFingerprint, filename: changedPath });
1589
1605
  } catch (err) {
1590
1606
  debugLog(`change event: failed to re-read ${changedPath}`, err);
1591
1607
  }