node-ikev2 0.1.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,1840 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.payloadTypeMapping = exports.PayloadEAP = exports.PayloadCP = exports.cfgType = exports.PayloadSK = exports.PayloadTSr = exports.PayloadTSi = exports.PayloadTS = exports.PayloadVENDOR = exports.PayloadDELETE = exports.PayloadNOTIFY = exports.notifyMessageType = exports.securityProtocolId = exports.PayloadNONCE = exports.PayloadAUTH = exports.PayloadCERTREQ = exports.PayloadCERT = exports.CertificateType = exports.PayloadIDr = exports.PayloadIDi = exports.PayloadID = exports.IDType = exports.PayloadKE = exports.PayloadSA = exports.Payload = exports.payloadType = void 0;
4
+ const proposal_1 = require("./proposal");
5
+ const attribute_1 = require("./attribute");
6
+ const selector_1 = require("./selector");
7
+ /*
8
+ IKEv2 Generic Payload Header
9
+
10
+ 0 1 2 3
11
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
12
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
13
+ ! Next Payload !C! RESERVED ! Payload Length !
14
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15
+
16
+ Generic Payload Header
17
+
18
+ Critical bit: specifies the processing by the recipient in case the type
19
+ of this payload is not understood:
20
+ - 0 payload skipped
21
+ - 1 message rejected
22
+ */
23
+ /**
24
+ * IKEv2 Payload Types: \
25
+ Next Payload Type Notation Value
26
+ --------------------------------------------------
27
+ No Next Payload 0 \
28
+ Security Association SA 33 \
29
+ Key Exchange KE 34 \
30
+ Identification - Initiator IDi 35 \
31
+ Identification - Responder IDr 36 \
32
+ Certificate CERT 37 \
33
+ Certificate Request CERTREQ 38 \
34
+ Authentication AUTH 39 \
35
+ Nonce Ni, Nr 40 \
36
+ Notify N 41 \
37
+ Delete D 42 \
38
+ Vendor ID V 43 \
39
+ Traffic Selector - Initiator TSi 44 \
40
+ Traffic Selector - Responder TSr 45 \
41
+ Encrypted and Authenticated SK 46 \
42
+ Configuration CP 47 \
43
+ Extensible Authentication EAP 48
44
+ */
45
+ var payloadType;
46
+ (function (payloadType) {
47
+ payloadType[payloadType["NONE"] = 0] = "NONE";
48
+ payloadType[payloadType["SA"] = 33] = "SA";
49
+ payloadType[payloadType["KE"] = 34] = "KE";
50
+ payloadType[payloadType["IDi"] = 35] = "IDi";
51
+ payloadType[payloadType["IDr"] = 36] = "IDr";
52
+ payloadType[payloadType["CERT"] = 37] = "CERT";
53
+ payloadType[payloadType["CERTREQ"] = 38] = "CERTREQ";
54
+ payloadType[payloadType["AUTH"] = 39] = "AUTH";
55
+ payloadType[payloadType["NONCE"] = 40] = "NONCE";
56
+ payloadType[payloadType["NOTIFY"] = 41] = "NOTIFY";
57
+ payloadType[payloadType["DELETE"] = 42] = "DELETE";
58
+ payloadType[payloadType["VENDOR"] = 43] = "VENDOR";
59
+ payloadType[payloadType["TSi"] = 44] = "TSi";
60
+ payloadType[payloadType["TSr"] = 45] = "TSr";
61
+ payloadType[payloadType["SK"] = 46] = "SK";
62
+ payloadType[payloadType["CP"] = 47] = "CP";
63
+ payloadType[payloadType["EAP"] = 48] = "EAP";
64
+ })(payloadType || (exports.payloadType = payloadType = {}));
65
+ /**
66
+ * IKEv2 Generic Payload Header
67
+ * @class
68
+ * @property {payloadType}
69
+ * @property {payloadType} nextPayload - 1 byte
70
+ * @property {boolean} critical - 1 bit
71
+ * @property {number} length - 2 bytes
72
+ */
73
+ class Payload {
74
+ constructor(type, nextPayload, critical = false, // default to false for all defined payloads in IKEv2
75
+ length) {
76
+ this.type = type;
77
+ this.nextPayload = nextPayload;
78
+ this.critical = critical;
79
+ this.length = length;
80
+ }
81
+ /**
82
+ * Parses a payload generic header from a buffer
83
+ * @param buffer
84
+ * @static
85
+ * @public
86
+ * @returns
87
+ */
88
+ static parse(buffer) {
89
+ try {
90
+ // Input validation
91
+ if (!Buffer.isBuffer(buffer)) {
92
+ throw new Error("Input must be a Buffer");
93
+ }
94
+ // Check minimum buffer length for payload header (4 bytes)
95
+ if (buffer.length < 4) {
96
+ throw new Error(`Buffer too short for payload header. Expected at least 4 bytes, got ${buffer.length}`);
97
+ }
98
+ const nextPayload = buffer.readUInt8(0);
99
+ const critical = (buffer.readUInt8(1) & 0x80) === 0x80;
100
+ const length = buffer.readUInt16BE(2);
101
+ // Validate payload length
102
+ if (length < 4) {
103
+ throw new Error(`Invalid payload length. Must be at least 4 bytes, got ${length}`);
104
+ }
105
+ // Check if buffer contains the full payload
106
+ if (buffer.length < length) {
107
+ throw new Error(`Buffer too short for declared payload length. Expected ${length} bytes, got ${buffer.length}`);
108
+ }
109
+ return new Payload(payloadType.NONE, nextPayload, critical, length);
110
+ }
111
+ catch (error) {
112
+ if (error instanceof Error) {
113
+ throw new Error(`Failed to parse generic payload header: ${error.message}`);
114
+ }
115
+ throw new Error("Failed to parse generic payload header");
116
+ }
117
+ }
118
+ /**
119
+ * Serialize a JSON payload to a buffer
120
+ * @param json
121
+ * @static
122
+ * @public
123
+ * @returns {Buffer}
124
+ */
125
+ static serializeJSON(json) {
126
+ try {
127
+ // Input validation
128
+ if (!json || typeof json !== "object") {
129
+ throw new Error("JSON input must be a valid object");
130
+ }
131
+ // Validate required fields
132
+ if (typeof json.nextPayload === "undefined") {
133
+ throw new Error("nextPayload is required");
134
+ }
135
+ if (typeof json.length === "undefined") {
136
+ throw new Error("length is required");
137
+ }
138
+ // Validate data types
139
+ if (!Number.isInteger(json.nextPayload) ||
140
+ json.nextPayload < 0 ||
141
+ json.nextPayload > 255) {
142
+ throw new Error(`nextPayload must be a valid 8-bit unsigned integer (0-255), got ${json.nextPayload}`);
143
+ }
144
+ if (!Number.isInteger(json.length) ||
145
+ json.length < 4 ||
146
+ json.length > 65535) {
147
+ throw new Error(`length must be a valid 16-bit unsigned integer (4-65535), got ${json.length}`);
148
+ }
149
+ // Validate critical flag
150
+ if (typeof json.critical !== "boolean") {
151
+ throw new Error(`critical must be a boolean, got ${typeof json.critical}`);
152
+ }
153
+ const buffer = Buffer.alloc(4);
154
+ buffer.writeUInt8(json.nextPayload, 0);
155
+ buffer.writeUInt8(json.critical ? 0x80 : 0, 1);
156
+ buffer.writeUInt16BE(json.length, 2);
157
+ return buffer;
158
+ }
159
+ catch (error) {
160
+ if (error instanceof Error) {
161
+ throw new Error(`Failed to serialize payload JSON: ${error.message}`);
162
+ }
163
+ throw new Error("Failed to serialize payload JSON");
164
+ }
165
+ }
166
+ /**
167
+ * Serializes the payload to a buffer
168
+ * @public
169
+ * @returns {Buffer}
170
+ */
171
+ serialize() {
172
+ // The length should be set by the child class before calling this method
173
+ if (this.length < 4) {
174
+ throw new Error(`Invalid payload length: ${this.length}`);
175
+ }
176
+ const buffer = Buffer.alloc(4);
177
+ buffer.writeUInt8(this.nextPayload, 0);
178
+ buffer.writeUInt8(this.critical ? 0x80 : 0, 1);
179
+ buffer.writeUInt16BE(this.length, 2);
180
+ return buffer;
181
+ }
182
+ /**
183
+ * Returns a JSON representation of the payload
184
+ * @public
185
+ * @returns {Record<string, any>}
186
+ */
187
+ toJSON() {
188
+ return {};
189
+ }
190
+ /**
191
+ * Returns a string representation of the payload
192
+ * @public
193
+ * @returns {string}
194
+ */
195
+ genToJSON() {
196
+ return {
197
+ type: this.type,
198
+ nextPayload: this.nextPayload,
199
+ critical: this.critical,
200
+ length: this.length,
201
+ };
202
+ }
203
+ /**
204
+ * Returns a string representation of the payload
205
+ * @public
206
+ * @returns {string}
207
+ */
208
+ genToString() {
209
+ const prettyJson = this.genToJSON();
210
+ prettyJson.type = `${payloadType[prettyJson.type]} (${prettyJson.type})`;
211
+ prettyJson.nextPayload = `${payloadType[prettyJson.nextPayload]} (${prettyJson.nextPayload})`;
212
+ prettyJson.critical = prettyJson.critical ? "Critical" : "Non-critical";
213
+ return JSON.stringify(prettyJson, null, 2);
214
+ }
215
+ }
216
+ exports.Payload = Payload;
217
+ /**
218
+ * IKEv2 Security Association Payload
219
+ * @class
220
+ * @extends Payload
221
+ */
222
+ class PayloadSA extends Payload {
223
+ constructor(nextPayload, proposals, critical = false, length = 0) {
224
+ super(payloadType.SA, nextPayload, critical, length > 0
225
+ ? length
226
+ : 4 + proposals.reduce((acc, prop) => acc + prop.length, 0));
227
+ this.nextPayload = nextPayload;
228
+ this.proposals = proposals;
229
+ this.critical = critical;
230
+ this.length = length;
231
+ }
232
+ /**
233
+ * Parses a Security Association Payload from a buffer
234
+ * @param buffer
235
+ * @static
236
+ * @public
237
+ * @returns {PayloadSA}
238
+ */
239
+ static parse(buffer) {
240
+ const genericPayload = Payload.parse(buffer);
241
+ // Validate that buffer is at least as long as the declared payload length
242
+ if (buffer.length < genericPayload.length) {
243
+ throw new Error(`Buffer too short for declared payload length. Expected at least ${genericPayload.length} bytes, got ${buffer.length}`);
244
+ }
245
+ const proposals = [];
246
+ let offset = 4;
247
+ while (offset < genericPayload.length) {
248
+ // Check if we have enough data for the next proposal header (8 bytes minimum)
249
+ if (offset + 8 > genericPayload.length) {
250
+ throw new Error(`Insufficient data for proposal header at offset ${offset}. Need at least 8 bytes, have ${genericPayload.length - offset}`);
251
+ }
252
+ // Read proposal length from the buffer to determine exact slice size
253
+ const proposalLength = buffer.readUInt16BE(offset + 2);
254
+ // Validate proposal length
255
+ if (proposalLength < 8) {
256
+ throw new Error(`Invalid proposal length. Must be at least 8 bytes, got ${proposalLength}`);
257
+ }
258
+ // Check if we have enough data for the complete proposal
259
+ if (offset + proposalLength > genericPayload.length) {
260
+ throw new Error(`Insufficient data for complete proposal at offset ${offset}. Need ${proposalLength} bytes, have ${genericPayload.length - offset}`);
261
+ }
262
+ // Pass only the exact buffer slice for this proposal
263
+ const proposalBuffer = buffer.subarray(offset, offset + proposalLength);
264
+ const proposal = proposal_1.Proposal.parse(proposalBuffer);
265
+ proposals.push(proposal);
266
+ offset += proposalLength;
267
+ // Safety check to prevent infinite loops
268
+ if (offset > genericPayload.length) {
269
+ throw new Error(`Proposal parsing exceeded payload length. Offset: ${offset}, Payload length: ${genericPayload.length}`);
270
+ }
271
+ }
272
+ return new PayloadSA(genericPayload.nextPayload, proposals, genericPayload.critical, genericPayload.length);
273
+ }
274
+ /**
275
+ * Serializes a JSON representation of the SA payload to a buffer
276
+ * @param json
277
+ * @static
278
+ * @public
279
+ * @returns {Buffer}
280
+ */
281
+ static serializeJSON(json) {
282
+ const proposalsBuffer = json.proposals.map((proposal) => proposal_1.Proposal.serializeJSON(proposal));
283
+ const buffer = Buffer.alloc(json.length);
284
+ const genericPayload = Payload.serializeJSON(json);
285
+ genericPayload.copy(buffer);
286
+ let offset = 4;
287
+ for (const proposalBuffer of proposalsBuffer) {
288
+ proposalBuffer.copy(buffer, offset);
289
+ offset += proposalBuffer.length;
290
+ }
291
+ return buffer;
292
+ }
293
+ /**
294
+ * Serializes the SA payload to a buffer
295
+ * @public
296
+ * @returns {Buffer}
297
+ */
298
+ serialize() {
299
+ // Encode deep first, to calculate the total length
300
+ const proposalsBuffer = this.proposals.map((proposal) => proposal.serialize());
301
+ const proposals = Buffer.concat(proposalsBuffer);
302
+ // Fix the length
303
+ this.length = 4 + proposals.length;
304
+ const buffer = Buffer.alloc(this.length);
305
+ super.serialize().copy(buffer);
306
+ proposals.copy(buffer, 4);
307
+ return buffer;
308
+ }
309
+ /**
310
+ * Returns a JSON representation of the SA payload
311
+ * @public
312
+ * @returns {Record<string, any>}
313
+ */
314
+ toJSON() {
315
+ const json = super.genToJSON();
316
+ json.proposals = this.proposals.map((proposal) => proposal.toJSON());
317
+ return json;
318
+ }
319
+ /**
320
+ * Returns a string representation of the SA payload
321
+ * @public
322
+ * @returns {string}
323
+ */
324
+ toString() {
325
+ const genericString = super.genToString();
326
+ const proposalsString = this.proposals.map((proposal) => proposal.toString());
327
+ return `${genericString}\nProposals:\n${proposalsString.join("\n")}`;
328
+ }
329
+ }
330
+ exports.PayloadSA = PayloadSA;
331
+ /**
332
+ * IKEv2 Key Exchange Payload
333
+ * @class
334
+ * @extends Payload
335
+ */
336
+ class PayloadKE extends Payload {
337
+ constructor(nextPayload, dhGroup, keyData, critical = false, length = 0) {
338
+ super(payloadType.KE, nextPayload, critical, length > 0 ? length : 8 + keyData.length);
339
+ this.nextPayload = nextPayload;
340
+ this.dhGroup = dhGroup;
341
+ this.keyData = keyData;
342
+ this.critical = critical;
343
+ this.length = length;
344
+ }
345
+ /**
346
+ * Parses a Key Exchange Payload from a buffer
347
+ * @param buffer
348
+ * @static
349
+ * @public
350
+ * @returns {PayloadKE}
351
+ */
352
+ static parse(buffer) {
353
+ const genericPayload = Payload.parse(buffer);
354
+ // Validate that buffer is at least as long as the declared payload length
355
+ if (buffer.length < genericPayload.length) {
356
+ throw new Error(`Buffer too short for declared payload length. Expected at least ${genericPayload.length} bytes, got ${buffer.length}`);
357
+ }
358
+ // Check if we have enough data for dhGroup (2 bytes) and reserved field (2 bytes)
359
+ if (genericPayload.length < 8) {
360
+ throw new Error(`Payload too short for KE payload. Expected at least 8 bytes, got ${genericPayload.length}`);
361
+ }
362
+ const dhGroup = buffer.readUInt16BE(4);
363
+ const keyData = buffer.subarray(8, genericPayload.length);
364
+ return new PayloadKE(genericPayload.nextPayload, dhGroup, keyData, genericPayload.critical, genericPayload.length);
365
+ }
366
+ /**
367
+ * Serializes a JSON representation of the KE payload to a buffer
368
+ * @param json
369
+ * @static
370
+ * @public
371
+ * @returns {Buffer}
372
+ */
373
+ static serializeJSON(json) {
374
+ try {
375
+ // Input validation
376
+ if (!json || typeof json !== "object") {
377
+ throw new Error("JSON input must be a valid object");
378
+ }
379
+ // Validate required fields
380
+ if (typeof json.dhGroup === "undefined") {
381
+ throw new Error("dhGroup is required");
382
+ }
383
+ if (typeof json.keyData === "undefined") {
384
+ throw new Error("keyData is required");
385
+ }
386
+ // Validate dhGroup
387
+ if (!Number.isInteger(json.dhGroup) ||
388
+ json.dhGroup < 0 ||
389
+ json.dhGroup > 65535) {
390
+ throw new Error(`dhGroup must be a valid 16-bit unsigned integer (0-65535), got ${json.dhGroup}`);
391
+ }
392
+ // Validate keyData
393
+ if (typeof json.keyData !== "string") {
394
+ throw new Error(`keyData must be a hex string, got ${typeof json.keyData}`);
395
+ }
396
+ // Validate hex string format
397
+ if (!/^[0-9a-fA-F]*$/.test(json.keyData)) {
398
+ throw new Error("keyData must be a valid hex string");
399
+ }
400
+ const buffer = Buffer.alloc(json.length);
401
+ const genericPayload = Payload.serializeJSON(json);
402
+ genericPayload.copy(buffer);
403
+ buffer.writeUInt16BE(json.dhGroup, 4);
404
+ buffer.writeUInt16BE(0, 6); // Reserved - use big-endian for consistency
405
+ Buffer.from(json.keyData, "hex").copy(buffer, 8);
406
+ return buffer;
407
+ }
408
+ catch (error) {
409
+ if (error instanceof Error) {
410
+ throw new Error(`Failed to serialize KE payload JSON: ${error.message}`);
411
+ }
412
+ throw new Error("Failed to serialize KE payload JSON");
413
+ }
414
+ }
415
+ /**
416
+ * Serializes the KE payload to a buffer
417
+ * @public
418
+ * @returns {Buffer}
419
+ */
420
+ serialize() {
421
+ // Fix the length
422
+ this.length = 8 + this.keyData.length;
423
+ const buffer = Buffer.alloc(this.length);
424
+ super.serialize().copy(buffer);
425
+ buffer.writeUInt16BE(this.dhGroup, 4);
426
+ // No need to blank 2 reserved bytes, Buffer.alloc does that
427
+ this.keyData.copy(buffer, 8);
428
+ return buffer;
429
+ }
430
+ /**
431
+ * Returns a JSON representation of the KE payload
432
+ * @public
433
+ * @returns {Record<string, any>}
434
+ */
435
+ toJSON() {
436
+ const json = super.genToJSON();
437
+ json.dhGroup = this.dhGroup;
438
+ json.keyData = this.keyData.toString("hex");
439
+ return json;
440
+ }
441
+ /**
442
+ * Returns a string representation of the KE payload
443
+ * @public
444
+ * @returns {string}
445
+ */
446
+ toString() {
447
+ const genericString = super.genToString();
448
+ return `${genericString}\ndhGroup: ${this.dhGroup}\nkeyData: "${this.keyData.toString("hex")}"`;
449
+ }
450
+ }
451
+ exports.PayloadKE = PayloadKE;
452
+ /**
453
+ * IKEv2 Identification Payload
454
+ * @enum
455
+ */
456
+ var IDType;
457
+ (function (IDType) {
458
+ IDType[IDType["ID_IPV4_ADDR"] = 1] = "ID_IPV4_ADDR";
459
+ IDType[IDType["ID_FQDN"] = 2] = "ID_FQDN";
460
+ IDType[IDType["ID_RFC822_ADDR"] = 3] = "ID_RFC822_ADDR";
461
+ IDType[IDType["ID_IPV6_ADDR"] = 5] = "ID_IPV6_ADDR";
462
+ IDType[IDType["ID_DER_ASN1_DN"] = 9] = "ID_DER_ASN1_DN";
463
+ IDType[IDType["ID_DER_ASN1_GN"] = 10] = "ID_DER_ASN1_GN";
464
+ IDType[IDType["ID_KEY_ID"] = 11] = "ID_KEY_ID";
465
+ })(IDType || (exports.IDType = IDType = {}));
466
+ /**
467
+ * IKEv2 Identification Payload
468
+ * @class
469
+ * @extends Payload
470
+ */
471
+ class PayloadID extends Payload {
472
+ constructor(nextPayload, idType, idData, critical = false, length = 0) {
473
+ super(payloadType.NONE, nextPayload, critical, length > 0 ? length : 5 + idData.length);
474
+ this.nextPayload = nextPayload;
475
+ this.idType = idType;
476
+ this.idData = idData;
477
+ this.critical = critical;
478
+ this.length = length;
479
+ }
480
+ /**
481
+ * Parses an Identification Payload from a buffer
482
+ * @param buffer
483
+ * @static
484
+ * @public
485
+ * @returns {PayloadID}
486
+ */
487
+ static parse(buffer) {
488
+ const genericPayload = Payload.parse(buffer);
489
+ // Validate that buffer is at least as long as the declared payload length
490
+ if (buffer.length < genericPayload.length) {
491
+ throw new Error(`Buffer too short for declared payload length. Expected at least ${genericPayload.length} bytes, got ${buffer.length}`);
492
+ }
493
+ // Check if we have enough data for idType (1 byte) and reserved field (3 bytes)
494
+ if (genericPayload.length < 8) {
495
+ throw new Error(`Payload too short for ID payload. Expected at least 8 bytes, got ${genericPayload.length}`);
496
+ }
497
+ const idType = buffer.readUInt8(4);
498
+ const idData = buffer.subarray(8, genericPayload.length);
499
+ return new PayloadID(genericPayload.nextPayload, idType, idData, genericPayload.critical, genericPayload.length);
500
+ }
501
+ /**
502
+ * Serializes a JSON representation of the ID payload to a buffer
503
+ * @param json
504
+ * @static
505
+ * @public
506
+ * @returns {Buffer}
507
+ */
508
+ static serializeJSON(json) {
509
+ try {
510
+ // Input validation
511
+ if (!json || typeof json !== "object") {
512
+ throw new Error("JSON input must be a valid object");
513
+ }
514
+ // Validate required fields
515
+ if (typeof json.idType === "undefined") {
516
+ throw new Error("idType is required");
517
+ }
518
+ if (typeof json.idData === "undefined") {
519
+ throw new Error("idData is required");
520
+ }
521
+ // Validate idType
522
+ if (!Number.isInteger(json.idType) ||
523
+ json.idType < 0 ||
524
+ json.idType > 255) {
525
+ throw new Error(`idType must be a valid 8-bit unsigned integer (0-255), got ${json.idType}`);
526
+ }
527
+ // Validate idData
528
+ if (typeof json.idData !== "string") {
529
+ throw new Error(`idData must be a hex string, got ${typeof json.idData}`);
530
+ }
531
+ // Validate hex string format
532
+ if (!/^[0-9a-fA-F]*$/.test(json.idData)) {
533
+ throw new Error("idData must be a valid hex string");
534
+ }
535
+ const buffer = Buffer.alloc(json.length);
536
+ const genericPayload = Payload.serializeJSON(json);
537
+ genericPayload.copy(buffer);
538
+ buffer.writeUInt8(json.idType, 4);
539
+ // Write 3-byte reserved field as zeros in big-endian order
540
+ buffer.writeUInt8(0, 5);
541
+ buffer.writeUInt8(0, 6);
542
+ buffer.writeUInt8(0, 7);
543
+ Buffer.from(json.idData, "hex").copy(buffer, 8);
544
+ return buffer;
545
+ }
546
+ catch (error) {
547
+ if (error instanceof Error) {
548
+ throw new Error(`Failed to serialize ID payload JSON: ${error.message}`);
549
+ }
550
+ throw new Error("Failed to serialize ID payload JSON");
551
+ }
552
+ }
553
+ /**
554
+ * Serializes the ID payload to a buffer
555
+ * @public
556
+ * @returns {Buffer}
557
+ */
558
+ serialize() {
559
+ // Fix the length
560
+ this.length = 8 + this.idData.length;
561
+ const buffer = Buffer.alloc(this.length);
562
+ super.serialize().copy(buffer);
563
+ buffer.writeUInt8(this.idType, 4);
564
+ // No need to blank 3 reserved bytes, Buffer.alloc does that
565
+ this.idData.copy(buffer, 8);
566
+ return buffer;
567
+ }
568
+ /**
569
+ * Returns a JSON representation of the ID payload
570
+ * @public
571
+ * @returns {Record<string, any>}
572
+ */
573
+ toJSON() {
574
+ const json = super.genToJSON();
575
+ json.idType = this.idType;
576
+ json.idData = this.idData.toString("hex");
577
+ return json;
578
+ }
579
+ /**
580
+ * Returns a string representation of the ID payload
581
+ * @public
582
+ * @returns {string}
583
+ */
584
+ toString() {
585
+ const genericString = super.genToString();
586
+ return `${genericString}\nidType: ${IDType[this.idType]}\nidData: "${this.idData.toString("hex")}"`;
587
+ }
588
+ }
589
+ exports.PayloadID = PayloadID;
590
+ /**
591
+ * IKEv2 Identification - Initiator Payload
592
+ * @class
593
+ * @extends PayloadID
594
+ */
595
+ class PayloadIDi extends PayloadID {
596
+ constructor(nextPayload, idType, idData, critical = false, length = 0) {
597
+ super(nextPayload, idType, idData, critical, length > 0 ? length : 5 + idData.length);
598
+ this.nextPayload = nextPayload;
599
+ this.idType = idType;
600
+ this.idData = idData;
601
+ this.critical = critical;
602
+ this.length = length;
603
+ this.type = payloadType.IDi;
604
+ }
605
+ }
606
+ exports.PayloadIDi = PayloadIDi;
607
+ /**
608
+ * IKEv2 Identification - Responder Payload
609
+ * @class
610
+ * @extends PayloadID
611
+ */
612
+ class PayloadIDr extends PayloadID {
613
+ constructor(nextPayload, idType, idData, critical, length) {
614
+ super(nextPayload, idType, idData, critical, length > 0 ? length : 5 + idData.length);
615
+ this.nextPayload = nextPayload;
616
+ this.idType = idType;
617
+ this.idData = idData;
618
+ this.critical = critical;
619
+ this.length = length;
620
+ this.type = payloadType.IDr;
621
+ }
622
+ }
623
+ exports.PayloadIDr = PayloadIDr;
624
+ /**
625
+ * IKEv2 Notify Message Types
626
+ * @enum
627
+ */
628
+ var CertificateType;
629
+ (function (CertificateType) {
630
+ CertificateType[CertificateType["RESERVED"] = 0] = "RESERVED";
631
+ CertificateType[CertificateType["PKCS7_X509_CERTIFICATE"] = 1] = "PKCS7_X509_CERTIFICATE";
632
+ CertificateType[CertificateType["PGP_CERTIFICATE"] = 2] = "PGP_CERTIFICATE";
633
+ CertificateType[CertificateType["DNS_SIGNED_KEY"] = 3] = "DNS_SIGNED_KEY";
634
+ CertificateType[CertificateType["X509_CERTIFICATE_SIGNATURE"] = 4] = "X509_CERTIFICATE_SIGNATURE";
635
+ CertificateType[CertificateType["UNDEFINED"] = 5] = "UNDEFINED";
636
+ CertificateType[CertificateType["KERBEROS_TOKENS"] = 6] = "KERBEROS_TOKENS";
637
+ CertificateType[CertificateType["CRL"] = 7] = "CRL";
638
+ CertificateType[CertificateType["ARL"] = 8] = "ARL";
639
+ CertificateType[CertificateType["SPKI_CERTIFICATE"] = 9] = "SPKI_CERTIFICATE";
640
+ CertificateType[CertificateType["X509_CERTIFICATE_ATTRIBUTE"] = 10] = "X509_CERTIFICATE_ATTRIBUTE";
641
+ CertificateType[CertificateType["RAW_RSA_KEY"] = 11] = "RAW_RSA_KEY";
642
+ CertificateType[CertificateType["HASH_AND_URL_X509_CERTIFICATE"] = 12] = "HASH_AND_URL_X509_CERTIFICATE";
643
+ CertificateType[CertificateType["HASH_AND_URL_X509_BUNDLE"] = 13] = "HASH_AND_URL_X509_BUNDLE";
644
+ CertificateType[CertificateType["OCSP_CONTENT"] = 14] = "OCSP_CONTENT";
645
+ })(CertificateType || (exports.CertificateType = CertificateType = {}));
646
+ /**
647
+ * IKEv2 Certificate Payload
648
+ * @class
649
+ * @extends Payload
650
+ */
651
+ class PayloadCERT extends Payload {
652
+ constructor(nextPayload, certEncoding, certData, critical = false, length = 0) {
653
+ super(payloadType.CERT, nextPayload, critical, length > 0 ? length : 5 + certData.length);
654
+ this.nextPayload = nextPayload;
655
+ this.certEncoding = certEncoding;
656
+ this.certData = certData;
657
+ this.critical = critical;
658
+ this.length = length;
659
+ }
660
+ /**
661
+ * Parses a Certificate Payload from a buffer
662
+ * @param buffer
663
+ * @static
664
+ * @public
665
+ * @returns {PayloadCERT}
666
+ */
667
+ static parse(buffer) {
668
+ const genericPayload = Payload.parse(buffer);
669
+ // Validate that buffer is at least as long as the declared payload length
670
+ if (buffer.length < genericPayload.length) {
671
+ throw new Error(`Buffer too short for declared payload length. Expected at least ${genericPayload.length} bytes, got ${buffer.length}`);
672
+ }
673
+ // Check if we have enough data for certEncoding (1 byte)
674
+ if (genericPayload.length < 5) {
675
+ throw new Error(`Payload too short for CERT payload. Expected at least 5 bytes, got ${genericPayload.length}`);
676
+ }
677
+ const certEncoding = buffer.readUInt8(4);
678
+ const certData = buffer.subarray(5, genericPayload.length);
679
+ return new PayloadCERT(genericPayload.nextPayload, certEncoding, certData, genericPayload.critical, genericPayload.length);
680
+ }
681
+ /**
682
+ * Serializes a JSON representation of the CERT payload to a buffer
683
+ * @param json
684
+ * @static
685
+ * @public
686
+ * @returns {Buffer}
687
+ */
688
+ static serializeJSON(json) {
689
+ const buffer = Buffer.alloc(json.length);
690
+ const genericPayload = Payload.serializeJSON(json);
691
+ genericPayload.copy(buffer);
692
+ buffer.writeUInt8(json.certEncoding, 4);
693
+ Buffer.from(json.certData, "hex").copy(buffer, 5);
694
+ return buffer;
695
+ }
696
+ /**
697
+ * Serializes the CERT payload to a buffer
698
+ * @public
699
+ * @returns {Buffer}
700
+ */
701
+ serialize() {
702
+ // Fix the length
703
+ this.length = 5 + this.certData.length;
704
+ const buffer = Buffer.alloc(this.length);
705
+ super.serialize().copy(buffer);
706
+ buffer.writeUInt8(this.certEncoding, 4);
707
+ this.certData.copy(buffer, 5);
708
+ return buffer;
709
+ }
710
+ /**
711
+ * Returns a JSON representation of the CERT payload
712
+ * @public
713
+ * @returns {Record<string, any>}
714
+ */
715
+ toJSON() {
716
+ const json = super.genToJSON();
717
+ json.certEncoding = this.certEncoding;
718
+ json.certData = this.certData.toString("hex");
719
+ return json;
720
+ }
721
+ /**
722
+ * Returns a string representation of the CERT payload
723
+ * @public
724
+ * @returns {string}
725
+ */
726
+ toString() {
727
+ const genericString = super.genToString();
728
+ return `${genericString}\ncertEncoding: ${CertificateType[this.certEncoding]} (${this.certEncoding})\ncertData: "${this.certData.toString("hex")}"`;
729
+ }
730
+ }
731
+ exports.PayloadCERT = PayloadCERT;
732
+ /**
733
+ * IKEv2 Certificate Request Payload
734
+ * @class
735
+ * @extends Payload
736
+ */
737
+ class PayloadCERTREQ extends Payload {
738
+ constructor(nextPayload, certEncoding, certAuthority, critical = false, length = 0) {
739
+ super(payloadType.CERTREQ, nextPayload, critical, length > 0 ? length : 5 + certAuthority.length);
740
+ this.nextPayload = nextPayload;
741
+ this.certEncoding = certEncoding;
742
+ this.certAuthority = certAuthority;
743
+ this.critical = critical;
744
+ this.length = length;
745
+ }
746
+ /**
747
+ * Parses a Certificate Request Payload from a buffer
748
+ * @param buffer
749
+ * @static
750
+ * @public
751
+ * @returns {PayloadCERTREQ}
752
+ */
753
+ static parse(buffer) {
754
+ const genericPayload = Payload.parse(buffer);
755
+ const certEncoding = buffer.readUInt8(4);
756
+ const certAuthority = buffer.subarray(5, genericPayload.length);
757
+ return new PayloadCERTREQ(genericPayload.nextPayload, certEncoding, certAuthority, genericPayload.critical, genericPayload.length);
758
+ }
759
+ /**
760
+ * Serializes a JSON representation of the CERTREQ payload to a buffer
761
+ * @param json
762
+ * @static
763
+ * @public
764
+ * @returns {Buffer}
765
+ */
766
+ static serializeJSON(json) {
767
+ const buffer = Buffer.alloc(json.length);
768
+ const genericPayload = Payload.serializeJSON(json);
769
+ genericPayload.copy(buffer);
770
+ buffer.writeUInt8(json.certEncoding, 4);
771
+ Buffer.from(json.certAuthority, "hex").copy(buffer, 5);
772
+ return buffer;
773
+ }
774
+ /**
775
+ * Serializes the CERTREQ payload to a buffer
776
+ * @public
777
+ * @returns {Buffer}
778
+ */
779
+ serialize() {
780
+ // Fix the length
781
+ this.length = 5 + this.certAuthority.length;
782
+ const buffer = Buffer.alloc(this.length);
783
+ super.serialize().copy(buffer);
784
+ buffer.writeUInt8(this.certEncoding, 4);
785
+ this.certAuthority.copy(buffer, 5);
786
+ return buffer;
787
+ }
788
+ /**
789
+ * Returns a JSON representation of the CERTREQ payload
790
+ * @public
791
+ * @returns {Record<string, any>}
792
+ */
793
+ toJSON() {
794
+ const json = super.genToJSON();
795
+ json.certEncoding = this.certEncoding;
796
+ json.certAuthority = this.certAuthority.toString("hex");
797
+ return json;
798
+ }
799
+ /**
800
+ * Returns a string representation of the CERTREQ payload
801
+ * @public
802
+ * @returns {string}
803
+ */
804
+ toString() {
805
+ const genericString = super.genToString();
806
+ return `${genericString}\ncertEncoding: ${CertificateType[this.certEncoding]} (${this.certEncoding})\ncertAuthority: "${this.certAuthority.toString("hex")}"`;
807
+ }
808
+ }
809
+ exports.PayloadCERTREQ = PayloadCERTREQ;
810
+ /**
811
+ * IKEv2 Authentication Payload
812
+ * @class
813
+ * @extends Payload
814
+ */
815
+ class PayloadAUTH extends Payload {
816
+ constructor(nextPayload, authMethod, authData, critical = false, length = 0) {
817
+ super(payloadType.AUTH, nextPayload, critical, length > 0 ? length : 5 + authData.length);
818
+ this.nextPayload = nextPayload;
819
+ this.authMethod = authMethod;
820
+ this.authData = authData;
821
+ this.critical = critical;
822
+ this.length = length;
823
+ }
824
+ /**
825
+ * Parses an Authentication Payload from a buffer
826
+ * @param buffer
827
+ * @static
828
+ * @public
829
+ * @returns {PayloadAUTH}
830
+ */
831
+ static parse(buffer) {
832
+ const genericPayload = Payload.parse(buffer);
833
+ const authMethod = buffer.readUInt8(4);
834
+ const authData = buffer.subarray(5, genericPayload.length);
835
+ return new PayloadAUTH(genericPayload.nextPayload, authMethod, authData, genericPayload.critical, genericPayload.length);
836
+ }
837
+ /**
838
+ * Serializes a JSON representation of the AUTH payload to a buffer
839
+ * @param json
840
+ * @static
841
+ * @public
842
+ * @returns {Buffer}
843
+ */
844
+ static serializeJSON(json) {
845
+ const buffer = Buffer.alloc(json.length);
846
+ const genericPayload = Payload.serializeJSON(json);
847
+ genericPayload.copy(buffer);
848
+ buffer.writeUInt8(json.authMethod, 4);
849
+ // Write 3-byte reserved field as zeros in big-endian order
850
+ buffer.writeUInt8(0, 5);
851
+ buffer.writeUInt8(0, 6);
852
+ buffer.writeUInt8(0, 7);
853
+ Buffer.from(json.authData, "hex").copy(buffer, 8);
854
+ return buffer;
855
+ }
856
+ /**
857
+ * Serializes the AUTH payload to a buffer
858
+ * @public
859
+ * @returns {Buffer}
860
+ */
861
+ serialize() {
862
+ // Fix the length
863
+ this.length = 8 + this.authData.length;
864
+ const buffer = Buffer.alloc(this.length);
865
+ super.serialize().copy(buffer);
866
+ buffer.writeUInt8(this.authMethod, 4);
867
+ // No need to blank 3 reserved bytes, Buffer.alloc does that
868
+ this.authData.copy(buffer, 8);
869
+ return buffer;
870
+ }
871
+ /**
872
+ * Returns a JSON representation of the AUTH payload
873
+ * @public
874
+ * @returns {Record<string, any>}
875
+ */
876
+ toJSON() {
877
+ const json = super.genToJSON();
878
+ json.authMethod = this.authMethod;
879
+ json.authData = this.authData.toString("hex");
880
+ return json;
881
+ }
882
+ /**
883
+ * Returns a string representation of the AUTH payload
884
+ * @public
885
+ * @returns {string}
886
+ */
887
+ toString() {
888
+ const genericString = super.genToString();
889
+ return `${genericString}\nauthMethod: ${this.authMethod}\nauthData: "${this.authData.toString("hex")}"`;
890
+ }
891
+ }
892
+ exports.PayloadAUTH = PayloadAUTH;
893
+ /**
894
+ * IKEv2 Nonce Payload
895
+ * @class
896
+ * @extends Payload
897
+ */
898
+ class PayloadNONCE extends Payload {
899
+ constructor(nextPayload, nonceData, critical = false, length = 0) {
900
+ super(payloadType.NONCE, nextPayload, critical, length > 0 ? length : 4 + nonceData.length);
901
+ this.nextPayload = nextPayload;
902
+ this.nonceData = nonceData;
903
+ this.critical = critical;
904
+ this.length = length;
905
+ }
906
+ /**
907
+ * Parses a Nonce Payload from a buffer
908
+ * @param buffer
909
+ * @static
910
+ * @public
911
+ * @returns {PayloadNONCE}
912
+ */
913
+ static parse(buffer) {
914
+ const genericPayload = Payload.parse(buffer);
915
+ const nonceData = buffer.subarray(4, genericPayload.length);
916
+ return new PayloadNONCE(genericPayload.nextPayload, nonceData, genericPayload.critical, genericPayload.length);
917
+ }
918
+ /**
919
+ * Serializes a JSON representation of the NONCE payload to a buffer
920
+ * @param json
921
+ * @static
922
+ * @public
923
+ * @returns {Buffer}
924
+ */
925
+ static serializeJSON(json) {
926
+ const buffer = Buffer.alloc(json.length);
927
+ const genericPayload = Payload.serializeJSON(json);
928
+ genericPayload.copy(buffer);
929
+ Buffer.from(json.nonceData, "hex").copy(buffer, 4);
930
+ return buffer;
931
+ }
932
+ /**
933
+ * Serializes the NONCE payload to a buffer
934
+ * @public
935
+ * @returns {Buffer}
936
+ */
937
+ serialize() {
938
+ // Fix the length
939
+ this.length = 4 + this.nonceData.length;
940
+ const buffer = Buffer.alloc(this.length);
941
+ super.serialize().copy(buffer);
942
+ this.nonceData.copy(buffer, 4);
943
+ return buffer;
944
+ }
945
+ /**
946
+ * Returns a JSON representation of the NONCE payload
947
+ * @public
948
+ * @returns {Record<string, any>}
949
+ */
950
+ toJSON() {
951
+ const json = super.genToJSON();
952
+ json.nonceData = this.nonceData.toString("hex");
953
+ return json;
954
+ }
955
+ /**
956
+ * Returns a string representation of the NONCE payload
957
+ * @public
958
+ * @returns {string}
959
+ */
960
+ toString() {
961
+ const genericString = super.genToString();
962
+ return `${genericString}\nnonceData: "${this.nonceData.toString("hex")}"`;
963
+ }
964
+ }
965
+ exports.PayloadNONCE = PayloadNONCE;
966
+ /**
967
+ * IKEv2 Protocol Id
968
+ * @enum
969
+ */
970
+ var securityProtocolId;
971
+ (function (securityProtocolId) {
972
+ // 0 - Reserved
973
+ securityProtocolId[securityProtocolId["NONE"] = 0] = "NONE";
974
+ securityProtocolId[securityProtocolId["IKE"] = 1] = "IKE";
975
+ securityProtocolId[securityProtocolId["AH"] = 2] = "AH";
976
+ securityProtocolId[securityProtocolId["ESP"] = 3] = "ESP";
977
+ securityProtocolId[securityProtocolId["FC_ESP_HEADER"] = 4] = "FC_ESP_HEADER";
978
+ securityProtocolId[securityProtocolId["FC_CT_AUTHENTICATION"] = 5] = "FC_CT_AUTHENTICATION";
979
+ securityProtocolId[securityProtocolId["GIKE_UPDATE"] = 6] = "GIKE_UPDATE";
980
+ // 7-200 Unassigned
981
+ // 201-255 - Reserved for Private Use
982
+ })(securityProtocolId || (exports.securityProtocolId = securityProtocolId = {}));
983
+ /**
984
+ * IKEv2 Notify Message Types
985
+ * @enum
986
+ */
987
+ var notifyMessageType;
988
+ (function (notifyMessageType) {
989
+ notifyMessageType[notifyMessageType["UNSUPPORTED_CRITICAL_PAYLOAD"] = 1] = "UNSUPPORTED_CRITICAL_PAYLOAD";
990
+ notifyMessageType[notifyMessageType["INVALID_IKE_SPI"] = 4] = "INVALID_IKE_SPI";
991
+ notifyMessageType[notifyMessageType["INVALID_MAJOR_VERSION"] = 5] = "INVALID_MAJOR_VERSION";
992
+ notifyMessageType[notifyMessageType["INVALID_SYNTAX"] = 7] = "INVALID_SYNTAX";
993
+ notifyMessageType[notifyMessageType["INVALID_MESSAGE_ID"] = 9] = "INVALID_MESSAGE_ID";
994
+ notifyMessageType[notifyMessageType["INVALID_SPI"] = 11] = "INVALID_SPI";
995
+ notifyMessageType[notifyMessageType["NO_PROPOSAL_CHOSEN"] = 14] = "NO_PROPOSAL_CHOSEN";
996
+ notifyMessageType[notifyMessageType["INVALID_KE_PAYLOAD"] = 17] = "INVALID_KE_PAYLOAD";
997
+ notifyMessageType[notifyMessageType["AUTHENTICATION_FAILED"] = 24] = "AUTHENTICATION_FAILED";
998
+ notifyMessageType[notifyMessageType["SINGLE_PAIR_REQUIRED"] = 34] = "SINGLE_PAIR_REQUIRED";
999
+ notifyMessageType[notifyMessageType["NO_ADDITIONAL_SAS"] = 35] = "NO_ADDITIONAL_SAS";
1000
+ notifyMessageType[notifyMessageType["INTERNAL_ADDRESS_FAILURE"] = 36] = "INTERNAL_ADDRESS_FAILURE";
1001
+ notifyMessageType[notifyMessageType["FAILED_CP_REQUIRED"] = 37] = "FAILED_CP_REQUIRED";
1002
+ notifyMessageType[notifyMessageType["TS_UNACCEPTABLE"] = 38] = "TS_UNACCEPTABLE";
1003
+ notifyMessageType[notifyMessageType["INVALID_SELECTORS"] = 39] = "INVALID_SELECTORS";
1004
+ notifyMessageType[notifyMessageType["TEMPORARY_FAILURE"] = 43] = "TEMPORARY_FAILURE";
1005
+ notifyMessageType[notifyMessageType["CHILD_SA_NOT_FOUND"] = 44] = "CHILD_SA_NOT_FOUND";
1006
+ notifyMessageType[notifyMessageType["INITIAL_CONTACT"] = 16384] = "INITIAL_CONTACT";
1007
+ notifyMessageType[notifyMessageType["SET_WINDOW_SIZE"] = 16385] = "SET_WINDOW_SIZE";
1008
+ notifyMessageType[notifyMessageType["ADDITIONAL_TS_POSSIBLE"] = 16386] = "ADDITIONAL_TS_POSSIBLE";
1009
+ notifyMessageType[notifyMessageType["IPCOMP_SUPPORTED"] = 16387] = "IPCOMP_SUPPORTED";
1010
+ notifyMessageType[notifyMessageType["NAT_DETECTION_SOURCE_IP"] = 16388] = "NAT_DETECTION_SOURCE_IP";
1011
+ notifyMessageType[notifyMessageType["NAT_DETECTION_DESTINATION_IP"] = 16389] = "NAT_DETECTION_DESTINATION_IP";
1012
+ notifyMessageType[notifyMessageType["COOKIE"] = 16390] = "COOKIE";
1013
+ notifyMessageType[notifyMessageType["USE_TRANSPORT_MODE"] = 16391] = "USE_TRANSPORT_MODE";
1014
+ notifyMessageType[notifyMessageType["HTTP_CERT_LOOKUP_SUPPORTED"] = 16392] = "HTTP_CERT_LOOKUP_SUPPORTED";
1015
+ notifyMessageType[notifyMessageType["REKEY_SA"] = 16393] = "REKEY_SA";
1016
+ notifyMessageType[notifyMessageType["ESP_TFC_PADDING_NOT_SUPPORTED"] = 16394] = "ESP_TFC_PADDING_NOT_SUPPORTED";
1017
+ notifyMessageType[notifyMessageType["NON_FIRST_FRAGMENTS_ALSO"] = 16395] = "NON_FIRST_FRAGMENTS_ALSO";
1018
+ notifyMessageType[notifyMessageType["MOBIKE_SUPPORTED"] = 16396] = "MOBIKE_SUPPORTED";
1019
+ notifyMessageType[notifyMessageType["ADDITIONAL_IP4_ADDRESS"] = 16397] = "ADDITIONAL_IP4_ADDRESS";
1020
+ notifyMessageType[notifyMessageType["ADDITIONAL_IP6_ADDRESS"] = 16398] = "ADDITIONAL_IP6_ADDRESS";
1021
+ notifyMessageType[notifyMessageType["NO_ADDITIONAL_ADDRESSES"] = 16399] = "NO_ADDITIONAL_ADDRESSES";
1022
+ notifyMessageType[notifyMessageType["UPDATE_SA_ADDRESSES"] = 16400] = "UPDATE_SA_ADDRESSES";
1023
+ notifyMessageType[notifyMessageType["COOKIE2"] = 16401] = "COOKIE2";
1024
+ notifyMessageType[notifyMessageType["NO_NATS_ALLOWED"] = 16402] = "NO_NATS_ALLOWED";
1025
+ notifyMessageType[notifyMessageType["AUTH_LIFETIME"] = 16403] = "AUTH_LIFETIME";
1026
+ notifyMessageType[notifyMessageType["MULTIPLE_AUTH_SUPPORTED"] = 16404] = "MULTIPLE_AUTH_SUPPORTED";
1027
+ notifyMessageType[notifyMessageType["ANOTHER_AUTH_FOLLOWS"] = 16405] = "ANOTHER_AUTH_FOLLOWS";
1028
+ notifyMessageType[notifyMessageType["REDIRECT_SUPPORTED"] = 16406] = "REDIRECT_SUPPORTED";
1029
+ notifyMessageType[notifyMessageType["REDIRECT"] = 16407] = "REDIRECT";
1030
+ notifyMessageType[notifyMessageType["REDIRECTED_FROM"] = 16408] = "REDIRECTED_FROM";
1031
+ notifyMessageType[notifyMessageType["TICKET_LT_OPAQUE"] = 16409] = "TICKET_LT_OPAQUE";
1032
+ notifyMessageType[notifyMessageType["TICKET_REQUEST"] = 16410] = "TICKET_REQUEST";
1033
+ notifyMessageType[notifyMessageType["TICKET_ACK"] = 16411] = "TICKET_ACK";
1034
+ notifyMessageType[notifyMessageType["TICKET_NACK"] = 16412] = "TICKET_NACK";
1035
+ notifyMessageType[notifyMessageType["TICKET_OPAQUE"] = 16413] = "TICKET_OPAQUE";
1036
+ notifyMessageType[notifyMessageType["LINK_ID"] = 16414] = "LINK_ID";
1037
+ notifyMessageType[notifyMessageType["USE_WESP_MODE"] = 16415] = "USE_WESP_MODE";
1038
+ notifyMessageType[notifyMessageType["ROHC_SUPPORTED"] = 16416] = "ROHC_SUPPORTED";
1039
+ notifyMessageType[notifyMessageType["EAP_ONLY_AUTHENTICATION"] = 16417] = "EAP_ONLY_AUTHENTICATION";
1040
+ notifyMessageType[notifyMessageType["CHILDLESS_IKEV2_SUPPORTED"] = 16418] = "CHILDLESS_IKEV2_SUPPORTED";
1041
+ notifyMessageType[notifyMessageType["QUICK_CRASH_DETECTION"] = 16419] = "QUICK_CRASH_DETECTION";
1042
+ notifyMessageType[notifyMessageType["IKEV2_MESSAGE_ID_SYNC_SUPPORTED"] = 16420] = "IKEV2_MESSAGE_ID_SYNC_SUPPORTED";
1043
+ notifyMessageType[notifyMessageType["IPSEC_REPLAY_COUNTER_SYNC_SUPPORTED"] = 16421] = "IPSEC_REPLAY_COUNTER_SYNC_SUPPORTED";
1044
+ notifyMessageType[notifyMessageType["IKEV2_MESSAGE_ID_SYNC"] = 16422] = "IKEV2_MESSAGE_ID_SYNC";
1045
+ notifyMessageType[notifyMessageType["IPSEC_REPLAY_COUNTER_SYNC"] = 16423] = "IPSEC_REPLAY_COUNTER_SYNC";
1046
+ notifyMessageType[notifyMessageType["SECURE_PASSWORD_METHODS"] = 16424] = "SECURE_PASSWORD_METHODS";
1047
+ notifyMessageType[notifyMessageType["PSK_PERSIST"] = 16425] = "PSK_PERSIST";
1048
+ notifyMessageType[notifyMessageType["PSK_CONFIRM"] = 16426] = "PSK_CONFIRM";
1049
+ notifyMessageType[notifyMessageType["ERX_SUPPORTED"] = 16427] = "ERX_SUPPORTED";
1050
+ notifyMessageType[notifyMessageType["IFOM_CAPABILITY"] = 16428] = "IFOM_CAPABILITY";
1051
+ notifyMessageType[notifyMessageType["SENDER_REQUEST_ID"] = 16429] = "SENDER_REQUEST_ID";
1052
+ notifyMessageType[notifyMessageType["IKEV2_FRAGMENTATION_SUPPORTED"] = 16430] = "IKEV2_FRAGMENTATION_SUPPORTED";
1053
+ notifyMessageType[notifyMessageType["SIGNATURE_HASH_ALGORITHMS"] = 16431] = "SIGNATURE_HASH_ALGORITHMS";
1054
+ notifyMessageType[notifyMessageType["CLONE_IKE_SA_SUPPORTED"] = 16432] = "CLONE_IKE_SA_SUPPORTED";
1055
+ notifyMessageType[notifyMessageType["CLONE_IKE_SA"] = 16433] = "CLONE_IKE_SA";
1056
+ notifyMessageType[notifyMessageType["PUZZLE"] = 16434] = "PUZZLE";
1057
+ notifyMessageType[notifyMessageType["USE_PPK"] = 16435] = "USE_PPK";
1058
+ notifyMessageType[notifyMessageType["PPK_IDENTITY"] = 16436] = "PPK_IDENTITY";
1059
+ notifyMessageType[notifyMessageType["NO_PPK_AUTH"] = 16437] = "NO_PPK_AUTH";
1060
+ notifyMessageType[notifyMessageType["INTERMEDIATE_EXCHANGE_SUPPORTED"] = 16438] = "INTERMEDIATE_EXCHANGE_SUPPORTED";
1061
+ notifyMessageType[notifyMessageType["IP4_ALLOWED_1"] = 16439] = "IP4_ALLOWED_1";
1062
+ notifyMessageType[notifyMessageType["IP4_ALLOWED_2"] = 16440] = "IP4_ALLOWED_2";
1063
+ notifyMessageType[notifyMessageType["ADDITIONAL_KEY_EXCHANGE"] = 16441] = "ADDITIONAL_KEY_EXCHANGE";
1064
+ notifyMessageType[notifyMessageType["USE_AGGFRAG"] = 16442] = "USE_AGGFRAG";
1065
+ notifyMessageType[notifyMessageType["RESERVED_TO_IANA_STATUS_TYPES"] = 16443] = "RESERVED_TO_IANA_STATUS_TYPES";
1066
+ })(notifyMessageType || (exports.notifyMessageType = notifyMessageType = {}));
1067
+ /**
1068
+ * IKEv2 Notify Payload
1069
+ * @class
1070
+ * @extends Payload
1071
+ */
1072
+ class PayloadNOTIFY extends Payload {
1073
+ constructor(nextPayload, protocolId, spiSize, notifyType, spi, notifyData, critical = false, length = 0) {
1074
+ super(payloadType.NOTIFY, nextPayload, critical, length > 0 ? length : 8 + spi.length + notifyData.length);
1075
+ this.nextPayload = nextPayload;
1076
+ this.protocolId = protocolId;
1077
+ this.spiSize = spiSize;
1078
+ this.notifyType = notifyType;
1079
+ this.spi = spi;
1080
+ this.notifyData = notifyData;
1081
+ this.critical = critical;
1082
+ this.length = length;
1083
+ }
1084
+ /**
1085
+ * Parses a Notify Payload from a buffer
1086
+ * @param buffer
1087
+ * @static
1088
+ * @public
1089
+ * @returns {PayloadNOTIFY}
1090
+ */
1091
+ static parse(buffer) {
1092
+ const genericPayload = Payload.parse(buffer);
1093
+ const protocolId = buffer.readUInt8(4);
1094
+ const spiSize = buffer.readUInt8(5);
1095
+ const notifyType = buffer.readUInt16BE(6);
1096
+ const spi = buffer.subarray(8, 8 + spiSize);
1097
+ const notifyData = buffer.subarray(8 + spiSize, genericPayload.length);
1098
+ return new PayloadNOTIFY(genericPayload.nextPayload, protocolId, spiSize, notifyType, spi, notifyData, genericPayload.critical, genericPayload.length);
1099
+ }
1100
+ /**
1101
+ * Serializes a JSON representation of the NOTIFY payload to a buffer
1102
+ * @param json
1103
+ * @static
1104
+ * @public
1105
+ * @returns {Buffer}
1106
+ */
1107
+ static serializeJSON(json) {
1108
+ const buffer = Buffer.alloc(json.length);
1109
+ const genericPayload = Payload.serializeJSON(json);
1110
+ genericPayload.copy(buffer);
1111
+ buffer.writeUInt8(json.protocolId, 4);
1112
+ buffer.writeUInt8(json.spiSize, 5);
1113
+ buffer.writeUInt16BE(json.notifyType, 6);
1114
+ json.spi.length > 0
1115
+ ? Buffer.from(json.spi, "hex").copy(buffer, 8)
1116
+ : Buffer.alloc(0).copy(buffer, 8);
1117
+ json.notifyData.length > 0
1118
+ ? Buffer.from(json.notifyData, "hex").copy(buffer, 8 + json.spiSize)
1119
+ : Buffer.alloc(0).copy(buffer, 8 + json.spiSize);
1120
+ return buffer;
1121
+ }
1122
+ /**
1123
+ * Serializes the NOTIFY payload to a buffer
1124
+ * @public
1125
+ * @returns {Buffer}
1126
+ */
1127
+ serialize() {
1128
+ // Fix the length
1129
+ this.length = 8 + this.spi.length + this.notifyData.length;
1130
+ const buffer = Buffer.alloc(this.length);
1131
+ super.serialize().copy(buffer);
1132
+ buffer.writeUInt8(this.protocolId, 4);
1133
+ buffer.writeUInt8(this.spiSize, 5);
1134
+ buffer.writeUInt16BE(this.notifyType, 6);
1135
+ this.spi.copy(buffer, 8);
1136
+ this.notifyData.copy(buffer, 8 + this.spiSize);
1137
+ return buffer;
1138
+ }
1139
+ /**
1140
+ * Returns a JSON representation of the NOTIFY payload
1141
+ * @public
1142
+ * @returns {Record<string, any>}
1143
+ */
1144
+ toJSON() {
1145
+ const json = super.genToJSON();
1146
+ json.protocolId = this.protocolId;
1147
+ json.spiSize = this.spiSize;
1148
+ json.notifyType = this.notifyType;
1149
+ json.spi = this.spi.toString("hex");
1150
+ json.notifyData = this.notifyData.toString("hex");
1151
+ return json;
1152
+ }
1153
+ /**
1154
+ * Returns a string representation of the NOTIFY payload
1155
+ * @public
1156
+ * @returns {string}
1157
+ */
1158
+ toString() {
1159
+ var _a, _b;
1160
+ const genericString = super.genToString();
1161
+ return `${genericString}\nprotocolId: ${securityProtocolId[this.protocolId]}\nspiSize: ${this.spiSize}\nnotifyType: ${notifyMessageType[this.notifyType]} (${this.notifyType})\nspi: "${(_b = (_a = this.spi) === null || _a === void 0 ? void 0 : _a.toString("hex")) !== null && _b !== void 0 ? _b : "N/A"}"\nnotifyData: "${this.notifyData.toString("hex")}"`;
1162
+ }
1163
+ }
1164
+ exports.PayloadNOTIFY = PayloadNOTIFY;
1165
+ /**
1166
+ * IKEv2 Delete Payload
1167
+ * @class
1168
+ * @extends Payload
1169
+ */
1170
+ class PayloadDELETE extends Payload {
1171
+ constructor(nextPayload, protocolId, spiSize, numSpi, spis, critical = false, length = 0) {
1172
+ super(payloadType.DELETE, nextPayload, critical, length > 0 ? length : 8 + spiSize * numSpi);
1173
+ this.nextPayload = nextPayload;
1174
+ this.protocolId = protocolId;
1175
+ this.spiSize = spiSize;
1176
+ this.numSpi = numSpi;
1177
+ this.spis = spis;
1178
+ this.critical = critical;
1179
+ this.length = length;
1180
+ }
1181
+ /**
1182
+ * Parses a Delete Payload from a buffer
1183
+ * @param buffer
1184
+ * @static
1185
+ * @public
1186
+ * @returns {PayloadDELETE}
1187
+ */
1188
+ static parse(buffer) {
1189
+ const genericPayload = Payload.parse(buffer);
1190
+ const protocolId = buffer.readUInt8(4);
1191
+ const spiSize = buffer.readUInt8(5);
1192
+ const numSpi = buffer.readUInt16BE(6);
1193
+ const spis = [];
1194
+ let offset = 8;
1195
+ for (let i = 0; i < numSpi; i++) {
1196
+ const spi = buffer.subarray(offset, offset + spiSize);
1197
+ spis.push(spi);
1198
+ offset += spiSize;
1199
+ }
1200
+ return new PayloadDELETE(genericPayload.nextPayload, protocolId, spiSize, numSpi, spis, genericPayload.critical, genericPayload.length);
1201
+ }
1202
+ /**
1203
+ * Serializes a JSON representation of the DELETE payload to a buffer
1204
+ * @param json
1205
+ * @static
1206
+ * @public
1207
+ * @returns {Buffer}
1208
+ */
1209
+ static serializeJSON(json) {
1210
+ var _a;
1211
+ const buffer = Buffer.alloc(json.length);
1212
+ const genericPayload = Payload.serializeJSON(json);
1213
+ genericPayload.copy(buffer);
1214
+ buffer.writeUInt8(json.protocolId, 4);
1215
+ buffer.writeUInt8(json.spiSize, 5);
1216
+ buffer.writeUInt16BE(json.numSpi, 6);
1217
+ let offset = 8;
1218
+ const spisBuffer = ((_a = json.spis) === null || _a === void 0 ? void 0 : _a.length) > 0
1219
+ ? json.spis.map((spi) => Buffer.from(spi, "hex"))
1220
+ : [Buffer.alloc(0)];
1221
+ for (const spiBuffer of spisBuffer) {
1222
+ spiBuffer.copy(buffer, offset);
1223
+ offset += json.spiSize;
1224
+ }
1225
+ return buffer;
1226
+ }
1227
+ /**
1228
+ * Serializes the DELETE payload to a buffer
1229
+ * @public
1230
+ * @returns {Buffer}
1231
+ */
1232
+ serialize() {
1233
+ // Fix the length
1234
+ this.length = 8 + this.spiSize * this.numSpi;
1235
+ const buffer = Buffer.alloc(this.length);
1236
+ super.serialize().copy(buffer);
1237
+ buffer.writeUInt8(this.protocolId, 4);
1238
+ buffer.writeUInt8(this.spiSize, 5);
1239
+ buffer.writeUInt16BE(this.numSpi, 6);
1240
+ let offset = 8;
1241
+ for (const spi of this.spis) {
1242
+ spi.copy(buffer, offset);
1243
+ offset += this.spiSize;
1244
+ }
1245
+ return buffer;
1246
+ }
1247
+ /**
1248
+ * Returns a JSON representation of the DELETE payload
1249
+ * @public
1250
+ * @returns {Record<string, any>}
1251
+ */
1252
+ toJSON() {
1253
+ const json = super.genToJSON();
1254
+ json.protocolId = this.protocolId;
1255
+ json.spiSize = this.spiSize;
1256
+ json.numSpi = this.numSpi;
1257
+ json.spis = this.spis.map((spi) => spi.toString("hex"));
1258
+ return json;
1259
+ }
1260
+ /**
1261
+ * Returns a string representation of the DELETE payload
1262
+ * @public
1263
+ * @returns {string}
1264
+ */
1265
+ toString() {
1266
+ const genericString = super.genToString();
1267
+ return `${genericString}\nprotocolId: ${this.protocolId}\nspiSize: ${this.spiSize}\nnumSpi: ${this.numSpi}\nspis: ${this.spis.map((spi) => spi.toString("hex")).join(",")}`;
1268
+ }
1269
+ }
1270
+ exports.PayloadDELETE = PayloadDELETE;
1271
+ /**
1272
+ * IKEv2 Vendor ID Payload
1273
+ * @class
1274
+ * @extends Payload
1275
+ */
1276
+ class PayloadVENDOR extends Payload {
1277
+ constructor(nextPayload, vendorId, critical = false, length = 0) {
1278
+ super(payloadType.VENDOR, nextPayload, critical, length > 0 ? length : 4 + vendorId.length);
1279
+ this.nextPayload = nextPayload;
1280
+ this.vendorId = vendorId;
1281
+ this.critical = critical;
1282
+ this.length = length;
1283
+ }
1284
+ /**
1285
+ * Parses a Vendor ID Payload from a buffer
1286
+ * @param buffer
1287
+ * @static
1288
+ * @public
1289
+ * @returns {PayloadVENDOR}
1290
+ */
1291
+ static parse(buffer) {
1292
+ const genericPayload = Payload.parse(buffer);
1293
+ const vendorId = buffer.subarray(4, genericPayload.length);
1294
+ return new PayloadVENDOR(genericPayload.nextPayload, vendorId, genericPayload.critical, genericPayload.length);
1295
+ }
1296
+ /**
1297
+ * Serializes a JSON representation of the VENDOR payload to a buffer
1298
+ * @param json
1299
+ * @static
1300
+ * @public
1301
+ * @returns {Buffer}
1302
+ */
1303
+ static serializeJSON(json) {
1304
+ const buffer = Buffer.alloc(json.length);
1305
+ const genericPayload = Payload.serializeJSON(json);
1306
+ genericPayload.copy(buffer);
1307
+ Buffer.from(json.vendorId, "hex").copy(buffer, 4);
1308
+ return buffer;
1309
+ }
1310
+ /**
1311
+ * Serializes the VENDOR payload to a buffer
1312
+ * @public
1313
+ * @returns {Buffer}
1314
+ */
1315
+ serialize() {
1316
+ // Fix the length
1317
+ this.length = 4 + this.vendorId.length;
1318
+ const buffer = Buffer.alloc(this.length);
1319
+ super.serialize().copy(buffer);
1320
+ this.vendorId.copy(buffer, 4);
1321
+ return buffer;
1322
+ }
1323
+ /**
1324
+ * Returns a JSON representation of the VENDOR payload
1325
+ * @public
1326
+ * @returns {Record<string, any>}
1327
+ */
1328
+ toJSON() {
1329
+ const json = super.genToJSON();
1330
+ json.vendorId = this.vendorId.toString("hex");
1331
+ return json;
1332
+ }
1333
+ /**
1334
+ * Returns a string representation of the VENDOR payload
1335
+ * @public
1336
+ * @returns {string}
1337
+ */
1338
+ toString() {
1339
+ const genericString = super.genToString();
1340
+ return `${genericString}\nvendorId: "${this.vendorId.toString("hex")}"`;
1341
+ }
1342
+ }
1343
+ exports.PayloadVENDOR = PayloadVENDOR;
1344
+ /**
1345
+ * IKEv2 Traffic Selector
1346
+ * @class
1347
+ * @extends Payload
1348
+ */
1349
+ class PayloadTS extends Payload {
1350
+ constructor(nextPayload, numTs, tsList, critical = false, length = 0) {
1351
+ super(payloadType.NONE, nextPayload, critical, length > 0 ? length : 5 + tsList.reduce((acc, ts) => acc + ts.length, 0));
1352
+ this.nextPayload = nextPayload;
1353
+ this.numTs = numTs;
1354
+ this.tsList = tsList;
1355
+ this.critical = critical;
1356
+ this.length = length;
1357
+ }
1358
+ /**
1359
+ * Parses a Traffic Selector Payload from a buffer
1360
+ * @param buffer
1361
+ * @static
1362
+ * @public
1363
+ * @returns {PayloadTS}
1364
+ */
1365
+ static parse(buffer) {
1366
+ const genericPayload = Payload.parse(buffer);
1367
+ const numTs = buffer.readUInt8(4);
1368
+ const tsList = [];
1369
+ let offset = 8;
1370
+ for (let i = 0; i < numTs; i++) {
1371
+ const ts = selector_1.TrafficSelector.parse(buffer.subarray(offset, genericPayload.length));
1372
+ tsList.push(ts);
1373
+ offset += ts.length;
1374
+ }
1375
+ return new PayloadTS(genericPayload.nextPayload, numTs, tsList, genericPayload.critical, genericPayload.length);
1376
+ }
1377
+ /**
1378
+ * Serializes a JSON representation of the TS payload to a buffer
1379
+ * @param json
1380
+ * @static
1381
+ * @public
1382
+ * @returns {Buffer}
1383
+ */
1384
+ static serializeJSON(json) {
1385
+ var _a;
1386
+ const buffer = Buffer.alloc(json.length);
1387
+ const genericPayload = Payload.serializeJSON(json);
1388
+ genericPayload.copy(buffer);
1389
+ buffer.writeUInt8(json.numTs, 4);
1390
+ const tsListBuffer = ((_a = json.tList) === null || _a === void 0 ? void 0 : _a.lenght) > 0
1391
+ ? json.tsList.map((ts) => selector_1.TrafficSelector.serializeJSON(ts))
1392
+ : [Buffer.alloc(0)];
1393
+ let offset = 8;
1394
+ for (const tsBuffer of tsListBuffer) {
1395
+ tsBuffer.copy(buffer, offset);
1396
+ offset += tsBuffer.length;
1397
+ }
1398
+ return buffer;
1399
+ }
1400
+ /**
1401
+ * Serializes the TS payload to a buffer
1402
+ * @public
1403
+ * @returns {Buffer}
1404
+ */
1405
+ serialize() {
1406
+ // Encode deep first to calculate length
1407
+ const tsListBuffer = this.tsList.map((ts) => ts.serialize());
1408
+ const tsBuffer = Buffer.concat(tsListBuffer);
1409
+ // Fix the length
1410
+ this.length = 5 + tsBuffer.length;
1411
+ const buffer = Buffer.alloc(this.length);
1412
+ super.serialize().copy(buffer);
1413
+ buffer.writeUInt8(this.numTs, 4);
1414
+ // No need to blank 3 reserved bytes, Buffer.alloc does that
1415
+ tsBuffer.copy(buffer, 8);
1416
+ return buffer;
1417
+ }
1418
+ /**
1419
+ * Returns a JSON representation of the TS payload
1420
+ * @public
1421
+ * @returns {Record<string, any>}
1422
+ */
1423
+ toJSON() {
1424
+ const json = super.genToJSON();
1425
+ json.numTs = this.numTs;
1426
+ json.tsList = this.tsList.map((ts) => ts.toJSON());
1427
+ return json;
1428
+ }
1429
+ /**
1430
+ * Returns a string representation of the TS payload
1431
+ * @public
1432
+ * @returns {string}
1433
+ */
1434
+ toString() {
1435
+ const genericString = super.genToString();
1436
+ return `${genericString}\nnumTs: ${this.numTs}\ntsList: ${this.tsList.map((ts) => ts.toString()).join(", ")}`;
1437
+ }
1438
+ }
1439
+ exports.PayloadTS = PayloadTS;
1440
+ /**
1441
+ * IKEv2 Traffic Selector - Initiator Payload
1442
+ * @class
1443
+ * @extends Payload
1444
+ */
1445
+ class PayloadTSi extends PayloadTS {
1446
+ constructor(nextPayload, numTs, tsList, critical = false, length = 0) {
1447
+ super(nextPayload, numTs, tsList, critical, length > 0 ? length : 5 + tsList.reduce((acc, ts) => acc + ts.length, 0));
1448
+ this.nextPayload = nextPayload;
1449
+ this.numTs = numTs;
1450
+ this.tsList = tsList;
1451
+ this.critical = critical;
1452
+ this.length = length;
1453
+ this.type = payloadType.TSi;
1454
+ }
1455
+ }
1456
+ exports.PayloadTSi = PayloadTSi;
1457
+ /**
1458
+ * IKEv2 Traffic Selector - Responder Payload
1459
+ * @class
1460
+ * @extends Payload
1461
+ */
1462
+ class PayloadTSr extends PayloadTS {
1463
+ constructor(nextPayload, numTs, tsList, critical = false, length = 0) {
1464
+ super(nextPayload, numTs, tsList, critical, length > 0 ? length : 5 + tsList.reduce((acc, ts) => acc + ts.length, 0));
1465
+ this.nextPayload = nextPayload;
1466
+ this.numTs = numTs;
1467
+ this.tsList = tsList;
1468
+ this.critical = critical;
1469
+ this.length = length;
1470
+ this.type = payloadType.TSr;
1471
+ }
1472
+ }
1473
+ exports.PayloadTSr = PayloadTSr;
1474
+ /**
1475
+ * IKEv2 Encrypted and Authenticated Payload
1476
+ * @class
1477
+ * @extends Payload
1478
+ */
1479
+ class PayloadSK extends Payload {
1480
+ constructor(nextPayload, encryptedData, critical = false, length = 0) {
1481
+ super(payloadType.SK, nextPayload, critical, length > 0 ? length : 4 + encryptedData.length);
1482
+ this.nextPayload = nextPayload;
1483
+ this.encryptedData = encryptedData;
1484
+ this.critical = critical;
1485
+ this.length = length;
1486
+ }
1487
+ /**
1488
+ * Parses an SK Payload from a buffer
1489
+ * @param buffer
1490
+ * @static
1491
+ * @public
1492
+ * @returns {PayloadSK}
1493
+ */
1494
+ static parse(buffer) {
1495
+ const genericPayload = Payload.parse(buffer);
1496
+ const encryptedData = buffer.subarray(4, genericPayload.length);
1497
+ return new PayloadSK(genericPayload.nextPayload, encryptedData, genericPayload.critical, genericPayload.length);
1498
+ }
1499
+ /**
1500
+ * Serializes a JSON representation of the SK payload to a buffer
1501
+ * @param json
1502
+ * @static
1503
+ * @public
1504
+ * @returns {Buffer}
1505
+ */
1506
+ static serializeJSON(json) {
1507
+ const buffer = Buffer.alloc(json.length);
1508
+ const genericPayload = Payload.serializeJSON(json);
1509
+ genericPayload.copy(buffer);
1510
+ Buffer.from(json.encryptedData, "hex").copy(buffer, 4);
1511
+ return buffer;
1512
+ }
1513
+ /**
1514
+ * Serializes the SK payload to a buffer
1515
+ * @public
1516
+ * @returns {Buffer}
1517
+ */
1518
+ serialize() {
1519
+ // Fix the length
1520
+ this.length = 4 + this.encryptedData.length;
1521
+ const buffer = Buffer.alloc(this.length);
1522
+ super.serialize().copy(buffer);
1523
+ this.encryptedData.copy(buffer, 4);
1524
+ return buffer;
1525
+ }
1526
+ /**
1527
+ * Returns a JSON representation of the SK payload
1528
+ * @public
1529
+ * @returns {Record<string, any>}
1530
+ */
1531
+ toJSON() {
1532
+ const json = super.genToJSON();
1533
+ json.encryptedData = this.encryptedData.toString("hex");
1534
+ return json;
1535
+ }
1536
+ /**
1537
+ * Returns a string representation of the SK payload
1538
+ * @public
1539
+ * @returns {string}
1540
+ */
1541
+ toString() {
1542
+ const genericString = super.genToString();
1543
+ return `${genericString}\nencryptedData: "${this.encryptedData.toString("hex")}"`;
1544
+ }
1545
+ /**
1546
+ * Decrypts the encrypted data in the SK payload.
1547
+ *
1548
+ * The decryptFunction should handle removing the IV, Padding and Integrity Checksum Data.
1549
+ *
1550
+ * This should be called after checking the Integrity Checksum Data (except for AEAD algorithms, which are
1551
+ * self-checking).
1552
+ *
1553
+ * @param aad Additional Authenticated Data to include in the Integrity Checksum Data calculation - include here
1554
+ * the entire IKE header and the SK payload header (first 4 bytes of the SK payload), so everything before the IV
1555
+ * inside the SK payload. This is needed for AEAD algorithms, which include integrity protection in the encryption
1556
+ * process (they output inClearData is shorter than the encryptedData).
1557
+ * @param decryptFunction Function that takes a Buffer and returns a decrypted Buffer
1558
+ * @returns {Payload[]} Array of decrypted Payloads
1559
+ * @public
1560
+ */
1561
+ decrypt(decryptFunction, aad) {
1562
+ if (this.encryptedData.length === 0) {
1563
+ throw new Error("No encrypted data to decrypt - must contain at least the IV and the Integrity Checksum Data");
1564
+ }
1565
+ let nextPayload = this.nextPayload;
1566
+ let offset = 0;
1567
+ const payloads = [];
1568
+ if (nextPayload === payloadType.NONE) {
1569
+ return {
1570
+ firstPayload: payloadType.NONE,
1571
+ inClearPayloads: [],
1572
+ iv: Buffer.alloc(0),
1573
+ };
1574
+ }
1575
+ // Decrypt data
1576
+ const { inClearData, iv } = decryptFunction(this.encryptedData, aad);
1577
+ if (inClearData.length === 0) {
1578
+ return {
1579
+ firstPayload: payloadType.NONE,
1580
+ inClearPayloads: [],
1581
+ iv: iv,
1582
+ };
1583
+ }
1584
+ let nextPayloadClass = exports.payloadTypeMapping[nextPayload];
1585
+ if (!nextPayloadClass) {
1586
+ throw new Error(`Unknown payload type: ${nextPayload}`);
1587
+ }
1588
+ while (offset < inClearData.length &&
1589
+ nextPayloadClass &&
1590
+ nextPayload !== payloadType.NONE) {
1591
+ // Validate we have enough data for the next payload
1592
+ if (offset + 4 > inClearData.length) {
1593
+ throw new Error(`Insufficient data for payload header at offset ${offset}`);
1594
+ }
1595
+ const payload = nextPayloadClass.parse(inClearData.subarray(offset, inClearData.length));
1596
+ payloads.push(payload);
1597
+ offset += payload.length;
1598
+ nextPayload = payload.nextPayload;
1599
+ nextPayloadClass = exports.payloadTypeMapping[nextPayload];
1600
+ // Validate payload length
1601
+ if (offset > inClearData.length) {
1602
+ throw new Error(`Payload length exceeds packet size. Offset: ${offset}, Packet size: ${inClearData.length}`);
1603
+ }
1604
+ }
1605
+ return {
1606
+ firstPayload: this.nextPayload /* the original payload type */,
1607
+ inClearPayloads: payloads,
1608
+ iv: iv,
1609
+ };
1610
+ }
1611
+ /**
1612
+ * Encrypts data and sets it as the encrypted data in the SK payload. Should be called before serializing the IKE
1613
+ * message, when the SK payload is included and is the last one in the message.
1614
+ *
1615
+ * Also sets the nextPayload in the SK payload as the type of the first payload inside the encrypted data. This is
1616
+ * an exception to the rule, but the SK payload is always the last one in the message, to compensate.
1617
+ *
1618
+ * The encryptFunction should include pre-pending the IV, appending Padding and space for the Integrity Checksum Data.
1619
+ *
1620
+ * The Integrity Checksum Data bytes will have to be updated after the entire IKE message is serialized. The IV is
1621
+ * needed then, so it is returned by this function.
1622
+ *
1623
+ * @param inClearPayloads Array of Payloads to encrypt
1624
+ * @param aad Additional Authenticated Data to include in the Integrity Checksum Data calculation - include here
1625
+ * the entire IKE header and the SK payload header (first 4 bytes of the SK payload), so everything before the IV
1626
+ * inside the SK payload. This is needed for AEAD algorithms, which include integrity protection in the encryption
1627
+ * process (they would also produce more data than the plaintext payloads data).
1628
+ * @param encryptFunction Function that takes a Buffer and returns an encrypted Buffer
1629
+ * @returns The IV used for encryption, to be used in the message.updateIntegrityChecksumData function
1630
+ */
1631
+ encrypt(inClearPayloads, encryptFunction, aad) {
1632
+ if (inClearPayloads.length === 0) {
1633
+ throw new Error("No in-clear payloads to encrypt - must contain at least one payload");
1634
+ }
1635
+ // Fix the nextPayload in the SK payload and the inner payloads
1636
+ this.nextPayload = inClearPayloads[0].type;
1637
+ for (let i = 0; i < inClearPayloads.length - 1; i++) {
1638
+ inClearPayloads[i].nextPayload = inClearPayloads[i + 1].type;
1639
+ }
1640
+ inClearPayloads[inClearPayloads.length - 1].nextPayload = payloadType.NONE;
1641
+ // Serialize all payloads to encrypt
1642
+ const inClearData = Buffer.concat(inClearPayloads.map((p) => p.serialize()));
1643
+ const { skPayloadData, iv } = encryptFunction(inClearData, aad);
1644
+ this.encryptedData = skPayloadData;
1645
+ return { iv: iv };
1646
+ }
1647
+ }
1648
+ exports.PayloadSK = PayloadSK;
1649
+ /**
1650
+ * IKEv2 Configuration Payload - Types
1651
+ * @enum
1652
+ */
1653
+ var cfgType;
1654
+ (function (cfgType) {
1655
+ cfgType[cfgType["CFG_REQUEST"] = 1] = "CFG_REQUEST";
1656
+ cfgType[cfgType["CFG_REPLY"] = 2] = "CFG_REPLY";
1657
+ cfgType[cfgType["CFG_SET"] = 3] = "CFG_SET";
1658
+ cfgType[cfgType["CFG_ACK"] = 4] = "CFG_ACK";
1659
+ })(cfgType || (exports.cfgType = cfgType = {}));
1660
+ /**
1661
+ * IKEv2 Configuration Payload
1662
+ * @class
1663
+ * @extends Payload
1664
+ */
1665
+ class PayloadCP extends Payload {
1666
+ constructor(nextPayload, cfgType, cfgData, critical = false, length = 0) {
1667
+ super(payloadType.CP, nextPayload, critical, length > 0 ? length : 5 + cfgData.length);
1668
+ this.nextPayload = nextPayload;
1669
+ this.cfgType = cfgType;
1670
+ this.cfgData = cfgData;
1671
+ this.critical = critical;
1672
+ this.length = length;
1673
+ }
1674
+ /**
1675
+ * Parses a Configuration Payload from a buffer
1676
+ * @param buffer
1677
+ * @static
1678
+ * @public
1679
+ * @returns {PayloadCP}
1680
+ */
1681
+ static parse(buffer) {
1682
+ const genericPayload = Payload.parse(buffer);
1683
+ const cfgType = buffer.readUInt8(4);
1684
+ const cfgData = buffer.subarray(5, genericPayload.length);
1685
+ return new PayloadCP(genericPayload.nextPayload, cfgType, cfgData, genericPayload.critical, genericPayload.length);
1686
+ }
1687
+ /**
1688
+ * Serializes a JSON representation of the CP payload to a buffer
1689
+ * @param json
1690
+ * @static
1691
+ * @public
1692
+ * @returns {Buffer}
1693
+ */
1694
+ static serializeJSON(json) {
1695
+ const buffer = Buffer.alloc(json.length);
1696
+ const genericPayload = Payload.serializeJSON(json);
1697
+ genericPayload.copy(buffer);
1698
+ buffer.writeUInt8(json.cfgType, 4);
1699
+ // Write 3-byte reserved field as zeros in big-endian order
1700
+ buffer.writeUInt8(0, 5);
1701
+ buffer.writeUInt8(0, 6);
1702
+ buffer.writeUInt8(0, 7);
1703
+ Buffer.from(json.cfgData, "hex").copy(buffer, 8);
1704
+ return buffer;
1705
+ }
1706
+ /**
1707
+ * Serializes the CP payload to a buffer
1708
+ * @public
1709
+ * @returns {Buffer}
1710
+ */
1711
+ serialize() {
1712
+ // Fix the length
1713
+ this.length = 8 + this.cfgData.length;
1714
+ const buffer = Buffer.alloc(this.length);
1715
+ super.serialize().copy(buffer);
1716
+ buffer.writeUInt8(this.cfgType, 4);
1717
+ // No need to blank 3 reserved bytes, Buffer.alloc does that
1718
+ this.cfgData.copy(buffer, 8);
1719
+ return buffer;
1720
+ }
1721
+ /**
1722
+ * Returns a JSON representation of the CP payload
1723
+ * @public
1724
+ * @returns {Record<string, any>}
1725
+ */
1726
+ toJSON() {
1727
+ const json = super.genToJSON();
1728
+ json.cfgType = this.cfgType;
1729
+ json.cfgData = this.cfgData.toString("hex");
1730
+ return json;
1731
+ }
1732
+ /**
1733
+ * Returns a string representation of the CP payload
1734
+ * @public
1735
+ * @returns {string}
1736
+ */
1737
+ toString() {
1738
+ const genericString = super.genToString();
1739
+ return `${genericString}\ncfgType: ${cfgType[this.cfgType]}\ncfgData: "${this.cfgData.toString("hex")}"`;
1740
+ }
1741
+ }
1742
+ exports.PayloadCP = PayloadCP;
1743
+ /**
1744
+ * IKEv2 Extensible Authentication Payload
1745
+ * @class
1746
+ * @extends Payload
1747
+ */
1748
+ class PayloadEAP extends Payload {
1749
+ constructor(nextPayload, tlvData, critical = false, length = 0) {
1750
+ super(payloadType.EAP, nextPayload, critical, length > 0 ? length : 4 + tlvData.length);
1751
+ this.nextPayload = nextPayload;
1752
+ this.tlvData = tlvData;
1753
+ this.critical = critical;
1754
+ this.length = length;
1755
+ }
1756
+ /**
1757
+ * Parses an EAP Payload from a buffer
1758
+ * @param buffer
1759
+ * @static
1760
+ * @public
1761
+ * @returns {PayloadEAP}
1762
+ */
1763
+ static parse(buffer) {
1764
+ const genericPayload = Payload.parse(buffer);
1765
+ const tlvData = attribute_1.Attribute.parse(buffer.subarray(4, genericPayload.length));
1766
+ return new PayloadEAP(genericPayload.nextPayload, tlvData, genericPayload.critical, genericPayload.length);
1767
+ }
1768
+ /**
1769
+ * Serializes a JSON representation of the EAP payload to a buffer
1770
+ * @param json
1771
+ * @static
1772
+ * @public
1773
+ * @returns {Buffer}
1774
+ */
1775
+ static serializeJSON(json) {
1776
+ const buffer = Buffer.alloc(json.length);
1777
+ const genericPayload = Payload.serializeJSON(json);
1778
+ genericPayload.copy(buffer);
1779
+ const tlvDataBuffer = attribute_1.Attribute.serializeJSON(json.tlvData);
1780
+ tlvDataBuffer.copy(buffer, 4);
1781
+ return buffer;
1782
+ }
1783
+ /**
1784
+ * Serializes the EAP payload to a buffer
1785
+ * @public
1786
+ * @returns {Buffer}
1787
+ */
1788
+ serialize() {
1789
+ // Encode deep first to calculate length
1790
+ const tlvDataBuffer = this.tlvData.serialize();
1791
+ // Fix the length
1792
+ this.length = 4 + tlvDataBuffer.length;
1793
+ const buffer = Buffer.alloc(this.length);
1794
+ super.serialize().copy(buffer);
1795
+ tlvDataBuffer.copy(buffer, 4);
1796
+ return buffer;
1797
+ }
1798
+ /**
1799
+ * Returns a JSON representation of the EAP payload
1800
+ * @public
1801
+ * @returns {Record<string, any>}
1802
+ */
1803
+ toJSON() {
1804
+ const json = super.genToJSON();
1805
+ json.tlvData = this.tlvData.toJSON();
1806
+ return json;
1807
+ }
1808
+ /**
1809
+ * Returns a string representation of the EAP payload
1810
+ * @public
1811
+ * @returns {string}
1812
+ */
1813
+ toString() {
1814
+ const genericString = super.genToString();
1815
+ return `${genericString}\ntlvData: ${this.tlvData.toString()}`;
1816
+ }
1817
+ }
1818
+ exports.PayloadEAP = PayloadEAP;
1819
+ /**
1820
+ * Payload Type to its class mapping for IKEv2 payloads
1821
+ */
1822
+ exports.payloadTypeMapping = {
1823
+ [payloadType.NONE]: Payload,
1824
+ [payloadType.SA]: PayloadSA,
1825
+ [payloadType.KE]: PayloadKE,
1826
+ [payloadType.IDi]: PayloadIDi,
1827
+ [payloadType.IDr]: PayloadIDr,
1828
+ [payloadType.CERT]: PayloadCERT,
1829
+ [payloadType.CERTREQ]: PayloadCERTREQ,
1830
+ [payloadType.AUTH]: PayloadAUTH,
1831
+ [payloadType.NONCE]: PayloadNONCE,
1832
+ [payloadType.NOTIFY]: PayloadNOTIFY,
1833
+ [payloadType.DELETE]: PayloadDELETE,
1834
+ [payloadType.VENDOR]: PayloadVENDOR,
1835
+ [payloadType.TSi]: PayloadTSi,
1836
+ [payloadType.TSr]: PayloadTSr,
1837
+ [payloadType.SK]: PayloadSK,
1838
+ [payloadType.CP]: PayloadCP,
1839
+ [payloadType.EAP]: PayloadEAP,
1840
+ };