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/bin/pki.mjs +60 -27
- package/dist/bin/pki.mjs.map +1 -1
- package/dist/index.js +59 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
1207
|
+
exploreCertificateCached(leafCertificate);
|
|
1190
1208
|
} catch (_err) {
|
|
1191
1209
|
return "BadCertificateInvalid" /* BadCertificateInvalid */;
|
|
1192
1210
|
}
|
|
@@ -1246,7 +1264,7 @@ var init_certificate_manager = __esm({
|
|
|
1246
1264
|
*
|
|
1247
1265
|
*/
|
|
1248
1266
|
async findIssuerCertificate(certificate) {
|
|
1249
|
-
const certInfo =
|
|
1267
|
+
const certInfo = exploreCertificateCached(certificate);
|
|
1250
1268
|
if (isSelfSigned2(certInfo)) {
|
|
1251
1269
|
return certificate;
|
|
1252
1270
|
}
|
|
@@ -1327,7 +1345,7 @@ var init_certificate_manager = __esm({
|
|
|
1327
1345
|
});
|
|
1328
1346
|
}
|
|
1329
1347
|
#findAssociatedCRLs(issuerCertificate) {
|
|
1330
|
-
const issuerCertificateInfo =
|
|
1348
|
+
const issuerCertificateInfo = exploreCertificateCached(issuerCertificate);
|
|
1331
1349
|
const key = issuerCertificateInfo.tbsCertificate.subjectFingerPrint;
|
|
1332
1350
|
return this.#thumbs.issuersCrl.get(key) ?? this.#thumbs.crl.get(key) ?? null;
|
|
1333
1351
|
}
|
|
@@ -1361,7 +1379,7 @@ var init_certificate_manager = __esm({
|
|
|
1361
1379
|
if (!crls) {
|
|
1362
1380
|
return "BadCertificateRevocationUnknown" /* BadCertificateRevocationUnknown */;
|
|
1363
1381
|
}
|
|
1364
|
-
const certInfo =
|
|
1382
|
+
const certInfo = exploreCertificateCached(certificate);
|
|
1365
1383
|
const serialNumber = certInfo.tbsCertificate.serialNumber || certInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.serial || "";
|
|
1366
1384
|
const key = certInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.authorityCertIssuerFingerPrint || "<unknown>";
|
|
1367
1385
|
const crl2 = this.#thumbs.crl.get(key) ?? null;
|
|
@@ -1428,22 +1446,31 @@ var init_certificate_manager = __esm({
|
|
|
1428
1446
|
...usePolling ? { interval: pollingInterval } : {},
|
|
1429
1447
|
persistent: false
|
|
1430
1448
|
};
|
|
1431
|
-
const
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1449
|
+
const allCapturedHandles = [];
|
|
1450
|
+
const origWatch = fs4.watch;
|
|
1451
|
+
let watcherReadyCount = 0;
|
|
1452
|
+
const totalWatchers = 5;
|
|
1453
|
+
fs4.watch = ((...args) => {
|
|
1454
|
+
const handle = origWatch.apply(fs4, args);
|
|
1455
|
+
handle.setMaxListeners(handle.getMaxListeners() + 1);
|
|
1456
|
+
handle.on("error", () => {
|
|
1438
1457
|
});
|
|
1458
|
+
allCapturedHandles.push(handle);
|
|
1459
|
+
return handle;
|
|
1460
|
+
});
|
|
1461
|
+
const createUnreffedWatcher = (folder) => {
|
|
1462
|
+
const startIdx = allCapturedHandles.length;
|
|
1439
1463
|
const w = chokidar.watch(folder, chokidarOptions);
|
|
1440
1464
|
const unreffAll = () => {
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1465
|
+
for (let i = startIdx; i < allCapturedHandles.length; i++) {
|
|
1466
|
+
allCapturedHandles[i].unref();
|
|
1467
|
+
}
|
|
1468
|
+
watcherReadyCount++;
|
|
1469
|
+
if (watcherReadyCount >= totalWatchers) {
|
|
1470
|
+
fs4.watch = origWatch;
|
|
1444
1471
|
}
|
|
1445
1472
|
};
|
|
1446
|
-
return { w, capturedHandles, unreffAll };
|
|
1473
|
+
return { w, capturedHandles: allCapturedHandles.slice(startIdx), unreffAll };
|
|
1447
1474
|
};
|
|
1448
1475
|
await Promise.all([
|
|
1449
1476
|
this.#scanCertFolder(this.trustedFolder, this.#thumbs.trusted),
|
|
@@ -1472,7 +1499,7 @@ var init_certificate_manager = __esm({
|
|
|
1472
1499
|
const stat = await fs4.promises.stat(filename);
|
|
1473
1500
|
if (!stat.isFile()) continue;
|
|
1474
1501
|
const certificate = await readCertificateAsync(filename);
|
|
1475
|
-
const info =
|
|
1502
|
+
const info = exploreCertificateCached(certificate);
|
|
1476
1503
|
const fingerprint2 = makeFingerprint(certificate);
|
|
1477
1504
|
index.set(fingerprint2, { certificate, filename, info });
|
|
1478
1505
|
this.#filenameToHash.set(filename, fingerprint2);
|
|
@@ -1505,6 +1532,9 @@ var init_certificate_manager = __esm({
|
|
|
1505
1532
|
*/
|
|
1506
1533
|
#startCrlWatcher(folder, index, createUnreffedWatcher, store) {
|
|
1507
1534
|
const { w, unreffAll } = createUnreffedWatcher(folder);
|
|
1535
|
+
w.on("error", (err) => {
|
|
1536
|
+
debugLog(`chokidar CRL watcher error on ${folder}:`, err);
|
|
1537
|
+
});
|
|
1508
1538
|
let ready = false;
|
|
1509
1539
|
w.on("unlink", (filename) => {
|
|
1510
1540
|
for (const [key, data] of index.entries()) {
|
|
@@ -1540,6 +1570,9 @@ var init_certificate_manager = __esm({
|
|
|
1540
1570
|
*/
|
|
1541
1571
|
#startWatcher(folder, index, createUnreffedWatcher, store) {
|
|
1542
1572
|
const { w, unreffAll } = createUnreffedWatcher(folder);
|
|
1573
|
+
w.on("error", (err) => {
|
|
1574
|
+
debugLog(`chokidar cert watcher error on ${folder}:`, err);
|
|
1575
|
+
});
|
|
1543
1576
|
let ready = false;
|
|
1544
1577
|
w.on("unlink", (filename) => {
|
|
1545
1578
|
debugLog(chalk3.cyan(`unlink in folder ${folder}`), filename);
|
|
@@ -1553,7 +1586,7 @@ var init_certificate_manager = __esm({
|
|
|
1553
1586
|
debugLog(chalk3.cyan(`add in folder ${folder}`), filename);
|
|
1554
1587
|
try {
|
|
1555
1588
|
const certificate = readCertificate(filename);
|
|
1556
|
-
const info =
|
|
1589
|
+
const info = exploreCertificateCached(certificate);
|
|
1557
1590
|
const fingerprint2 = makeFingerprint(certificate);
|
|
1558
1591
|
const isNew = !index.has(fingerprint2);
|
|
1559
1592
|
index.set(fingerprint2, { certificate, filename, info });
|
|
@@ -1581,7 +1614,7 @@ var init_certificate_manager = __esm({
|
|
|
1581
1614
|
if (oldHash && oldHash !== newFingerprint) {
|
|
1582
1615
|
index.delete(oldHash);
|
|
1583
1616
|
}
|
|
1584
|
-
index.set(newFingerprint, { certificate, filename: changedPath, info:
|
|
1617
|
+
index.set(newFingerprint, { certificate, filename: changedPath, info: exploreCertificateCached(certificate) });
|
|
1585
1618
|
this.#filenameToHash.set(changedPath, newFingerprint);
|
|
1586
1619
|
this.emit("certificateChange", { store, certificate, fingerprint: newFingerprint, filename: changedPath });
|
|
1587
1620
|
} catch (err) {
|