Skip to content

Commit

Permalink
use server certificate manager registering client
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Feb 8, 2021
1 parent 048f917 commit f27efa6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 34 deletions.
Expand Up @@ -74,7 +74,7 @@ export class OPCUACertificateManager extends CertificateManager implements ICert
public static defaultCertificateSubject = "/O=Sterfive/L=Orleans/C=FR";

public static registry = new ObjectRegistry({});
public isShared: boolean;
public referenceCounter: number;
public automaticallyAcceptUnknownCertificate: boolean;
/* */
constructor(options: OPCUACertificateManagerOptions) {
Expand All @@ -91,7 +91,7 @@ export class OPCUACertificateManager extends CertificateManager implements ICert
};
super(_options);

this.isShared = false;
this.referenceCounter = 0;

this.automaticallyAcceptUnknownCertificate = !!options.automaticallyAcceptUnknownCertificate;
}
Expand All @@ -108,12 +108,14 @@ export class OPCUACertificateManager extends CertificateManager implements ICert
}

public async dispose(): Promise<void> {
if (!this.isShared) {
if (this.referenceCounter === 0) {
if (this.initialized) {
// OPCUACertificateManager.registry.unregister(this);
}
await super.dispose();
this.initialized = false;
} else {
this.referenceCounter--;
}
}

Expand Down
Expand Up @@ -15,7 +15,8 @@ import {
TimestampsToReturn,
ErrorCallback,
ApplicationType,
ClientSession
ClientSession,
OPCUACertificateManager
} from "node-opcua";

import { make_debugLog, checkDebugFlag } from "node-opcua-debug";
Expand Down Expand Up @@ -299,8 +300,9 @@ module.exports = () => {

it("T0g- registration manager as a standalone object 2/2", function (done) {
const registrationManager = new RegisterServerManager({
discoveryServerEndpointUrl: "opc.tcp://localhost:48481", //<< not existing
discoveryServerEndpointUrl: "opc.tcp://localhost:48481", // << not existing
server: {
serverCertificateManager: new OPCUACertificateManager({}),
certificateFile: "",
privateKeyFile: "",
capabilitiesForMDNS: [],
Expand Down Expand Up @@ -335,6 +337,7 @@ module.exports = () => {
const registrationManager = new RegisterServerManager({
discoveryServerEndpointUrl,
server: {
serverCertificateManager: new OPCUACertificateManager({}),
certificateFile: "",
privateKeyFile: "",
capabilitiesForMDNS: [],
Expand Down
14 changes: 5 additions & 9 deletions packages/node-opcua-secure-channel/test/test_security.ts
Expand Up @@ -46,14 +46,10 @@ fs.existsSync(certificateFolder).should.eql(true, "expecting certificate store a
// tslint:disable:no-var-requires
const describe = require("node-opcua-leak-detector").describeWithLeakDetector;
describe("Testing secure client and server connection", () => {

const certificateManager = new OPCUACertificateManager({

});

const certificateManager = new OPCUACertificateManager({});

before(async () => {
certificateManager.isShared = true;
certificateManager.referenceCounter++;
await certificateManager.initialize();
const issuerCertificateFile = path.join(certificateFolder, "CA/public/cacert.pem");
const issuerCertificate = readCertificate(issuerCertificateFile);
Expand All @@ -63,9 +59,9 @@ describe("Testing secure client and server connection", () => {
const crl = await readCertificateRevocationList(issuerCertificateRevocationListFile);
await certificateManager.addRevocationList(crl);
});
after(()=> {
certificateManager.isShared = false;

after(() => {
certificateManager.referenceCounter--;
certificateManager.dispose();
});

Expand Down
56 changes: 36 additions & 20 deletions packages/node-opcua-server/source/register_server_manager.ts
Expand Up @@ -28,6 +28,7 @@ import {
import { ApplicationType, EndpointDescription, MdnsDiscoveryConfiguration, RegisteredServerOptions } from "node-opcua-types";
import { IRegisterServerManager } from "./i_register_server_manager";
import { exploreCertificate } from "node-opcua-crypto";
import { OPCUACertificateManager } from "node-opcua-certificate-manager";

const doDebug = checkDebugFlag(__filename);
const debugLog = make_debugLog(__filename);
Expand Down Expand Up @@ -109,7 +110,7 @@ function findSecureEndpoint(endpoints: EndpointDescription[]): EndpointDescripti
return endpoints[0];
}

function constructRegisteredServer(server: _IServer, isOnline: boolean): RegisteredServerOptions {
function constructRegisteredServer(server: IPartialServer, isOnline: boolean): RegisteredServerOptions {
const discoveryUrls = server.getDiscoveryUrls();
assert(!isOnline || discoveryUrls.length >= 1, "expecting some discoveryUrls if we go online ....");

Expand All @@ -119,11 +120,17 @@ function constructRegisteredServer(server: _IServer, isOnline: boolean): Registe
const serverUri = info.tbsCertificate.extensions?.subjectAltName.uniformResourceIdentifier[0];
// istanbul ignore next
if (serverUri !== server.serverInfo.applicationUri) {
console.log(chalk.yellow("Warning certificate uniformResourceIdentifier doesn't match serverInfo.applicationUri"));
console.log(" subjectKeyIdentifier : ", info.tbsCertificate.extensions?.subjectKeyIdentifier);
console.log(" subjectAltName : ", info.tbsCertificate.extensions?.subjectAltName);
console.log(" commonName : ", info.tbsCertificate.subject.commonName!);
console.log(" serverInfo.applicationUri : ", server.serverInfo.applicationUri);
warningLog(
chalk.yellow("Warning certificate uniformResourceIdentifier doesn't match serverInfo.applicationUri"),
"\n subjectKeyIdentifier : ",
info.tbsCertificate.extensions?.subjectKeyIdentifier,
"\n subjectAltName : ",
info.tbsCertificate.extensions?.subjectAltName,
"\n commonName : ",
info.tbsCertificate.subject.commonName!,
"\n serverInfo.applicationUri : ",
server.serverInfo.applicationUri
);
}

// istanbul ignore next
Expand Down Expand Up @@ -153,14 +160,14 @@ function constructRegisteredServer(server: _IServer, isOnline: boolean): Registe
};
return s;
}
function constructRegisterServerRequest(serverB: _IServer, isOnline: boolean): RegisterServerRequest {
function constructRegisterServerRequest(serverB: IPartialServer, isOnline: boolean): RegisterServerRequest {
const server = constructRegisteredServer(serverB, isOnline);
return new RegisterServerRequest({
server
});
}

function constructRegisterServer2Request(serverB: _IServer, isOnline: boolean): RegisterServer2Request {
function constructRegisterServer2Request(serverB: IPartialServer, isOnline: boolean): RegisterServer2Request {
const server = constructRegisteredServer(serverB, isOnline);

return new RegisterServer2Request({
Expand Down Expand Up @@ -194,7 +201,7 @@ interface ClientBaseEx extends OPCUAClientBase {
performMessageTransaction(request: RegisterServerRequest, callback: ResponseCallback<RegisterServerResponse>): void;
}

function sendRegisterServerRequest(server: _IServer, client: ClientBaseEx, isOnline: boolean, callback: ErrorCallback) {
function sendRegisterServerRequest(server: IPartialServer, client: ClientBaseEx, isOnline: boolean, callback: ErrorCallback) {
// try to send a RegisterServer2Request
const request = constructRegisterServer2Request(server, isOnline);

Expand All @@ -209,7 +216,6 @@ function sendRegisterServerRequest(server: _IServer, client: ClientBaseEx, isOnl
debugLog("RegisterServerManager#_registerServer" + " falling back to using sendRegisterServerRequest instead");
// fall back to
const request1 = constructRegisterServerRequest(server, isOnline);
// xx console.log("request",request.toString());
client.performMessageTransaction(request1, (err1: Error | null, response1?: RegisterServerResponse) => {
if (!err1) {
debugLog(
Expand All @@ -231,7 +237,8 @@ function sendRegisterServerRequest(server: _IServer, client: ClientBaseEx, isOnl
});
}

export interface _IServer {
export interface IPartialServer {
serverCertificateManager: OPCUACertificateManager;
certificateFile: string;
privateKeyFile: string;
serverType: ApplicationType;
Expand All @@ -245,7 +252,7 @@ export interface _IServer {
getCertificate(): Buffer;
}
export interface RegisterServerManagerOptions {
server: _IServer;
server: IPartialServer;
discoveryServerEndpointUrl: string;
}
/**
Expand Down Expand Up @@ -287,7 +294,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
public discoveryServerEndpointUrl: string;
public timeout: number;

private server: _IServer | null;
private server: IPartialServer | null;
private _registrationTimerId: NodeJS.Timer | null;
private state: RegisterServerManagerStatus = RegisterServerManagerStatus.INACTIVE;
private _registration_client: OPCUAClientBase | null = null;
Expand Down Expand Up @@ -383,6 +390,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
this.selectedEndpoint = undefined;

// Retry Strategy must be set
this.server.serverCertificateManager.referenceCounter++;
const client = OPCUAClientBase.create({
clientName: this.server.serverInfo.applicationUri!,

Expand All @@ -392,6 +400,8 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ

connectionStrategy: infinite_connectivity_strategy,

clientCertificateManager: this.server.serverCertificateManager,

certificateFile: this.server.certificateFile,
privateKeyFile: this.server.privateKeyFile
}) as ClientBaseEx;
Expand Down Expand Up @@ -597,15 +607,18 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
const selectedEndpoint = this.selectedEndpoint;

if (!selectedEndpoint) {
console.log("Warning : cannot register server - no endpoint available");
warningLog("Warning : cannot register server - no endpoint available");
return outer_callback(new Error("Cannot registerServer"));
}

server.serverCertificateManager.referenceCounter++;
const options: OPCUAClientBaseOptions = {
securityMode: selectedEndpoint.securityMode,
securityPolicy: coerceSecurityPolicy(selectedEndpoint.securityPolicyUri),
serverCertificate: selectedEndpoint.serverCertificate,

clientCertificateManager: server.serverCertificateManager,

certificateFile: server.certificateFile,
privateKeyFile: server.privateKeyFile,

Expand Down Expand Up @@ -643,14 +656,17 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
"RegisterServerManager#_registerServer " +
"=> please check that you server certificate is trusted by the LDS"
);
console.log(
warningLog(
"RegisterServer to the LDS has failed during secure connection " +
"=> please check that you server certificate is trusted by the LDS. err: " +
err.message
"=> please check that you server certificate is trusted by the LDS.",
"\nerr: " + err.message,
"\nLDS endpoint :",
selectedEndpoint?.endpointUrl!,
"\nsecurity mode :",
MessageSecurityMode[selectedEndpoint.securityMode],
"\nsecurity policy :",
coerceSecurityPolicy(selectedEndpoint.securityPolicyUri)
);
console.log("LDS endpoint :", selectedEndpoint?.endpointUrl!);
console.log("security mode :", MessageSecurityMode[selectedEndpoint.securityMode]);
console.log("security policy :", coerceSecurityPolicy(selectedEndpoint.securityPolicyUri));
// xx debugLog(options);
client.disconnect(() => {
debugLog("RegisterServerManager#_registerServer client disconnected");
Expand Down

0 comments on commit f27efa6

Please sign in to comment.