node-opcua-pki 6.12.2 → 6.13.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.
- package/dist/bin/pki.mjs +89 -6
- package/dist/bin/pki.mjs.map +1 -1
- package/dist/index.d.mts +60 -1
- package/dist/index.d.ts +60 -1
- package/dist/index.js +90 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -2022,6 +2022,14 @@ var CertificateManagerState = /* @__PURE__ */ ((CertificateManagerState2) => {
|
|
|
2022
2022
|
CertificateManagerState2[CertificateManagerState2["Disposed"] = 4] = "Disposed";
|
|
2023
2023
|
return CertificateManagerState2;
|
|
2024
2024
|
})(CertificateManagerState || {});
|
|
2025
|
+
var ChainCompletionStatus = /* @__PURE__ */ ((ChainCompletionStatus2) => {
|
|
2026
|
+
ChainCompletionStatus2["AlreadyComplete"] = "AlreadyComplete";
|
|
2027
|
+
ChainCompletionStatus2["ChainCompleted"] = "ChainCompleted";
|
|
2028
|
+
ChainCompletionStatus2["IssuerNotFound"] = "IssuerNotFound";
|
|
2029
|
+
ChainCompletionStatus2["EmptyChain"] = "EmptyChain";
|
|
2030
|
+
ChainCompletionStatus2["MaxDepthReached"] = "MaxDepthReached";
|
|
2031
|
+
return ChainCompletionStatus2;
|
|
2032
|
+
})(ChainCompletionStatus || {});
|
|
2025
2033
|
var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
2026
2034
|
// ── Global instance registry ─────────────────────────────────
|
|
2027
2035
|
// Tracks all initialized CertificateManager instances so their
|
|
@@ -2114,6 +2122,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
2114
2122
|
#filenameToHash = /* @__PURE__ */ new Map();
|
|
2115
2123
|
#initializingPromise;
|
|
2116
2124
|
#addCertValidation;
|
|
2125
|
+
#disableFileWatchers;
|
|
2117
2126
|
#thumbs = {
|
|
2118
2127
|
rejected: /* @__PURE__ */ new Map(),
|
|
2119
2128
|
trusted: /* @__PURE__ */ new Map(),
|
|
@@ -2147,6 +2156,7 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
2147
2156
|
ignoreMissingRevocationList: v.ignoreMissingRevocationList ?? false,
|
|
2148
2157
|
maxChainLength: v.maxChainLength ?? 5
|
|
2149
2158
|
};
|
|
2159
|
+
this.#disableFileWatchers = options.disableFileWatchers ?? process.env.OPCUA_PKI_DISABLE_FILE_WATCHERS === "true";
|
|
2150
2160
|
mkdirRecursiveSync(options.location);
|
|
2151
2161
|
if (!fs10.existsSync(this.#location)) {
|
|
2152
2162
|
throw new Error(`CertificateManager cannot access location ${this.#location}`);
|
|
@@ -3011,6 +3021,75 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
3011
3021
|
}
|
|
3012
3022
|
return selectedTrustedCertificates.length > 0 ? selectedTrustedCertificates[0].certificate : null;
|
|
3013
3023
|
}
|
|
3024
|
+
/**
|
|
3025
|
+
* Outcome status for {@link CertificateManager.completeCertificateChain}.
|
|
3026
|
+
*/
|
|
3027
|
+
static ChainCompletionStatus = ChainCompletionStatus;
|
|
3028
|
+
/**
|
|
3029
|
+
* Complete a certificate chain by walking the issuer store.
|
|
3030
|
+
*
|
|
3031
|
+
* Starting from the last certificate in the provided chain, this method
|
|
3032
|
+
* repeatedly calls {@link findIssuerCertificate} to locate the parent
|
|
3033
|
+
* certificate until it reaches a self-signed root or can no longer find
|
|
3034
|
+
* an issuer.
|
|
3035
|
+
*
|
|
3036
|
+
* @param chain - the (potentially partial) certificate chain, leaf first
|
|
3037
|
+
* @param maxDepth - maximum number of issuers to append (default: 10)
|
|
3038
|
+
* @returns a {@link ChainCompletionResult} containing the (possibly completed)
|
|
3039
|
+
* chain, a status code, and an optional diagnostic message.
|
|
3040
|
+
*/
|
|
3041
|
+
async completeCertificateChain(chain, maxDepth = 10) {
|
|
3042
|
+
if (chain.length === 0) {
|
|
3043
|
+
return {
|
|
3044
|
+
chain,
|
|
3045
|
+
status: "EmptyChain" /* EmptyChain */,
|
|
3046
|
+
message: "Input chain is empty \u2014 nothing to complete."
|
|
3047
|
+
};
|
|
3048
|
+
}
|
|
3049
|
+
await this.#scanCertFolder(this.issuersCertFolder, this.#thumbs.issuers.certs);
|
|
3050
|
+
const result = [...chain];
|
|
3051
|
+
let depth = 0;
|
|
3052
|
+
while (depth < maxDepth) {
|
|
3053
|
+
const lastCert = result[result.length - 1];
|
|
3054
|
+
const lastInfo = exploreCertificate2(lastCert);
|
|
3055
|
+
if (isSelfSigned2(lastInfo)) {
|
|
3056
|
+
const wasExtended = result.length > chain.length;
|
|
3057
|
+
return {
|
|
3058
|
+
chain: result,
|
|
3059
|
+
status: wasExtended ? "ChainCompleted" /* ChainCompleted */ : "AlreadyComplete" /* AlreadyComplete */,
|
|
3060
|
+
message: wasExtended ? `Chain completed: ${result.length - chain.length} issuer(s) appended, ending at self-signed root "${lastInfo.tbsCertificate.subject.commonName}".` : `Chain is already complete (self-signed root "${lastInfo.tbsCertificate.subject.commonName}").`
|
|
3061
|
+
};
|
|
3062
|
+
}
|
|
3063
|
+
const issuerCert = await this.findIssuerCertificate(lastCert);
|
|
3064
|
+
if (!issuerCert) {
|
|
3065
|
+
const cn = lastInfo.tbsCertificate.subject.commonName ?? "?";
|
|
3066
|
+
const akid = lastInfo.tbsCertificate.extensions?.authorityKeyIdentifier?.keyIdentifier ?? "?";
|
|
3067
|
+
const msg = `Cannot find issuer for "${cn}" (authorityKeyIdentifier: ${akid}). Ensure the CA certificate is present in the issuers/certs folder.`;
|
|
3068
|
+
warningLog(`completeCertificateChain: ${msg}`);
|
|
3069
|
+
return {
|
|
3070
|
+
chain: result,
|
|
3071
|
+
status: "IssuerNotFound" /* IssuerNotFound */,
|
|
3072
|
+
message: msg
|
|
3073
|
+
};
|
|
3074
|
+
}
|
|
3075
|
+
const issuerFingerprint = makeFingerprint(issuerCert);
|
|
3076
|
+
const alreadyInChain = result.some((c) => makeFingerprint(c) === issuerFingerprint);
|
|
3077
|
+
if (alreadyInChain) {
|
|
3078
|
+
return {
|
|
3079
|
+
chain: result,
|
|
3080
|
+
status: "AlreadyComplete" /* AlreadyComplete */,
|
|
3081
|
+
message: `Chain ends at root "${exploreCertificate2(issuerCert).tbsCertificate.subject.commonName}" (already present in chain).`
|
|
3082
|
+
};
|
|
3083
|
+
}
|
|
3084
|
+
result.push(issuerCert);
|
|
3085
|
+
depth++;
|
|
3086
|
+
}
|
|
3087
|
+
return {
|
|
3088
|
+
chain: result,
|
|
3089
|
+
status: "MaxDepthReached" /* MaxDepthReached */,
|
|
3090
|
+
message: `Chain completion stopped after ${maxDepth} iterations \u2014 possible circular chain or very deep hierarchy.`
|
|
3091
|
+
};
|
|
3092
|
+
}
|
|
3014
3093
|
/**
|
|
3015
3094
|
*
|
|
3016
3095
|
* check if the certificate explicitly appear in the trust list, the reject list or none.
|
|
@@ -3206,11 +3285,15 @@ var CertificateManager = class _CertificateManager extends EventEmitter {
|
|
|
3206
3285
|
this.#scanCrlFolder(this.crlFolder, this.#thumbs.crl),
|
|
3207
3286
|
this.#scanCrlFolder(this.issuersCrlFolder, this.#thumbs.issuersCrl)
|
|
3208
3287
|
]);
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3288
|
+
if (this.#disableFileWatchers) {
|
|
3289
|
+
fs10.watch = origWatch;
|
|
3290
|
+
} else {
|
|
3291
|
+
this.#startWatcher(this.trustedFolder, this.#thumbs.trusted, createUnreffedWatcher, "trusted");
|
|
3292
|
+
this.#startWatcher(this.issuersCertFolder, this.#thumbs.issuers.certs, createUnreffedWatcher, "issuersCerts");
|
|
3293
|
+
this.#startWatcher(this.rejectedFolder, this.#thumbs.rejected, createUnreffedWatcher, "rejected");
|
|
3294
|
+
this.#startCrlWatcher(this.crlFolder, this.#thumbs.crl, createUnreffedWatcher, "crl");
|
|
3295
|
+
this.#startCrlWatcher(this.issuersCrlFolder, this.#thumbs.issuersCrl, createUnreffedWatcher, "issuersCrl");
|
|
3296
|
+
}
|
|
3214
3297
|
}
|
|
3215
3298
|
/**
|
|
3216
3299
|
* Scan a certificate folder and populate the in-memory index.
|
|
@@ -3391,6 +3474,7 @@ export {
|
|
|
3391
3474
|
CertificateAuthority,
|
|
3392
3475
|
CertificateManager,
|
|
3393
3476
|
CertificateManagerState,
|
|
3477
|
+
ChainCompletionStatus,
|
|
3394
3478
|
Subject,
|
|
3395
3479
|
VerificationStatus,
|
|
3396
3480
|
adjustApplicationUri,
|