react-native-nitro-net 0.1.5 → 0.2.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.
Files changed (48) hide show
  1. package/README.md +56 -4
  2. package/android/libs/arm64-v8a/librust_c_net.so +0 -0
  3. package/android/libs/armeabi-v7a/librust_c_net.so +0 -0
  4. package/android/libs/x86/librust_c_net.so +0 -0
  5. package/android/libs/x86_64/librust_c_net.so +0 -0
  6. package/cpp/HybridNetDriver.hpp +68 -0
  7. package/cpp/HybridNetServerDriver.hpp +9 -0
  8. package/cpp/HybridNetSocketDriver.hpp +149 -0
  9. package/cpp/NetBindings.hpp +52 -1
  10. package/ios/Frameworks/RustCNet.xcframework/Info.plist +5 -5
  11. package/ios/Frameworks/RustCNet.xcframework/ios-arm64/RustCNet.framework/RustCNet +0 -0
  12. package/ios/Frameworks/RustCNet.xcframework/ios-arm64_x86_64-simulator/RustCNet.framework/RustCNet +0 -0
  13. package/lib/Net.nitro.d.ts +27 -1
  14. package/lib/Net.nitro.js +3 -1
  15. package/lib/index.d.ts +4 -3
  16. package/lib/index.js +47 -6
  17. package/lib/tls.d.ts +124 -0
  18. package/lib/tls.js +451 -0
  19. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.cpp +38 -1
  20. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.hpp +8 -0
  21. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.cpp +4 -0
  22. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.hpp +1 -0
  23. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.cpp +70 -0
  24. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.hpp +15 -0
  25. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetDriverSpec.kt +33 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetServerDriverSpec.kt +4 -0
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetSocketDriverSpec.kt +60 -0
  28. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.hpp +95 -44
  29. package/nitrogen/generated/ios/c++/HybridNetDriverSpecSwift.hpp +58 -0
  30. package/nitrogen/generated/ios/c++/HybridNetServerDriverSpecSwift.hpp +6 -0
  31. package/nitrogen/generated/ios/c++/HybridNetSocketDriverSpecSwift.hpp +109 -0
  32. package/nitrogen/generated/ios/swift/HybridNetDriverSpec.swift +8 -0
  33. package/nitrogen/generated/ios/swift/HybridNetDriverSpec_cxx.swift +118 -0
  34. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec.swift +1 -0
  35. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec_cxx.swift +25 -0
  36. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec.swift +15 -0
  37. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec_cxx.swift +278 -0
  38. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.cpp +8 -0
  39. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.hpp +9 -0
  40. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.cpp +1 -0
  41. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.hpp +1 -0
  42. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.cpp +15 -0
  43. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.hpp +16 -0
  44. package/package.json +5 -3
  45. package/react-native-nitro-net.podspec +1 -3
  46. package/src/Net.nitro.ts +27 -1
  47. package/src/index.ts +18 -9
  48. package/src/tls.ts +532 -0
package/lib/index.js CHANGED
@@ -1,6 +1,39 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.connect = exports.Server = exports.Socket = exports.BlockList = exports.SocketAddress = void 0;
36
+ exports.tls = exports.connect = exports.Server = exports.Socket = exports.BlockList = exports.SocketAddress = void 0;
4
37
  exports.createConnection = createConnection;
5
38
  exports.createServer = createServer;
6
39
  exports.isIP = isIP;
@@ -219,13 +252,14 @@ class Socket extends readable_stream_1.Duplex {
219
252
  return;
220
253
  const id = this._driver.id ?? this._driver._id;
221
254
  this._driver.onEvent = (eventType, data) => {
255
+ this.emit('event', eventType, data);
222
256
  if (eventType === 3) { // ERROR
223
257
  const msg = new TextDecoder().decode(data);
224
258
  debugLog(`Socket (id: ${id}) NATIVE ERROR: ${msg}`);
225
259
  }
226
- if (eventType === 9) { // DEBUG
227
- const msg = new TextDecoder().decode(data);
228
- debugLog(`Socket (id: ${id}) NATIVE DEBUG: ${msg}`);
260
+ if (eventType === 9) { // SESSION/DEBUG
261
+ debugLog(`Socket (id: ${id}) NATIVE SESSION EVENT RECEIVED`);
262
+ this.emit('session', data);
229
263
  return;
230
264
  }
231
265
  debugLog(`Socket (id: ${id}, localPort: ${this.localPort}) Event TYPE: ${eventType}, data len: ${data?.byteLength}`);
@@ -635,8 +669,8 @@ class Server extends eventemitter3_1.EventEmitter {
635
669
  this.emit('error', new Error(data ? react_native_nitro_buffer_1.Buffer.from(data).toString() : 'Unknown server error'));
636
670
  break;
637
671
  case Net_nitro_1.NetServerEvent.DEBUG: {
638
- const msg = data ? react_native_nitro_buffer_1.Buffer.from(data).toString() : 'Unknown debug message';
639
- debugLog(`Server NATIVE DEBUG: ${msg}`);
672
+ debugLog(`Server NATIVE SESSION/DEBUG EVENT RECEIVED`);
673
+ this.emit('session', data);
640
674
  break;
641
675
  }
642
676
  case Net_nitro_1.NetServerEvent.CLOSE:
@@ -724,6 +758,12 @@ class Server extends eventemitter3_1.EventEmitter {
724
758
  return this;
725
759
  }
726
760
  close(callback) {
761
+ // Destroy all active connections first
762
+ for (const socket of this._sockets) {
763
+ socket.destroy();
764
+ }
765
+ this._sockets.clear();
766
+ this._connections = 0;
727
767
  this._driver.close();
728
768
  if (callback)
729
769
  this.once('close', callback);
@@ -763,6 +803,7 @@ exports.connect = createConnection;
763
803
  function createServer(options, connectionListener) {
764
804
  return new Server(options, connectionListener);
765
805
  }
806
+ exports.tls = __importStar(require("./tls"));
766
807
  exports.default = {
767
808
  Socket,
768
809
  Server,
package/lib/tls.d.ts ADDED
@@ -0,0 +1,124 @@
1
+ import { Socket, Server as NetServer, SocketOptions } from './index';
2
+ export interface PeerCertificate {
3
+ subject: {
4
+ [key: string]: string;
5
+ };
6
+ issuer: {
7
+ [key: string]: string;
8
+ };
9
+ valid_from: string;
10
+ valid_to: string;
11
+ fingerprint: string;
12
+ fingerprint256: string;
13
+ serialNumber: string;
14
+ }
15
+ export interface ConnectionOptions extends SocketOptions {
16
+ host?: string;
17
+ port?: number;
18
+ path?: string;
19
+ servername?: string;
20
+ rejectUnauthorized?: boolean;
21
+ session?: ArrayBuffer;
22
+ secureContext?: SecureContext;
23
+ ca?: string | string[];
24
+ cert?: string | string[];
25
+ key?: string | string[];
26
+ pfx?: string | ArrayBuffer;
27
+ passphrase?: string;
28
+ keylog?: boolean;
29
+ }
30
+ export interface SecureContextOptions {
31
+ pfx?: string | ArrayBuffer;
32
+ passphrase?: string;
33
+ cert?: string | string[];
34
+ key?: string | string[];
35
+ ca?: string | string[];
36
+ }
37
+ export declare const DEFAULT_MIN_VERSION = "TLSv1.2";
38
+ export declare const DEFAULT_MAX_VERSION = "TLSv1.3";
39
+ export declare const rootCertificates: string[];
40
+ export declare const DEFAULT_ECDH_CURVE = "auto";
41
+ export declare const SLAB_BUFFER_SIZE: number;
42
+ export declare class SecureContext {
43
+ private _id;
44
+ constructor(options?: SecureContextOptions);
45
+ setOCSPResponse(ocsp: ArrayBuffer): void;
46
+ getTicketKeys(): ArrayBuffer | undefined;
47
+ setTicketKeys(keys: ArrayBuffer): void;
48
+ get id(): number;
49
+ addCACert(ca: string): void;
50
+ }
51
+ export declare function createSecureContext(options?: SecureContextOptions): SecureContext;
52
+ export declare class TLSSocket extends Socket {
53
+ private _servername?;
54
+ get encrypted(): boolean;
55
+ get servername(): string | undefined;
56
+ get authorized(): boolean;
57
+ get authorizationError(): string | undefined;
58
+ get alpnProtocol(): string | undefined;
59
+ getProtocol(): string | undefined;
60
+ getCipher(): {
61
+ name: string;
62
+ version: string;
63
+ } | undefined;
64
+ getPeerCertificate(detailed?: boolean): PeerCertificate | {};
65
+ isSessionReused(): boolean;
66
+ getSession(): ArrayBuffer | undefined;
67
+ getEphemeralKeyInfo(): string | undefined;
68
+ getFinished(): Buffer | undefined;
69
+ getPeerFinished(): Buffer | undefined;
70
+ getSharedSigalgs(): string | undefined;
71
+ renegotiate(options: any, callback: (err: Error | null) => void): boolean;
72
+ disableRenegotiation(): void;
73
+ constructor(socket: Socket, options?: ConnectionOptions);
74
+ constructor(options: ConnectionOptions);
75
+ connect(options: any, connectionListener?: () => void): this;
76
+ }
77
+ export declare function connect(options: ConnectionOptions, connectionListener?: () => void): TLSSocket;
78
+ export declare function connect(port: number, host?: string, options?: ConnectionOptions, connectionListener?: () => void): TLSSocket;
79
+ export declare function connect(port: number, options?: ConnectionOptions, connectionListener?: () => void): TLSSocket;
80
+ export declare class Server extends NetServer {
81
+ private _secureContextId;
82
+ constructor(options?: any, connectionListener?: (socket: Socket) => void);
83
+ addContext(hostname: string, context: {
84
+ key: string;
85
+ cert: string;
86
+ }): void;
87
+ setSecureContext(options: {
88
+ key: string;
89
+ cert: string;
90
+ ca?: string | string[];
91
+ }): void;
92
+ getTicketKeys(): ArrayBuffer | undefined;
93
+ setTicketKeys(keys: ArrayBuffer): void;
94
+ listen(port?: any, host?: any, backlog?: any, callback?: any): this;
95
+ }
96
+ export declare function createServer(options?: any, connectionListener?: (socket: Socket) => void): Server;
97
+ export declare function getCiphers(): string[];
98
+ export declare function checkServerIdentity(hostname: string, cert: PeerCertificate): Error | undefined;
99
+ /**
100
+ * Legacy CryptoStream for Node.js compatibility.
101
+ * In this implementation, it's a simple wrapper around TLSSocket.
102
+ */
103
+ export declare class CryptoStream extends TLSSocket {
104
+ constructor(options?: ConnectionOptions);
105
+ }
106
+ /**
107
+ * Legacy SecurePair for Node.js compatibility.
108
+ */
109
+ export declare class SecurePair {
110
+ cleartext: CryptoStream;
111
+ encrypted: CryptoStream;
112
+ constructor(secureContext?: SecureContext, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean);
113
+ }
114
+ export declare function createSecurePair(secureContext?: SecureContext, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair;
115
+ /**
116
+ * Legacy certificate string parser.
117
+ */
118
+ export declare function parseCertString(certString: string): {
119
+ [key: string]: string;
120
+ };
121
+ /**
122
+ * Mock implementation of convertTLSV1CertToPEM.
123
+ */
124
+ export declare function convertTLSV1CertToPEM(cert: string | Buffer): string;
package/lib/tls.js ADDED
@@ -0,0 +1,451 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecurePair = exports.CryptoStream = exports.Server = exports.TLSSocket = exports.SecureContext = exports.SLAB_BUFFER_SIZE = exports.DEFAULT_ECDH_CURVE = exports.rootCertificates = exports.DEFAULT_MAX_VERSION = exports.DEFAULT_MIN_VERSION = void 0;
4
+ exports.createSecureContext = createSecureContext;
5
+ exports.connect = connect;
6
+ exports.createServer = createServer;
7
+ exports.getCiphers = getCiphers;
8
+ exports.checkServerIdentity = checkServerIdentity;
9
+ exports.createSecurePair = createSecurePair;
10
+ exports.parseCertString = parseCertString;
11
+ exports.convertTLSV1CertToPEM = convertTLSV1CertToPEM;
12
+ const index_1 = require("./index");
13
+ const Driver_1 = require("./Driver");
14
+ exports.DEFAULT_MIN_VERSION = 'TLSv1.2';
15
+ exports.DEFAULT_MAX_VERSION = 'TLSv1.3';
16
+ exports.rootCertificates = [];
17
+ exports.DEFAULT_ECDH_CURVE = 'auto'; // Managed by rustls
18
+ exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB default
19
+ class SecureContext {
20
+ constructor(options) {
21
+ if (options && options.pfx) {
22
+ this._id = Driver_1.Driver.createEmptySecureContext();
23
+ const pfx = typeof options.pfx === 'string' ? Buffer.from(options.pfx).buffer : options.pfx;
24
+ Driver_1.Driver.setPFXToSecureContext(this._id, pfx, options.passphrase);
25
+ }
26
+ else if (options && options.cert && options.key) {
27
+ const cert = Array.isArray(options.cert) ? options.cert[0] : options.cert;
28
+ const key = Array.isArray(options.key) ? options.key[0] : options.key;
29
+ this._id = Driver_1.Driver.createSecureContext(cert, key, options.passphrase);
30
+ }
31
+ else {
32
+ this._id = Driver_1.Driver.createEmptySecureContext();
33
+ }
34
+ if (options && options.ca) {
35
+ const cas = Array.isArray(options.ca) ? options.ca : [options.ca];
36
+ for (const ca of cas) {
37
+ Driver_1.Driver.addCACertToSecureContext(this._id, ca);
38
+ }
39
+ }
40
+ }
41
+ setOCSPResponse(ocsp) {
42
+ Driver_1.Driver.setOCSPResponseToSecureContext(this._id, ocsp);
43
+ }
44
+ getTicketKeys() {
45
+ return Driver_1.Driver.getTicketKeys(this._id);
46
+ }
47
+ setTicketKeys(keys) {
48
+ Driver_1.Driver.setTicketKeys(this._id, keys);
49
+ }
50
+ get id() {
51
+ return this._id;
52
+ }
53
+ // Node.js doesn't have these on SecureContext but we might need them
54
+ addCACert(ca) {
55
+ Driver_1.Driver.addCACertToSecureContext(this._id, ca);
56
+ }
57
+ }
58
+ exports.SecureContext = SecureContext;
59
+ function createSecureContext(options) {
60
+ return new SecureContext(options);
61
+ }
62
+ class TLSSocket extends index_1.Socket {
63
+ get encrypted() {
64
+ return true;
65
+ }
66
+ get servername() {
67
+ return this._servername;
68
+ }
69
+ get authorized() {
70
+ const driver = this._driver;
71
+ return driver.getAuthorizationError() === undefined;
72
+ }
73
+ get authorizationError() {
74
+ const driver = this._driver;
75
+ return driver.getAuthorizationError();
76
+ }
77
+ get alpnProtocol() {
78
+ const driver = this._driver;
79
+ return driver.getALPN();
80
+ }
81
+ getProtocol() {
82
+ const driver = this._driver;
83
+ return driver.getProtocol();
84
+ }
85
+ getCipher() {
86
+ const driver = this._driver;
87
+ const cipher = driver.getCipher();
88
+ const protocol = driver.getProtocol();
89
+ if (cipher) {
90
+ return {
91
+ name: cipher,
92
+ version: protocol || 'Unknown'
93
+ };
94
+ }
95
+ return undefined;
96
+ }
97
+ getPeerCertificate(detailed) {
98
+ const driver = this._driver;
99
+ const json = driver.getPeerCertificateJSON();
100
+ if (json) {
101
+ try {
102
+ return JSON.parse(json);
103
+ }
104
+ catch (e) {
105
+ console.error('Failed to parse peer certificate JSON', e);
106
+ }
107
+ }
108
+ return {};
109
+ }
110
+ isSessionReused() {
111
+ const driver = this._driver;
112
+ return driver.isSessionReused();
113
+ }
114
+ getSession() {
115
+ const driver = this._driver;
116
+ return driver.getSession();
117
+ }
118
+ getEphemeralKeyInfo() {
119
+ const driver = this._driver;
120
+ return driver.getEphemeralKeyInfo();
121
+ }
122
+ getFinished() {
123
+ throw new Error('getFinished is not supported by rustls');
124
+ }
125
+ getPeerFinished() {
126
+ throw new Error('getPeerFinished is not supported by rustls');
127
+ }
128
+ getSharedSigalgs() {
129
+ const driver = this._driver;
130
+ return driver.getSharedSigalgs();
131
+ }
132
+ renegotiate(options, callback) {
133
+ if (callback) {
134
+ process.nextTick(() => callback(new Error('Renegotiation is not supported by rustls')));
135
+ }
136
+ return false;
137
+ }
138
+ disableRenegotiation() {
139
+ // No-op, already effectively disabled
140
+ }
141
+ constructor(socketOrOptions, options) {
142
+ let opts = {};
143
+ if (socketOrOptions instanceof index_1.Socket) {
144
+ opts = { ...options, socketDriver: socketOrOptions._driver };
145
+ }
146
+ else {
147
+ opts = socketOrOptions || {};
148
+ }
149
+ super(opts);
150
+ if (socketOrOptions instanceof index_1.Socket) {
151
+ this._servername = socketOrOptions._servername;
152
+ }
153
+ this.on('event', (event, data) => {
154
+ if (event === 10 && data) { // KEYLOG
155
+ this.emit('keylog', Buffer.from(data));
156
+ }
157
+ else if (event === 11 && data) { // OCSP
158
+ this.emit('OCSPResponse', Buffer.from(data));
159
+ }
160
+ });
161
+ }
162
+ connect(options, connectionListener) {
163
+ // Override connect to use connectTLS
164
+ const port = typeof options === 'number' ? options : options.port;
165
+ const host = (typeof options === 'object' && options.host) ? options.host : (typeof options === 'string' ? arguments[1] : 'localhost');
166
+ const path = (typeof options === 'object' && options.path) ? options.path : undefined;
167
+ const servername = (typeof options === 'object' && options.servername) ? options.servername : (path ? 'localhost' : host);
168
+ this._servername = servername;
169
+ const rejectUnauthorized = (typeof options === 'object' && options.rejectUnauthorized !== undefined) ? options.rejectUnauthorized : true;
170
+ const session = (typeof options === 'object' && options.session) ? options.session : undefined;
171
+ const driver = this._driver;
172
+ if (driver) {
173
+ this.connecting = true;
174
+ if (connectionListener)
175
+ this.once('secureConnect', connectionListener);
176
+ this.once('connect', () => {
177
+ this.emit('secureConnect');
178
+ });
179
+ if (session) {
180
+ driver.setSession(session);
181
+ }
182
+ const secureContext = (typeof options === 'object' && options.secureContext) ? options.secureContext : undefined;
183
+ let secureContextId = secureContext ? secureContext.id : undefined;
184
+ // If cert/key/ca provided directly, create a temporary secure context
185
+ if (!secureContextId && typeof options === 'object' && (options.cert || options.key || options.ca)) {
186
+ secureContextId = createSecureContext({
187
+ cert: options.cert,
188
+ key: options.key,
189
+ ca: options.ca
190
+ }).id;
191
+ }
192
+ if (options && options.keylog) {
193
+ driver.enableKeylog();
194
+ }
195
+ if (path) {
196
+ if (secureContextId !== undefined) {
197
+ driver.connectUnixTLSWithContext(path, servername, rejectUnauthorized, secureContextId);
198
+ }
199
+ else {
200
+ driver.connectUnixTLS(path, servername, rejectUnauthorized);
201
+ }
202
+ }
203
+ else {
204
+ if (secureContextId !== undefined) {
205
+ driver.connectTLSWithContext(host, port, servername, rejectUnauthorized, secureContextId);
206
+ }
207
+ else {
208
+ driver.connectTLS(host, port, servername, rejectUnauthorized);
209
+ }
210
+ }
211
+ }
212
+ return this;
213
+ }
214
+ }
215
+ exports.TLSSocket = TLSSocket;
216
+ function connect(...args) {
217
+ let port;
218
+ let host = 'localhost';
219
+ let options = {};
220
+ let listener;
221
+ if (typeof args[0] === 'object') {
222
+ options = args[0];
223
+ port = options.port || 443;
224
+ host = options.host || 'localhost';
225
+ listener = args[1];
226
+ }
227
+ else {
228
+ port = args[0];
229
+ if (typeof args[1] === 'string') {
230
+ host = args[1];
231
+ options = args[2] || {};
232
+ listener = args[3];
233
+ }
234
+ else if (typeof args[1] === 'object') {
235
+ options = args[1];
236
+ listener = args[2];
237
+ }
238
+ else if (typeof args[1] === 'function') {
239
+ listener = args[1];
240
+ }
241
+ }
242
+ const socket = new TLSSocket(options);
243
+ socket.connect({
244
+ port,
245
+ host,
246
+ ...options
247
+ }, listener);
248
+ return socket;
249
+ }
250
+ class Server extends index_1.Server {
251
+ constructor(options, connectionListener) {
252
+ super(options);
253
+ this._secureContextId = 0;
254
+ if (options && options.secureContext) {
255
+ this._secureContextId = options.secureContext.id;
256
+ }
257
+ else if (options && (options.key || options.cert || options.ca)) {
258
+ this._secureContextId = createSecureContext({
259
+ cert: options.cert,
260
+ key: options.key,
261
+ ca: options.ca
262
+ }).id;
263
+ }
264
+ this.on('connection', (socket) => {
265
+ const tlsSocket = new TLSSocket(socket);
266
+ this.emit('secureConnection', tlsSocket);
267
+ });
268
+ this.on('session', (data) => {
269
+ this.emit('newSession', data);
270
+ });
271
+ if (options && options.SNICallback) {
272
+ console.warn("SNICallback is not supported yet, use addContext() instead");
273
+ }
274
+ if (connectionListener) {
275
+ this.on('secureConnection', connectionListener);
276
+ }
277
+ }
278
+ addContext(hostname, context) {
279
+ if (!this._secureContextId) {
280
+ throw new Error("Cannot addContext to a non-TLS server. Provide initial cert/key in constructor.");
281
+ }
282
+ Driver_1.Driver.addContextToSecureContext(this._secureContextId, hostname, context.cert, context.key);
283
+ }
284
+ setSecureContext(options) {
285
+ this._secureContextId = createSecureContext(options).id;
286
+ }
287
+ getTicketKeys() {
288
+ return this._secureContextId ? Driver_1.Driver.getTicketKeys(this._secureContextId) : undefined;
289
+ }
290
+ setTicketKeys(keys) {
291
+ if (!this._secureContextId)
292
+ throw new Error("Not a TLS server");
293
+ Driver_1.Driver.setTicketKeys(this._secureContextId, keys);
294
+ }
295
+ listen(port, host, backlog, callback) {
296
+ if (!this._secureContextId) {
297
+ return super.listen(port, host, backlog, callback);
298
+ }
299
+ let _port = 0;
300
+ let _host;
301
+ let _backlog;
302
+ let _path;
303
+ let _callback;
304
+ let ipv6Only = false;
305
+ let reusePort = false;
306
+ let handle;
307
+ if (typeof port === 'object' && port !== null) {
308
+ if (typeof port.fd === 'number') {
309
+ handle = port;
310
+ _backlog = port.backlog;
311
+ _callback = host;
312
+ }
313
+ else {
314
+ _port = port.port;
315
+ _host = port.host;
316
+ _backlog = port.backlog;
317
+ _path = port.path;
318
+ ipv6Only = port.ipv6Only === true;
319
+ reusePort = port.reusePort === true;
320
+ _callback = host;
321
+ }
322
+ }
323
+ else {
324
+ _port = typeof port === 'number' ? port : (typeof port === 'string' && !isNaN(Number(port)) ? Number(port) : 0);
325
+ if (typeof port === 'string' && isNaN(Number(port)))
326
+ _path = port;
327
+ if (typeof host === 'string')
328
+ _host = host;
329
+ else if (typeof host === 'function')
330
+ _callback = host;
331
+ if (typeof backlog === 'number')
332
+ _backlog = backlog;
333
+ else if (typeof backlog === 'function')
334
+ _callback = backlog;
335
+ if (typeof callback === 'function')
336
+ _callback = callback;
337
+ }
338
+ if (_callback)
339
+ this.once('listening', _callback);
340
+ const driver = this._driver;
341
+ if (handle || _path) {
342
+ console.warn("TLS over Unix sockets/handles not fully implemented yet");
343
+ }
344
+ driver.listenTLS(_port || 0, this._secureContextId, _backlog, ipv6Only, reusePort);
345
+ return this;
346
+ }
347
+ }
348
+ exports.Server = Server;
349
+ function createServer(options, connectionListener) {
350
+ return new Server(options, connectionListener);
351
+ }
352
+ function getCiphers() {
353
+ return [
354
+ 'TLS_AES_128_GCM_SHA256',
355
+ 'TLS_AES_256_GCM_SHA384',
356
+ 'TLS_CHACHA20_POLY1305_SHA256',
357
+ 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256',
358
+ 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',
359
+ 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256',
360
+ 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
361
+ 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
362
+ 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'
363
+ ];
364
+ }
365
+ function checkServerIdentity(hostname, cert) {
366
+ const subject = cert.subject;
367
+ const dnsNames = [];
368
+ // In a real implementation we'd extract SANs from the cert object if available.
369
+ // Our PeerCertificate already has subject.CN.
370
+ if (subject && subject.CN) {
371
+ dnsNames.push(subject.CN);
372
+ }
373
+ // SANs are preferred over CN but our current peer_cert JSON might not have them exploded yet
374
+ // unless x509-parser logic is updated. For now, we match against CN.
375
+ // Wildcard matching logic:
376
+ const matchHash = (host, pattern) => {
377
+ const parts = host.split('.');
378
+ const patternParts = pattern.split('.');
379
+ if (parts.length !== patternParts.length)
380
+ return false;
381
+ for (let i = 0; i < parts.length; i++) {
382
+ if (patternParts[i] === '*')
383
+ continue;
384
+ if (parts[i].toLowerCase() !== patternParts[i].toLowerCase())
385
+ return false;
386
+ }
387
+ return true;
388
+ };
389
+ const matches = dnsNames.some(name => {
390
+ if (name.includes('*')) {
391
+ return matchHash(hostname, name);
392
+ }
393
+ return name.toLowerCase() === hostname.toLowerCase();
394
+ });
395
+ if (!matches) {
396
+ const err = new Error(`Hostname/IP does not match certificate's altnames: Host: ${hostname}. is not in cert's altnames: ${dnsNames.join(', ')}`);
397
+ err.reason = 'Host name mismatch';
398
+ err.host = hostname;
399
+ err.cert = cert;
400
+ return err;
401
+ }
402
+ return undefined;
403
+ }
404
+ // -----------------------------------------------------------------------------
405
+ // Legacy Classes & Utils
406
+ // -----------------------------------------------------------------------------
407
+ /**
408
+ * Legacy CryptoStream for Node.js compatibility.
409
+ * In this implementation, it's a simple wrapper around TLSSocket.
410
+ */
411
+ class CryptoStream extends TLSSocket {
412
+ constructor(options) {
413
+ super(options || {});
414
+ }
415
+ }
416
+ exports.CryptoStream = CryptoStream;
417
+ /**
418
+ * Legacy SecurePair for Node.js compatibility.
419
+ */
420
+ class SecurePair {
421
+ constructor(secureContext, isServer, requestCert, rejectUnauthorized) {
422
+ this.cleartext = new CryptoStream();
423
+ this.encrypted = this.cleartext; // Logically the same in our simplified model
424
+ }
425
+ }
426
+ exports.SecurePair = SecurePair;
427
+ function createSecurePair(secureContext, isServer, requestCert, rejectUnauthorized) {
428
+ return new SecurePair(secureContext, isServer, requestCert, rejectUnauthorized);
429
+ }
430
+ /**
431
+ * Legacy certificate string parser.
432
+ */
433
+ function parseCertString(certString) {
434
+ const out = {};
435
+ const parts = certString.split('/');
436
+ for (const part of parts) {
437
+ const [key, value] = part.split('=');
438
+ if (key && value)
439
+ out[key] = value;
440
+ }
441
+ return out;
442
+ }
443
+ /**
444
+ * Mock implementation of convertTLSV1CertToPEM.
445
+ */
446
+ function convertTLSV1CertToPEM(cert) {
447
+ if (typeof cert === 'string' && cert.includes('BEGIN CERTIFICATE'))
448
+ return cert;
449
+ const body = (cert instanceof Buffer) ? cert.toString('base64') : Buffer.from(cert).toString('base64');
450
+ return `-----BEGIN CERTIFICATE-----\n${body}\n-----END CERTIFICATE-----`;
451
+ }