node-opcua-server-configuration 2.71.0 → 2.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 -465
- package/dist/clientTools/push_certificate_management_client.js.map +1 -1
- 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_CertificateAlarm.d.ts +11 -5
- package/dist/server/install_CertificateAlarm.js +45 -37
- package/dist/server/install_CertificateAlarm.js.map +1 -1
- package/dist/server/install_certificate_file_watcher.d.ts +5 -0
- package/dist/server/install_certificate_file_watcher.js +24 -0
- package/dist/server/install_certificate_file_watcher.js.map +1 -0
- package/dist/server/install_push_certitifate_management.d.ts +19 -15
- package/dist/server/install_push_certitifate_management.js +213 -214
- package/dist/server/install_push_certitifate_management.js.map +1 -1
- 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 -7
- package/dist/server/push_certificate_manager_helpers.js +409 -306
- 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/push_certificate_manager_server_impl.js.map +1 -1
- 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/tools.js.map +1 -1
- package/dist/server/trust_list_server.d.ts +13 -13
- package/dist/server/trust_list_server.js +89 -89
- package/dist/server/trust_list_server.js.map +1 -1
- 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 +12 -10
- package/source/clientTools/push_certificate_management_client.ts +16 -37
- package/source/server/install_CertificateAlarm.ts +35 -29
- package/source/server/install_certificate_file_watcher.ts +25 -0
- package/source/server/install_push_certitifate_management.ts +8 -8
- package/source/server/push_certificate_manager_helpers.ts +142 -26
- package/source/server/push_certificate_manager_server_impl.ts +6 -7
- package/source/server/tools.ts +1 -1
- package/source/server/trust_list_server.ts +3 -3
- package/dist/push_certificate_manager_helpers.d.ts +0 -6
- package/dist/push_certificate_manager_helpers.js +0 -221
- package/dist/push_certificate_manager_helpers.js.map +0 -1
package/dist/trust_list.d.ts
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { StatusCode } from "node-opcua-basic-types";
|
|
3
|
-
/**
|
|
4
|
-
* @module node-opcua-server-configuration
|
|
5
|
-
*/
|
|
6
|
-
export interface ITrustList {
|
|
7
|
-
/**
|
|
8
|
-
* The CloseAndUpdate Method closes the file and applies the changes to the Trust List. It can
|
|
9
|
-
* only be called if the file was opened for writing. If the Close Method is called any cached data
|
|
10
|
-
* is discarded and the Trust List is not changed.
|
|
11
|
-
*
|
|
12
|
-
* The Server shall verify that every Certificate in the new Trust List is valid according to the
|
|
13
|
-
* mandatory rules defined in Part 4. If an invalid Certificate is found the Server shall return an
|
|
14
|
-
* error and shall not update the Trust List. If only part of the Trust List is being updated the
|
|
15
|
-
* Server creates a temporary Trust List that includes the existing Trust List plus any updates
|
|
16
|
-
* and validates the temporary Trust List.
|
|
17
|
-
*
|
|
18
|
-
* If the file cannot be processed this Method still closes the file and discards the data before
|
|
19
|
-
* returning an error. This Method is required if the Server supports updates to the Trust List.
|
|
20
|
-
* The structure uploaded includes a mask (see 7.5.8) which specifies which fields are updated.
|
|
21
|
-
* If a bit is not set then the associated field is not changed.
|
|
22
|
-
*
|
|
23
|
-
* @param fileHandle UInt32 - The handle of the previously opened file
|
|
24
|
-
* @return applyChangesRequired - A flag indicating whether the ApplyChanges Method (see 7.7.5) shall be called
|
|
25
|
-
* before the new Trust List will be used by the Server.
|
|
26
|
-
* **Result Code**
|
|
27
|
-
* - BadUserAccessDenied The current user does not have the rights required.
|
|
28
|
-
* - BadCertificateInvalid The Server could not validate all Certificates in the Trust List.
|
|
29
|
-
* The DiagnosticInfo shall specify which Certificate(s) are invalid and the specific
|
|
30
|
-
* error.
|
|
31
|
-
*/
|
|
32
|
-
closeAndUpdate(applyChangesRequired: boolean): Promise<boolean>;
|
|
33
|
-
/**
|
|
34
|
-
* The AddCertificate Method allows a Client to add a single Certificate to the Trust List.
|
|
35
|
-
*
|
|
36
|
-
* The Server shall verify that the Certificate is valid according to the rules defined in Part 4.
|
|
37
|
-
*
|
|
38
|
-
* If an invalid Certificate is found the Server shall return an error and shall not update the Trust List.
|
|
39
|
-
*
|
|
40
|
-
* If the Certificate is issued by a CA then the Client shall provide the entire chain in the
|
|
41
|
-
* certificate argument (see Part 6).
|
|
42
|
-
*
|
|
43
|
-
* After validating the Certificate, the Server shall add the CA Certificates to the Issuers list in the Trust List.
|
|
44
|
-
*
|
|
45
|
-
* The leaf Certificate is added to the list specified by the isTrustedCertificate argument.
|
|
46
|
-
*
|
|
47
|
-
* This method cannot be called if the file object is open
|
|
48
|
-
* @param certificate - The DER encoded Certificate to add as a ByteStrng
|
|
49
|
-
* @param isTrustedCertificate - If TRUE the Certificate is added to the Trusted Certificates List. If FALSE the Certificate is added to the Issuer Certificates List.
|
|
50
|
-
*
|
|
51
|
-
* **Result Code**
|
|
52
|
-
* - BadUserAccessDenied: The current user does not have the rights required.
|
|
53
|
-
* - BadCertificateInvalid: The certificate to add is invalid.
|
|
54
|
-
* - BadInvalidState: The object is opened.
|
|
55
|
-
*
|
|
56
|
-
*/
|
|
57
|
-
addCertificate(certificate: Buffer, isTrustedCertificate: boolean): Promise<StatusCode>;
|
|
58
|
-
/**
|
|
59
|
-
* The RemoveCertificate Method allows a Client to remove a single Certificate from the Trust List.
|
|
60
|
-
*
|
|
61
|
-
* It returns BadInvalidArgument if the thumbprint does not match a Certificate in the Trust List.
|
|
62
|
-
*
|
|
63
|
-
* If the Certificate is a CA Certificate with associated CRLs then all CRLs are removed as well.
|
|
64
|
-
*
|
|
65
|
-
* This method cannot be called if the file object is open.
|
|
66
|
-
*
|
|
67
|
-
* @param thumbprint - The SHA1 hash of the Certificate to remove
|
|
68
|
-
* @param isTrustedCertificate - If TRUE the Certificate is removed from the Trusted Certificates List.
|
|
69
|
-
* If FALSE the Certificate is removed from the Issuer Certificates List.
|
|
70
|
-
*
|
|
71
|
-
* **Result Code**
|
|
72
|
-
* -BadUserAccessDenied: The current user does not have the rights required.
|
|
73
|
-
* -BadInvalidArgument: The certificate to remove was not found.
|
|
74
|
-
* -BadInvalidState: The object is opened.
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*/
|
|
78
|
-
removeCertificate(thumbprint: string, isTrustedCertificate: boolean): Promise<StatusCode>;
|
|
79
|
-
}
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { StatusCode } from "node-opcua-basic-types";
|
|
3
|
+
/**
|
|
4
|
+
* @module node-opcua-server-configuration
|
|
5
|
+
*/
|
|
6
|
+
export interface ITrustList {
|
|
7
|
+
/**
|
|
8
|
+
* The CloseAndUpdate Method closes the file and applies the changes to the Trust List. It can
|
|
9
|
+
* only be called if the file was opened for writing. If the Close Method is called any cached data
|
|
10
|
+
* is discarded and the Trust List is not changed.
|
|
11
|
+
*
|
|
12
|
+
* The Server shall verify that every Certificate in the new Trust List is valid according to the
|
|
13
|
+
* mandatory rules defined in Part 4. If an invalid Certificate is found the Server shall return an
|
|
14
|
+
* error and shall not update the Trust List. If only part of the Trust List is being updated the
|
|
15
|
+
* Server creates a temporary Trust List that includes the existing Trust List plus any updates
|
|
16
|
+
* and validates the temporary Trust List.
|
|
17
|
+
*
|
|
18
|
+
* If the file cannot be processed this Method still closes the file and discards the data before
|
|
19
|
+
* returning an error. This Method is required if the Server supports updates to the Trust List.
|
|
20
|
+
* The structure uploaded includes a mask (see 7.5.8) which specifies which fields are updated.
|
|
21
|
+
* If a bit is not set then the associated field is not changed.
|
|
22
|
+
*
|
|
23
|
+
* @param fileHandle UInt32 - The handle of the previously opened file
|
|
24
|
+
* @return applyChangesRequired - A flag indicating whether the ApplyChanges Method (see 7.7.5) shall be called
|
|
25
|
+
* before the new Trust List will be used by the Server.
|
|
26
|
+
* **Result Code**
|
|
27
|
+
* - BadUserAccessDenied The current user does not have the rights required.
|
|
28
|
+
* - BadCertificateInvalid The Server could not validate all Certificates in the Trust List.
|
|
29
|
+
* The DiagnosticInfo shall specify which Certificate(s) are invalid and the specific
|
|
30
|
+
* error.
|
|
31
|
+
*/
|
|
32
|
+
closeAndUpdate(applyChangesRequired: boolean): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* The AddCertificate Method allows a Client to add a single Certificate to the Trust List.
|
|
35
|
+
*
|
|
36
|
+
* The Server shall verify that the Certificate is valid according to the rules defined in Part 4.
|
|
37
|
+
*
|
|
38
|
+
* If an invalid Certificate is found the Server shall return an error and shall not update the Trust List.
|
|
39
|
+
*
|
|
40
|
+
* If the Certificate is issued by a CA then the Client shall provide the entire chain in the
|
|
41
|
+
* certificate argument (see Part 6).
|
|
42
|
+
*
|
|
43
|
+
* After validating the Certificate, the Server shall add the CA Certificates to the Issuers list in the Trust List.
|
|
44
|
+
*
|
|
45
|
+
* The leaf Certificate is added to the list specified by the isTrustedCertificate argument.
|
|
46
|
+
*
|
|
47
|
+
* This method cannot be called if the file object is open
|
|
48
|
+
* @param certificate - The DER encoded Certificate to add as a ByteStrng
|
|
49
|
+
* @param isTrustedCertificate - If TRUE the Certificate is added to the Trusted Certificates List. If FALSE the Certificate is added to the Issuer Certificates List.
|
|
50
|
+
*
|
|
51
|
+
* **Result Code**
|
|
52
|
+
* - BadUserAccessDenied: The current user does not have the rights required.
|
|
53
|
+
* - BadCertificateInvalid: The certificate to add is invalid.
|
|
54
|
+
* - BadInvalidState: The object is opened.
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
addCertificate(certificate: Buffer, isTrustedCertificate: boolean): Promise<StatusCode>;
|
|
58
|
+
/**
|
|
59
|
+
* The RemoveCertificate Method allows a Client to remove a single Certificate from the Trust List.
|
|
60
|
+
*
|
|
61
|
+
* It returns BadInvalidArgument if the thumbprint does not match a Certificate in the Trust List.
|
|
62
|
+
*
|
|
63
|
+
* If the Certificate is a CA Certificate with associated CRLs then all CRLs are removed as well.
|
|
64
|
+
*
|
|
65
|
+
* This method cannot be called if the file object is open.
|
|
66
|
+
*
|
|
67
|
+
* @param thumbprint - The SHA1 hash of the Certificate to remove
|
|
68
|
+
* @param isTrustedCertificate - If TRUE the Certificate is removed from the Trusted Certificates List.
|
|
69
|
+
* If FALSE the Certificate is removed from the Issuer Certificates List.
|
|
70
|
+
*
|
|
71
|
+
* **Result Code**
|
|
72
|
+
* -BadUserAccessDenied: The current user does not have the rights required.
|
|
73
|
+
* -BadInvalidArgument: The certificate to remove was not found.
|
|
74
|
+
* -BadInvalidState: The object is opened.
|
|
75
|
+
*
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
removeCertificate(thumbprint: string, isTrustedCertificate: boolean): Promise<StatusCode>;
|
|
79
|
+
}
|
package/dist/trust_list.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//# sourceMappingURL=trust_list.js.map
|
package/dist/trust_list_impl.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// /**
|
|
3
|
-
// * @module node-opcua-server-configuration
|
|
4
|
-
// */
|
|
5
|
-
// import { StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
6
|
-
// import { ITrustList } from "./trust_list";
|
|
7
|
-
// export class TrustList implements ITrustList {
|
|
8
|
-
// public async closeAndUpdate(
|
|
9
|
-
// applyChangesRequired: boolean
|
|
10
|
-
// ): Promise<boolean> {
|
|
11
|
-
// return false;
|
|
12
|
-
// }
|
|
13
|
-
// public async addCertificate(
|
|
14
|
-
// certificate: Buffer,
|
|
15
|
-
// isTrustedCertificate: boolean
|
|
16
|
-
// ): Promise<StatusCode> {
|
|
17
|
-
// return StatusCodes.BadNotImplemented;
|
|
18
|
-
// }
|
|
19
|
-
// public async removeCertificate(
|
|
20
|
-
// thumbprint: string,
|
|
21
|
-
// isTrustedCertificate: boolean
|
|
22
|
-
// ): Promise<StatusCode> {
|
|
23
|
-
// return StatusCodes.BadNotImplemented;
|
|
24
|
-
// }
|
|
25
|
-
// }
|
|
1
|
+
"use strict";
|
|
2
|
+
// /**
|
|
3
|
+
// * @module node-opcua-server-configuration
|
|
4
|
+
// */
|
|
5
|
+
// import { StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
6
|
+
// import { ITrustList } from "./trust_list";
|
|
7
|
+
// export class TrustList implements ITrustList {
|
|
8
|
+
// public async closeAndUpdate(
|
|
9
|
+
// applyChangesRequired: boolean
|
|
10
|
+
// ): Promise<boolean> {
|
|
11
|
+
// return false;
|
|
12
|
+
// }
|
|
13
|
+
// public async addCertificate(
|
|
14
|
+
// certificate: Buffer,
|
|
15
|
+
// isTrustedCertificate: boolean
|
|
16
|
+
// ): Promise<StatusCode> {
|
|
17
|
+
// return StatusCodes.BadNotImplemented;
|
|
18
|
+
// }
|
|
19
|
+
// public async removeCertificate(
|
|
20
|
+
// thumbprint: string,
|
|
21
|
+
// isTrustedCertificate: boolean
|
|
22
|
+
// ): Promise<StatusCode> {
|
|
23
|
+
// return StatusCodes.BadNotImplemented;
|
|
24
|
+
// }
|
|
25
|
+
// }
|
|
26
26
|
//# sourceMappingURL=trust_list_impl.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-opcua-server-configuration",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.72.0",
|
|
4
4
|
"description": "pure nodejs OPCUA SDK - module -server",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsc -b",
|
|
@@ -12,26 +12,28 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"memfs": "^3.4.7",
|
|
15
|
-
"node-opcua-address-space": "2.
|
|
15
|
+
"node-opcua-address-space": "2.72.0",
|
|
16
|
+
"node-opcua-address-space-base": "2.72.0",
|
|
16
17
|
"node-opcua-assert": "2.66.0",
|
|
17
18
|
"node-opcua-basic-types": "2.71.0",
|
|
18
19
|
"node-opcua-certificate-manager": "2.71.0",
|
|
19
|
-
"node-opcua-client": "2.
|
|
20
|
+
"node-opcua-client": "2.72.0",
|
|
21
|
+
"node-opcua-common": "2.72.0",
|
|
20
22
|
"node-opcua-constants": "2.70.0",
|
|
21
23
|
"node-opcua-crypto": "^1.11.0",
|
|
22
24
|
"node-opcua-data-model": "2.71.0",
|
|
23
25
|
"node-opcua-debug": "2.71.0",
|
|
24
|
-
"node-opcua-file-transfer": "2.
|
|
26
|
+
"node-opcua-file-transfer": "2.72.0",
|
|
25
27
|
"node-opcua-hostname": "2.67.0",
|
|
26
28
|
"node-opcua-nodeid": "2.71.0",
|
|
27
29
|
"node-opcua-nodesets": "2.71.0",
|
|
28
30
|
"node-opcua-pki": "^2.17.0",
|
|
29
|
-
"node-opcua-pseudo-session": "2.
|
|
30
|
-
"node-opcua-secure-channel": "2.
|
|
31
|
-
"node-opcua-server": "2.
|
|
32
|
-
"node-opcua-service-translate-browse-path": "2.
|
|
31
|
+
"node-opcua-pseudo-session": "2.72.0",
|
|
32
|
+
"node-opcua-secure-channel": "2.72.0",
|
|
33
|
+
"node-opcua-server": "2.72.0",
|
|
34
|
+
"node-opcua-service-translate-browse-path": "2.72.0",
|
|
33
35
|
"node-opcua-status-code": "2.71.0",
|
|
34
|
-
"node-opcua-types": "2.
|
|
36
|
+
"node-opcua-types": "2.72.0",
|
|
35
37
|
"node-opcua-variant": "2.71.0",
|
|
36
38
|
"rimraf": "^3.0.2"
|
|
37
39
|
},
|
|
@@ -57,5 +59,5 @@
|
|
|
57
59
|
"internet of things"
|
|
58
60
|
],
|
|
59
61
|
"homepage": "http://node-opcua.github.io/",
|
|
60
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "3c5f00e20bf5bef91a1ca3663af149b903760e5c"
|
|
61
63
|
}
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
import { ITrustList } from "../trust_list";
|
|
24
24
|
import { TrustListMasks } from "../server/trust_list_server";
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
const serverConfigurationNodeId = resolveNodeId("ServerConfiguration");
|
|
28
27
|
const createSigningRequestMethod = resolveNodeId("ServerConfiguration_CreateSigningRequest");
|
|
29
28
|
const getRejectedListMethod = resolveNodeId("ServerConfiguration_GetRejectedList");
|
|
@@ -41,7 +40,6 @@ function findCertificateGroupName(certificateGroupNodeId: NodeId): string {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
function findCertificateGroupNodeId(certificateGroup: NodeId | string): NodeId {
|
|
44
|
-
|
|
45
43
|
if (certificateGroup instanceof NodeId) {
|
|
46
44
|
return certificateGroup;
|
|
47
45
|
}
|
|
@@ -64,10 +62,7 @@ function findCertificateTypeIdNodeId(certificateTypeId: NodeId | string): NodeId
|
|
|
64
62
|
return resolveNodeId(certificateTypeId);
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
65
|
export class TrustListClient extends ClientFile implements ITrustList {
|
|
70
|
-
|
|
71
66
|
private closeAndUpdateNodeId?: NodeId;
|
|
72
67
|
private addCertificateNodeId?: NodeId;
|
|
73
68
|
private removeCertificateNodeId?: NodeId;
|
|
@@ -80,12 +75,11 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
80
75
|
* @private
|
|
81
76
|
*/
|
|
82
77
|
async _extractMethodIds(): Promise<void> {
|
|
83
|
-
|
|
84
78
|
const browseResults = await this.session.translateBrowsePath([
|
|
85
|
-
makeBrowsePath(this.nodeId, "/CloseAndUpdate"),
|
|
86
|
-
makeBrowsePath(this.nodeId, "/AddCertificate"),
|
|
79
|
+
makeBrowsePath(this.nodeId, "/CloseAndUpdate"), // Optional
|
|
80
|
+
makeBrowsePath(this.nodeId, "/AddCertificate"), // Optional
|
|
87
81
|
makeBrowsePath(this.nodeId, "/RemoveCertificate"), // Optional
|
|
88
|
-
makeBrowsePath(this.nodeId, "/OpenWithMasks")
|
|
82
|
+
makeBrowsePath(this.nodeId, "/OpenWithMasks") // OpenWithMasks Mandatory
|
|
89
83
|
]);
|
|
90
84
|
|
|
91
85
|
this.closeAndUpdateNodeId = browseResults[0].targets![0].targetId;
|
|
@@ -114,9 +108,7 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
114
108
|
if (!this.openWithMasksNodeId) {
|
|
115
109
|
throw new Error("OpenWithMasks doesn't exist");
|
|
116
110
|
}
|
|
117
|
-
const inputArguments = [
|
|
118
|
-
{ dataType: DataType.UInt32, value: trustListMask },
|
|
119
|
-
];
|
|
111
|
+
const inputArguments = [{ dataType: DataType.UInt32, value: trustListMask }];
|
|
120
112
|
const methodToCall: CallMethodRequestLike = {
|
|
121
113
|
inputArguments,
|
|
122
114
|
methodId: this.openWithMasksNodeId,
|
|
@@ -140,7 +132,7 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
140
132
|
}
|
|
141
133
|
const inputArguments = [
|
|
142
134
|
{ dataType: DataType.UInt32, value: this.fileHandle },
|
|
143
|
-
{ dataType: DataType.Boolean, value: !!applyChangesRequired }
|
|
135
|
+
{ dataType: DataType.Boolean, value: !!applyChangesRequired }
|
|
144
136
|
];
|
|
145
137
|
const methodToCall: CallMethodRequestLike = {
|
|
146
138
|
inputArguments,
|
|
@@ -159,7 +151,7 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
159
151
|
|
|
160
152
|
const inputArguments: VariantLike[] = [
|
|
161
153
|
{ dataType: DataType.ByteString, value: certificate },
|
|
162
|
-
{ dataType: DataType.Boolean, value: !!isTrustedCertificate }
|
|
154
|
+
{ dataType: DataType.Boolean, value: !!isTrustedCertificate }
|
|
163
155
|
];
|
|
164
156
|
const methodToCall: CallMethodRequestLike = {
|
|
165
157
|
inputArguments,
|
|
@@ -175,7 +167,7 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
175
167
|
|
|
176
168
|
const inputArguments: VariantLike[] = [
|
|
177
169
|
{ dataType: DataType.String, value: thumbprint },
|
|
178
|
-
{ dataType: DataType.Boolean, value: !!isTrustedCertificate }
|
|
170
|
+
{ dataType: DataType.Boolean, value: !!isTrustedCertificate }
|
|
179
171
|
];
|
|
180
172
|
const methodToCall: CallMethodRequestLike = {
|
|
181
173
|
inputArguments,
|
|
@@ -188,7 +180,7 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
188
180
|
|
|
189
181
|
/**
|
|
190
182
|
* helper function to retrieve the list of certificates ...
|
|
191
|
-
* @returns
|
|
183
|
+
* @returns
|
|
192
184
|
*/
|
|
193
185
|
async readTrustedCertificateList(): Promise<TrustListDataType> {
|
|
194
186
|
// const size = await this.size();
|
|
@@ -218,13 +210,9 @@ export class TrustListClient extends ClientFile implements ITrustList {
|
|
|
218
210
|
trustedList.encode(stream);
|
|
219
211
|
return await this.closeAndUpdate(true);
|
|
220
212
|
}
|
|
221
|
-
|
|
222
213
|
}
|
|
223
214
|
export class CertificateGroup {
|
|
224
|
-
|
|
225
|
-
constructor(public session: IBasicSession, public nodeId: NodeId) {
|
|
226
|
-
|
|
227
|
-
}
|
|
215
|
+
constructor(public session: IBasicSession, public nodeId: NodeId) {}
|
|
228
216
|
async getCertificateTypes(): Promise<NodeId[]> {
|
|
229
217
|
const browsePathResult = await this.session.translateBrowsePath(makeBrowsePath(this.nodeId, "/CertificateTypes"));
|
|
230
218
|
if (browsePathResult.statusCode !== StatusCodes.Good) {
|
|
@@ -244,12 +232,9 @@ export class CertificateGroup {
|
|
|
244
232
|
}
|
|
245
233
|
const trustListNodeId = browsePathResult.targets![0].targetId;
|
|
246
234
|
return new TrustListClient(this.session, trustListNodeId);
|
|
247
|
-
|
|
248
235
|
}
|
|
249
|
-
|
|
250
236
|
}
|
|
251
237
|
export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
252
|
-
|
|
253
238
|
public static rsaSha256ApplicationCertificateType: NodeId = resolveNodeId("i=12560");
|
|
254
239
|
|
|
255
240
|
public session: IBasicSession;
|
|
@@ -303,7 +288,6 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
303
288
|
regeneratePrivateKey?: boolean,
|
|
304
289
|
nonce?: ByteString
|
|
305
290
|
): Promise<CreateSigningRequestResult> {
|
|
306
|
-
|
|
307
291
|
nonce = nonce || Buffer.alloc(0);
|
|
308
292
|
|
|
309
293
|
const inputArguments = [
|
|
@@ -428,7 +412,6 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
428
412
|
privateKeyFormat?: string,
|
|
429
413
|
privateKey?: Buffer
|
|
430
414
|
): Promise<UpdateCertificateResult> {
|
|
431
|
-
|
|
432
415
|
const inputArguments: VariantLike[] = [
|
|
433
416
|
{ dataType: DataType.NodeId, value: findCertificateGroupNodeId(certificateGroupId) },
|
|
434
417
|
{ dataType: DataType.NodeId, value: findCertificateTypeIdNodeId(certificateTypeId) },
|
|
@@ -481,7 +464,6 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
481
464
|
* BadUserAccessDenied The current user does not have the rights required.
|
|
482
465
|
*/
|
|
483
466
|
public async applyChanges(): Promise<StatusCode> {
|
|
484
|
-
|
|
485
467
|
const methodToCall: CallMethodRequestLike = {
|
|
486
468
|
inputArguments: [],
|
|
487
469
|
methodId: applyChangesMethod,
|
|
@@ -496,7 +478,6 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
496
478
|
}
|
|
497
479
|
|
|
498
480
|
public async getSupportedPrivateKeyFormats(): Promise<string[]> {
|
|
499
|
-
|
|
500
481
|
const dataValue = await this.session.read({
|
|
501
482
|
attributeId: AttributeIds.Value,
|
|
502
483
|
nodeId: supportedPrivateKeyFormatsNodeId
|
|
@@ -505,7 +486,6 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
505
486
|
}
|
|
506
487
|
|
|
507
488
|
public async getCertificateGroupId(certificateGroupName: string): Promise<NodeId> {
|
|
508
|
-
|
|
509
489
|
if (certificateGroupName === "DefaultApplicationGroup") {
|
|
510
490
|
return defaultApplicationGroup;
|
|
511
491
|
}
|
|
@@ -513,20 +493,19 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
513
493
|
throw new Error("Not Implemented yet");
|
|
514
494
|
}
|
|
515
495
|
|
|
516
|
-
|
|
517
|
-
|
|
518
496
|
/**
|
|
519
|
-
*
|
|
520
|
-
* @param browseName
|
|
497
|
+
*
|
|
498
|
+
* @param browseName
|
|
521
499
|
*/
|
|
522
500
|
public async getCertificateGroup(
|
|
523
|
-
browseName: QualifiedNameLike | "DefaultApplicationGroup" | "DefaultUserTokenGroup"
|
|
501
|
+
browseName: QualifiedNameLike | "DefaultApplicationGroup" | "DefaultUserTokenGroup"
|
|
502
|
+
): Promise<CertificateGroup> {
|
|
524
503
|
browseName = coerceQualifiedName(browseName);
|
|
525
504
|
if (browseName.toString() === "DefaultApplicationGroup") {
|
|
526
|
-
return new CertificateGroup(this.session,
|
|
505
|
+
return new CertificateGroup(this.session, defaultApplicationGroup);
|
|
527
506
|
}
|
|
528
507
|
if (browseName.toString() === "DefaultUserTokenGroup") {
|
|
529
|
-
return new CertificateGroup(this.session,
|
|
508
|
+
return new CertificateGroup(this.session, defaultUserTokenGroup);
|
|
530
509
|
}
|
|
531
510
|
// istanbul ignore next
|
|
532
511
|
throw new Error("Not Implemented yet");
|
|
@@ -535,6 +514,6 @@ export class ClientPushCertificateManagement implements PushCertificateManager {
|
|
|
535
514
|
return this.getCertificateGroup("DefaultApplicationGroup");
|
|
536
515
|
}
|
|
537
516
|
public async getUserTokenGroup(): Promise<CertificateGroup> {
|
|
538
|
-
return this.getCertificateGroup("
|
|
517
|
+
return this.getCertificateGroup("DefaultUserTokenGroup");
|
|
539
518
|
}
|
|
540
519
|
}
|
|
@@ -3,48 +3,54 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
5
|
AddressSpace,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
BaseNode,
|
|
7
|
+
UACertificateExpirationAlarmEx,
|
|
8
|
+
UACertificateExpirationAlarmImpl,
|
|
9
|
+
UAObject
|
|
8
10
|
} from "node-opcua-address-space";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "node-opcua-debug";
|
|
14
|
-
import {
|
|
15
|
-
NodeId
|
|
16
|
-
} from "node-opcua-nodeid";
|
|
11
|
+
import { InstantiateOffNormalAlarmOptions } from "node-opcua-address-space/src/alarms_and_conditions/ua_off_normal_alarm_impl";
|
|
12
|
+
import { coerceQualifiedName, NodeClass } from "node-opcua-data-model";
|
|
13
|
+
import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
|
|
14
|
+
import { NodeId, sameNodeId } from "node-opcua-nodeid";
|
|
17
15
|
import { DataType } from "node-opcua-variant";
|
|
18
16
|
|
|
19
17
|
const debugLog = make_debugLog("ServerConfiguration");
|
|
20
18
|
const errorLog = make_errorLog("ServerConfiguration");
|
|
21
19
|
const doDebug = checkDebugFlag("ServerConfiguration");
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param addressSpace
|
|
24
|
+
* @returns
|
|
25
|
+
* @deprecated
|
|
26
|
+
*/
|
|
27
|
+
export function installCertificateExpirationAlarm(addressSpace: AddressSpace): UACertificateExpirationAlarmEx {
|
|
25
28
|
debugLog("installCertificateExpirationAlarm");
|
|
26
|
-
|
|
29
|
+
/**
|
|
30
|
+
* note: the ServerCertificateAlarm is not in the OPCUA standard
|
|
31
|
+
*/
|
|
27
32
|
const server = addressSpace.rootFolder.objects.server;
|
|
28
|
-
|
|
29
33
|
const namespace = addressSpace.getOwnNamespace();
|
|
30
34
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const options = {
|
|
35
|
+
const options: InstantiateOffNormalAlarmOptions = {
|
|
34
36
|
browseName: "ServerCertificateAlarm",
|
|
35
|
-
conditionSource:
|
|
37
|
+
conditionSource: undefined,
|
|
36
38
|
eventSourceOf: server,
|
|
37
39
|
inputNode: new NodeId(),
|
|
38
|
-
normalState: new NodeId()
|
|
40
|
+
normalState: new NodeId(),
|
|
41
|
+
optionals: ["ExpirationLimit"]
|
|
39
42
|
};
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
const certificateExpirationAlarm = UACertificateExpirationAlarmImpl.instantiate(
|
|
44
|
+
namespace,
|
|
45
|
+
"CertificateExpirationAlarmType",
|
|
46
|
+
options
|
|
47
|
+
);
|
|
48
|
+
certificateExpirationAlarm.currentBranch().setRetain(false);
|
|
49
|
+
certificateExpirationAlarm.activeState.setValue(false);
|
|
50
|
+
certificateExpirationAlarm.ackedState.setValue(false);
|
|
51
|
+
certificateExpirationAlarm.suppressedState?.setValue(false);
|
|
52
|
+
certificateExpirationAlarm.certificate.setValueFromSource({ dataType: DataType.ByteString, value: null });
|
|
53
|
+
certificateExpirationAlarm.eventId.setValueFromSource({ dataType: DataType.ByteString, value: null });
|
|
54
|
+
|
|
55
|
+
return certificateExpirationAlarm;
|
|
50
56
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { UAObject } from "node-opcua-address-space-base";
|
|
4
|
+
import { make_debugLog } from "node-opcua-debug";
|
|
5
|
+
|
|
6
|
+
const debugLog = make_debugLog("ServerConfiguration");
|
|
7
|
+
|
|
8
|
+
export interface ChangeDetector {
|
|
9
|
+
on(eventName: "certificateChange", handler: () => void): this;
|
|
10
|
+
}
|
|
11
|
+
export function installCertificateFileWatcher(node: UAObject, certificateFile: string): ChangeDetector {
|
|
12
|
+
const fileToWatch = path.basename(certificateFile);
|
|
13
|
+
const fsWatcher = fs.watch(path.dirname(certificateFile), { persistent: false }, (eventType: "rename" | "change", filename) => {
|
|
14
|
+
/** */
|
|
15
|
+
if (filename === fileToWatch) {
|
|
16
|
+
debugLog("filename changed = ", filename, fileToWatch);
|
|
17
|
+
node.emit("certificateChange");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const addressSpace = node.addressSpace!;
|
|
21
|
+
addressSpace.registerShutdownTask(() => {
|
|
22
|
+
fsWatcher.close();
|
|
23
|
+
});
|
|
24
|
+
return node as unknown as ChangeDetector;
|
|
25
|
+
}
|
|
@@ -7,13 +7,14 @@ import * as path from "path";
|
|
|
7
7
|
|
|
8
8
|
import * as chalk from "chalk";
|
|
9
9
|
|
|
10
|
-
import { UAServerConfiguration } from "node-opcua-address-space";
|
|
10
|
+
import { UAServerConfiguration, AddressSpace } from "node-opcua-address-space";
|
|
11
11
|
import { assert } from "node-opcua-assert";
|
|
12
12
|
import { OPCUACertificateManager } from "node-opcua-certificate-manager";
|
|
13
13
|
import { Certificate, convertPEMtoDER, makeSHA1Thumbprint, PrivateKeyPEM, split_der } from "node-opcua-crypto";
|
|
14
14
|
import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
|
|
15
15
|
import { getFullyQualifiedDomainName } from "node-opcua-hostname";
|
|
16
16
|
import { ICertificateKeyPairProvider } from "node-opcua-secure-channel";
|
|
17
|
+
import { ICertificateKeyPairProviderPriv } from "node-opcua-common";
|
|
17
18
|
import { OPCUAServer, OPCUAServerEndPoint } from "node-opcua-server";
|
|
18
19
|
import { ApplicationDescriptionOptions } from "node-opcua-types";
|
|
19
20
|
import { installPushCertificateManagement } from "./push_certificate_manager_helpers";
|
|
@@ -26,15 +27,15 @@ const debugLog = make_debugLog("ServerConfiguration");
|
|
|
26
27
|
const errorLog = make_errorLog("ServerConfiguration");
|
|
27
28
|
const doDebug = checkDebugFlag("ServerConfiguration");
|
|
28
29
|
|
|
29
|
-
export interface OPCUAServerPartial extends
|
|
30
|
+
export interface OPCUAServerPartial extends ICertificateKeyPairProviderPriv {
|
|
30
31
|
serverInfo?: ApplicationDescriptionOptions;
|
|
31
32
|
serverCertificateManager: OPCUACertificateManager;
|
|
32
33
|
privateKeyFile: string;
|
|
33
34
|
certificateFile: string;
|
|
34
|
-
|
|
35
|
-
$$
|
|
36
|
-
$$
|
|
37
|
-
|
|
35
|
+
$$certificate: null | Certificate;
|
|
36
|
+
$$certificateChain: null | Certificate;
|
|
37
|
+
$$privateKeyPEM: null | PrivateKeyPEM;
|
|
38
|
+
engine: { addressSpace?: AddressSpace };
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
function getCertificate(this: OPCUAServerPartial): Certificate {
|
|
@@ -176,7 +177,7 @@ async function onCertificateChange(server: OPCUAServer) {
|
|
|
176
177
|
_server.$$certificateChain = convertPEMtoDER(certificatePEM);
|
|
177
178
|
_server.$$privateKeyPEM = privateKeyPEM;
|
|
178
179
|
// note : $$certificate will be reconstructed on demand
|
|
179
|
-
_server.$$certificate =
|
|
180
|
+
_server.$$certificate = split_der(_server.$$certificateChain)[0];
|
|
180
181
|
|
|
181
182
|
setTimeout(async () => {
|
|
182
183
|
try {
|
|
@@ -190,7 +191,6 @@ async function onCertificateChange(server: OPCUAServer) {
|
|
|
190
191
|
|
|
191
192
|
debugLog(chalk.yellow("channels have been closed -> client should reconnect "));
|
|
192
193
|
} catch (err) {
|
|
193
|
-
// tslint:disable:no-console
|
|
194
194
|
if (err instanceof Error) {
|
|
195
195
|
errorLog("Error in CertificateChanged handler ", err.message);
|
|
196
196
|
}
|