node-opcua-server-configuration 2.166.0 → 2.168.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.
Files changed (32) hide show
  1. package/dist/clientTools/push_certificate_management_client.d.ts +2 -2
  2. package/dist/clientTools/push_certificate_management_client.js +9 -2
  3. package/dist/clientTools/push_certificate_management_client.js.map +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/server/{install_push_certitifate_management.d.ts → install_push_certificate_management.d.ts} +4 -7
  7. package/dist/server/install_push_certificate_management.js +122 -0
  8. package/dist/server/install_push_certificate_management.js.map +1 -0
  9. package/dist/server/promote_trust_list.js +32 -4
  10. package/dist/server/promote_trust_list.js.map +1 -1
  11. package/dist/server/push_certificate_manager/create_signing_request.js +3 -3
  12. package/dist/server/push_certificate_manager/create_signing_request.js.map +1 -1
  13. package/dist/server/push_certificate_manager/update_certificate.js +12 -3
  14. package/dist/server/push_certificate_manager/update_certificate.js.map +1 -1
  15. package/dist/server/push_certificate_manager_helpers.js +3 -3
  16. package/dist/server/push_certificate_manager_helpers.js.map +1 -1
  17. package/dist/server/push_certificate_manager_server_impl.js.map +1 -1
  18. package/dist/server/trust_list_server.js +9 -3
  19. package/dist/server/trust_list_server.js.map +1 -1
  20. package/package.json +25 -27
  21. package/source/clientTools/push_certificate_management_client.ts +11 -3
  22. package/source/index.ts +1 -1
  23. package/source/server/install_push_certificate_management.ts +160 -0
  24. package/source/server/promote_trust_list.ts +41 -9
  25. package/source/server/push_certificate_manager/create_signing_request.ts +3 -3
  26. package/source/server/push_certificate_manager/update_certificate.ts +16 -5
  27. package/source/server/push_certificate_manager_helpers.ts +3 -3
  28. package/source/server/push_certificate_manager_server_impl.ts +3 -9
  29. package/source/server/trust_list_server.ts +9 -3
  30. package/dist/server/install_push_certitifate_management.js +0 -178
  31. package/dist/server/install_push_certitifate_management.js.map +0 -1
  32. package/source/server/install_push_certitifate_management.ts +0 -250
@@ -2,13 +2,18 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { BinaryStream } from "node-opcua-binary-stream";
4
4
  import type { OPCUACertificateManager } from "node-opcua-certificate-manager";
5
- import { readCertificate, readCertificateRevocationList } from "node-opcua-crypto";
5
+ import { readCertificateChainAsync, readCertificateRevocationList } from "node-opcua-crypto";
6
6
  import { make_errorLog } from "node-opcua-debug";
7
7
  import type { AbstractFs } from "node-opcua-file-transfer";
8
8
  import { TrustListDataType } from "node-opcua-types";
9
9
 
10
10
  const errorLog = make_errorLog("TrustListServer");
11
11
 
12
+ /**
13
+ * Read all certificate (chains) and CRLs in a folder
14
+ * @param folder
15
+ * @returns
16
+ */
12
17
  async function readAll(folder: string): Promise<Buffer[]> {
13
18
  const results: Buffer[] = [];
14
19
  const files = await fs.promises.readdir(folder);
@@ -16,8 +21,9 @@ async function readAll(folder: string): Promise<Buffer[]> {
16
21
  const file = path.join(folder, f);
17
22
  const ext = path.extname(file);
18
23
  if (ext === ".der" || ext === ".pem") {
19
- const buf = await readCertificate(file);
20
- results.push(buf);
24
+ const chain = await readCertificateChainAsync(file);
25
+ const concatenated = Buffer.concat(chain);
26
+ results.push(concatenated);
21
27
  } else if (ext === ".crl") {
22
28
  // Strict validation: only accept valid CRL files
23
29
  const buf = await readCertificateRevocationList(file);
@@ -1,178 +0,0 @@
1
- /**
2
- * @module node-opcua-server-configuration-server
3
- */
4
- import fs from "node:fs";
5
- import path from "node:path";
6
- import chalk from "chalk";
7
- import { assert } from "node-opcua-assert";
8
- import { readPrivateKey } from "node-opcua-crypto";
9
- import { convertPEMtoDER, split_der } from "node-opcua-crypto/web";
10
- import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
11
- import { getFullyQualifiedDomainName, getIpAddresses } from "node-opcua-hostname";
12
- import { installPushCertificateManagement } from "./push_certificate_manager_helpers.js";
13
- // node 14 onward : import { readFile } from "fs/promises";
14
- const { readFile } = fs.promises;
15
- const debugLog = make_debugLog("ServerConfiguration");
16
- const errorLog = make_errorLog("ServerConfiguration");
17
- const doDebug = checkDebugFlag("ServerConfiguration");
18
- function getCertificate() {
19
- if (!this.$$certificate) {
20
- const certificateChain = getCertificateChain.call(this);
21
- this.$$certificate = split_der(certificateChain)[0];
22
- }
23
- return this.$$certificate;
24
- }
25
- function getCertificateChain() {
26
- if (!this.$$certificateChain) {
27
- throw new Error("internal Error. cannot find $$certificateChain");
28
- }
29
- return this.$$certificateChain;
30
- }
31
- function getPrivateKey() {
32
- // c8 ignore next
33
- if (!this.$$privateKey) {
34
- throw new Error("internal Error. cannot find $$privateKey");
35
- }
36
- return this.$$privateKey;
37
- }
38
- /**
39
- *
40
- */
41
- async function install() {
42
- doDebug && debugLog("install push certificate management", this.serverCertificateManager.rootDir);
43
- Object.defineProperty(this, "privateKeyFile", {
44
- get: () => this.serverCertificateManager.privateKey,
45
- configurable: true
46
- });
47
- Object.defineProperty(this, "certificateFile", {
48
- get: () => path.join(this.serverCertificateManager.rootDir, "own/certs/certificate.pem"),
49
- configurable: true
50
- });
51
- if (!this.$$privateKey) {
52
- this.$$privateKey = readPrivateKey(this.serverCertificateManager.privateKey);
53
- }
54
- if (!this.$$certificateChain) {
55
- const certificateFile = this.certificateFile;
56
- if (!fs.existsSync(certificateFile)) {
57
- // this is the first time server is launch
58
- // let's create a default self signed certificate with limited validity
59
- const fqdn = await getFullyQualifiedDomainName();
60
- const ipAddresses = await getIpAddresses();
61
- const applicationUri = (this.serverInfo ? this.serverInfo.applicationUri : null) || "uri:MISSING";
62
- const options = {
63
- applicationUri,
64
- dns: [fqdn],
65
- ip: ipAddresses,
66
- subject: `/CN=${applicationUri};/L=Paris`,
67
- startDate: new Date(),
68
- validity: 365 * 5, // five year
69
- /* */
70
- outputFile: certificateFile
71
- };
72
- doDebug && debugLog("creating self signed certificate", options);
73
- await this.serverCertificateManager.createSelfSignedCertificate(options);
74
- }
75
- const certificatePEM = await readFile(certificateFile, "utf8");
76
- this.$$certificateChain = convertPEMtoDER(certificatePEM);
77
- // await this.serverCertificateManager.trustCertificate( this.$$certificateChain);
78
- }
79
- }
80
- function getCertificateChainEP() {
81
- const certificateFile = path.join(this.certificateManager.rootDir, "own/certs/certificate.pem");
82
- const certificatePEM = fs.readFileSync(certificateFile, "utf8");
83
- const $$certificateChain = convertPEMtoDER(certificatePEM);
84
- return $$certificateChain;
85
- }
86
- function getPrivateKeyEP() {
87
- const privateKey = readPrivateKey(this.certificateManager.privateKey);
88
- return privateKey;
89
- }
90
- async function onCertificateAboutToChange(server) {
91
- doDebug && debugLog(chalk.yellow(" onCertificateAboutToChange => Suspending End points"));
92
- await server.suspendEndPoints();
93
- doDebug && debugLog(chalk.yellow(" onCertificateAboutToChange => End points suspended"));
94
- }
95
- /**
96
- * onCertificateChange is called when the serverConfiguration notifies
97
- * that the server certificate and/or private key has changed.
98
- *
99
- * this function suspends all endpoint listeners and stop all existing channels
100
- * then start all endpoint listener
101
- *
102
- * @param server
103
- */
104
- async function onCertificateChange(server) {
105
- doDebug && debugLog("on CertificateChanged");
106
- const _server = server;
107
- _server.$$privateKey = readPrivateKey(server.serverCertificateManager.privateKey);
108
- const certificateFile = path.join(server.serverCertificateManager.rootDir, "own/certs/certificate.pem");
109
- const certificatePEM = fs.readFileSync(certificateFile, "utf8");
110
- const privateKeyFile = server.serverCertificateManager.privateKey;
111
- const privateKey = readPrivateKey(privateKeyFile);
112
- // also reread the private key
113
- _server.$$certificateChain = convertPEMtoDER(certificatePEM);
114
- _server.$$privateKey = privateKey;
115
- // note : $$certificate will be reconstructed on demand
116
- _server.$$certificate = split_der(_server.$$certificateChain)[0];
117
- setTimeout(async () => {
118
- try {
119
- doDebug && debugLog(chalk.yellow(" onCertificateChange => shutting down channels"));
120
- await server.shutdownChannels();
121
- doDebug && debugLog(chalk.yellow(" onCertificateChange => channels shut down"));
122
- doDebug && debugLog(chalk.yellow(" onCertificateChange => resuming end points"));
123
- await server.resumeEndPoints();
124
- doDebug && debugLog(chalk.yellow(" onCertificateChange => end points resumed"));
125
- debugLog(chalk.yellow("channels have been closed -> client should reconnect "));
126
- }
127
- catch (err) {
128
- errorLog("Error in CertificateChanged handler ", err.message);
129
- debugLog("err = ", err);
130
- }
131
- }, 2000);
132
- }
133
- export async function installPushCertificateManagementOnServer(server) {
134
- if (!server.engine || !server.engine.addressSpace) {
135
- throw new Error("Server must have a valid address space." +
136
- "you need to call installPushCertificateManagementOnServer after server has been initialized");
137
- }
138
- await install.call(server);
139
- server.getCertificate = getCertificate;
140
- server.getCertificateChain = getCertificateChain;
141
- server.getPrivateKey = getPrivateKey;
142
- for (const endpoint of server.endpoints) {
143
- const endpointPriv = endpoint;
144
- endpointPriv._certificateChain = null;
145
- endpointPriv._privateKey = null;
146
- endpoint.getCertificateChain = getCertificateChainEP;
147
- endpoint.getPrivateKey = getPrivateKeyEP;
148
- for (const e of endpoint.endpointDescriptions()) {
149
- Object.defineProperty(e, "serverCertificate", {
150
- get: () => endpoint.getCertificate(),
151
- configurable: true
152
- });
153
- }
154
- }
155
- await installPushCertificateManagement(server.engine.addressSpace, {
156
- applicationGroup: server.serverCertificateManager,
157
- userTokenGroup: server.userCertificateManager,
158
- applicationUri: server.serverInfo.applicationUri || "InvalidURI"
159
- });
160
- const serverConfiguration = server.engine.addressSpace.rootFolder.objects.server.getChildByName("ServerConfiguration");
161
- const serverConfigurationPriv = serverConfiguration;
162
- assert(serverConfigurationPriv.$pushCertificateManager);
163
- serverConfigurationPriv.$pushCertificateManager.on("CertificateAboutToChange", (actionQueue) => {
164
- actionQueue.push(async () => {
165
- doDebug && debugLog("CertificateAboutToChange Event received");
166
- await onCertificateAboutToChange(server);
167
- doDebug && debugLog("CertificateAboutToChange Event processed");
168
- });
169
- });
170
- serverConfigurationPriv.$pushCertificateManager.on("CertificateChanged", (actionQueue) => {
171
- actionQueue.push(async () => {
172
- doDebug && debugLog("CertificateChanged Event received");
173
- await onCertificateChange(server);
174
- doDebug && debugLog("CertificateChanged Event processed");
175
- });
176
- });
177
- }
178
- //# sourceMappingURL=install_push_certitifate_management.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"install_push_certitifate_management.js","sourceRoot":"","sources":["../../source/server/install_push_certitifate_management.ts"],"names":[],"mappings":"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"}
@@ -1,250 +0,0 @@
1
- /**
2
- * @module node-opcua-server-configuration-server
3
- */
4
- import fs from "node:fs";
5
- import path from "node:path";
6
-
7
- import chalk from "chalk";
8
-
9
- import type { AddressSpace, UAServerConfiguration } from "node-opcua-address-space";
10
- import { assert } from "node-opcua-assert";
11
- import type { OPCUACertificateManager } from "node-opcua-certificate-manager";
12
- import type { ICertificateKeyPairProviderPriv } from "node-opcua-common";
13
- import { readPrivateKey } from "node-opcua-crypto";
14
- import { type Certificate, convertPEMtoDER, type PrivateKey, split_der } from "node-opcua-crypto/web";
15
- import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
16
- import { getFullyQualifiedDomainName, getIpAddresses } from "node-opcua-hostname";
17
- import type { OPCUAServer, OPCUAServerEndPoint } from "node-opcua-server";
18
- import type { ApplicationDescriptionOptions } from "node-opcua-types";
19
-
20
- import { installPushCertificateManagement } from "./push_certificate_manager_helpers.js";
21
- import type { ActionQueue, PushCertificateManagerServerImpl } from "./push_certificate_manager_server_impl.js";
22
-
23
- // node 14 onward : import { readFile } from "fs/promises";
24
- const { readFile } = fs.promises;
25
-
26
- const debugLog = make_debugLog("ServerConfiguration");
27
- const errorLog = make_errorLog("ServerConfiguration");
28
- const doDebug = checkDebugFlag("ServerConfiguration");
29
-
30
- export interface OPCUAServerPartial extends ICertificateKeyPairProviderPriv {
31
- serverInfo?: ApplicationDescriptionOptions;
32
- serverCertificateManager: OPCUACertificateManager;
33
- privateKeyFile: string;
34
- certificateFile: string;
35
- $$certificate: null | Certificate;
36
- $$certificateChain: null | Certificate;
37
- $$privateKey: null | PrivateKey;
38
- engine: { addressSpace?: AddressSpace };
39
- }
40
-
41
- function getCertificate(this: OPCUAServerPartial): Certificate {
42
- if (!this.$$certificate) {
43
- const certificateChain = getCertificateChain.call(this);
44
- this.$$certificate = split_der(certificateChain)[0];
45
- }
46
- return this.$$certificate;
47
- }
48
-
49
- function getCertificateChain(this: OPCUAServerPartial): Certificate {
50
- if (!this.$$certificateChain) {
51
- throw new Error("internal Error. cannot find $$certificateChain");
52
- }
53
- return this.$$certificateChain;
54
- }
55
-
56
- function getPrivateKey(this: OPCUAServerPartial): PrivateKey {
57
- // c8 ignore next
58
- if (!this.$$privateKey) {
59
- throw new Error("internal Error. cannot find $$privateKey");
60
- }
61
- return this.$$privateKey;
62
- }
63
-
64
-
65
-
66
- /**
67
- *
68
- */
69
- async function install(this: OPCUAServerPartial): Promise<void> {
70
- doDebug && debugLog("install push certificate management", this.serverCertificateManager.rootDir);
71
-
72
- Object.defineProperty(this, "privateKeyFile", {
73
- get: () => this.serverCertificateManager.privateKey,
74
- configurable: true
75
- });
76
- Object.defineProperty(this, "certificateFile", {
77
- get: () => path.join(this.serverCertificateManager.rootDir, "own/certs/certificate.pem"),
78
- configurable: true
79
- });
80
-
81
- if (!this.$$privateKey) {
82
- this.$$privateKey = readPrivateKey(this.serverCertificateManager.privateKey);
83
- }
84
-
85
- if (!this.$$certificateChain) {
86
- const certificateFile = this.certificateFile;
87
-
88
- if (!fs.existsSync(certificateFile)) {
89
- // this is the first time server is launch
90
- // let's create a default self signed certificate with limited validity
91
-
92
- const fqdn = await getFullyQualifiedDomainName();
93
- const ipAddresses = await getIpAddresses();
94
-
95
- const applicationUri = (this.serverInfo ? this.serverInfo.applicationUri : null) || "uri:MISSING";
96
-
97
- const options = {
98
- applicationUri,
99
-
100
- dns: [fqdn],
101
- ip: ipAddresses,
102
-
103
- subject: `/CN=${applicationUri};/L=Paris`,
104
-
105
- startDate: new Date(),
106
-
107
- validity: 365 * 5, // five year
108
-
109
- /* */
110
- outputFile: certificateFile
111
- };
112
-
113
- doDebug && debugLog("creating self signed certificate", options);
114
- await this.serverCertificateManager.createSelfSignedCertificate(options);
115
- }
116
- const certificatePEM = await readFile(certificateFile, "utf8");
117
-
118
- this.$$certificateChain = convertPEMtoDER(certificatePEM);
119
-
120
- // await this.serverCertificateManager.trustCertificate( this.$$certificateChain);
121
- }
122
- }
123
-
124
- function getCertificateChainEP(this: OPCUAServerEndPoint): Certificate {
125
- const certificateFile = path.join(this.certificateManager.rootDir, "own/certs/certificate.pem");
126
- const certificatePEM = fs.readFileSync(certificateFile, "utf8");
127
- const $$certificateChain = convertPEMtoDER(certificatePEM);
128
- return $$certificateChain;
129
- }
130
-
131
- function getPrivateKeyEP(this: OPCUAServerEndPoint): PrivateKey {
132
- const privateKey = readPrivateKey(this.certificateManager.privateKey);
133
- return privateKey;
134
- }
135
-
136
- async function onCertificateAboutToChange(server: OPCUAServer) {
137
- doDebug && debugLog(chalk.yellow(" onCertificateAboutToChange => Suspending End points"));
138
- await server.suspendEndPoints();
139
- doDebug && debugLog(chalk.yellow(" onCertificateAboutToChange => End points suspended"));
140
- }
141
-
142
- /**
143
- * onCertificateChange is called when the serverConfiguration notifies
144
- * that the server certificate and/or private key has changed.
145
- *
146
- * this function suspends all endpoint listeners and stop all existing channels
147
- * then start all endpoint listener
148
- *
149
- * @param server
150
- */
151
- async function onCertificateChange(server: OPCUAServer) {
152
- doDebug && debugLog("on CertificateChanged");
153
-
154
- const _server = server as unknown as OPCUAServerPartial;
155
-
156
- _server.$$privateKey = readPrivateKey(server.serverCertificateManager.privateKey);
157
- const certificateFile = path.join(server.serverCertificateManager.rootDir, "own/certs/certificate.pem");
158
- const certificatePEM = fs.readFileSync(certificateFile, "utf8");
159
-
160
- const privateKeyFile = server.serverCertificateManager.privateKey;
161
- const privateKey = readPrivateKey(privateKeyFile);
162
- // also reread the private key
163
-
164
- _server.$$certificateChain = convertPEMtoDER(certificatePEM);
165
- _server.$$privateKey = privateKey;
166
- // note : $$certificate will be reconstructed on demand
167
- _server.$$certificate = split_der(_server.$$certificateChain)[0];
168
-
169
- setTimeout(async () => {
170
- try {
171
- doDebug && debugLog(chalk.yellow(" onCertificateChange => shutting down channels"));
172
- await server.shutdownChannels();
173
- doDebug && debugLog(chalk.yellow(" onCertificateChange => channels shut down"));
174
-
175
- doDebug && debugLog(chalk.yellow(" onCertificateChange => resuming end points"));
176
- await server.resumeEndPoints();
177
- doDebug && debugLog(chalk.yellow(" onCertificateChange => end points resumed"));
178
-
179
- debugLog(chalk.yellow("channels have been closed -> client should reconnect "));
180
- } catch (err) {
181
- errorLog("Error in CertificateChanged handler ", (err as Error).message);
182
- debugLog("err = ", err);
183
- }
184
- }, 2000);
185
- }
186
-
187
- interface UAServerConfigurationEx extends UAServerConfiguration {
188
- $pushCertificateManager: PushCertificateManagerServerImpl;
189
- }
190
-
191
- type OPCUAServerEndPointEx = typeof OPCUAServerEndPoint & {
192
- _certificateChain: Buffer | null;
193
- _privateKey: PrivateKey | null;
194
- };
195
-
196
- export async function installPushCertificateManagementOnServer(server: OPCUAServer): Promise<void> {
197
- if (!server.engine || !server.engine.addressSpace) {
198
- throw new Error(
199
- "Server must have a valid address space." +
200
- "you need to call installPushCertificateManagementOnServer after server has been initialized"
201
- );
202
- }
203
- await install.call(server as unknown as OPCUAServerPartial);
204
-
205
- server.getCertificate = getCertificate;
206
- server.getCertificateChain = getCertificateChain;
207
- server.getPrivateKey = getPrivateKey;
208
-
209
- for (const endpoint of server.endpoints) {
210
- const endpointPriv: OPCUAServerEndPointEx = endpoint as unknown as OPCUAServerEndPointEx;
211
- endpointPriv._certificateChain = null;
212
- endpointPriv._privateKey = null;
213
-
214
- endpoint.getCertificateChain = getCertificateChainEP;
215
- endpoint.getPrivateKey = getPrivateKeyEP;
216
-
217
- for (const e of endpoint.endpointDescriptions()) {
218
- Object.defineProperty(e, "serverCertificate", {
219
- get: () => endpoint.getCertificate(),
220
- configurable: true
221
- });
222
- }
223
- }
224
-
225
- await installPushCertificateManagement(server.engine.addressSpace, {
226
- applicationGroup: server.serverCertificateManager,
227
- userTokenGroup: server.userCertificateManager,
228
-
229
- applicationUri: server.serverInfo.applicationUri || "InvalidURI"
230
- });
231
-
232
- const serverConfiguration = server.engine.addressSpace.rootFolder.objects.server.getChildByName("ServerConfiguration");
233
- const serverConfigurationPriv = serverConfiguration as UAServerConfigurationEx;
234
- assert(serverConfigurationPriv.$pushCertificateManager);
235
-
236
- serverConfigurationPriv.$pushCertificateManager.on("CertificateAboutToChange", (actionQueue: ActionQueue) => {
237
- actionQueue.push(async (): Promise<void> => {
238
- doDebug && debugLog("CertificateAboutToChange Event received");
239
- await onCertificateAboutToChange(server);
240
- doDebug && debugLog("CertificateAboutToChange Event processed");
241
- });
242
- });
243
- serverConfigurationPriv.$pushCertificateManager.on("CertificateChanged", (actionQueue: ActionQueue) => {
244
- actionQueue.push(async (): Promise<void> => {
245
- doDebug && debugLog("CertificateChanged Event received");
246
- await onCertificateChange(server);
247
- doDebug && debugLog("CertificateChanged Event processed");
248
- });
249
- });
250
- }