@omindu/yaksha 1.0.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.
@@ -0,0 +1,338 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Yaksha Traffic Obfuscation
5
+ * Make VPN traffic undetectable through pattern randomization
6
+ */
7
+
8
+ const crypto = require('crypto');
9
+
10
+ class TrafficObfuscation {
11
+ constructor(securityLevel = 'medium', options = {}) {
12
+ this.securityLevel = securityLevel;
13
+ this.mode = this._selectMode(securityLevel);
14
+ this.enabled = options.enabled !== false;
15
+ this.maxJitter = options.maxJitter || 50; // milliseconds
16
+ this.maxPadding = options.maxPadding || 255; // bytes
17
+ }
18
+
19
+ /**
20
+ * Select obfuscation mode based on security level
21
+ */
22
+ _selectMode(level) {
23
+ switch (level) {
24
+ case 'low':
25
+ return 'xor';
26
+ case 'medium':
27
+ return 'chacha20';
28
+ case 'high':
29
+ return 'aes-256-gcm';
30
+ default:
31
+ return 'chacha20';
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Simple XOR obfuscation (low security, high speed)
37
+ */
38
+ _xorObfuscate(data, key) {
39
+ const result = Buffer.allocUnsafe(data.length);
40
+
41
+ for (let i = 0; i < data.length; i++) {
42
+ result[i] = data[i] ^ key[i % key.length];
43
+ }
44
+
45
+ return result;
46
+ }
47
+
48
+ /**
49
+ * ChaCha20 stream cipher obfuscation
50
+ */
51
+ _chacha20Obfuscate(data, key, nonce) {
52
+ const cipher = crypto.createCipheriv('chacha20', key, nonce);
53
+ return Buffer.concat([cipher.update(data), cipher.final()]);
54
+ }
55
+
56
+ /**
57
+ * ChaCha20 stream cipher deobfuscation
58
+ */
59
+ _chacha20Deobfuscate(data, key, nonce) {
60
+ const decipher = crypto.createDecipheriv('chacha20', key, nonce);
61
+ return Buffer.concat([decipher.update(data), decipher.final()]);
62
+ }
63
+
64
+ /**
65
+ * AES-256-GCM obfuscation
66
+ */
67
+ _aesObfuscate(data, key, nonce) {
68
+ const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce);
69
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
70
+ const authTag = cipher.getAuthTag();
71
+
72
+ return { data: encrypted, authTag };
73
+ }
74
+
75
+ /**
76
+ * AES-256-GCM deobfuscation
77
+ */
78
+ _aesDeobfuscate(data, key, nonce, authTag) {
79
+ const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);
80
+ decipher.setAuthTag(authTag);
81
+ return Buffer.concat([decipher.update(data), decipher.final()]);
82
+ }
83
+
84
+ /**
85
+ * Add random padding to data
86
+ */
87
+ addRandomPadding(data) {
88
+ const paddingSize = crypto.randomInt(0, this.maxPadding + 1);
89
+
90
+ if (paddingSize === 0) {
91
+ return { data, paddingSize: 0 };
92
+ }
93
+
94
+ const padding = crypto.randomBytes(paddingSize);
95
+ const padded = Buffer.concat([data, padding]);
96
+
97
+ return { data: padded, paddingSize };
98
+ }
99
+
100
+ /**
101
+ * Remove padding from data
102
+ */
103
+ removePadding(data, paddingSize) {
104
+ if (paddingSize === 0 || paddingSize >= data.length) {
105
+ return data;
106
+ }
107
+
108
+ return data.slice(0, -paddingSize);
109
+ }
110
+
111
+ /**
112
+ * Add timing jitter (async delay)
113
+ */
114
+ async addTimingJitter() {
115
+ if (!this.enabled) {
116
+ return;
117
+ }
118
+
119
+ const jitter = crypto.randomInt(0, this.maxJitter + 1);
120
+
121
+ if (jitter > 0) {
122
+ await new Promise(resolve => setTimeout(resolve, jitter));
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Randomize packet size by splitting or combining
128
+ */
129
+ randomizePacketSize(data, targetSize = null) {
130
+ if (!targetSize) {
131
+ // Random target size between 500 and 1500 bytes
132
+ targetSize = crypto.randomInt(500, 1501);
133
+ }
134
+
135
+ if (data.length <= targetSize) {
136
+ // Add padding to reach target size
137
+ const paddingSize = targetSize - data.length;
138
+ if (paddingSize > 0) {
139
+ const padding = crypto.randomBytes(paddingSize);
140
+ return {
141
+ packets: [Buffer.concat([data, padding])],
142
+ paddingSizes: [paddingSize]
143
+ };
144
+ }
145
+ return { packets: [data], paddingSizes: [0] };
146
+ }
147
+
148
+ // Split into multiple packets
149
+ const packets = [];
150
+ const paddingSizes = [];
151
+ let offset = 0;
152
+
153
+ while (offset < data.length) {
154
+ const chunkSize = Math.min(
155
+ crypto.randomInt(Math.floor(targetSize * 0.7), targetSize + 1),
156
+ data.length - offset
157
+ );
158
+
159
+ const chunk = data.slice(offset, offset + chunkSize);
160
+
161
+ // Add random padding to each chunk
162
+ const paddingSize = crypto.randomInt(0, 100);
163
+ const padding = crypto.randomBytes(paddingSize);
164
+ const paddedChunk = Buffer.concat([chunk, padding]);
165
+
166
+ packets.push(paddedChunk);
167
+ paddingSizes.push(paddingSize);
168
+ offset += chunkSize;
169
+ }
170
+
171
+ return { packets, paddingSizes };
172
+ }
173
+
174
+ /**
175
+ * Obfuscate data
176
+ */
177
+ obfuscate(data) {
178
+ if (!this.enabled) {
179
+ return {
180
+ data,
181
+ metadata: { mode: 'none' }
182
+ };
183
+ }
184
+
185
+ let result;
186
+ let metadata = { mode: this.mode };
187
+
188
+ switch (this.mode) {
189
+ case 'xor': {
190
+ const key = crypto.randomBytes(32);
191
+ result = this._xorObfuscate(data, key);
192
+ metadata.key = key;
193
+ break;
194
+ }
195
+
196
+ case 'chacha20': {
197
+ const key = crypto.randomBytes(32);
198
+ const nonce = crypto.randomBytes(12);
199
+ result = this._chacha20Obfuscate(data, key, nonce);
200
+ metadata.key = key;
201
+ metadata.nonce = nonce;
202
+ break;
203
+ }
204
+
205
+ case 'aes-256-gcm': {
206
+ const key = crypto.randomBytes(32);
207
+ const nonce = crypto.randomBytes(12);
208
+ const { data: encrypted, authTag } = this._aesObfuscate(data, key, nonce);
209
+ result = encrypted;
210
+ metadata.key = key;
211
+ metadata.nonce = nonce;
212
+ metadata.authTag = authTag;
213
+ break;
214
+ }
215
+
216
+ default:
217
+ result = data;
218
+ }
219
+
220
+ // Add random padding
221
+ const { data: padded, paddingSize } = this.addRandomPadding(result);
222
+ metadata.paddingSize = paddingSize;
223
+
224
+ return {
225
+ data: padded,
226
+ metadata
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Deobfuscate data
232
+ */
233
+ deobfuscate(data, metadata) {
234
+ if (!this.enabled || metadata.mode === 'none') {
235
+ return data;
236
+ }
237
+
238
+ // Remove padding first
239
+ let unpadded = this.removePadding(data, metadata.paddingSize || 0);
240
+
241
+ let result;
242
+
243
+ switch (metadata.mode) {
244
+ case 'xor':
245
+ result = this._xorObfuscate(unpadded, metadata.key); // XOR is symmetric
246
+ break;
247
+
248
+ case 'chacha20':
249
+ result = this._chacha20Deobfuscate(unpadded, metadata.key, metadata.nonce);
250
+ break;
251
+
252
+ case 'aes-256-gcm':
253
+ result = this._aesDeobfuscate(unpadded, metadata.key, metadata.nonce, metadata.authTag);
254
+ break;
255
+
256
+ default:
257
+ result = unpadded;
258
+ }
259
+
260
+ return result;
261
+ }
262
+
263
+ /**
264
+ * Mimic HTTP/2 traffic pattern
265
+ */
266
+ mimicHTTP2Pattern(data) {
267
+ // Add HTTP/2 frame-like header (simplified)
268
+ const frameHeader = Buffer.allocUnsafe(9);
269
+
270
+ // Length (3 bytes)
271
+ const length = Math.min(data.length, 16383); // Max frame size
272
+ frameHeader.writeUIntBE(length, 0, 3);
273
+
274
+ // Type (1 byte) - DATA frame
275
+ frameHeader.writeUInt8(0x00, 3);
276
+
277
+ // Flags (1 byte)
278
+ frameHeader.writeUInt8(0x00, 4);
279
+
280
+ // Stream ID (4 bytes)
281
+ frameHeader.writeUInt32BE(crypto.randomInt(1, 1000), 5);
282
+
283
+ return Buffer.concat([frameHeader, data.slice(0, length)]);
284
+ }
285
+
286
+ /**
287
+ * Simulate burst traffic (like video streaming)
288
+ */
289
+ async simulateBurstTraffic(dataChunks, callback) {
290
+ if (!this.enabled) {
291
+ for (const chunk of dataChunks) {
292
+ await callback(chunk);
293
+ }
294
+ return;
295
+ }
296
+
297
+ // Send in bursts with pauses
298
+ const burstSize = crypto.randomInt(2, 6);
299
+
300
+ for (let i = 0; i < dataChunks.length; i++) {
301
+ await callback(dataChunks[i]);
302
+
303
+ // Add pause after burst
304
+ if ((i + 1) % burstSize === 0) {
305
+ const pauseDuration = crypto.randomInt(50, 200);
306
+ await new Promise(resolve => setTimeout(resolve, pauseDuration));
307
+ }
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Enable obfuscation
313
+ */
314
+ enable() {
315
+ this.enabled = true;
316
+ }
317
+
318
+ /**
319
+ * Disable obfuscation
320
+ */
321
+ disable() {
322
+ this.enabled = false;
323
+ }
324
+
325
+ /**
326
+ * Get statistics
327
+ */
328
+ getStats() {
329
+ return {
330
+ enabled: this.enabled,
331
+ mode: this.mode,
332
+ maxJitter: this.maxJitter,
333
+ maxPadding: this.maxPadding
334
+ };
335
+ }
336
+ }
337
+
338
+ module.exports = TrafficObfuscation;
package/src/index.js ADDED
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Yaksha VPN Protocol Library
5
+ * Main entry point and exports
6
+ *
7
+ * @author Omindu Dissanayaka (SE U. G)
8
+ * @version 1.1.0
9
+ * @license MIT
10
+ */
11
+
12
+ // Core modules
13
+ const Protocol = require('./core/protocol');
14
+ const Encryption = require('./core/encryption');
15
+ const Connection = require('./core/connection');
16
+
17
+ // Security modules
18
+ const Authentication = require('./security/auth');
19
+ const SecurityLevels = require('./security/levels');
20
+
21
+ // Feature modules
22
+ const SNISpoofing = require('./features/sni-spoof');
23
+ const TrafficObfuscation = require('./features/traffic-obfuscation');
24
+ const MultiPath = require('./features/multi-path');
25
+ const DNSOverride = require('./features/dns-override');
26
+ const TLSCamouflage = require('./features/tls-camouflage');
27
+
28
+ // Bypass modules
29
+ const FirewallEvasion = require('./bypass/firewall-evasion');
30
+
31
+ // Server and Client
32
+ const YakshaServer = require('./server');
33
+ const YakshaClient = require('./client');
34
+
35
+ // Utilities
36
+ const Logger = require('./utils/logger');
37
+ const Config = require('./utils/config');
38
+ const BufferPool = require('./utils/buffer-pool');
39
+
40
+ /**
41
+ * Create a new Yaksha VPN server
42
+ * @param {Object} options - Server configuration options
43
+ * @returns {YakshaServer}
44
+ */
45
+ function createServer(options = {}) {
46
+ return new YakshaServer(options);
47
+ }
48
+
49
+ /**
50
+ * Create a new Yaksha VPN client
51
+ * @param {Object} options - Client configuration options
52
+ * @returns {YakshaClient}
53
+ */
54
+ function createClient(options = {}) {
55
+ return new YakshaClient(options);
56
+ }
57
+
58
+ /**
59
+ * Get version information
60
+ * @returns {string}
61
+ */
62
+ function getVersion() {
63
+ return '1.1.0';
64
+ }
65
+
66
+ // Main exports
67
+ module.exports = {
68
+ // Factory functions
69
+ createServer,
70
+ createClient,
71
+
72
+ // Server and Client classes
73
+ YakshaServer,
74
+ YakshaClient,
75
+
76
+ // Core
77
+ Protocol,
78
+ Encryption,
79
+ Connection,
80
+
81
+ // Security
82
+ Authentication,
83
+ SecurityLevels,
84
+
85
+ // Features
86
+ SNISpoofing,
87
+ TrafficObfuscation,
88
+ MultiPath,
89
+ DNSOverride,
90
+ TLSCamouflage,
91
+
92
+ // Bypass
93
+ FirewallEvasion,
94
+
95
+ // Utilities
96
+ Logger,
97
+ Config,
98
+ BufferPool,
99
+
100
+ // Info
101
+ version: getVersion(),
102
+ getVersion
103
+ };
104
+
105
+ // Default export
106
+ module.exports.default = module.exports;