node-opcua-server-configuration 2.163.1 → 2.165.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 (100) hide show
  1. package/dist/clientTools/certificate_types.d.ts +15 -0
  2. package/dist/clientTools/certificate_types.js +19 -0
  3. package/dist/clientTools/certificate_types.js.map +1 -0
  4. package/dist/clientTools/get_certificate_key_type.d.ts +6 -0
  5. package/dist/clientTools/get_certificate_key_type.js +55 -0
  6. package/dist/clientTools/get_certificate_key_type.js.map +1 -0
  7. package/dist/clientTools/index.d.ts +2 -1
  8. package/dist/clientTools/index.js +2 -17
  9. package/dist/clientTools/index.js.map +1 -1
  10. package/dist/clientTools/push_certificate_management_client.d.ts +10 -10
  11. package/dist/clientTools/push_certificate_management_client.js +85 -89
  12. package/dist/clientTools/push_certificate_management_client.js.map +1 -1
  13. package/dist/index.d.ts +9 -7
  14. package/dist/index.js +9 -23
  15. package/dist/index.js.map +1 -1
  16. package/dist/push_certificate_manager.d.ts +6 -5
  17. package/dist/push_certificate_manager.js +1 -2
  18. package/dist/server/certificate_validation.d.ts +15 -0
  19. package/dist/server/certificate_validation.js +76 -0
  20. package/dist/server/certificate_validation.js.map +1 -0
  21. package/dist/server/file_transaction_manager.d.ts +30 -0
  22. package/dist/server/file_transaction_manager.js +223 -0
  23. package/dist/server/file_transaction_manager.js.map +1 -0
  24. package/dist/server/install_certificate_file_watcher.d.ts +1 -1
  25. package/dist/server/install_certificate_file_watcher.js +8 -14
  26. package/dist/server/install_certificate_file_watcher.js.map +1 -1
  27. package/dist/server/install_push_certitifate_management.d.ts +6 -6
  28. package/dist/server/install_push_certitifate_management.js +59 -81
  29. package/dist/server/install_push_certitifate_management.js.map +1 -1
  30. package/dist/server/promote_trust_list.d.ts +1 -1
  31. package/dist/server/promote_trust_list.js +348 -82
  32. package/dist/server/promote_trust_list.js.map +1 -1
  33. package/dist/server/push_certificate_manager/apply_changes.d.ts +4 -0
  34. package/dist/server/push_certificate_manager/apply_changes.js +65 -0
  35. package/dist/server/push_certificate_manager/apply_changes.js.map +1 -0
  36. package/dist/server/push_certificate_manager/create_signing_request.d.ts +5 -0
  37. package/dist/server/push_certificate_manager/create_signing_request.js +108 -0
  38. package/dist/server/push_certificate_manager/create_signing_request.js.map +1 -0
  39. package/dist/server/push_certificate_manager/get_rejected_list.d.ts +3 -0
  40. package/dist/server/push_certificate_manager/get_rejected_list.js +46 -0
  41. package/dist/server/push_certificate_manager/get_rejected_list.js.map +1 -0
  42. package/dist/server/push_certificate_manager/internal_context.d.ts +35 -0
  43. package/dist/server/push_certificate_manager/internal_context.js +45 -0
  44. package/dist/server/push_certificate_manager/internal_context.js.map +1 -0
  45. package/dist/server/push_certificate_manager/subject_to_string.d.ts +3 -0
  46. package/dist/server/push_certificate_manager/subject_to_string.js +27 -0
  47. package/dist/server/push_certificate_manager/subject_to_string.js.map +1 -0
  48. package/dist/server/push_certificate_manager/update_certificate.d.ts +5 -0
  49. package/dist/server/push_certificate_manager/update_certificate.js +134 -0
  50. package/dist/server/push_certificate_manager/update_certificate.js.map +1 -0
  51. package/dist/server/push_certificate_manager/util.d.ts +29 -0
  52. package/dist/server/push_certificate_manager/util.js +117 -0
  53. package/dist/server/push_certificate_manager/util.js.map +1 -0
  54. package/dist/server/push_certificate_manager_helpers.d.ts +5 -2
  55. package/dist/server/push_certificate_manager_helpers.js +110 -113
  56. package/dist/server/push_certificate_manager_helpers.js.map +1 -1
  57. package/dist/server/push_certificate_manager_server_impl.d.ts +37 -30
  58. package/dist/server/push_certificate_manager_server_impl.js +58 -438
  59. package/dist/server/push_certificate_manager_server_impl.js.map +1 -1
  60. package/dist/server/roles_and_permissions.d.ts +1 -1
  61. package/dist/server/roles_and_permissions.js +24 -27
  62. package/dist/server/roles_and_permissions.js.map +1 -1
  63. package/dist/server/tools.d.ts +1 -1
  64. package/dist/server/tools.js +7 -13
  65. package/dist/server/tools.js.map +1 -1
  66. package/dist/server/trust_list_server.d.ts +2 -2
  67. package/dist/server/trust_list_server.js +40 -29
  68. package/dist/server/trust_list_server.js.map +1 -1
  69. package/dist/standard_certificate_types.js +6 -9
  70. package/dist/standard_certificate_types.js.map +1 -1
  71. package/dist/trust_list.d.ts +2 -2
  72. package/dist/trust_list.js +1 -2
  73. package/dist/trust_list_impl.js +1 -2
  74. package/dist/trust_list_impl.js.map +1 -1
  75. package/package.json +30 -30
  76. package/source/clientTools/certificate_types.ts +21 -0
  77. package/source/clientTools/get_certificate_key_type.ts +73 -0
  78. package/source/clientTools/index.ts +2 -1
  79. package/source/clientTools/push_certificate_management_client.ts +49 -44
  80. package/source/index.ts +9 -7
  81. package/source/push_certificate_manager.ts +17 -18
  82. package/source/server/certificate_validation.ts +103 -0
  83. package/source/server/file_transaction_manager.ts +253 -0
  84. package/source/server/install_certificate_file_watcher.ts +15 -11
  85. package/source/server/install_push_certitifate_management.ts +52 -68
  86. package/source/server/promote_trust_list.ts +392 -73
  87. package/source/server/push_certificate_manager/apply_changes.ts +73 -0
  88. package/source/server/push_certificate_manager/create_signing_request.ts +137 -0
  89. package/source/server/push_certificate_manager/get_rejected_list.ts +63 -0
  90. package/source/server/push_certificate_manager/internal_context.ts +63 -0
  91. package/source/server/push_certificate_manager/subject_to_string.ts +25 -0
  92. package/source/server/push_certificate_manager/update_certificate.ts +203 -0
  93. package/source/server/push_certificate_manager/util.ts +145 -0
  94. package/source/server/push_certificate_manager_helpers.ts +62 -52
  95. package/source/server/push_certificate_manager_server_impl.ts +133 -552
  96. package/source/server/roles_and_permissions.ts +7 -8
  97. package/source/server/tools.ts +2 -5
  98. package/source/server/trust_list_server.ts +24 -9
  99. package/source/standard_certificate_types.ts +2 -3
  100. package/source/trust_list.ts +26 -33
@@ -1,120 +1,383 @@
1
- "use strict";
2
1
  /**
3
2
  * @module node-opcua-server-configuration
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.promoteTrustList = promoteTrustList;
7
- exports.installAccessRestrictionOnTrustList = installAccessRestrictionOnTrustList;
8
- const memfs_1 = require("memfs");
9
- const node_opcua_debug_1 = require("node-opcua-debug");
10
- const node_opcua_status_code_1 = require("node-opcua-status-code");
11
- const node_opcua_variant_1 = require("node-opcua-variant");
12
- const node_opcua_data_model_1 = require("node-opcua-data-model");
13
- const node_opcua_file_transfer_1 = require("node-opcua-file-transfer");
14
- const web_1 = require("node-opcua-crypto/web");
15
- const trust_list_server_1 = require("./trust_list_server");
16
- const tools_1 = require("./tools");
17
- const roles_and_permissions_1 = require("./roles_and_permissions");
18
- const debugLog = (0, node_opcua_debug_1.make_debugLog)("ServerConfiguration");
19
- const doDebug = (0, node_opcua_debug_1.checkDebugFlag)("ServerConfiguration");
20
- doDebug;
21
- const warningLog = (0, node_opcua_debug_1.make_warningLog)("ServerConfiguration");
22
- const errorLog = debugLog;
4
+ import { fs as MemFs } from "memfs";
5
+ import { BinaryStream } from "node-opcua-binary-stream";
6
+ import { split_der, verifyCertificateChain } from "node-opcua-crypto/web";
7
+ import { AccessRestrictionsFlag } from "node-opcua-data-model";
8
+ import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
9
+ import { installFileType, OpenFileMode } from "node-opcua-file-transfer";
10
+ import { VerificationStatus } from "node-opcua-pki";
11
+ import { StatusCodes } from "node-opcua-status-code";
12
+ import { TrustListDataType } from "node-opcua-types";
13
+ import { DataType, Variant } from "node-opcua-variant";
14
+ import { rolePermissionAdminOnly } from "./roles_and_permissions.js";
15
+ import { hasEncryptedChannel, hasExpectedUserAccess } from "./tools.js";
16
+ import { TrustListMasks, writeTrustList } from "./trust_list_server.js";
17
+ const debugLog = make_debugLog("ServerConfiguration");
18
+ const doDebug = checkDebugFlag("ServerConfiguration");
19
+ const warningLog = make_warningLog("ServerConfiguration");
20
+ const errorLog = make_errorLog("ServerConfiguration");
21
+ /**
22
+ * Navigate from a TrustList node up to the push certificate manager
23
+ * and emit a `"trustListUpdated"` event with the certificate-group
24
+ * browse-name.
25
+ */
26
+ function emitTrustListUpdated(trustList) {
27
+ try {
28
+ const certificateGroup = trustList.parent;
29
+ const groupName = certificateGroup?.browseName?.name ?? "Unknown";
30
+ const serverConfiguration = trustList.addressSpace.rootFolder
31
+ .objects.server.getChildByName("ServerConfiguration");
32
+ if (!serverConfiguration)
33
+ return;
34
+ const pushManager = serverConfiguration.$pushCertificateManager;
35
+ if (pushManager) {
36
+ pushManager.emit("trustListUpdated", groupName);
37
+ }
38
+ }
39
+ catch (err) {
40
+ errorLog("emitTrustListUpdated error:", err.message);
41
+ }
42
+ }
23
43
  function trustListIsAlreadyOpened(trustList) {
24
- return false; // to do...
44
+ // TrustList extends FileType, which has an openCount property tracking how many handles are open
45
+ const openCountNode = trustList.openCount;
46
+ if (!openCountNode) {
47
+ return false;
48
+ }
49
+ const dataValue = openCountNode.readValue();
50
+ if (!dataValue || !dataValue.value) {
51
+ return false;
52
+ }
53
+ const openCount = dataValue.value.value;
54
+ return openCount > 0;
55
+ }
56
+ /**
57
+ * Update the mandatory LastUpdateTime property whenever the trust list is modified.
58
+ * Per OPC UA Part 12 spec, this must be updated after AddCertificate, RemoveCertificate, or CloseAndUpdate.
59
+ */
60
+ function updateLastUpdateTime(trustList) {
61
+ try {
62
+ const lastUpdateTimeNode = trustList.lastUpdateTime;
63
+ if (lastUpdateTimeNode) {
64
+ lastUpdateTimeNode.setValueFromSource({
65
+ dataType: DataType.DateTime,
66
+ value: new Date()
67
+ });
68
+ doDebug && debugLog("Updated LastUpdateTime to", new Date().toISOString());
69
+ }
70
+ else {
71
+ warningLog("LastUpdateTime property not found on TrustList");
72
+ }
73
+ }
74
+ catch (err) {
75
+ errorLog("Error updating LastUpdateTime:", err);
76
+ }
77
+ }
78
+ async function applyTrustListChanges(cm, trustListData) {
79
+ try {
80
+ // Automatically update specifiedLists mask
81
+ if (trustListData.issuerCrls && trustListData.issuerCrls.length > 0) {
82
+ trustListData.specifiedLists |= TrustListMasks.IssuerCrls;
83
+ }
84
+ if (trustListData.trustedCrls && trustListData.trustedCrls.length > 0) {
85
+ trustListData.specifiedLists |= TrustListMasks.TrustedCrls;
86
+ }
87
+ if (trustListData.trustedCertificates && trustListData.trustedCertificates.length > 0) {
88
+ trustListData.specifiedLists |= TrustListMasks.TrustedCertificates;
89
+ }
90
+ if (trustListData.issuerCertificates && trustListData.issuerCertificates.length > 0) {
91
+ trustListData.specifiedLists |= TrustListMasks.IssuerCertificates;
92
+ }
93
+ // Process CRLs
94
+ if ((trustListData.specifiedLists & TrustListMasks.IssuerCrls) === TrustListMasks.IssuerCrls) {
95
+ doDebug && debugLog("Processing issuer CRLs");
96
+ await cm.clearRevocationLists("issuers");
97
+ if (trustListData.issuerCrls && trustListData.issuerCrls.length > 0) {
98
+ doDebug && debugLog(` Writing ${trustListData.issuerCrls.length} issuer CRLs`);
99
+ for (const crl of trustListData.issuerCrls) {
100
+ await cm.addRevocationList(crl, "issuers");
101
+ }
102
+ }
103
+ }
104
+ if ((trustListData.specifiedLists & TrustListMasks.TrustedCrls) === TrustListMasks.TrustedCrls) {
105
+ doDebug && debugLog("Processing trusted CRLs");
106
+ await cm.clearRevocationLists("trusted");
107
+ if (trustListData.trustedCrls && trustListData.trustedCrls.length > 0) {
108
+ doDebug && debugLog(` Writing ${trustListData.trustedCrls.length} trusted CRLs`);
109
+ for (const crl of trustListData.trustedCrls) {
110
+ await cm.addRevocationList(crl, "trusted");
111
+ }
112
+ }
113
+ }
114
+ // Validate all trusted certificates
115
+ if ((trustListData.specifiedLists & TrustListMasks.TrustedCertificates) === TrustListMasks.TrustedCertificates &&
116
+ trustListData.trustedCertificates) {
117
+ for (const cert of trustListData.trustedCertificates) {
118
+ try {
119
+ const certs = split_der(cert);
120
+ const validationResult = await verifyCertificateChain([certs[0]]);
121
+ if (validationResult.status !== "Good") {
122
+ warningLog("Invalid certificate in trust list:", validationResult.status, validationResult.reason);
123
+ return StatusCodes.BadCertificateInvalid;
124
+ }
125
+ }
126
+ catch (validationErr) {
127
+ errorLog("Certificate validation failed:", validationErr);
128
+ return StatusCodes.BadCertificateInvalid;
129
+ }
130
+ }
131
+ }
132
+ // Validate all issuer certificates
133
+ if ((trustListData.specifiedLists & TrustListMasks.IssuerCertificates) === TrustListMasks.IssuerCertificates &&
134
+ trustListData.issuerCertificates) {
135
+ for (const cert of trustListData.issuerCertificates) {
136
+ try {
137
+ const certs = split_der(cert);
138
+ const validationResult = await verifyCertificateChain([certs[0]]);
139
+ if (validationResult.status !== "Good") {
140
+ warningLog("Invalid issuer certificate in trust list:", validationResult.status, validationResult.reason);
141
+ return StatusCodes.BadCertificateInvalid;
142
+ }
143
+ }
144
+ catch (validationErr) {
145
+ errorLog("Issuer certificate validation failed:", validationErr);
146
+ return StatusCodes.BadCertificateInvalid;
147
+ }
148
+ }
149
+ }
150
+ // Update certificates
151
+ if ((trustListData.specifiedLists & TrustListMasks.TrustedCertificates) === TrustListMasks.TrustedCertificates &&
152
+ trustListData.trustedCertificates) {
153
+ for (const cert of trustListData.trustedCertificates) {
154
+ await cm.trustCertificate(cert);
155
+ }
156
+ }
157
+ if ((trustListData.specifiedLists & TrustListMasks.IssuerCertificates) === TrustListMasks.IssuerCertificates &&
158
+ trustListData.issuerCertificates) {
159
+ for (const cert of trustListData.issuerCertificates) {
160
+ await cm.addIssuer(cert);
161
+ }
162
+ }
163
+ return StatusCodes.Good;
164
+ }
165
+ catch (err) {
166
+ errorLog("Error in applyTrustListChanges:", err);
167
+ return StatusCodes.BadInternalError;
168
+ }
25
169
  }
26
- async function _closeAndUpdate(inputArguments, context) {
27
- return { statusCode: node_opcua_status_code_1.StatusCodes.Good };
170
+ async function _closeAndUpdate(inputArguments, context, _close_method) {
171
+ const trustList = context.object;
172
+ const cm = trustList.$$certificateManager;
173
+ const filename = trustList.$$filename;
174
+ // Clear the write lock when closing
175
+ trustList.$$openedForWrite = false;
176
+ // Get the close method if not provided
177
+ if (!_close_method) {
178
+ const closeMethod = trustList.getChildByName("Close");
179
+ if (closeMethod) {
180
+ _close_method = closeMethod._asyncExecutionFunction;
181
+ }
182
+ }
183
+ if (!cm || !filename) {
184
+ return { statusCode: StatusCodes.BadInternalError };
185
+ }
186
+ let processStatusCode = StatusCodes.Good;
187
+ try {
188
+ if (MemFs.existsSync(filename)) {
189
+ const data = await new Promise((resolve, reject) => {
190
+ MemFs.readFile(filename, (err, data) => {
191
+ if (err)
192
+ reject(err);
193
+ else
194
+ resolve(data);
195
+ });
196
+ });
197
+ // Decode the TrustListDataType
198
+ const stream = new BinaryStream(data);
199
+ const trustListData = new TrustListDataType();
200
+ trustListData.decode(stream);
201
+ processStatusCode = await applyTrustListChanges(cm, trustListData);
202
+ if (processStatusCode === StatusCodes.Good) {
203
+ // OPC UA Spec: Update LastUpdateTime after successful trust list update
204
+ updateLastUpdateTime(trustList);
205
+ emitTrustListUpdated(trustList);
206
+ }
207
+ }
208
+ }
209
+ catch (err) {
210
+ errorLog("Error in _closeAndUpdate:", err);
211
+ processStatusCode = StatusCodes.BadInternalError;
212
+ }
213
+ // Close the underlying file to decrement openCount
214
+ // OPC UA spec: "This Method closes the file and applies the changes."
215
+ if (_close_method) {
216
+ return new Promise((resolve, reject) => {
217
+ _close_method.call(this, inputArguments, context, (err, result) => {
218
+ if (err) {
219
+ reject(err);
220
+ }
221
+ else {
222
+ // Override the output argument to match CloseAndUpdate signature
223
+ resolve({
224
+ statusCode: processStatusCode === StatusCodes.Good ? result?.statusCode || StatusCodes.Good : processStatusCode,
225
+ outputArguments: [new Variant({ dataType: DataType.Boolean, value: false })]
226
+ });
227
+ }
228
+ });
229
+ });
230
+ }
231
+ return {
232
+ statusCode: processStatusCode,
233
+ outputArguments: [new Variant({ dataType: DataType.Boolean, value: false })]
234
+ };
28
235
  }
29
236
  // in TrustList
30
237
  async function _addCertificate(inputArguments, context) {
31
- // If the Certificate is issued by a CA then the Client shall provide the entire
32
- // chain in the certificate argument (see OPC 10000-6). After validating the Certificate,
33
- // the Server shall add the CA Certificates to the Issuers list in the Trust List.
34
- // The leaf Certificate is added to the list specified by the isTrustedCertificate argument.
35
- if (!(0, tools_1.hasEncryptedChannel)(context)) {
36
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadSecurityModeInsufficient };
238
+ if (!hasEncryptedChannel(context)) {
239
+ return { statusCode: StatusCodes.BadSecurityModeInsufficient };
37
240
  }
38
- if (!(0, tools_1.hasExpectedUserAccess)(context)) {
39
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied };
241
+ if (!hasExpectedUserAccess(context)) {
242
+ return { statusCode: StatusCodes.BadUserAccessDenied };
40
243
  }
41
244
  const trustList = context.object;
42
- const cm = trustList.$$certificateManager || null;
43
- // The trust list must have been bound
245
+ const cm = trustList.$$certificateManager;
44
246
  if (!cm) {
45
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError };
247
+ return { statusCode: StatusCodes.BadInternalError };
46
248
  }
47
- // This method cannot be called if the file object is open.
48
- if (trustListIsAlreadyOpened(trustList)) {
49
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidState };
249
+ if (trustListIsAlreadyOpened(trustList) || trustList.$$openedForWrite) {
250
+ return { statusCode: StatusCodes.BadInvalidState };
50
251
  }
51
- const certificateChain = inputArguments[0].value;
252
+ const certificateBuffer = inputArguments[0].value;
52
253
  const isTrustedCertificate = inputArguments[1].value;
53
- const certificates = (0, web_1.split_der)(certificateChain);
54
- // validate certificate first
55
- const r = await (0, web_1.verifyCertificateChain)(certificates);
56
- if (r.status !== "Good") {
57
- warningLog("Invalid certificate ", r.status, r.reason);
58
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadCertificateInvalid };
59
- }
60
- for (let i = 0; i < certificates.length; i++) {
61
- const certificate = certificates[i];
62
- if (i === certificates.length - 1 && isTrustedCertificate) {
63
- await cm.trustCertificate(certificate);
254
+ // OPC UA Spec: "If FALSE Bad_CertificateInvalid is returned."
255
+ if (!isTrustedCertificate) {
256
+ return { statusCode: StatusCodes.BadCertificateInvalid };
257
+ }
258
+ try {
259
+ const certificates = split_der(certificateBuffer);
260
+ if (certificates.length > 1) {
261
+ warningLog("AddCertificate received a certificate chain. Only the leaf certificate will be added.");
262
+ warningLog("Issuer certificates must be added using the Write/CloseAndUpdate methods.");
64
263
  }
65
- else {
66
- await cm.addIssuer(certificate);
264
+ const status = await cm.addTrustedCertificateFromChain(certificateBuffer);
265
+ if (status !== VerificationStatus.Good) {
266
+ warningLog("Certificate validation failed:", status);
267
+ return { statusCode: StatusCodes.BadCertificateInvalid };
67
268
  }
269
+ updateLastUpdateTime(trustList);
270
+ emitTrustListUpdated(trustList);
271
+ doDebug && debugLog("_addCertificate - done, leaf certificate has been added to trustedCertificates");
272
+ return { statusCode: StatusCodes.Good };
273
+ }
274
+ catch (err) {
275
+ errorLog("Error in _addCertificate:", err);
276
+ return { statusCode: StatusCodes.BadCertificateInvalid };
68
277
  }
69
- debugLog("_addCertificate - done isTrustedCertificate= ", isTrustedCertificate);
70
- return { statusCode: node_opcua_status_code_1.StatusCodes.Good };
71
278
  }
72
279
  async function _removeCertificate(inputArguments, context) {
73
- if (!(0, tools_1.hasEncryptedChannel)(context)) {
74
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadSecurityModeInsufficient };
280
+ if (!hasEncryptedChannel(context)) {
281
+ return { statusCode: StatusCodes.BadSecurityModeInsufficient };
282
+ }
283
+ if (!hasExpectedUserAccess(context)) {
284
+ return { statusCode: StatusCodes.BadUserAccessDenied };
285
+ }
286
+ const trustList = context.object;
287
+ const cm = trustList.$$certificateManager;
288
+ if (!cm) {
289
+ return { statusCode: StatusCodes.BadInternalError };
290
+ }
291
+ if (trustListIsAlreadyOpened(trustList) || trustList.$$openedForWrite) {
292
+ return { statusCode: StatusCodes.BadInvalidState };
75
293
  }
76
- if (!(0, tools_1.hasExpectedUserAccess)(context)) {
77
- return { statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied };
294
+ const thumbprint = inputArguments[0].value;
295
+ const isTrustedCertificate = inputArguments[1].value;
296
+ try {
297
+ // Normalize thumbprint - remove "NodeOPCUA[" prefix if present
298
+ const normalizedThumbprint = thumbprint.replace(/^NodeOPCUA\[|\]$/g, "").toLowerCase();
299
+ if (isTrustedCertificate) {
300
+ // Remove from trusted store
301
+ const removed = await cm.removeTrustedCertificate(normalizedThumbprint);
302
+ if (!removed) {
303
+ return { statusCode: StatusCodes.BadInvalidArgument };
304
+ }
305
+ }
306
+ else {
307
+ // Removing an issuer certificate — first check if it's still
308
+ // needed by any trusted certificate
309
+ const issuerCert = await cm.removeIssuer(normalizedThumbprint);
310
+ if (!issuerCert) {
311
+ return { statusCode: StatusCodes.BadInvalidArgument };
312
+ }
313
+ // Check dependency: is any trusted cert signed by this issuer?
314
+ if (await cm.isIssuerInUseByTrustedCertificate(issuerCert)) {
315
+ // Re-add the issuer since we can't remove it
316
+ await cm.addIssuer(issuerCert);
317
+ warningLog("Certificate is needed for chain validation");
318
+ return { statusCode: StatusCodes.BadCertificateChainIncomplete };
319
+ }
320
+ // Also remove CRLs issued by this CA
321
+ await cm.removeRevocationListsForIssuer(issuerCert, "issuers");
322
+ }
323
+ updateLastUpdateTime(trustList);
324
+ emitTrustListUpdated(trustList);
325
+ doDebug && debugLog("_removeCertificate - done, isTrustedCertificate=", isTrustedCertificate);
326
+ return { statusCode: StatusCodes.Good };
327
+ }
328
+ catch (err) {
329
+ errorLog("Error in _removeCertificate:", err);
330
+ return { statusCode: StatusCodes.BadInternalError };
78
331
  }
79
- return { statusCode: node_opcua_status_code_1.StatusCodes.Good };
80
332
  }
81
333
  let counter = 0;
82
- async function promoteTrustList(trustList) {
334
+ export async function promoteTrustList(trustList) {
83
335
  const filename = `/tmpFile${counter}`;
84
336
  counter += 1;
85
- (0, node_opcua_file_transfer_1.installFileType)(trustList, { filename, fileSystem: memfs_1.fs });
337
+ const trustListEx = trustList;
338
+ // Store filename for use in _closeAndUpdate
339
+ trustListEx.$$filename = filename;
340
+ // Initialize write lock flag
341
+ trustListEx.$$openedForWrite = false;
342
+ installFileType(trustList, { filename, fileSystem: MemFs });
86
343
  // we need to change the default open method
87
344
  const open = trustList.getChildByName("Open");
88
345
  const _open_asyncExecutionFunction = open._asyncExecutionFunction;
89
346
  // ... and bind the extended methods as well.
347
+ const close = trustList.getChildByName("Close");
348
+ const _close_asyncExecutionFunction = close._asyncExecutionFunction;
90
349
  const closeAndUpdate = trustList.getChildByName("CloseAndUpdate");
91
350
  const openWithMasks = trustList.getChildByName("OpenWithMasks");
92
351
  const addCertificate = trustList.getChildByName("AddCertificate");
93
352
  const removeCertificate = trustList.getChildByName("RemoveCertificate");
94
353
  function _openTrustList(trustMask, inputArgs, context, callback) {
95
- if (trustListIsAlreadyOpened(trustList)) {
96
- return callback(null, { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidState });
97
- }
98
- // if (trustList.isOpened) {
99
- // warningLog("TrustList is already opened")
100
- // return { statusCode: StatusCodes.BadInvalidState};
101
- // }
102
354
  // The Open Method shall not support modes other than Read (0x01) and the Write + EraseExisting (0x06).
103
355
  const openMask = inputArgs[0].value;
104
- if (openMask !== node_opcua_file_transfer_1.OpenFileMode.Read && openMask !== node_opcua_file_transfer_1.OpenFileMode.WriteEraseExisting) {
105
- return callback(null, { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument });
356
+ if (openMask !== OpenFileMode.Read && openMask !== OpenFileMode.WriteEraseExisting) {
357
+ // OPC UA Spec: "If other modes are requested the return code is Bad_NotSupported."
358
+ return callback(null, { statusCode: StatusCodes.BadNotSupported });
359
+ }
360
+ // OPC UA Spec: BadInvalidState - The Open Method was called with write access
361
+ // and the CloseAndUpdate Method has not been called.
362
+ // If already opened for write, no subsequent opens (read or write) are allowed.
363
+ const isOpenedForWrite = trustListEx.$$openedForWrite;
364
+ if (isOpenedForWrite) {
365
+ return callback(null, { statusCode: StatusCodes.BadInvalidState });
106
366
  }
107
367
  // possible statusCode: Bad_UserAccessDenied The current user does not have the rights required.
108
- const certificateManager = trustList.$$certificateManager || undefined;
368
+ const certificateManager = trustListEx.$$certificateManager;
109
369
  if (certificateManager) {
110
- (0, trust_list_server_1.writeTrustList)(memfs_1.fs, filename, trustMask, certificateManager)
370
+ writeTrustList(MemFs, filename, trustMask, certificateManager)
111
371
  .then(() => {
112
- // trustList.isOpened = true;
372
+ // Track if opened for write to enforce BadInvalidState on subsequent opens
373
+ if (openMask === OpenFileMode.WriteEraseExisting) {
374
+ trustListEx.$$openedForWrite = true;
375
+ }
113
376
  _open_asyncExecutionFunction.call(this, inputArgs, context, callback);
114
377
  })
115
378
  .catch((err) => {
116
- errorLog(err);
117
- callback(err, { statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError });
379
+ errorLog(err.message);
380
+ callback(err, { statusCode: StatusCodes.BadInternalError });
118
381
  });
119
382
  }
120
383
  else {
@@ -123,12 +386,12 @@ async function promoteTrustList(trustList) {
123
386
  }
124
387
  }
125
388
  function _openCallback(inputArgs, context, callback) {
126
- _openTrustList.call(this, trust_list_server_1.TrustListMasks.All, inputArgs, context, callback);
389
+ _openTrustList.call(this, TrustListMasks.All, inputArgs, context, callback);
127
390
  }
128
391
  open.bindMethod(_openCallback);
129
392
  function _openWithMaskCallback(inputArgs, context, callback) {
130
393
  const trustListMask = inputArgs[0].value;
131
- inputArgs[0] = new node_opcua_variant_1.Variant({ dataType: node_opcua_variant_1.DataType.Byte, value: node_opcua_file_transfer_1.OpenFileMode.Read });
394
+ inputArgs[0] = new Variant({ dataType: DataType.Byte, value: OpenFileMode.Read });
132
395
  _openTrustList.call(this, trustListMask, inputArgs, context, callback);
133
396
  }
134
397
  // The OpenWithMasks Method allows a Client to read only the portion of the Trust List.
@@ -136,24 +399,27 @@ async function promoteTrustList(trustList) {
136
399
  openWithMasks.bindMethod(_openWithMaskCallback);
137
400
  addCertificate.bindMethod(_addCertificate);
138
401
  removeCertificate.bindMethod(_removeCertificate);
139
- closeAndUpdate?.bindMethod(_closeAndUpdate);
402
+ // Wrapper to pass the underlying close method to _closeAndUpdate
403
+ closeAndUpdate?.bindMethod(async function (inputArguments, context) {
404
+ return _closeAndUpdate.call(this, inputArguments, context, _close_asyncExecutionFunction);
405
+ });
140
406
  function install_method_handle_on_TrustListType(addressSpace) {
141
407
  const fileType = addressSpace.findObjectType("TrustListType");
142
408
  if (!fileType || fileType.addCertificate.isBound()) {
143
409
  return;
144
410
  }
145
- fileType.open && fileType.open.bindMethod(_openCallback);
411
+ fileType.open?.bindMethod(_openCallback);
146
412
  fileType.addCertificate.bindMethod(_addCertificate);
147
413
  fileType.removeCertificate.bindMethod(_removeCertificate);
148
- fileType.openWithMasks && fileType.openWithMasks.bindMethod(_openWithMaskCallback);
149
- fileType.closeAndUpdate && fileType.closeAndUpdate.bindMethod(_closeAndUpdate);
414
+ fileType.openWithMasks?.bindMethod(_openWithMaskCallback);
415
+ fileType.closeAndUpdate?.bindMethod(_closeAndUpdate);
150
416
  }
151
417
  install_method_handle_on_TrustListType(trustList.addressSpace);
152
418
  }
153
- function installAccessRestrictionOnTrustList(trustList) {
419
+ export function installAccessRestrictionOnTrustList(trustList) {
154
420
  for (const m of trustList.getComponents()) {
155
- m?.setRolePermissions(roles_and_permissions_1.rolePermissionAdminOnly);
156
- m?.setAccessRestrictions(node_opcua_data_model_1.AccessRestrictionsFlag.SigningRequired | node_opcua_data_model_1.AccessRestrictionsFlag.EncryptionRequired);
421
+ m?.setRolePermissions(rolePermissionAdminOnly);
422
+ m?.setAccessRestrictions(AccessRestrictionsFlag.SigningRequired | AccessRestrictionsFlag.EncryptionRequired);
157
423
  }
158
424
  }
159
425
  //# sourceMappingURL=promote_trust_list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"promote_trust_list.js","sourceRoot":"","sources":["../../source/server/promote_trust_list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"promote_trust_list.js","sourceRoot":"","sources":["../../source/server/promote_trust_list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ISessionContext } from "node-opcua-address-space-base";
2
+ import { type StatusCode } from "node-opcua-status-code";
3
+ import type { PushCertificateManagerInternalContext } from "./internal_context.js";
4
+ export declare function executeApplyChanges(serverImpl: PushCertificateManagerInternalContext, sessionContext?: ISessionContext): Promise<StatusCode>;
@@ -0,0 +1,65 @@
1
+ import { make_errorLog, make_warningLog } from "node-opcua-debug";
2
+ import { StatusCodes } from "node-opcua-status-code";
3
+ const errorLog = make_errorLog("ServerConfiguration");
4
+ const warningLog = make_warningLog("ServerConfiguration");
5
+ // Helper: Flush action queue
6
+ async function flushActionQueue(serverImpl) {
7
+ while (serverImpl.actionQueue.length) {
8
+ const first = serverImpl.actionQueue.pop();
9
+ await first?.();
10
+ }
11
+ }
12
+ export async function executeApplyChanges(serverImpl, sessionContext) {
13
+ // ApplyChanges is used to tell the Server to apply any security changes.
14
+ // This Method should only be called if a previous call to a Method that changed the
15
+ // configuration returns applyChangesRequired=true.
16
+ if (serverImpl.operationInProgress) {
17
+ return StatusCodes.BadTooManyOperations;
18
+ }
19
+ // Check if there are any pending tasks
20
+ if (serverImpl.fileTransactionManager.pendingTasksCount === 0 && serverImpl.actionQueue.length === 0) {
21
+ // If ApplyChanges is called and there is no active transaction then return Bad_NothingToDo
22
+ return StatusCodes.BadNothingToDo;
23
+ }
24
+ serverImpl.operationInProgress = true;
25
+ try {
26
+ try {
27
+ serverImpl.emit("CertificateAboutToChange", serverImpl.actionQueue);
28
+ }
29
+ catch (err) {
30
+ errorLog("Event listener error:", err.message);
31
+ }
32
+ await flushActionQueue(serverImpl);
33
+ try {
34
+ await serverImpl.fileTransactionManager.applyFileOps();
35
+ }
36
+ catch (err) {
37
+ await serverImpl.fileTransactionManager.abortTransaction();
38
+ warningLog("err ", err.message);
39
+ return StatusCodes.BadInternalError;
40
+ }
41
+ try {
42
+ serverImpl.emit("CertificateChanged", serverImpl.actionQueue);
43
+ }
44
+ catch (err) {
45
+ errorLog("Event listener error:", err.message);
46
+ }
47
+ await flushActionQueue(serverImpl);
48
+ // Dispose and clear temporary certificate manager after applying changes
49
+ if (serverImpl.tmpCertificateManager) {
50
+ await serverImpl.tmpCertificateManager.dispose();
51
+ }
52
+ serverImpl.tmpCertificateManager = undefined;
53
+ try {
54
+ serverImpl.emit("applyChangesCompleted", sessionContext);
55
+ }
56
+ catch (err) {
57
+ errorLog("Event listener error:", err.message);
58
+ }
59
+ return StatusCodes.Good;
60
+ }
61
+ finally {
62
+ serverImpl.operationInProgress = false;
63
+ }
64
+ }
65
+ //# sourceMappingURL=apply_changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply_changes.js","sourceRoot":"","sources":["../../../source/server/push_certificate_manager/apply_changes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAmB,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGtE,MAAM,QAAQ,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;AACtD,MAAM,UAAU,GAAG,eAAe,CAAC,qBAAqB,CAAC,CAAC;AAE1D,6BAA6B;AAC7B,KAAK,UAAU,gBAAgB,CAAC,UAAiD;IAC7E,OAAO,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QAC3C,MAAM,KAAK,EAAE,EAAE,CAAC;IACpB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACrC,UAAiD,EACjD,cAAgC;IAEhC,yEAAyE;IACzE,oFAAoF;IACpF,mDAAmD;IAEnD,IAAI,UAAU,CAAC,mBAAmB,EAAE,CAAC;QACjC,OAAO,WAAW,CAAC,oBAAoB,CAAC;IAC5C,CAAC;IAED,uCAAuC;IACvC,IAAI,UAAU,CAAC,sBAAsB,CAAC,iBAAiB,KAAK,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnG,2FAA2F;QAC3F,OAAO,WAAW,CAAC,cAAc,CAAC;IACtC,CAAC;IAED,UAAU,CAAC,mBAAmB,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC;QACD,IAAI,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,0BAA0B,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,uBAAuB,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEnC,IAAI,CAAC;YACD,MAAM,UAAU,CAAC,sBAAsB,CAAC,YAAY,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,UAAU,CAAC,sBAAsB,CAAC,gBAAgB,EAAE,CAAC;YAC3D,UAAU,CAAC,MAAM,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,WAAW,CAAC,gBAAgB,CAAC;QACxC,CAAC;QACD,IAAI,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,uBAAuB,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEnC,yEAAyE;QACzE,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YACnC,MAAM,UAAU,CAAC,qBAAqB,CAAC,OAAO,EAAE,CAAC;QACrD,CAAC;QACD,UAAU,CAAC,qBAAqB,GAAG,SAAS,CAAC;QAE7C,IAAI,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,uBAAuB,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,WAAW,CAAC,IAAI,CAAC;IAC5B,CAAC;YAAS,CAAC;QACP,UAAU,CAAC,mBAAmB,GAAG,KAAK,CAAC;IAC3C,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { NodeId } from "node-opcua-nodeid";
2
+ import type { SubjectOptions } from "node-opcua-pki";
3
+ import type { CreateSigningRequestResult } from "../../push_certificate_manager.js";
4
+ import type { PushCertificateManagerInternalContext } from "./internal_context.js";
5
+ export declare function executeCreateSigningRequest(serverImpl: PushCertificateManagerInternalContext, certificateGroupId: NodeId | string, certificateTypeId: NodeId | string, subjectName: string | SubjectOptions | null, regeneratePrivateKey?: boolean, nonce?: Buffer): Promise<CreateSigningRequestResult>;