Skip to content

Commit

Permalink
Merge 798646a into 06dc420
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Dec 15, 2022
2 parents 06dc420 + 798646a commit 209e81c
Show file tree
Hide file tree
Showing 40 changed files with 328 additions and 278 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/workflow.yml
Expand Up @@ -55,6 +55,7 @@ jobs:
- run: pnpm recursive install --no-frozen-lockfile
- run: pnpm run build
- run: hostname
- run: openssl version
- run: pnpm run pretest
- run: pnpm test
coverage:
Expand All @@ -78,6 +79,7 @@ jobs:
- run: pnpm recursive install --no-frozen-lockfile
- run: pnpm run build
- run: hostname
- run: openssl version
- run: pnpm run pretest
- run: make test-cov

Expand Down
22 changes: 10 additions & 12 deletions documentation/sample_server.js
@@ -1,9 +1,7 @@
const os = require("os");
const { OPCUAServer, Variant, DataType, StatusCodes } = require("node-opcua");


(async () => {

// Let's create an instance of OPCUAServer
const server = new OPCUAServer({
port: 4334, // the port of the listening socket of the server
Expand All @@ -15,7 +13,6 @@ const { OPCUAServer, Variant, DataType, StatusCodes } = require("node-opcua");
}
});
await server.initialize();
console.log("initialized");

const addressSpace = server.engine.addressSpace;
const namespace = addressSpace.getOwnNamespace();
Expand All @@ -29,29 +26,32 @@ const { OPCUAServer, Variant, DataType, StatusCodes } = require("node-opcua");
// add some variables
// add a variable named MyVariable1 to the newly created folder "MyDevice"


const variable1 = namespace.addVariable({
componentOf: device,
browseName: "MyVariable1",
dataType: "Double",
minimumSamplingInterval: 100,
minimumSamplingInterval: 100
});

let counter = 0;
// emulate variable1 changing every 500 ms
const timerId = setInterval(() => { counter += 1; variable1.setValueFromSource({ dataType: DataType.Double, value: counter }) }, 500);
const timerId = setInterval(() => {
counter += 1;
variable1.setValueFromSource({ dataType: DataType.Double, value: counter });
}, 500);

addressSpace.registerShutdownTask(() => { clearInterval(timerId); });
addressSpace.registerShutdownTask(() => {
clearInterval(timerId);
});

// add a variable named MyVariable2 to the newly created folder "MyDevice"

namespace.addVariable({

componentOf: device,
nodeId: "ns=1;b=1020FFAA", // some opaque NodeId in namespace 4
browseName: "MyVariable2",
dataType: "Double",
minimumSamplingInterval: 0, // this variable will be event driven
minimumSamplingInterval: 0 // this variable will be event driven
});

/**
Expand All @@ -60,11 +60,10 @@ const { OPCUAServer, Variant, DataType, StatusCodes } = require("node-opcua");
*/
function available_memory() {
// var value = process.memoryUsage().heapUsed / 1000000;
const percentageMemUsed = os.freemem() / os.totalmem() * 100.0;
const percentageMemUsed = (os.freemem() / os.totalmem()) * 100.0;
return percentageMemUsed;
}
namespace.addVariable({

componentOf: device,

nodeId: "s=free_memory", // a string nodeID
Expand All @@ -85,5 +84,4 @@ const { OPCUAServer, Variant, DataType, StatusCodes } = require("node-opcua");
console.log("shuting down");
await server.shutdown();
});

})();
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -132,8 +132,8 @@
"memfs": "^3.4.12",
"mkdirp": "1.0.4",
"mocha-clean": "^1.0.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-pki": "^2.18.4",
"node-opcua-crypto": "^2.1.2",
"node-opcua-pki": "^3.0.1",
"object.values": "^1.1.6",
"once": "^1.4.0",
"pretty-ms": "^8.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/node-opcua-address-space-base/package.json
Expand Up @@ -18,7 +18,7 @@
"dependencies": {
"node-opcua-basic-types": "2.85.0",
"node-opcua-constants": "2.77.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-crypto": "^2.1.2",
"node-opcua-data-model": "2.85.0",
"node-opcua-data-value": "2.85.0",
"node-opcua-date-time": "2.85.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/node-opcua-address-space/package.json
Expand Up @@ -28,7 +28,7 @@
"node-opcua-binary-stream": "2.85.0",
"node-opcua-client-dynamic-extension-object": "2.85.0",
"node-opcua-constants": "2.77.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-crypto": "^2.1.2",
"node-opcua-data-access": "2.85.0",
"node-opcua-data-model": "2.85.0",
"node-opcua-data-value": "2.85.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/node-opcua-certificate-manager/package.json
Expand Up @@ -16,10 +16,10 @@
"env-paths": "2.2.1",
"mkdirp": "1.0.4",
"node-opcua-assert": "2.77.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-crypto": "^2.1.2",
"node-opcua-debug": "2.85.0",
"node-opcua-object-registry": "2.85.0",
"node-opcua-pki": "^2.18.4",
"node-opcua-pki": "^3.0.1",
"node-opcua-status-code": "2.85.0",
"thenify": "^3.3.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/node-opcua-client-crawler/package.json
Expand Up @@ -22,7 +22,7 @@
"node-opcua-data-value": "2.85.0",
"node-opcua-debug": "2.85.0",
"node-opcua-nodeid": "2.85.0",
"node-opcua-pki": "^2.18.4",
"node-opcua-pki": "^3.0.1",
"node-opcua-service-browse": "2.85.0",
"node-opcua-status-code": "2.85.0",
"node-opcua-types": "2.85.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/node-opcua-client/package.json
Expand Up @@ -26,7 +26,7 @@
"node-opcua-client-dynamic-extension-object": "2.85.0",
"node-opcua-common": "2.85.0",
"node-opcua-constants": "2.77.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-crypto": "^2.1.2",
"node-opcua-data-model": "2.85.0",
"node-opcua-data-value": "2.85.0",
"node-opcua-date-time": "2.85.0",
Expand All @@ -35,7 +35,7 @@
"node-opcua-hostname": "2.77.0",
"node-opcua-nodeid": "2.85.0",
"node-opcua-object-registry": "2.85.0",
"node-opcua-pki": "^2.18.4",
"node-opcua-pki": "^3.0.1",
"node-opcua-pseudo-session": "2.85.0",
"node-opcua-schemas": "2.85.0",
"node-opcua-secure-channel": "2.85.0",
Expand Down
17 changes: 15 additions & 2 deletions packages/node-opcua-client/source/private/client_base_impl.ts
Expand Up @@ -579,9 +579,10 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
"the server certificate has changed, we need to retrieve server certificate again: ",
err.message
);
const oldServerCertificate = this.serverCertificate;
warningLog(
"old server certificate ",
this.serverCertificate ? makeSHA1Thumbprint(this.serverCertificate!).toString("hex") : "undefined"
oldServerCertificate ? makeSHA1Thumbprint(oldServerCertificate!).toString("hex") : "undefined"
);
// the server may have shut down the channel because its certificate
// has changed ....
Expand All @@ -590,7 +591,19 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
if (err1) {
return _failAndRetry(err1, "Failing to fetch new server certificate", callback);
}
warningLog("new server certificate ", makeSHA1Thumbprint(this.serverCertificate!).toString("hex"));
const newServerCertificate = this.serverCertificate!;
warningLog("new server certificate ", makeSHA1Thumbprint(newServerCertificate).toString("hex"));

const sha1Old = makeSHA1Thumbprint(oldServerCertificate!);
const sha1New = makeSHA1Thumbprint(newServerCertificate);
if (sha1Old === sha1New) {
warningLog("server certificate has not changed, but was expected to have changed");
return _failAndRetry(
new Error("Server Certificate not changed"),
"Failing to fetch new server certificate",
callback
);
}
this._internal_create_secure_channel(infiniteConnectionRetry, (err3?: Error | null) => {
if (err3) {
return _failAndRetry(err3, "trying to create new channel with new certificate", callback);
Expand Down
14 changes: 7 additions & 7 deletions packages/node-opcua-client/source/private/opcua_client_impl.ts
Expand Up @@ -6,6 +6,7 @@
// tslint:disable:no-empty

import * as crypto from "crypto";
import { createPublicKey } from "crypto";
import { callbackify } from "util";
import * as async from "async";
import * as chalk from "chalk";
Expand All @@ -17,22 +18,21 @@ import {
exploreCertificate,
extractPublicKeyFromCertificateSync,
Nonce,
PrivateKey,
PrivateKeyPEM,
toPem
} from "node-opcua-crypto";

import { LocalizedText } from "node-opcua-data-model";
import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
import { extractFullyQualifiedDomainName, getHostname, resolveFullyQualifiedDomainName } from "node-opcua-hostname";
import { extractFullyQualifiedDomainName } from "node-opcua-hostname";
import { ClientSecureChannelLayer, computeSignature, fromURI, getCryptoFactory, SecurityPolicy } from "node-opcua-secure-channel";
import { ApplicationDescriptionOptions, ApplicationType, EndpointDescription, UserTokenType } from "node-opcua-service-endpoints";
import { MessageSecurityMode, UserTokenPolicy } from "node-opcua-service-secure-channel";
import {
ActivateSessionRequest,
ActivateSessionResponse,
AnonymousIdentityToken,
CloseSessionRequest,
CloseSessionResponse,
CreateSessionRequest,
CreateSessionResponse,
UserNameIdentityToken,
Expand All @@ -41,7 +41,7 @@ import {
import { CallbackT, StatusCode, StatusCodes } from "node-opcua-status-code";
import { ErrorCallback, Callback } from "node-opcua-status-code";

import { SignatureData, SignatureDataOptions, UserIdentityToken } from "node-opcua-types";
import { SignatureDataOptions, UserIdentityToken } from "node-opcua-types";
import { isNullOrUndefined, matchUri } from "node-opcua-utils";

import { ClientSession } from "../client_session";
Expand Down Expand Up @@ -132,7 +132,7 @@ interface X509TokenAndSignature {
function createX509IdentityToken(
context: IdentityTokenContext,
certificate: Certificate,
privateKey: PrivateKeyPEM
privateKey: PrivateKey
): X509TokenAndSignature {
const endpoint = context.endpoint;
assert(endpoint instanceof EndpointDescription);
Expand Down Expand Up @@ -250,7 +250,7 @@ function createUserNameIdentityToken(

assert(serverCertificate instanceof Buffer);
serverCertificate = toPem(serverCertificate, "CERTIFICATE");
const publicKey = extractPublicKeyFromCertificateSync(serverCertificate);
const publicKey = createPublicKey(extractPublicKeyFromCertificateSync(serverCertificate));

const serverNonce: Nonce = session.serverNonce || Buffer.alloc(0);
assert(serverNonce instanceof Buffer);
Expand Down Expand Up @@ -1236,7 +1236,7 @@ export class OPCUAClientImpl extends ClientBaseImpl implements OPCUAClient {

case UserTokenType.Certificate: {
const certificate = userIdentityInfo.certificateData;
const privateKey = userIdentityInfo.privateKey;
const privateKey = crypto.createPrivateKey(userIdentityInfo.privateKey);
({ userIdentityToken, userTokenSignature } = createX509IdentityToken(context, certificate, privateKey));
break;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/node-opcua-client/source/verify.ts
@@ -1,3 +1,4 @@
import { createPrivateKey } from "crypto";
import { OPCUACertificateManager } from "node-opcua-certificate-manager";
import { OPCUASecureObject } from "node-opcua-common";

Expand Down Expand Up @@ -126,7 +127,7 @@ export async function performCertificateSanityCheck(
): Promise<void> {
// verify that certificate is matching private key, and inform the developper if not
const certificate = this.getCertificate();
const privateKey = convertPEMtoDER(this.getPrivateKey());
const privateKey = this.getPrivateKey();
//
if (!publicKeyAndPrivateKeyMatches(certificate, privateKey)) {
errorLog("[NODE-OPCUA-E01] Configuration error : the certificate and the private key do not match !");
Expand Down
6 changes: 3 additions & 3 deletions packages/node-opcua-client/test/test_x509_signature.ts
Expand Up @@ -8,7 +8,7 @@ import "mocha";
import { assert } from "node-opcua-assert";
import { decodeExpandedNodeId } from "node-opcua-basic-types";
import { BinaryStream } from "node-opcua-binary-stream";
import { Certificate, PrivateKeyPEM, readCertificate, readPrivateKeyPEM, split_der } from "node-opcua-crypto";
import { Certificate, PrivateKey, readCertificate, readPrivateKey, split_der } from "node-opcua-crypto";
import { makeBufferFromTrace } from "node-opcua-debug";
import { BaseUAObject, getStandardDataTypeFactory } from "node-opcua-factory";
import {
Expand Down Expand Up @@ -104,7 +104,7 @@ const verifyX509UserIdentity1 = promisify(verifyX509UserIdentity);
function rebuildSignature(
certificate: Certificate, // server certificate
serverNonce: Buffer,
privateKey: PrivateKeyPEM,
privateKey: PrivateKey,
securityPolicy: SecurityPolicy
) {
// The signature generated with private key associated with the User Certificate
Expand Down Expand Up @@ -135,7 +135,7 @@ describe("X509 - Wireshark Analysis", () => {
};

const userCertificate = readCertificate(path.join(__dirname, "./fixtures/user1_certificate.pem"));
const privateKey = readPrivateKeyPEM(path.join(__dirname, "./fixtures/private_key.pem"));
const privateKey = readPrivateKey(path.join(__dirname, "./fixtures/private_key.pem"));

const signatureData = rebuildSignature(serverCertificate, serverNonce, privateKey, securityPolicy);

Expand Down
2 changes: 1 addition & 1 deletion packages/node-opcua-common/package.json
Expand Up @@ -12,7 +12,7 @@
"types": "./dist/index.d.ts",
"dependencies": {
"node-opcua-assert": "2.77.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-crypto": "^2.1.2",
"node-opcua-types": "2.85.0"
},
"devDependencies": {
Expand Down
19 changes: 10 additions & 9 deletions packages/node-opcua-common/source/opcua_secure_object.ts
@@ -1,29 +1,30 @@
/**
* @module node-opcua-common
*/
import { createPrivateKey } from "crypto";
import { EventEmitter } from "events";
import * as fs from "fs";

import { assert } from "node-opcua-assert";
import { Certificate, PrivateKeyPEM, readCertificate, readKeyPem, split_der } from "node-opcua-crypto";
import { Certificate, PrivateKey, readCertificate, readPrivateKey, split_der } from "node-opcua-crypto";

export interface ICertificateKeyPairProvider {
getCertificate(): Certificate;
getCertificateChain(): Certificate;
getPrivateKey(): PrivateKeyPEM;
getPrivateKey(): PrivateKey;
}
export interface ICertificateKeyPairProviderPriv extends ICertificateKeyPairProvider {
$$certificate: null | Certificate;
$$certificateChain: null | Certificate;
$$privateKeyPEM: null | PrivateKeyPEM;
$$privateKey: null | PrivateKey;
}
function _load_certificate(certificateFilename: string): Certificate {
const der = readCertificate(certificateFilename);
return der;
}

function _load_private_key_pem(privateKeyFilename: string): PrivateKeyPEM {
return readKeyPem(privateKeyFilename);
function _load_private_key(privateKeyFilename: string): PrivateKey {
return readPrivateKey(privateKeyFilename);
}

export interface IOPCUASecureObjectOptions {
Expand Down Expand Up @@ -74,12 +75,12 @@ export class OPCUASecureObject extends EventEmitter implements ICertificateKeyPa
return priv.$$certificateChain;
}

public getPrivateKey(): PrivateKeyPEM {
public getPrivateKey(): PrivateKey {
const priv = this as unknown as ICertificateKeyPairProviderPriv;
if (!priv.$$privateKeyPEM) {
if (!priv.$$privateKey) {
assert(fs.existsSync(this.privateKeyFile), "private file must exist :" + this.privateKeyFile);
priv.$$privateKeyPEM = _load_private_key_pem(this.privateKeyFile);
priv.$$privateKey = _load_private_key(this.privateKeyFile);
}
return priv.$$privateKeyPEM;
return priv.$$privateKey;
}
}
4 changes: 2 additions & 2 deletions packages/node-opcua-end2end-test/package.json
Expand Up @@ -26,7 +26,7 @@
"node-opcua-client-crawler": "2.85.0",
"node-opcua-client-proxy": "2.85.0",
"node-opcua-constants": "2.77.0",
"node-opcua-crypto": "^1.12.0",
"node-opcua-crypto": "^2.1.2",
"node-opcua-debug": "2.85.0",
"node-opcua-extension-object": "2.85.0",
"node-opcua-factory": "2.85.0",
Expand All @@ -35,7 +35,7 @@
"node-opcua-nodeid": "2.85.0",
"node-opcua-nodeset-ijt": "2.85.0",
"node-opcua-packet-analyzer": "2.85.0",
"node-opcua-pki": "^2.18.4",
"node-opcua-pki": "^3.0.1",
"node-opcua-server": "2.85.0",
"node-opcua-server-discovery": "2.85.0",
"node-opcua-service-browse": "2.85.0",
Expand Down

0 comments on commit 209e81c

Please sign in to comment.