@@ -17,8 +17,6 @@ import { Subscription } from "rxjs/Subscription";
1717import { promisify } from "util" ;
1818import { Readable } from "stream" ;
1919import { URL } from "url" ;
20- import path from "path" ;
21- import envPath from "env-paths" ;
2220import {
2321 ProtocolClient ,
2422 Content ,
@@ -54,25 +52,23 @@ import {
5452 getBuiltInDataType ,
5553 readNamespaceArray ,
5654 UserIdentityInfo ,
57- UserIdentityInfoUserName ,
58- UserIdentityInfoX509 ,
5955} from "node-opcua-pseudo-session" ;
6056import { makeNodeId , NodeId , NodeIdLike , NodeIdType , resolveNodeId } from "node-opcua-nodeid" ;
6157import { AttributeIds , BrowseDirection , makeResultMask } from "node-opcua-data-model" ;
6258import { makeBrowsePath } from "node-opcua-service-translate-browse-path" ;
6359import { StatusCodes } from "node-opcua-status-code" ;
64- import { coercePrivateKeyPem , convertPEMtoDER , readPrivateKey } from "node-opcua-crypto" ;
60+ import { coercePrivateKeyPem , readPrivateKey } from "node-opcua-crypto" ;
6561import { opcuaJsonEncodeVariant } from "node-opcua-json" ;
6662import { Argument , BrowseDescription , BrowseResult , MessageSecurityMode , UserTokenType } from "node-opcua-types" ;
67- import { isGoodish2 , OPCUACertificateManager , ReferenceTypeIds } from "node-opcua" ;
63+ import { isGoodish2 , ReferenceTypeIds } from "node-opcua" ;
6864
6965import { schemaDataValue } from "./codec" ;
7066import { OPCUACAuthenticationScheme , OPCUAChannelSecurityScheme } from "./security_scheme" ;
67+ import { CertificateManagerSingleton } from "./certificate-manager-singleton" ;
68+ import { resolveChannelSecurity , resolvedUserIdentity } from "./opcua-security-resolver" ;
7169
7270const { debug } = createLoggers ( "binding-opcua" , "opcua-protocol-client" ) ;
7371
74- const env = envPath ( "binding-opcua" , { suffix : "node-wot" } ) ;
75-
7672export type Command = "Read" | "Write" | "Subscribe" ;
7773
7874export interface NodeByBrowsePath {
@@ -167,32 +163,6 @@ export class OPCUAProtocolClient implements ProtocolClient {
167163 private _securityPolicy : SecurityPolicy = SecurityPolicy . None ;
168164 private _userIdentity : UserIdentityInfo = < AnonymousIdentity > { type : UserTokenType . Anonymous } ;
169165
170- private static _certificateManager : OPCUACertificateManager | null = null ;
171-
172- public static async getCertificateManager ( ) : Promise < OPCUACertificateManager > {
173- if ( OPCUAProtocolClient . _certificateManager ) {
174- return OPCUAProtocolClient . _certificateManager ;
175- }
176- const rootFolder = path . join ( env . config , "PKI" ) ;
177- debug ( "OPCUA PKI folder" , rootFolder ) ;
178- const certificateManager = new OPCUACertificateManager ( {
179- rootFolder,
180- } ) ;
181- await certificateManager . initialize ( ) ;
182- certificateManager . referenceCounter ++ ;
183- OPCUAProtocolClient . _certificateManager = certificateManager ;
184- return certificateManager ;
185- }
186-
187- public static releaseCertificateManager ( ) : void {
188- if ( OPCUAProtocolClient . _certificateManager ) {
189- OPCUAProtocolClient . _certificateManager . referenceCounter -- ;
190- // dispose is degined to free resources if referenceCounter==0;
191- OPCUAProtocolClient . _certificateManager . dispose ( ) ;
192- OPCUAProtocolClient . _certificateManager = null ;
193- }
194- }
195-
196166 private async _withConnection < T > ( form : OPCUAForm , next : ( connection : OPCUAConnection ) => Promise < T > ) : Promise < T > {
197167 const endpoint = form . href ;
198168 const matchesScheme : boolean = endpoint ?. match ( / ^ o p c .t c p : \/ \/ / ) != null ;
@@ -202,7 +172,7 @@ export class OPCUAProtocolClient implements ProtocolClient {
202172 }
203173 let c : OPCUAConnectionEx | undefined = this . _connections . get ( endpoint ) ;
204174 if ( ! c ) {
205- const clientCertificateManager = await OPCUAProtocolClient . getCertificateManager ( ) ;
175+ const clientCertificateManager = await CertificateManagerSingleton . getCertificateManager ( ) ;
206176 const client = OPCUAClient . create ( {
207177 endpointMustExist : false ,
208178 connectionStrategy : {
@@ -540,57 +510,18 @@ export class OPCUAProtocolClient implements ProtocolClient {
540510 await connection . session . close ( ) ;
541511 await connection . client . disconnect ( ) ;
542512 }
543- await OPCUAProtocolClient . _certificateManager ?. dispose ( ) ;
513+ CertificateManagerSingleton . releaseCertificateManager ( ) ;
544514 }
545515
546- private setChannelSecurity ( security : OPCUAChannelSecurityScheme ) : boolean {
547- const foundSecurity = SecurityPolicy [ security . policy as keyof typeof SecurityPolicy ] ;
548-
549- if ( foundSecurity === undefined ) {
550- return false ;
551- }
552-
553- this . _securityPolicy = foundSecurity ;
554-
555- switch ( security . messageMode ) {
556- case "sign" :
557- this . _securityMode = MessageSecurityMode . Sign ;
558- break ;
559- case "sign_encrypt" :
560- this . _securityMode = MessageSecurityMode . SignAndEncrypt ;
561- break ;
562- default :
563- this . _securityMode = MessageSecurityMode . None ;
564- break ;
565- }
566-
516+ #setChannelSecurity( security : OPCUAChannelSecurityScheme ) : boolean {
517+ const { messageSecurityMode, securityPolicy } = resolveChannelSecurity ( security ) ;
518+ this . _securityMode = messageSecurityMode ;
519+ this . _securityPolicy = securityPolicy ;
567520 return true ;
568521 }
569522
570- private setAuthentication ( security : OPCUACAuthenticationScheme ) : boolean {
571- switch ( security . tokenType ) {
572- case "username" :
573- this . _userIdentity = < UserIdentityInfoUserName > {
574- type : UserTokenType . UserName ,
575- password : security . password ,
576- userName : security . userName ,
577- } ;
578- break ;
579- case "certificate" :
580- this . _userIdentity = < UserIdentityInfoX509 > {
581- type : UserTokenType . Certificate ,
582- certificateData : convertPEMtoDER ( security . certificate ) ,
583- privateKey : security . privateKey ,
584- } ;
585- break ;
586- case "anonymous" :
587- this . _userIdentity = < UserIdentityInfo > {
588- type : UserTokenType . Anonymous ,
589- } ;
590- break ;
591- default :
592- return false ;
593- }
523+ #setAuthentication( security : OPCUACAuthenticationScheme ) : boolean {
524+ this . _userIdentity = resolvedUserIdentity ( security ) ;
594525 return true ;
595526 }
596527
@@ -599,10 +530,10 @@ export class OPCUAProtocolClient implements ProtocolClient {
599530 let success = true ;
600531 switch ( securityScheme . scheme ) {
601532 case "uav:channel-security" :
602- success = this . setChannelSecurity ( securityScheme as OPCUAChannelSecurityScheme ) ;
533+ success = this . # setChannelSecurity( securityScheme as OPCUAChannelSecurityScheme ) ;
603534 break ;
604535 case "uav:authentication" :
605- success = this . setAuthentication ( securityScheme as OPCUACAuthenticationScheme ) ;
536+ success = this . # setAuthentication( securityScheme as OPCUACAuthenticationScheme ) ;
606537 break ;
607538 case "combo" : {
608539 const combo = securityScheme as AllOfSecurityScheme | OneOfSecurityScheme ;
0 commit comments