ReadonlykeyRSA key size used when generating the private key.
Shared ownership counter.
Multiple clients/servers may share the same store.
dispose() only releases resources when the counter
reaches zero — preventing premature cleanup.
Current lifecycle state of this instance.
When true (the default), any certificate that is not
already in the trusted or rejected store is automatically
written to the rejected folder the first time it is seen.
StaticbookkeepingHow long checkCertificate waits, in milliseconds, for the store
to record its verdict (the move of the certificate into rejected/ or
trusted/) before answering with that verdict anyway.
The verdict is known before the move starts: the move is bookkeeping. It takes the store's file lock, and a lock that is contended or stuck must not hold the OpenSecureChannel of the client being answered (the CTT gives up after 20 s and reports BadTimeout instead of the status the server had already decided on). On timeout the move carries on in the background and a warning is logged.
Static ReadonlyChainOutcome status for CertificateManager.completeCertificateChain.
StaticdefaultStaticregistryPath to the OpenSSL configuration file.
Path to the trusted CRL folder.
Interval in milliseconds for file-system polling (when enabled).
Path to the issuer (CA) certificates folder.
Path to the issuer CRL folder.
Path to the own certificate folder.
Path to the private key file (own/private/private_key.pem).
Kept for backward compatibility with code that reads the key
directly from disk. When a passphrase or a privateKeyProvider is
configured, prefer getPrivateKey instead — this getter still
returns the on-disk path even if a provider is configured (there may
be no meaningful file in that case).
Path to the OpenSSL random seed file.
Path to the rejected certificates folder.
Root directory of the PKI store.
Path to the trusted certificates folder.
Optional[captureThe Symbol.for('nodejs.rejection') method is called in case a
promise rejection happens when emitting an event and
captureRejections is enabled on the emitter.
It is possible to use events.captureRejectionSymbol in
place of Symbol.for('nodejs.rejection').
import { EventEmitter, captureRejectionSymbol } from 'node:events';
class MyClass extends EventEmitter {
constructor() {
super({ captureRejections: true });
}
[captureRejectionSymbol](err, event, ...args) {
console.log('rejection happened for', event, 'with', err, ...args);
this.destroy(err);
}
destroy(err) {
// Tear the resource down here.
}
}
Add a CA (issuer) certificate to the issuers store. If the certificate is already present, this is a no-op.
the DER-encoded CA certificate
Optionalvalidate: boolean
if true, verify the certificate before adding
OptionaladdInTrustList: boolean
if true, also add to the trusted store
VerificationStatus.Good on success
Add multiple CA (issuer) certificates to the issuers store.
the DER-encoded CA certificates
Optionalvalidate: boolean
if true, verify each certificate before adding
OptionaladdInTrustList: boolean
if true, also add each certificate to the trusted store
VerificationStatus.Good on success
Add a CRL to the certificate manager.
the CRL to add
Optionaltarget: "issuers" | "trusted"
"issuers" (default) writes to issuers/crl, "trusted" writes to trusted/crl
Validate a certificate (optionally with its chain) and add the leaf certificate to the trusted store.
Performs OPC UA Part 4, Table 100 validation:
Only the leaf certificate is added to the trusted store.
DER-encoded certificate or chain
VerificationStatus.Good on success, or an error
status indicating why the certificate was rejected.
Check a peer certificate against the trust store.
Returns StatusCodes.Good if trusted,
StatusCodes.BadCertificateUntrusted if unknown/rejected,
or another StatusCode for validation failures.
Remove all CRL files from the specified folder(s) and clear the corresponding in-memory index.
"issuers" clears issuers/crl, "trusted" clears trusted/crl, "all" clears both.
Complete a certificate chain by walking the issuer store.
Starting from the last certificate in the provided chain, this method repeatedly calls findIssuerCertificate to locate the parent certificate until it reaches a self-signed root or can no longer find an issuer.
the (potentially partial) certificate chain, leaf first
OptionalmaxDepth: number
maximum number of issuers to append (default: 10)
a ChainCompletionResult containing the (possibly completed) chain, a status code, and an optional diagnostic message.
Create a Certificate Signing Request (CSR) using this PKI's private key and configuration.
The CSR file is written to own/certs/ with a timestamped
filename.
CSR parameters (subject, SANs)
the filesystem path to the generated CSR file
Create a self-signed certificate for this PKI's private key.
The certificate is written to params.outputFile or
own/certs/self_signed_certificate.pem by default.
certificate parameters (subject, SANs, validity, etc.)
Dispose of the CertificateManager, releasing file watchers and other resources. The instance should not be used after calling this method.
Synchronously calls each of the listeners registered for the event named
eventName, in the order they were registered, passing the supplied arguments
to each.
Returns true if the event had listeners, false otherwise.
import { EventEmitter } from 'node:events';
const myEmitter = new EventEmitter();
// First listener
myEmitter.on('event', function firstListener() {
console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third listener
myEmitter.on('event', function thirdListener(...args) {
const parameters = args.join(', ');
console.log(`event with parameters ${parameters} in third listener`);
});
console.log(myEmitter.listeners('event'));
myEmitter.emit('event', 1, 2, 3, 4, 5);
// Prints:
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Helloooo! first listener
// event with parameters 1, 2 in second listener
// event with parameters 1, 2, 3, 4, 5 in third listener
Returns an array listing the events for which the emitter has registered listeners.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Prints: [ 'foo', 'bar', Symbol(symbol) ]
find the issuer certificate among the trusted issuer certificates.
The findIssuerCertificate method is an asynchronous method that attempts to find the issuer certificate for a given certificate from the list of issuer certificate declared in the PKI
If the certificate is self-signed, it returns the certificate itself.
If the certificate has no extension 3, it is assumed to be generated by an old system, and a null value is returned.
the method checks both issuer and trusted certificates and returns the appropriate issuercertificate, if found. If multiple matching certificates are found, a warning is logged to the console.
The key as an opaque IKeyOperations — the recommended way to use the private key regardless of where it lives.
Returns the configured keyOperations object when the key is opaque.
Otherwise returns a stable lazy wrap over getPrivateKey: its
methods resolve the key on first use (disk read, passphrase,
privateKeyProvider — all async), so the wrap offers no synchronous
fast path; callers that need one resolve the key themselves and build
a LocalKeyOperations over it. The wrap follows key rotation: a
privateKeyProvider that starts returning a different key gets a
fresh underlying LocalKeyOperations.
Resolve the private key: from privateKeyProvider if configured,
otherwise from disk (decrypting with privateKeyPassphrase if the
key is encrypted). Fails closed — throws
PrivateKeyPassphraseRequiredError — if the on-disk key is encrypted
and no passphrase is configured, or if the wrong passphrase is
configured.
The on-disk key is read and decrypted once and then cached for the
lifetime of this instance, so a privateKeyPassphrase function is
called at most once (concurrent first calls share the same read). A
failed read is not cached, so a caller can fix the passphrase and
retry. A privateKeyProvider is consulted on every call: it is the
authority on what the current key is.
Resolve this manager's configured privateKeyPassphrase (calling it,
if it is a function, at most once — see
resolvePrivateKeyPassphrase). Returns undefined when no
passphrase is configured (plaintext key).
Intended for callers that need to write a new private key to disk with the same protection as this manager (push certificate management), rather than for reading the current key — prefer CertificateManager.getPrivateKey for that.
Return the number of certificates currently in the trusted store.
Check whether a certificate is currently trusted.
Check whether an issuer certificate with the given thumbprint is already registered.
hex-encoded SHA-1 thumbprint (lowercase)
Initialize the PKI directory structure, generate the private key (if missing), and start file-system watchers.
This method is idempotent — subsequent calls are no-ops. It must be called before any certificate operations.
Check whether a certificate has been revoked by its issuer's CRL.
issuerCertificate is provided, the method attempts
to find it via findIssuerCertificate.the DER-encoded certificate to check
OptionalissuerCertificate: DER | null
optional issuer certificate; looked up automatically when omitted
Good if not revoked, BadCertificateRevoked if the
serial number appears in a CRL,
BadCertificateRevocationUnknown if no CRL is available,
or BadCertificateChainIncomplete if the issuer cannot be
found.
Check if a certificate is in the trusted store.
If the certificate is unknown and untrustUnknownCertificate is set,
it will be written to the rejected folder.
"Good" if trusted, "BadCertificateUntrusted" if rejected/unknown,
or "BadCertificateInvalid" if the certificate cannot be parsed.
Check whether an issuer certificate is still needed by any certificate in the trusted store.
This is used before removing an issuer to ensure that doing so would not break the chain of any trusted certificate.
the CA certificate to check
true if at least one trusted certificate was
signed by this issuer.
true when this manager was constructed with privateKeyPassphrase
and/or privateKeyProvider — i.e. getPrivateKey() may need to do
asynchronous work (decrypt, or fetch from an external source) rather
than a plain synchronous disk read.
Consumers (e.g. OPCUAServer/OPCUAClient's private-key resolution)
use this to decide whether installing an async-resolved, permanently
cached provider is necessary at all: for a manager with neither option
set, the on-disk key is always plaintext, so a plain
DiskCertificateKeyPairProvider keeps working exactly as before —
including re-reading a manually replaced key after invalidate(),
which a resolved provider deliberately does not do (see
ResolvedCertificateKeyPairProvider in node-opcua-common).
True when this manager's key is opaque — configured through
keyOperations, held by an HSM/KMS, never obtainable as material.
When true, getPrivateKey throws PrivateKeyUnavailableError
and getKeyOperations is the only way to use the key.
Check whether the trusted certificate store is empty.
This inspects the in-memory index, which is kept in
sync with the trusted/certs/ folder by file-system
watchers after initialize has been called.
Returns the number of listeners listening for the event named eventName.
If listener is provided, it will return how many times the listener is found
in the list of the listeners of the event.
The name of the event being listened for
Optionallistener: (...args: any[]) => void
The event handler function
Returns a copy of the array of listeners for the event named eventName.
server.on('connection', (stream) => {
console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
// Prints: [ [Function] ]
Adds the listener function to the end of the listeners array for the
event named eventName. No checks are made to see if the listener has
already been added. Multiple calls passing the same combination of eventName
and listener will result in the listener being added, and called, multiple
times.
server.on('connection', (stream) => {
console.log('someone connected!');
});
Returns a reference to the EventEmitter, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The
emitter.prependListener() method can be used as an alternative to add the
event listener to the beginning of the listeners array.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
The name of the event.
The callback function
Adds a one-time listener function for the event named eventName. The
next time eventName is triggered, this listener is removed and then invoked.
server.once('connection', (stream) => {
console.log('Ah, we have our first user!');
});
Returns a reference to the EventEmitter, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The
emitter.prependOnceListener() method can be used as an alternative to add the
event listener to the beginning of the listeners array.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
The name of the event.
The callback function
Adds the listener function to the beginning of the listeners array for the
event named eventName. No checks are made to see if the listener has
already been added. Multiple calls passing the same combination of eventName
and listener will result in the listener being added, and called, multiple
times.
server.prependListener('connection', (stream) => {
console.log('someone connected!');
});
Returns a reference to the EventEmitter, so that calls can be chained.
The name of the event.
The callback function
Adds a one-time listener function for the event named eventName to the
beginning of the listeners array. The next time eventName is triggered, this
listener is removed, and then invoked.
server.prependOnceListener('connection', (stream) => {
console.log('Ah, we have our first user!');
});
Returns a reference to the EventEmitter, so that calls can be chained.
The name of the event.
The callback function
Returns a copy of the array of listeners for the event named eventName,
including any wrappers (such as those created by .once()).
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();
// Logs "log once" to the console and removes the listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');
// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');
Enable, disable, or rotate the passphrase protecting the on-disk
private key: decrypt with oldPassphrase (omit if the key is
currently unencrypted), then write back encrypted with
newPassphrase (omit to leave it unencrypted). The write goes to a
temporary file in the same directory and is atomically renamed into
place, so a crash mid-rotation cannot leave a partially-written key;
the temporary file is removed if anything fails, so a rotation to
plaintext can never leave a stray cleartext copy behind. Runs under
the same lock as initialize().
This only rewrites the on-disk file — it does not update this
instance's own privateKeyPassphrase (set at construction), and it
drops this instance's cached key so that disk stays the source of
truth. Construct a new CertificateManager with the new passphrase to
continue using it afterward.
Not supported when a privateKeyProvider is configured (there is no
disk file for this method to rewrite).
OptionaloldPassphrase: PrivateKeyPassphraseOptionalnewPassphrase: PrivateKeyPassphraseMove a certificate to the rejected store. If the certificate was previously trusted, it will be removed from the trusted folder.
the DER-encoded certificate or certificate chain
Force a full re-scan of all PKI folders, rebuilding
the in-memory _thumbs index from scratch.
Call this after external processes have modified the
PKI folders (e.g. via writeTrustList or CLI tools)
to ensure the CertificateManager sees the latest
state without waiting for file-system events.
Removes all listeners, or those of the specified eventName.
It is bad practice to remove listeners added elsewhere in the code,
particularly when the EventEmitter instance was created by some other
component or module (e.g. sockets or file streams).
Returns a reference to the EventEmitter, so that calls can be chained.
OptionaleventName: string | symbolRemove an issuer certificate identified by its SHA-1 thumbprint. Deletes the file on disk and removes the entry from the in-memory index.
hex-encoded SHA-1 thumbprint (lowercase)
the removed certificate buffer, or null if not found
Removes the specified listener from the listener array for the event named
eventName.
const callback = (stream) => {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
removeListener() will remove, at most, one instance of a listener from the
listener array. If any single listener has been added multiple times to the
listener array for the specified eventName, then removeListener() must be
called multiple times to remove each instance.
Once an event is emitted, all listeners attached to it at the
time of emitting are called in order. This implies that any
removeListener() or removeAllListeners() calls after emitting and
before the last listener finishes execution will not remove them from
emit() in progress. Subsequent events behave as expected.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
const callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA removes listener callbackB but it will still be called.
// Internal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
// A
// B
// callbackB is now removed.
// Internal listener array [callbackA]
myEmitter.emit('event');
// Prints:
// A
Because listeners are managed using an internal array, calling this will
change the position indexes of any listener registered after the listener
being removed. This will not impact the order in which listeners are called,
but it means that any copies of the listener array as returned by
the emitter.listeners() method will need to be recreated.
When a single function has been added as a handler multiple times for a single
event (as in the example below), removeListener() will remove the most
recently added instance. In the example the once('ping')
listener is removed:
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
function pong() {
console.log('pong');
}
ee.on('ping', pong);
ee.once('ping', pong);
ee.removeListener('ping', pong);
ee.emit('ping');
ee.emit('ping');
Returns a reference to the EventEmitter, so that calls can be chained.
Remove all CRL files that were issued by the given CA certificate from the specified folder (or both).
the CA certificate whose CRLs to remove
Optionaltarget: "all" | "issuers" | "trusted"
"issuers", "trusted", or "all" (default "all")
Remove a trusted certificate identified by its SHA-1 thumbprint. Deletes the file on disk and removes the entry from the in-memory index.
hex-encoded SHA-1 thumbprint (lowercase)
the removed certificate buffer, or null if not found
By default EventEmitters will print a warning if more than 10 listeners are
added for a particular event. This is a useful default that helps finding
memory leaks. The emitter.setMaxListeners() method allows the limit to be
modified for this specific EventEmitter instance. The value can be set to
Infinity (or 0) to indicate an unlimited number of listeners.
Returns a reference to the EventEmitter, so that calls can be chained.
Move a certificate to the trusted store. If the certificate was previously rejected, it will be removed from the rejected folder.
the DER-encoded certificate or certificate chain
Verify a certificate against the PKI trust store.
This performs a full validation including trust status, issuer chain, CRL revocation checks, and time validity.
the DER-encoded certificate to verify
Optionaloptions: VerifyCertificateOptions
optional flags to relax validation rules
the verification status code
ProtectedverifyInternal verification hook called by verifyCertificate.
Subclasses can override this to inject additional validation logic (e.g. application-level policy checks) while still delegating to the default chain/CRL/trust verification.
the DER-encoded certificate to verify
verification options forwarded from the public API
the verification status code
ProtectedwithStaticcheckAssert that all CertificateManager instances have been properly disposed. Throws an Error listing the locations of any leaked instances.
Intended for use in test afterAll() / afterEach()
hooks to catch missing dispose() calls early.
StaticdisposeDispose all active CertificateManager instances, closing their file watchers and freeing resources.
This is mainly useful in test tear-down to ensure the Node.js process can exit cleanly.
Deprecated
Use folderPollingInterval instead (typo fix).