/** * @module node-opcua-secure-channel */ import { EventEmitter } from "node:events"; import type { ICertificateManager } from "node-opcua-certificate-manager"; import { type Certificate, type PrivateKey, type PublicKeyLength } from "node-opcua-crypto/web"; import { ObjectRegistry } from "node-opcua-object-registry"; import type { EndpointDescription } from "node-opcua-service-endpoints"; import { MessageSecurityMode } from "node-opcua-service-secure-channel"; import { type ErrorCallback, type StatusCode } from "node-opcua-status-code"; import { type IHelloAckLimits, type ISocketLike } from "node-opcua-transport"; import { type ICertificateKeyPairProvider, type Request, type Response } from "../common"; import { type ObjectFactory } from "../message_builder"; import type { SecurityHeader } from "../secure_message_chunk_manager"; import { SecurityPolicy } from "../security_policy"; export interface ServerSecureChannelParent extends ICertificateKeyPairProvider { certificateManager: ICertificateManager; getCertificate(): Certificate; getCertificateChain(): Certificate[]; getPrivateKey(): PrivateKey; getEndpointDescription(securityMode: MessageSecurityMode, securityPolicy: SecurityPolicy, endpointUri: string | null): EndpointDescription | null; /** * Optional hook to adjust the certificate status code * returned by `checkCertificate()`. * * Called only when the base certificate check returns a * non-Good status. Implementations can choose to relax * certain errors based on application-level policy * (e.g. accepting untrusted certs during initial provisioning). * * If not implemented, the original status code is returned * unchanged. */ adjustCertificateStatus?(statusCode: StatusCode, certificate: Certificate): StatusCode | Promise; } export interface ServerSecureChannelLayerOptions { parent: ServerSecureChannelParent; /** * timeout in milliseconds [default = 30000] */ timeout?: number; /** * default secure token life time in milliseconds [default = 300000] */ defaultSecureTokenLifetime?: number; objectFactory?: ObjectFactory; adjustTransportLimits?: (hello: IHelloAckLimits) => IHelloAckLimits; } export interface IServerSession { keepAlive?: () => void; status: string; incrementTotalRequestCount(): void; incrementRequestErrorCounter(counterName: string): void; incrementRequestTotalCounter(counterName: string): void; } export interface Message { request: Request; requestId: number; securityHeader: SecurityHeader; channel?: ServerSecureChannelLayer; session?: IServerSession; session_statusCode?: StatusCode; } export { isEmptyNonce, Nonce, nonceAlreadyBeenUsed } from "./nonce_cache"; export interface IServerSessionBase { sessionTimeout: number; sessionName: string; clientLastContactTime: number; status: string; } /** */ export declare class ServerSecureChannelLayer extends EventEmitter { #private; static throttleTime: number; /** * @private */ static g_MinimumSecureTokenLifetime: number; private static g_counter; beforeHandleOpenSecureChannelRequest: () => Promise; get securityTokenCount(): number; get remoteAddress(): string; get remotePort(): number; /** * */ get aborted(): boolean; /** * the number of bytes read so far by this channel */ get bytesRead(): number; /** * the number of bytes written so far by this channel */ get bytesWritten(): number; get transactionsCount(): number; /** * true when the secure channel has been opened successfully * */ get isOpened(): boolean; /** * true when the secure channel is assigned to a active session */ get hasSession(): boolean; get certificateManager(): ICertificateManager; /** * The unique hash key to identify this secure channel * @property hashKey */ get hashKey(): number; static registry: ObjectRegistry; /** * Install a callback invoked after every response is sent on this channel. * Used by the server to emit "response" events for diagnostics. */ setResponseInterceptor(cb: (msgType: string, response: Response, message: Message) => void): void; sessionTokens: { [key: string]: IServerSessionBase; }; channelId: number; timeout: number; get clientCertificate(): Certificate | null; /** * the channel message security mode */ securityMode: MessageSecurityMode; /** * the channel message security policy */ securityPolicy: SecurityPolicy; get status(): "new" | "connecting" | "open" | "closing" | "closed"; toJSON(): Record; toString(): string; constructor(options: ServerSecureChannelLayerOptions); getTransportSettings(): { maxMessageSize: number; }; dispose(): void; abruptlyInterrupt(): void; /** * the endpoint associated with this secure channel * */ getEndpointDescription(_securityMode: MessageSecurityMode, securityPolicy: SecurityPolicy, endpointUri: string | null): EndpointDescription | null; setSecurity(securityMode: MessageSecurityMode, securityPolicy: SecurityPolicy): void; /** * @return the X509 DER form certificate */ getCertificateChain(): Certificate[]; /** * @return the X509 DER form certificate */ getCertificate(): Certificate; getSignatureLength(): PublicKeyLength; /** * @return the privateKey */ getPrivateKey(): PrivateKey; /** * This intialize the transport layer (TCP) used by this secure channel * * the function will also wait for the Hello Message from the client. * ( in the transport layer ) * and will initialize the OpenSecureChannelRequest watchdog and return * to the caller. * This means that the secure channel is ready to receive an OpenSecureChannelRequest * */ init(socket: ISocketLike, callback: ErrorCallback): void; /** * @internal */ send_response(msgType: string, response: Response, message: Message, callback?: ErrorCallback): void; getRemoteIPAddress(): string; getRemotePort(): number; getRemoteFamily(): string; /** * Abruptly close a Server SecureChannel ,by terminating the underlying transport. * */ close(callback?: ErrorCallback): void; protected checkCertificate(certificate: Certificate | null): Promise; write(messageChunk: Buffer): void; }