node-opcua-server-configuration 2.73.1 → 2.76.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/LICENSE +3 -1
- package/dist/clientTools/index.d.ts +1 -1
- package/dist/clientTools/index.js +17 -17
- package/dist/clientTools/push_certificate_management_client.d.ts +176 -176
- package/dist/clientTools/push_certificate_management_client.js +463 -463
- package/dist/index.d.ts +10 -10
- package/dist/index.js +27 -27
- package/dist/push_certificate_manager.d.ts +141 -141
- package/dist/push_certificate_manager.js +2 -2
- package/dist/server/install_certificate_file_watcher.d.ts +5 -5
- package/dist/server/install_certificate_file_watcher.js +23 -23
- package/dist/server/install_push_certitifate_management.d.ts +19 -19
- package/dist/server/install_push_certitifate_management.js +213 -213
- package/dist/server/promote_trust_list.d.ts +6 -6
- package/dist/server/promote_trust_list.js +175 -175
- package/dist/server/push_certificate_manager_helpers.d.ts +4 -4
- package/dist/server/push_certificate_manager_helpers.js +410 -409
- package/dist/server/push_certificate_manager_helpers.js.map +1 -1
- package/dist/server/push_certificate_manager_server_impl.d.ts +49 -49
- package/dist/server/push_certificate_manager_server_impl.js +522 -522
- package/dist/server/roles_and_permissions.d.ts +3 -3
- package/dist/server/roles_and_permissions.js +40 -40
- package/dist/server/tools.d.ts +3 -3
- package/dist/server/tools.js +19 -19
- package/dist/server/trust_list_server.d.ts +13 -13
- package/dist/server/trust_list_server.js +89 -89
- package/dist/standard_certificate_types.d.ts +6 -6
- package/dist/standard_certificate_types.js +13 -13
- package/dist/trust_list.d.ts +79 -79
- package/dist/trust_list.js +2 -2
- package/dist/trust_list_impl.js +25 -25
- package/package.json +28 -28
- package/source/server/push_certificate_manager_helpers.ts +3 -3
- package/dist/server/install_CertificateAlarm.d.ts +0 -11
- package/dist/server/install_CertificateAlarm.js +0 -46
- package/dist/server/install_CertificateAlarm.js.map +0 -1
- package/source/server/install_CertificateAlarm.ts +0 -56
|
@@ -1,464 +1,464 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ClientPushCertificateManagement = exports.CertificateGroup = exports.TrustListClient = void 0;
|
|
13
|
-
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
14
|
-
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
15
|
-
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
16
|
-
const node_opcua_file_transfer_1 = require("node-opcua-file-transfer");
|
|
17
|
-
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
18
|
-
const node_opcua_service_translate_browse_path_1 = require("node-opcua-service-translate-browse-path");
|
|
19
|
-
const node_opcua_types_1 = require("node-opcua-types");
|
|
20
|
-
const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
|
|
21
|
-
const serverConfigurationNodeId = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration");
|
|
22
|
-
const createSigningRequestMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CreateSigningRequest");
|
|
23
|
-
const getRejectedListMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_GetRejectedList");
|
|
24
|
-
const updateCertificateMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_UpdateCertificate");
|
|
25
|
-
const certificateGroups = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups");
|
|
26
|
-
const applyChangesMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_ApplyChanges");
|
|
27
|
-
const supportedPrivateKeyFormatsNodeId = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_SupportedPrivateKeyFormats");
|
|
28
|
-
const defaultApplicationGroup = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups_DefaultApplicationGroup");
|
|
29
|
-
const defaultHttpsGroup = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups_DefaultHttpsGroup");
|
|
30
|
-
const defaultUserTokenGroup = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups_DefaultUserTokenGroup");
|
|
31
|
-
function findCertificateGroupName(certificateGroupNodeId) {
|
|
32
|
-
return "todo";
|
|
33
|
-
}
|
|
34
|
-
function findCertificateGroupNodeId(certificateGroup) {
|
|
35
|
-
if (certificateGroup instanceof node_opcua_nodeid_1.NodeId) {
|
|
36
|
-
return certificateGroup;
|
|
37
|
-
}
|
|
38
|
-
switch (certificateGroup) {
|
|
39
|
-
case "DefaultApplicationGroup":
|
|
40
|
-
return defaultApplicationGroup;
|
|
41
|
-
case "DefaultHttpsGroup":
|
|
42
|
-
return defaultHttpsGroup;
|
|
43
|
-
case "DefaultUserTokenGroup":
|
|
44
|
-
return defaultUserTokenGroup;
|
|
45
|
-
default:
|
|
46
|
-
return (0, node_opcua_nodeid_1.resolveNodeId)(certificateGroup);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function findCertificateTypeIdNodeId(certificateTypeId) {
|
|
50
|
-
if (certificateTypeId instanceof node_opcua_nodeid_1.NodeId) {
|
|
51
|
-
return certificateTypeId;
|
|
52
|
-
}
|
|
53
|
-
return (0, node_opcua_nodeid_1.resolveNodeId)(certificateTypeId);
|
|
54
|
-
}
|
|
55
|
-
class TrustListClient extends node_opcua_file_transfer_1.ClientFile {
|
|
56
|
-
constructor(session, nodeId) {
|
|
57
|
-
super(session, nodeId);
|
|
58
|
-
this.nodeId = nodeId;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* @private
|
|
62
|
-
*/
|
|
63
|
-
_extractMethodIds() {
|
|
64
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
const browseResults = yield this.session.translateBrowsePath([
|
|
66
|
-
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/CloseAndUpdate"),
|
|
67
|
-
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/AddCertificate"),
|
|
68
|
-
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/RemoveCertificate"),
|
|
69
|
-
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/OpenWithMasks") // OpenWithMasks Mandatory
|
|
70
|
-
]);
|
|
71
|
-
this.closeAndUpdateNodeId = browseResults[0].targets[0].targetId;
|
|
72
|
-
this.addCertificateNodeId = browseResults[1].targets[0].targetId;
|
|
73
|
-
this.removeCertificateNodeId = browseResults[2].targets[0].targetId;
|
|
74
|
-
this.openWithMasksNodeId = browseResults[3].targets[0].targetId;
|
|
75
|
-
// istanbul ignore next
|
|
76
|
-
if (!this.openWithMasksNodeId || this.openWithMasksNodeId.isEmpty()) {
|
|
77
|
-
throw new Error("Cannot find mandatory method OpenWithMask on object");
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
extractMethodsIds() {
|
|
82
|
-
const _super = Object.create(null, {
|
|
83
|
-
extractMethodsIds: { get: () => super.extractMethodsIds }
|
|
84
|
-
});
|
|
85
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
-
yield _super.extractMethodsIds.call(this);
|
|
87
|
-
yield this._extractMethodIds();
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
openWithMasks(trustListMask) {
|
|
91
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
// istanbul ignore next
|
|
93
|
-
if (this.fileHandle) {
|
|
94
|
-
throw new Error("File has already be opened");
|
|
95
|
-
}
|
|
96
|
-
yield this.ensureInitialized();
|
|
97
|
-
// istanbul ignore next
|
|
98
|
-
if (!this.openWithMasksNodeId) {
|
|
99
|
-
throw new Error("OpenWithMasks doesn't exist");
|
|
100
|
-
}
|
|
101
|
-
const inputArguments = [{ dataType: node_opcua_variant_1.DataType.UInt32, value: trustListMask }];
|
|
102
|
-
const methodToCall = {
|
|
103
|
-
inputArguments,
|
|
104
|
-
methodId: this.openWithMasksNodeId,
|
|
105
|
-
objectId: this.nodeId
|
|
106
|
-
};
|
|
107
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
108
|
-
if (callMethodResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
109
|
-
throw new Error(callMethodResult.statusCode.name);
|
|
110
|
-
}
|
|
111
|
-
this.fileHandle = callMethodResult.outputArguments[0].value;
|
|
112
|
-
return this.fileHandle;
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
closeAndUpdate(applyChangesRequired) {
|
|
116
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
if (!this.fileHandle) {
|
|
118
|
-
throw new Error("File has node been opened yet");
|
|
119
|
-
}
|
|
120
|
-
yield this.ensureInitialized();
|
|
121
|
-
if (!this.closeAndUpdateNodeId) {
|
|
122
|
-
throw new Error("CloseAndUpdateMethod doesn't exist");
|
|
123
|
-
}
|
|
124
|
-
const inputArguments = [
|
|
125
|
-
{ dataType: node_opcua_variant_1.DataType.UInt32, value: this.fileHandle },
|
|
126
|
-
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!applyChangesRequired }
|
|
127
|
-
];
|
|
128
|
-
const methodToCall = {
|
|
129
|
-
inputArguments,
|
|
130
|
-
methodId: this.closeAndUpdateNodeId,
|
|
131
|
-
objectId: this.nodeId
|
|
132
|
-
};
|
|
133
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
134
|
-
if (callMethodResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
135
|
-
throw new Error(callMethodResult.statusCode.name);
|
|
136
|
-
}
|
|
137
|
-
return callMethodResult.outputArguments[0].value;
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
addCertificate(certificate, isTrustedCertificate) {
|
|
141
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
-
yield this.ensureInitialized();
|
|
143
|
-
const inputArguments = [
|
|
144
|
-
{ dataType: node_opcua_variant_1.DataType.ByteString, value: certificate },
|
|
145
|
-
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!isTrustedCertificate }
|
|
146
|
-
];
|
|
147
|
-
const methodToCall = {
|
|
148
|
-
inputArguments,
|
|
149
|
-
methodId: this.addCertificateNodeId,
|
|
150
|
-
objectId: this.nodeId
|
|
151
|
-
};
|
|
152
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
153
|
-
return callMethodResult.statusCode;
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
removeCertificate(thumbprint, isTrustedCertificate) {
|
|
157
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
-
yield this.ensureInitialized();
|
|
159
|
-
const inputArguments = [
|
|
160
|
-
{ dataType: node_opcua_variant_1.DataType.String, value: thumbprint },
|
|
161
|
-
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!isTrustedCertificate }
|
|
162
|
-
];
|
|
163
|
-
const methodToCall = {
|
|
164
|
-
inputArguments,
|
|
165
|
-
methodId: this.removeCertificateNodeId,
|
|
166
|
-
objectId: this.nodeId
|
|
167
|
-
};
|
|
168
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
169
|
-
return callMethodResult.statusCode;
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* helper function to retrieve the list of certificates ...
|
|
174
|
-
* @returns
|
|
175
|
-
*/
|
|
176
|
-
readTrustedCertificateList() {
|
|
177
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
-
// const size = await this.size();
|
|
179
|
-
const fileHandle = yield this.open(node_opcua_file_transfer_1.OpenFileMode.Read);
|
|
180
|
-
const buff = yield this.read(65525);
|
|
181
|
-
yield this.close();
|
|
182
|
-
const stream = new node_opcua_binary_stream_1.BinaryStream(buff);
|
|
183
|
-
const trustList = new node_opcua_types_1.TrustListDataType();
|
|
184
|
-
trustList.decode(stream);
|
|
185
|
-
return trustList;
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
readTrustedCertificateListWithMasks(trustListMask) {
|
|
189
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
190
|
-
// const size = await this.size();
|
|
191
|
-
const fileHandle = yield this.openWithMasks(trustListMask);
|
|
192
|
-
const buff = yield this.read(65525);
|
|
193
|
-
yield this.close();
|
|
194
|
-
const stream = new node_opcua_binary_stream_1.BinaryStream(buff);
|
|
195
|
-
const trustList = new node_opcua_types_1.TrustListDataType();
|
|
196
|
-
trustList.decode(stream);
|
|
197
|
-
return trustList;
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
writeTrustedCertificateList(trustedList) {
|
|
201
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
202
|
-
yield this.open(node_opcua_file_transfer_1.OpenFileMode.Write);
|
|
203
|
-
const s = trustedList.binaryStoreSize();
|
|
204
|
-
const stream = new node_opcua_binary_stream_1.BinaryStream(s);
|
|
205
|
-
trustedList.encode(stream);
|
|
206
|
-
return yield this.closeAndUpdate(true);
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
exports.TrustListClient = TrustListClient;
|
|
211
|
-
class CertificateGroup {
|
|
212
|
-
constructor(session, nodeId) {
|
|
213
|
-
this.session = session;
|
|
214
|
-
this.nodeId = nodeId;
|
|
215
|
-
}
|
|
216
|
-
getCertificateTypes() {
|
|
217
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
-
const browsePathResult = yield this.session.translateBrowsePath((0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/CertificateTypes"));
|
|
219
|
-
if (browsePathResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
220
|
-
throw new Error(browsePathResult.statusCode.name);
|
|
221
|
-
}
|
|
222
|
-
const certificateTypesNodeId = browsePathResult.targets[0].targetId;
|
|
223
|
-
const dataValue = yield this.session.read({ nodeId: certificateTypesNodeId, attributeId: node_opcua_data_model_1.AttributeIds.Value });
|
|
224
|
-
if (dataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
225
|
-
throw new Error(browsePathResult.statusCode.name);
|
|
226
|
-
}
|
|
227
|
-
return dataValue.value.value;
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
getTrustList() {
|
|
231
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
-
const browsePathResult = yield this.session.translateBrowsePath((0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/TrustList"));
|
|
233
|
-
if (browsePathResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
234
|
-
throw new Error(browsePathResult.statusCode.name);
|
|
235
|
-
}
|
|
236
|
-
const trustListNodeId = browsePathResult.targets[0].targetId;
|
|
237
|
-
return new TrustListClient(this.session, trustListNodeId);
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
exports.CertificateGroup = CertificateGroup;
|
|
242
|
-
class ClientPushCertificateManagement {
|
|
243
|
-
constructor(session) {
|
|
244
|
-
this.session = session;
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* CreateSigningRequest Method asks the Server to create a PKCS #10 DER encoded
|
|
248
|
-
* Certificate Request that is signed with the Server’s private key. This request can be then used
|
|
249
|
-
* to request a Certificate from a CA that expects requests in this format.
|
|
250
|
-
* This Method requires an encrypted channel and that the Client provide credentials with
|
|
251
|
-
* administrative rights on the Server.
|
|
252
|
-
*
|
|
253
|
-
* @param certificateGroupId - The NodeId of the Certificate Group Object which is affected by the request.
|
|
254
|
-
* If null the DefaultApplicationGroup is used.
|
|
255
|
-
* @param certificateTypeId - The type of Certificate being requested. The set of permitted types is specified by
|
|
256
|
-
* the CertificateTypes Property belonging to the Certificate Group.
|
|
257
|
-
* @param subjectName - The subject name to use in the Certificate Request.
|
|
258
|
-
* If not specified the SubjectName from the current Certificate is used.
|
|
259
|
-
* The subjectName parameter is a sequence of X.500 name value pairs separated by a ‘/’. For
|
|
260
|
-
* example: CN=ApplicationName/OU=Group/O=Company.
|
|
261
|
-
* If the certificateType is a subtype of ApplicationCertificateType the Certificate subject name
|
|
262
|
-
* shall have an organization (O=) or domain name (DC=) field. The public key length shall meet
|
|
263
|
-
* the length restrictions for the CertificateType. The domain name field specified in the subject
|
|
264
|
-
* name is a logical domain used to qualify the subject name that may or may not be the same
|
|
265
|
-
* as a domain or IP address in the subjectAltName field of the Certificate.
|
|
266
|
-
* If the certificateType is a subtype of HttpsCertificateType the Certificate common name (CN=)
|
|
267
|
-
* shall be the same as a domain from a DiscoveryUrl which uses HTTPS and the subject name
|
|
268
|
-
* shall have an organization (O=) field.
|
|
269
|
-
* If the subjectName is blank or null the CertificateManager generates a suitable default.
|
|
270
|
-
* @param regeneratePrivateKey If TRUE the Server shall create a new Private Key which it stores until the
|
|
271
|
-
* matching signed Certificate is uploaded with the UpdateCertificate Method.
|
|
272
|
-
* Previously created Private Keys may be discarded if UpdateCertificate was not
|
|
273
|
-
* called before calling this method again. If FALSE the Server uses its existing
|
|
274
|
-
* Private Key.
|
|
275
|
-
* @param nonce Additional entropy which the caller shall provide if regeneratePrivateKey is TRUE.
|
|
276
|
-
* It shall be at least 32 bytes long.
|
|
277
|
-
*
|
|
278
|
-
* @return The PKCS #10 DER encoded Certificate Request.
|
|
279
|
-
*
|
|
280
|
-
* Result Code Description
|
|
281
|
-
* BadInvalidArgument The certificateTypeId, certificateGroupId or subjectName is not valid.
|
|
282
|
-
* BadUserAccessDenied The current user does not have the rights required.
|
|
283
|
-
*/
|
|
284
|
-
createSigningRequest(certificateGroupId, certificateTypeId, subjectName, regeneratePrivateKey, nonce) {
|
|
285
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
-
nonce = nonce || Buffer.alloc(0);
|
|
287
|
-
const inputArguments = [
|
|
288
|
-
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateGroupNodeId(certificateGroupId) },
|
|
289
|
-
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateTypeIdNodeId(certificateTypeId) },
|
|
290
|
-
{ dataType: node_opcua_variant_1.DataType.String, value: subjectName },
|
|
291
|
-
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!regeneratePrivateKey },
|
|
292
|
-
{ dataType: node_opcua_variant_1.DataType.ByteString, value: nonce }
|
|
293
|
-
];
|
|
294
|
-
const methodToCall = {
|
|
295
|
-
inputArguments,
|
|
296
|
-
methodId: createSigningRequestMethod,
|
|
297
|
-
objectId: serverConfigurationNodeId
|
|
298
|
-
};
|
|
299
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
300
|
-
if (callMethodResult.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
301
|
-
// xx console.log(callMethodResult.toString());
|
|
302
|
-
return {
|
|
303
|
-
certificateSigningRequest: callMethodResult.outputArguments[0].value,
|
|
304
|
-
statusCode: callMethodResult.statusCode
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
return { statusCode: callMethodResult.statusCode };
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* GetRejectedList Method returns the list of Certificates that have been rejected by the Server.
|
|
314
|
-
* rules are defined for how the Server updates this list or how long a Certificate is kept in
|
|
315
|
-
* the list. It is recommended that every valid but untrusted Certificate be added to the rejected
|
|
316
|
-
* list as long as storage is available. Servers should omit older entries from the list returned if
|
|
317
|
-
* the maximum message size is not large enough to allow the entire list to be returned.
|
|
318
|
-
* This Method requires an encrypted channel and that the Client provides credentials with
|
|
319
|
-
* administrative rights on the Server
|
|
320
|
-
*
|
|
321
|
-
* @return certificates The DER encoded form of the Certificates rejected by the Server
|
|
322
|
-
*/
|
|
323
|
-
getRejectedList() {
|
|
324
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
const inputArguments = [];
|
|
326
|
-
const methodToCall = {
|
|
327
|
-
inputArguments,
|
|
328
|
-
methodId: getRejectedListMethod,
|
|
329
|
-
objectId: serverConfigurationNodeId
|
|
330
|
-
};
|
|
331
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
332
|
-
if (callMethodResult.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
333
|
-
if (callMethodResult.outputArguments[0].dataType !== node_opcua_variant_1.DataType.ByteString) {
|
|
334
|
-
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
certificates: callMethodResult.outputArguments[0].value,
|
|
338
|
-
statusCode: callMethodResult.statusCode
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
else {
|
|
342
|
-
return {
|
|
343
|
-
statusCode: callMethodResult.statusCode
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
updateCertificate(certificateGroupId, certificateTypeId, certificate, issuerCertificates, privateKeyFormat, privateKey) {
|
|
349
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
-
const inputArguments = [
|
|
351
|
-
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateGroupNodeId(certificateGroupId) },
|
|
352
|
-
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateTypeIdNodeId(certificateTypeId) },
|
|
353
|
-
{ dataType: node_opcua_variant_1.DataType.ByteString, value: certificate },
|
|
354
|
-
{ dataType: node_opcua_variant_1.DataType.ByteString, arrayType: node_opcua_variant_1.VariantArrayType.Array, value: issuerCertificates },
|
|
355
|
-
{ dataType: node_opcua_variant_1.DataType.String, value: privateKeyFormat || "" },
|
|
356
|
-
{ dataType: node_opcua_variant_1.DataType.ByteString, value: privateKeyFormat ? privateKey : Buffer.alloc(0) }
|
|
357
|
-
];
|
|
358
|
-
const methodToCall = {
|
|
359
|
-
inputArguments,
|
|
360
|
-
methodId: updateCertificateMethod,
|
|
361
|
-
objectId: serverConfigurationNodeId
|
|
362
|
-
};
|
|
363
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
364
|
-
if (callMethodResult.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
365
|
-
if (!callMethodResult.outputArguments || callMethodResult.outputArguments.length !== 1) {
|
|
366
|
-
return {
|
|
367
|
-
statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError
|
|
368
|
-
};
|
|
369
|
-
// throw Error("Internal Error, expecting 1 output result");
|
|
370
|
-
}
|
|
371
|
-
return {
|
|
372
|
-
applyChangesRequired: callMethodResult.outputArguments[0].value,
|
|
373
|
-
statusCode: callMethodResult.statusCode
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
return { statusCode: callMethodResult.statusCode };
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* ApplyChanges tells the Server to apply any security changes.
|
|
383
|
-
* This Method should only be called if a previous call to a Method that changed the
|
|
384
|
-
* configuration returns applyChangesRequired=true (see 7.7.4).
|
|
385
|
-
* If the Server Certificate has changed, Secure Channels using the old Certificate will
|
|
386
|
-
* eventually be interrupted. The only leeway the Server has is with the timing. In the best case,
|
|
387
|
-
* the Server can close the TransportConnections for the affected Endpoints and leave any
|
|
388
|
-
* Subscriptions intact. This should appear no different than a network interruption from the
|
|
389
|
-
* perspective of the Client. The Client should be prepared to deal with Certificate changes
|
|
390
|
-
* during its reconnect logic. In the worst case, a full shutdown which affects all connected
|
|
391
|
-
* Clients will be necessary. In the latter case, the Server shall advertise its intent to interrupt
|
|
392
|
-
* connections by setting the SecondsTillShutdown and ShutdownReason Properties in the
|
|
393
|
-
* ServerStatus Variable.
|
|
394
|
-
* If the Secure Channel being used to call this Method will be affected by the Certificate change
|
|
395
|
-
* then the Server shall introduce a delay long enough to allow the caller to receive a reply.
|
|
396
|
-
* This Method requires an encrypted channel and that the Client provide credentials with
|
|
397
|
-
* administrative rights on the Server.
|
|
398
|
-
*
|
|
399
|
-
* Result Code Description
|
|
400
|
-
* BadUserAccessDenied The current user does not have the rights required.
|
|
401
|
-
*/
|
|
402
|
-
applyChanges() {
|
|
403
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
404
|
-
const methodToCall = {
|
|
405
|
-
inputArguments: [],
|
|
406
|
-
methodId: applyChangesMethod,
|
|
407
|
-
objectId: serverConfigurationNodeId
|
|
408
|
-
};
|
|
409
|
-
const callMethodResult = yield this.session.call(methodToCall);
|
|
410
|
-
if (callMethodResult.outputArguments && callMethodResult.outputArguments.length) {
|
|
411
|
-
throw new Error("Invalid output arguments");
|
|
412
|
-
}
|
|
413
|
-
return callMethodResult.statusCode;
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
getSupportedPrivateKeyFormats() {
|
|
417
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
418
|
-
const dataValue = yield this.session.read({
|
|
419
|
-
attributeId: node_opcua_data_model_1.AttributeIds.Value,
|
|
420
|
-
nodeId: supportedPrivateKeyFormatsNodeId
|
|
421
|
-
});
|
|
422
|
-
return dataValue.value.value;
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
getCertificateGroupId(certificateGroupName) {
|
|
426
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
427
|
-
if (certificateGroupName === "DefaultApplicationGroup") {
|
|
428
|
-
return defaultApplicationGroup;
|
|
429
|
-
}
|
|
430
|
-
// toDO
|
|
431
|
-
throw new Error("Not Implemented yet");
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
*
|
|
436
|
-
* @param browseName
|
|
437
|
-
*/
|
|
438
|
-
getCertificateGroup(browseName) {
|
|
439
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
440
|
-
browseName = (0, node_opcua_data_model_1.coerceQualifiedName)(browseName);
|
|
441
|
-
if (browseName.toString() === "DefaultApplicationGroup") {
|
|
442
|
-
return new CertificateGroup(this.session, defaultApplicationGroup);
|
|
443
|
-
}
|
|
444
|
-
if (browseName.toString() === "DefaultUserTokenGroup") {
|
|
445
|
-
return new CertificateGroup(this.session, defaultUserTokenGroup);
|
|
446
|
-
}
|
|
447
|
-
// istanbul ignore next
|
|
448
|
-
throw new Error("Not Implemented yet");
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
getApplicationGroup() {
|
|
452
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
453
|
-
return this.getCertificateGroup("DefaultApplicationGroup");
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
getUserTokenGroup() {
|
|
457
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
458
|
-
return this.getCertificateGroup("DefaultUserTokenGroup");
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
exports.ClientPushCertificateManagement = ClientPushCertificateManagement;
|
|
463
|
-
ClientPushCertificateManagement.rsaSha256ApplicationCertificateType = (0, node_opcua_nodeid_1.resolveNodeId)("i=12560");
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ClientPushCertificateManagement = exports.CertificateGroup = exports.TrustListClient = void 0;
|
|
13
|
+
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
14
|
+
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
15
|
+
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
16
|
+
const node_opcua_file_transfer_1 = require("node-opcua-file-transfer");
|
|
17
|
+
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
18
|
+
const node_opcua_service_translate_browse_path_1 = require("node-opcua-service-translate-browse-path");
|
|
19
|
+
const node_opcua_types_1 = require("node-opcua-types");
|
|
20
|
+
const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
|
|
21
|
+
const serverConfigurationNodeId = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration");
|
|
22
|
+
const createSigningRequestMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CreateSigningRequest");
|
|
23
|
+
const getRejectedListMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_GetRejectedList");
|
|
24
|
+
const updateCertificateMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_UpdateCertificate");
|
|
25
|
+
const certificateGroups = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups");
|
|
26
|
+
const applyChangesMethod = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_ApplyChanges");
|
|
27
|
+
const supportedPrivateKeyFormatsNodeId = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_SupportedPrivateKeyFormats");
|
|
28
|
+
const defaultApplicationGroup = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups_DefaultApplicationGroup");
|
|
29
|
+
const defaultHttpsGroup = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups_DefaultHttpsGroup");
|
|
30
|
+
const defaultUserTokenGroup = (0, node_opcua_nodeid_1.resolveNodeId)("ServerConfiguration_CertificateGroups_DefaultUserTokenGroup");
|
|
31
|
+
function findCertificateGroupName(certificateGroupNodeId) {
|
|
32
|
+
return "todo";
|
|
33
|
+
}
|
|
34
|
+
function findCertificateGroupNodeId(certificateGroup) {
|
|
35
|
+
if (certificateGroup instanceof node_opcua_nodeid_1.NodeId) {
|
|
36
|
+
return certificateGroup;
|
|
37
|
+
}
|
|
38
|
+
switch (certificateGroup) {
|
|
39
|
+
case "DefaultApplicationGroup":
|
|
40
|
+
return defaultApplicationGroup;
|
|
41
|
+
case "DefaultHttpsGroup":
|
|
42
|
+
return defaultHttpsGroup;
|
|
43
|
+
case "DefaultUserTokenGroup":
|
|
44
|
+
return defaultUserTokenGroup;
|
|
45
|
+
default:
|
|
46
|
+
return (0, node_opcua_nodeid_1.resolveNodeId)(certificateGroup);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function findCertificateTypeIdNodeId(certificateTypeId) {
|
|
50
|
+
if (certificateTypeId instanceof node_opcua_nodeid_1.NodeId) {
|
|
51
|
+
return certificateTypeId;
|
|
52
|
+
}
|
|
53
|
+
return (0, node_opcua_nodeid_1.resolveNodeId)(certificateTypeId);
|
|
54
|
+
}
|
|
55
|
+
class TrustListClient extends node_opcua_file_transfer_1.ClientFile {
|
|
56
|
+
constructor(session, nodeId) {
|
|
57
|
+
super(session, nodeId);
|
|
58
|
+
this.nodeId = nodeId;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
_extractMethodIds() {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
const browseResults = yield this.session.translateBrowsePath([
|
|
66
|
+
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/CloseAndUpdate"),
|
|
67
|
+
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/AddCertificate"),
|
|
68
|
+
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/RemoveCertificate"),
|
|
69
|
+
(0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/OpenWithMasks") // OpenWithMasks Mandatory
|
|
70
|
+
]);
|
|
71
|
+
this.closeAndUpdateNodeId = browseResults[0].targets[0].targetId;
|
|
72
|
+
this.addCertificateNodeId = browseResults[1].targets[0].targetId;
|
|
73
|
+
this.removeCertificateNodeId = browseResults[2].targets[0].targetId;
|
|
74
|
+
this.openWithMasksNodeId = browseResults[3].targets[0].targetId;
|
|
75
|
+
// istanbul ignore next
|
|
76
|
+
if (!this.openWithMasksNodeId || this.openWithMasksNodeId.isEmpty()) {
|
|
77
|
+
throw new Error("Cannot find mandatory method OpenWithMask on object");
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
extractMethodsIds() {
|
|
82
|
+
const _super = Object.create(null, {
|
|
83
|
+
extractMethodsIds: { get: () => super.extractMethodsIds }
|
|
84
|
+
});
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
yield _super.extractMethodsIds.call(this);
|
|
87
|
+
yield this._extractMethodIds();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
openWithMasks(trustListMask) {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
// istanbul ignore next
|
|
93
|
+
if (this.fileHandle) {
|
|
94
|
+
throw new Error("File has already be opened");
|
|
95
|
+
}
|
|
96
|
+
yield this.ensureInitialized();
|
|
97
|
+
// istanbul ignore next
|
|
98
|
+
if (!this.openWithMasksNodeId) {
|
|
99
|
+
throw new Error("OpenWithMasks doesn't exist");
|
|
100
|
+
}
|
|
101
|
+
const inputArguments = [{ dataType: node_opcua_variant_1.DataType.UInt32, value: trustListMask }];
|
|
102
|
+
const methodToCall = {
|
|
103
|
+
inputArguments,
|
|
104
|
+
methodId: this.openWithMasksNodeId,
|
|
105
|
+
objectId: this.nodeId
|
|
106
|
+
};
|
|
107
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
108
|
+
if (callMethodResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
109
|
+
throw new Error(callMethodResult.statusCode.name);
|
|
110
|
+
}
|
|
111
|
+
this.fileHandle = callMethodResult.outputArguments[0].value;
|
|
112
|
+
return this.fileHandle;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
closeAndUpdate(applyChangesRequired) {
|
|
116
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
+
if (!this.fileHandle) {
|
|
118
|
+
throw new Error("File has node been opened yet");
|
|
119
|
+
}
|
|
120
|
+
yield this.ensureInitialized();
|
|
121
|
+
if (!this.closeAndUpdateNodeId) {
|
|
122
|
+
throw new Error("CloseAndUpdateMethod doesn't exist");
|
|
123
|
+
}
|
|
124
|
+
const inputArguments = [
|
|
125
|
+
{ dataType: node_opcua_variant_1.DataType.UInt32, value: this.fileHandle },
|
|
126
|
+
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!applyChangesRequired }
|
|
127
|
+
];
|
|
128
|
+
const methodToCall = {
|
|
129
|
+
inputArguments,
|
|
130
|
+
methodId: this.closeAndUpdateNodeId,
|
|
131
|
+
objectId: this.nodeId
|
|
132
|
+
};
|
|
133
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
134
|
+
if (callMethodResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
135
|
+
throw new Error(callMethodResult.statusCode.name);
|
|
136
|
+
}
|
|
137
|
+
return callMethodResult.outputArguments[0].value;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
addCertificate(certificate, isTrustedCertificate) {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
yield this.ensureInitialized();
|
|
143
|
+
const inputArguments = [
|
|
144
|
+
{ dataType: node_opcua_variant_1.DataType.ByteString, value: certificate },
|
|
145
|
+
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!isTrustedCertificate }
|
|
146
|
+
];
|
|
147
|
+
const methodToCall = {
|
|
148
|
+
inputArguments,
|
|
149
|
+
methodId: this.addCertificateNodeId,
|
|
150
|
+
objectId: this.nodeId
|
|
151
|
+
};
|
|
152
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
153
|
+
return callMethodResult.statusCode;
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
removeCertificate(thumbprint, isTrustedCertificate) {
|
|
157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
yield this.ensureInitialized();
|
|
159
|
+
const inputArguments = [
|
|
160
|
+
{ dataType: node_opcua_variant_1.DataType.String, value: thumbprint },
|
|
161
|
+
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!isTrustedCertificate }
|
|
162
|
+
];
|
|
163
|
+
const methodToCall = {
|
|
164
|
+
inputArguments,
|
|
165
|
+
methodId: this.removeCertificateNodeId,
|
|
166
|
+
objectId: this.nodeId
|
|
167
|
+
};
|
|
168
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
169
|
+
return callMethodResult.statusCode;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* helper function to retrieve the list of certificates ...
|
|
174
|
+
* @returns
|
|
175
|
+
*/
|
|
176
|
+
readTrustedCertificateList() {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
// const size = await this.size();
|
|
179
|
+
const fileHandle = yield this.open(node_opcua_file_transfer_1.OpenFileMode.Read);
|
|
180
|
+
const buff = yield this.read(65525);
|
|
181
|
+
yield this.close();
|
|
182
|
+
const stream = new node_opcua_binary_stream_1.BinaryStream(buff);
|
|
183
|
+
const trustList = new node_opcua_types_1.TrustListDataType();
|
|
184
|
+
trustList.decode(stream);
|
|
185
|
+
return trustList;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
readTrustedCertificateListWithMasks(trustListMask) {
|
|
189
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
190
|
+
// const size = await this.size();
|
|
191
|
+
const fileHandle = yield this.openWithMasks(trustListMask);
|
|
192
|
+
const buff = yield this.read(65525);
|
|
193
|
+
yield this.close();
|
|
194
|
+
const stream = new node_opcua_binary_stream_1.BinaryStream(buff);
|
|
195
|
+
const trustList = new node_opcua_types_1.TrustListDataType();
|
|
196
|
+
trustList.decode(stream);
|
|
197
|
+
return trustList;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
writeTrustedCertificateList(trustedList) {
|
|
201
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
202
|
+
yield this.open(node_opcua_file_transfer_1.OpenFileMode.Write);
|
|
203
|
+
const s = trustedList.binaryStoreSize();
|
|
204
|
+
const stream = new node_opcua_binary_stream_1.BinaryStream(s);
|
|
205
|
+
trustedList.encode(stream);
|
|
206
|
+
return yield this.closeAndUpdate(true);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.TrustListClient = TrustListClient;
|
|
211
|
+
class CertificateGroup {
|
|
212
|
+
constructor(session, nodeId) {
|
|
213
|
+
this.session = session;
|
|
214
|
+
this.nodeId = nodeId;
|
|
215
|
+
}
|
|
216
|
+
getCertificateTypes() {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
const browsePathResult = yield this.session.translateBrowsePath((0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/CertificateTypes"));
|
|
219
|
+
if (browsePathResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
220
|
+
throw new Error(browsePathResult.statusCode.name);
|
|
221
|
+
}
|
|
222
|
+
const certificateTypesNodeId = browsePathResult.targets[0].targetId;
|
|
223
|
+
const dataValue = yield this.session.read({ nodeId: certificateTypesNodeId, attributeId: node_opcua_data_model_1.AttributeIds.Value });
|
|
224
|
+
if (dataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
225
|
+
throw new Error(browsePathResult.statusCode.name);
|
|
226
|
+
}
|
|
227
|
+
return dataValue.value.value;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
getTrustList() {
|
|
231
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
+
const browsePathResult = yield this.session.translateBrowsePath((0, node_opcua_service_translate_browse_path_1.makeBrowsePath)(this.nodeId, "/TrustList"));
|
|
233
|
+
if (browsePathResult.statusCode !== node_opcua_status_code_1.StatusCodes.Good) {
|
|
234
|
+
throw new Error(browsePathResult.statusCode.name);
|
|
235
|
+
}
|
|
236
|
+
const trustListNodeId = browsePathResult.targets[0].targetId;
|
|
237
|
+
return new TrustListClient(this.session, trustListNodeId);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
exports.CertificateGroup = CertificateGroup;
|
|
242
|
+
class ClientPushCertificateManagement {
|
|
243
|
+
constructor(session) {
|
|
244
|
+
this.session = session;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* CreateSigningRequest Method asks the Server to create a PKCS #10 DER encoded
|
|
248
|
+
* Certificate Request that is signed with the Server’s private key. This request can be then used
|
|
249
|
+
* to request a Certificate from a CA that expects requests in this format.
|
|
250
|
+
* This Method requires an encrypted channel and that the Client provide credentials with
|
|
251
|
+
* administrative rights on the Server.
|
|
252
|
+
*
|
|
253
|
+
* @param certificateGroupId - The NodeId of the Certificate Group Object which is affected by the request.
|
|
254
|
+
* If null the DefaultApplicationGroup is used.
|
|
255
|
+
* @param certificateTypeId - The type of Certificate being requested. The set of permitted types is specified by
|
|
256
|
+
* the CertificateTypes Property belonging to the Certificate Group.
|
|
257
|
+
* @param subjectName - The subject name to use in the Certificate Request.
|
|
258
|
+
* If not specified the SubjectName from the current Certificate is used.
|
|
259
|
+
* The subjectName parameter is a sequence of X.500 name value pairs separated by a ‘/’. For
|
|
260
|
+
* example: CN=ApplicationName/OU=Group/O=Company.
|
|
261
|
+
* If the certificateType is a subtype of ApplicationCertificateType the Certificate subject name
|
|
262
|
+
* shall have an organization (O=) or domain name (DC=) field. The public key length shall meet
|
|
263
|
+
* the length restrictions for the CertificateType. The domain name field specified in the subject
|
|
264
|
+
* name is a logical domain used to qualify the subject name that may or may not be the same
|
|
265
|
+
* as a domain or IP address in the subjectAltName field of the Certificate.
|
|
266
|
+
* If the certificateType is a subtype of HttpsCertificateType the Certificate common name (CN=)
|
|
267
|
+
* shall be the same as a domain from a DiscoveryUrl which uses HTTPS and the subject name
|
|
268
|
+
* shall have an organization (O=) field.
|
|
269
|
+
* If the subjectName is blank or null the CertificateManager generates a suitable default.
|
|
270
|
+
* @param regeneratePrivateKey If TRUE the Server shall create a new Private Key which it stores until the
|
|
271
|
+
* matching signed Certificate is uploaded with the UpdateCertificate Method.
|
|
272
|
+
* Previously created Private Keys may be discarded if UpdateCertificate was not
|
|
273
|
+
* called before calling this method again. If FALSE the Server uses its existing
|
|
274
|
+
* Private Key.
|
|
275
|
+
* @param nonce Additional entropy which the caller shall provide if regeneratePrivateKey is TRUE.
|
|
276
|
+
* It shall be at least 32 bytes long.
|
|
277
|
+
*
|
|
278
|
+
* @return The PKCS #10 DER encoded Certificate Request.
|
|
279
|
+
*
|
|
280
|
+
* Result Code Description
|
|
281
|
+
* BadInvalidArgument The certificateTypeId, certificateGroupId or subjectName is not valid.
|
|
282
|
+
* BadUserAccessDenied The current user does not have the rights required.
|
|
283
|
+
*/
|
|
284
|
+
createSigningRequest(certificateGroupId, certificateTypeId, subjectName, regeneratePrivateKey, nonce) {
|
|
285
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
+
nonce = nonce || Buffer.alloc(0);
|
|
287
|
+
const inputArguments = [
|
|
288
|
+
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateGroupNodeId(certificateGroupId) },
|
|
289
|
+
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateTypeIdNodeId(certificateTypeId) },
|
|
290
|
+
{ dataType: node_opcua_variant_1.DataType.String, value: subjectName },
|
|
291
|
+
{ dataType: node_opcua_variant_1.DataType.Boolean, value: !!regeneratePrivateKey },
|
|
292
|
+
{ dataType: node_opcua_variant_1.DataType.ByteString, value: nonce }
|
|
293
|
+
];
|
|
294
|
+
const methodToCall = {
|
|
295
|
+
inputArguments,
|
|
296
|
+
methodId: createSigningRequestMethod,
|
|
297
|
+
objectId: serverConfigurationNodeId
|
|
298
|
+
};
|
|
299
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
300
|
+
if (callMethodResult.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
301
|
+
// xx console.log(callMethodResult.toString());
|
|
302
|
+
return {
|
|
303
|
+
certificateSigningRequest: callMethodResult.outputArguments[0].value,
|
|
304
|
+
statusCode: callMethodResult.statusCode
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
return { statusCode: callMethodResult.statusCode };
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* GetRejectedList Method returns the list of Certificates that have been rejected by the Server.
|
|
314
|
+
* rules are defined for how the Server updates this list or how long a Certificate is kept in
|
|
315
|
+
* the list. It is recommended that every valid but untrusted Certificate be added to the rejected
|
|
316
|
+
* list as long as storage is available. Servers should omit older entries from the list returned if
|
|
317
|
+
* the maximum message size is not large enough to allow the entire list to be returned.
|
|
318
|
+
* This Method requires an encrypted channel and that the Client provides credentials with
|
|
319
|
+
* administrative rights on the Server
|
|
320
|
+
*
|
|
321
|
+
* @return certificates The DER encoded form of the Certificates rejected by the Server
|
|
322
|
+
*/
|
|
323
|
+
getRejectedList() {
|
|
324
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
+
const inputArguments = [];
|
|
326
|
+
const methodToCall = {
|
|
327
|
+
inputArguments,
|
|
328
|
+
methodId: getRejectedListMethod,
|
|
329
|
+
objectId: serverConfigurationNodeId
|
|
330
|
+
};
|
|
331
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
332
|
+
if (callMethodResult.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
333
|
+
if (callMethodResult.outputArguments[0].dataType !== node_opcua_variant_1.DataType.ByteString) {
|
|
334
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
certificates: callMethodResult.outputArguments[0].value,
|
|
338
|
+
statusCode: callMethodResult.statusCode
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
return {
|
|
343
|
+
statusCode: callMethodResult.statusCode
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
updateCertificate(certificateGroupId, certificateTypeId, certificate, issuerCertificates, privateKeyFormat, privateKey) {
|
|
349
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
+
const inputArguments = [
|
|
351
|
+
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateGroupNodeId(certificateGroupId) },
|
|
352
|
+
{ dataType: node_opcua_variant_1.DataType.NodeId, value: findCertificateTypeIdNodeId(certificateTypeId) },
|
|
353
|
+
{ dataType: node_opcua_variant_1.DataType.ByteString, value: certificate },
|
|
354
|
+
{ dataType: node_opcua_variant_1.DataType.ByteString, arrayType: node_opcua_variant_1.VariantArrayType.Array, value: issuerCertificates },
|
|
355
|
+
{ dataType: node_opcua_variant_1.DataType.String, value: privateKeyFormat || "" },
|
|
356
|
+
{ dataType: node_opcua_variant_1.DataType.ByteString, value: privateKeyFormat ? privateKey : Buffer.alloc(0) }
|
|
357
|
+
];
|
|
358
|
+
const methodToCall = {
|
|
359
|
+
inputArguments,
|
|
360
|
+
methodId: updateCertificateMethod,
|
|
361
|
+
objectId: serverConfigurationNodeId
|
|
362
|
+
};
|
|
363
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
364
|
+
if (callMethodResult.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
365
|
+
if (!callMethodResult.outputArguments || callMethodResult.outputArguments.length !== 1) {
|
|
366
|
+
return {
|
|
367
|
+
statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError
|
|
368
|
+
};
|
|
369
|
+
// throw Error("Internal Error, expecting 1 output result");
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
applyChangesRequired: callMethodResult.outputArguments[0].value,
|
|
373
|
+
statusCode: callMethodResult.statusCode
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
return { statusCode: callMethodResult.statusCode };
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* ApplyChanges tells the Server to apply any security changes.
|
|
383
|
+
* This Method should only be called if a previous call to a Method that changed the
|
|
384
|
+
* configuration returns applyChangesRequired=true (see 7.7.4).
|
|
385
|
+
* If the Server Certificate has changed, Secure Channels using the old Certificate will
|
|
386
|
+
* eventually be interrupted. The only leeway the Server has is with the timing. In the best case,
|
|
387
|
+
* the Server can close the TransportConnections for the affected Endpoints and leave any
|
|
388
|
+
* Subscriptions intact. This should appear no different than a network interruption from the
|
|
389
|
+
* perspective of the Client. The Client should be prepared to deal with Certificate changes
|
|
390
|
+
* during its reconnect logic. In the worst case, a full shutdown which affects all connected
|
|
391
|
+
* Clients will be necessary. In the latter case, the Server shall advertise its intent to interrupt
|
|
392
|
+
* connections by setting the SecondsTillShutdown and ShutdownReason Properties in the
|
|
393
|
+
* ServerStatus Variable.
|
|
394
|
+
* If the Secure Channel being used to call this Method will be affected by the Certificate change
|
|
395
|
+
* then the Server shall introduce a delay long enough to allow the caller to receive a reply.
|
|
396
|
+
* This Method requires an encrypted channel and that the Client provide credentials with
|
|
397
|
+
* administrative rights on the Server.
|
|
398
|
+
*
|
|
399
|
+
* Result Code Description
|
|
400
|
+
* BadUserAccessDenied The current user does not have the rights required.
|
|
401
|
+
*/
|
|
402
|
+
applyChanges() {
|
|
403
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
404
|
+
const methodToCall = {
|
|
405
|
+
inputArguments: [],
|
|
406
|
+
methodId: applyChangesMethod,
|
|
407
|
+
objectId: serverConfigurationNodeId
|
|
408
|
+
};
|
|
409
|
+
const callMethodResult = yield this.session.call(methodToCall);
|
|
410
|
+
if (callMethodResult.outputArguments && callMethodResult.outputArguments.length) {
|
|
411
|
+
throw new Error("Invalid output arguments");
|
|
412
|
+
}
|
|
413
|
+
return callMethodResult.statusCode;
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
getSupportedPrivateKeyFormats() {
|
|
417
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
418
|
+
const dataValue = yield this.session.read({
|
|
419
|
+
attributeId: node_opcua_data_model_1.AttributeIds.Value,
|
|
420
|
+
nodeId: supportedPrivateKeyFormatsNodeId
|
|
421
|
+
});
|
|
422
|
+
return dataValue.value.value;
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
getCertificateGroupId(certificateGroupName) {
|
|
426
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
427
|
+
if (certificateGroupName === "DefaultApplicationGroup") {
|
|
428
|
+
return defaultApplicationGroup;
|
|
429
|
+
}
|
|
430
|
+
// toDO
|
|
431
|
+
throw new Error("Not Implemented yet");
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
*
|
|
436
|
+
* @param browseName
|
|
437
|
+
*/
|
|
438
|
+
getCertificateGroup(browseName) {
|
|
439
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
440
|
+
browseName = (0, node_opcua_data_model_1.coerceQualifiedName)(browseName);
|
|
441
|
+
if (browseName.toString() === "DefaultApplicationGroup") {
|
|
442
|
+
return new CertificateGroup(this.session, defaultApplicationGroup);
|
|
443
|
+
}
|
|
444
|
+
if (browseName.toString() === "DefaultUserTokenGroup") {
|
|
445
|
+
return new CertificateGroup(this.session, defaultUserTokenGroup);
|
|
446
|
+
}
|
|
447
|
+
// istanbul ignore next
|
|
448
|
+
throw new Error("Not Implemented yet");
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
getApplicationGroup() {
|
|
452
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
453
|
+
return this.getCertificateGroup("DefaultApplicationGroup");
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
getUserTokenGroup() {
|
|
457
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
458
|
+
return this.getCertificateGroup("DefaultUserTokenGroup");
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
exports.ClientPushCertificateManagement = ClientPushCertificateManagement;
|
|
463
|
+
ClientPushCertificateManagement.rsaSha256ApplicationCertificateType = (0, node_opcua_nodeid_1.resolveNodeId)("i=12560");
|
|
464
464
|
//# sourceMappingURL=push_certificate_management_client.js.map
|