lemon-tls 0.1.0 → 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.
package/tls_session.js DELETED
@@ -1,1441 +0,0 @@
1
- var nobleHashes={
2
- hmac: require("@noble/hashes/hmac.js")['hmac'],
3
- hkdf: require("@noble/hashes/hkdf.js")['hkdf'],
4
- hkdf_extract: require("@noble/hashes/hkdf.js")['extract'],
5
- hkdf_expand: require("@noble/hashes/hkdf.js")['expand'],
6
- sha256: require("@noble/hashes/sha2.js")['sha256'],
7
- };
8
-
9
- var { p256 } = require('@noble/curves/nist.js');
10
- var { x25519 } = require('@noble/curves/ed25519');
11
- var { sha256, sha384 } = require('@noble/hashes/sha2');
12
-
13
- var crypto = require('crypto');
14
-
15
- var {
16
- TLS_CIPHER_SUITES,
17
- build_cert_verify_tbs,
18
- get_handshake_finished,
19
- derive_handshake_traffic_secrets,
20
- derive_app_traffic_secrets
21
- } = require('./crypto');
22
-
23
-
24
- var {
25
- concatUint8Arrays,
26
- arraybufferEqual,
27
- arraysEqual
28
- } = require('./utils');
29
-
30
-
31
- var wire = require('./wire');
32
-
33
- /** מינימל-Emitter בסגנון שלך */
34
- function Emitter(){
35
- var listeners = {};
36
- return {
37
- on: function(name, fn){ (listeners[name] = listeners[name] || []).push(fn); },
38
- emit: function(name){
39
- var args = Array.prototype.slice.call(arguments, 1);
40
- var arr = listeners[name] || [];
41
- for (var i=0;i<arr.length;i++){ try{ arr[i].apply(null, args); }catch(e){} }
42
- }
43
- };
44
- }
45
-
46
-
47
-
48
-
49
-
50
-
51
- function arrOrDefault(a, d){
52
- return (a && a.length) ? a.slice(0) : d.slice(0);
53
- }
54
- function arrOrNull(a){
55
- return (a && a.length) ? a.slice(0) : null;
56
- }
57
-
58
-
59
- function normalizeHello(hello) {
60
- var out = {
61
- // Basics
62
- message: hello.message, // 'client_hello' | 'server_hello'
63
- legacy_version: hello.legacy_version, // 0x0303
64
- version: hello.version || hello.version_hint || null,
65
- random: hello.random || null, // Uint8Array(32)
66
- session_id: hello.session_id || null, // Uint8Array
67
-
68
- // Negotiation fields
69
- cipher_suites: hello.cipher_suites || null, // ClientHello array
70
- cipher_suite: hello.cipher_suite || null, // ServerHello selected
71
- legacy_compression: hello.legacy_compression || null,
72
-
73
- // Commonly used extensions (flattened)
74
- sni: null, // string
75
- alpn: null, // string[]
76
- key_shares: null, // Client: array of {group, key_exchange}; Server: {group, key_exchange}
77
- supported_versions: null, // Client: number[]; Server: number
78
- signature_algorithms: null, // number[]
79
- supported_groups: null, // number[]
80
-
81
- // TLS 1.2 / misc
82
- renegotiation_info: null, // Uint8Array
83
- status_request: null, // raw/decoded if available
84
- max_fragment_length: null, // number or enum
85
- signature_algorithms_cert: null, // number[]
86
- certificate_authorities: null, // raw/decoded if available
87
- sct: null, // SignedCertificateTimestamp list (raw/decoded)
88
- heartbeat: null, // heartbeat mode
89
- use_srtp: null, // SRTP profiles
90
-
91
- // TLS 1.3 specific
92
- cookie: null, // Uint8Array
93
- early_data: null, // true/params if present
94
- psk_key_exchange_modes: null, // number[]
95
-
96
- // Raw list of extensions
97
- extensions: hello.extensions || [],
98
-
99
- // Bucket for anything unmapped
100
- unknown: []
101
- };
102
-
103
- if (!hello.extensions) {
104
- return out;
105
- }
106
-
107
- for (var i = 0; i < hello.extensions.length; i++) {
108
- var e = hello.extensions[i];
109
- var val = (e.value !== undefined && e.value !== null) ? e.value : null;
110
-
111
- switch (e.name) {
112
- case 'SERVER_NAME':
113
- out.sni = val; // string
114
- break;
115
-
116
- case 'ALPN':
117
- out.alpn = val; // string[]
118
- break;
119
-
120
- case 'KEY_SHARE':
121
- out.key_shares = val; // client: array, server: object
122
- break;
123
-
124
- case 'SUPPORTED_VERSIONS':
125
- out.supported_versions = val; // array or number
126
- break;
127
-
128
- case 'SIGNATURE_ALGORITHMS':
129
- out.signature_algorithms = val; // number[]
130
- break;
131
-
132
- case 'SUPPORTED_GROUPS':
133
- out.supported_groups = val; // number[]
134
- break;
135
-
136
- // ---- TLS 1.2 & misc ----
137
- case 'RENEGOTIATION_INFO':
138
- out.renegotiation_info = val; // Uint8Array
139
- break;
140
-
141
- case 'STATUS_REQUEST':
142
- out.status_request = val; // currently raw unless a decoder is added
143
- break;
144
-
145
- case 'MAX_FRAGMENT_LENGTH':
146
- out.max_fragment_length = val; // number/enum (decoder not implemented yet)
147
- break;
148
-
149
- case 'SIGNATURE_ALGORITHMS_CERT':
150
- out.signature_algorithms_cert = val; // number[]
151
- break;
152
-
153
- case 'CERTIFICATE_AUTHORITIES':
154
- out.certificate_authorities = val; // raw list unless decoder added
155
- break;
156
-
157
- case 'SCT':
158
- out.sct = val; // raw/decoded SCT list
159
- break;
160
-
161
- case 'HEARTBEAT':
162
- out.heartbeat = val; // heartbeat mode
163
- break;
164
-
165
- case 'USE_SRTP':
166
- out.use_srtp = val; // SRTP params
167
- break;
168
-
169
- // ---- TLS 1.3 ----
170
- case 'COOKIE':
171
- out.cookie = val; // Uint8Array
172
- break;
173
-
174
- case 'EARLY_DATA':
175
- out.early_data = (val === null) ? true : val; // presence indicates support
176
- break;
177
-
178
- case 'PSK_KEY_EXCHANGE_MODES':
179
- out.psk_key_exchange_modes = val; // number[]
180
- break;
181
-
182
- default:
183
- out.unknown.push(e);
184
- }
185
- }
186
-
187
- // --- פוסט-פרוסס: השלמות ל-1.2 כשאין ext SUPPORTED_VERSIONS ---
188
- if (out.supported_versions == null) {
189
- if (out.message === 'client_hello' && typeof out.legacy_version === 'number') {
190
- // ב-1.2 הקליינט לא שולח ext, נשתול מערך עם הגרסה ה"מורשת" (לרוב 0x0303)
191
- out.supported_versions = [out.legacy_version|0];
192
- } else if (out.message === 'server_hello' && typeof out.legacy_version === 'number') {
193
- // בסרבר: הגרסה הנבחרת נמצאת בשדה הישן; שמור גם ב-version
194
- if (out.version == null) out.version = out.legacy_version|0;
195
- out.supported_versions = out.version; // שמור סכימה: בסרבר זה "number"
196
- }
197
- }
198
-
199
- // גם אם אין KEY_SHARE ב-1.2, נרצה אינדיקציה ריקה במקום null (קוד downstream נקי יותר)
200
- if (out.key_shares == null && out.message === 'client_hello') {
201
- out.key_shares = []; // ב-1.2 ה-ECDHE יבוא ב-ServerKeyExchange, לא כאן
202
- }
203
-
204
- return out;
205
- }
206
-
207
-
208
-
209
- function normalizeOptions(opts){
210
- opts = opts || {};
211
- var out = {
212
- minVersion: opts.minVersion || null,
213
- maxVersion: opts.maxVersion || null,
214
-
215
- cipherPreference: arrOrDefault(opts.cipherPreference, null),
216
- groupPreference: arrOrDefault(opts.groupPreference, null),
217
- sigAlgPreference: arrOrDefault(opts.sigAlgPreference, null),
218
-
219
- ALPNProtocols: arrOrNull(opts.ALPNProtocols),
220
-
221
- requestCert: !!opts.requestCert,
222
- rejectUnauthorized: !!opts.rejectUnauthorized,
223
-
224
- secureContext: opts.secureContext || null,
225
- isServer: !!opts.isServer
226
- };
227
-
228
- // ודא min<=max
229
- if (out.minVersion > out.maxVersion){
230
- var t = out.minVersion; out.minVersion = out.maxVersion; out.maxVersion = t;
231
- }
232
-
233
- return out;
234
- }
235
-
236
- function TLSSession(options){
237
- if (!(this instanceof TLSSession)) return new TLSSession(options);
238
- options = options || {};
239
-
240
- var ev = Emitter();
241
-
242
- var context = {
243
- state: 'new', //new | negotiating | ...
244
- isServer: !!options.isServer,
245
-
246
- SNICallback: options.SNICallback || null,
247
-
248
- local_versions: [], // [0x0304, 0x0303, ...]
249
- local_cipher_suites: [], //[0x1303, 0x1301, 0x1302]
250
- local_alpns: [], // ['h3','h2','http/1.1', ...]
251
- local_groups: [], //[0x001D, 0x0017, 0x0018]// x25519, secp256r1, secp384r1
252
- local_signature_algorithms: [], //[0x0403, 0x0804, 0x0805] //ecdsa_secp256r1_sha256 (0x0403), rsa_pss_rsae_sha256 (0x0804), rsa_pss_rsae_sha384 (0x0805)
253
- local_extensions: [], // [{ type, data }, ...]
254
-
255
- local_key_share_public: null, // Uint8Array (pubkey שנשלח)
256
- local_key_share_private: null, // Uint8Array (privkey זמני)
257
-
258
- // REMOTE (מה שהצד המרוחק שלח/מציע)
259
- remote_versions: [],
260
- remote_cipher_suites: [],
261
- remote_alpns: [],
262
- remote_groups: [],
263
- remote_signature_algorithms: [],
264
- remote_extensions: [],
265
- remote_key_shares: [],
266
- remote_sni: null,
267
- remote_session_id: null,
268
- remote_random: null,
269
-
270
-
271
- // SELECTED (מה שנקבע בפועל)
272
- selected_version: null, // 0x0304 / 0x0303
273
- selected_cipher_suite: null, // למשל 0x1301
274
- selected_alpn: null, // 'h3'/'h2'/... או null
275
- selected_group: null, // למשל 0x001D
276
- selected_signature_algorithm: null, // למשל 0x0804
277
- selected_extensions: [], // [type,...] או [{type,dataConfirmed}]
278
- selected_sni: null, // string|null
279
- selected_session_id: null, // TLS 1.2 בלבד
280
-
281
- // שאר מצב/מפתחות/תעודות/תזמון
282
- transcript: [], // Handshake inner messages
283
-
284
- local_random: null,
285
-
286
-
287
- //whats already sent?
288
- hello_sent: false,
289
- encrypted_exts_sent: false,
290
- cert_sent: false,
291
- cert_verify_sent: false,
292
- finished_sent: false,
293
-
294
- message_sent_seq: 0,
295
-
296
- remote_finished: null,
297
- expected_remote_finished: null,
298
- remote_finished_ok: false,
299
-
300
- local_key_share_private: null,
301
- local_key_share_public: null,
302
- ecdhe_shared_secret: null,
303
-
304
- handshake_secret: null,
305
-
306
- client_handshake_traffic_secret: null,
307
- server_handshake_traffic_secret: null,
308
-
309
- client_app_traffic_secret: null,
310
- server_app_traffic_secret: null,
311
-
312
- local_cert_chain: null,
313
- remote_cert_chain: null,
314
-
315
- selected_cert: null,
316
-
317
- cert_private_key: null
318
- };
319
-
320
- function process_income_message(data){
321
-
322
- var message = wire.parse_message(data);
323
-
324
- if (message.type == wire.TLS_MESSAGE_TYPE.CLIENT_HELLO || message.type == wire.TLS_MESSAGE_TYPE.SERVER_HELLO) {
325
- var hello = wire.parse_hello(message.type, message.body);
326
-
327
- var info = normalizeHello(hello);
328
- //console.log(info);
329
- context.transcript.push(data);
330
-
331
- set_context({
332
- remote_random: info.random || null,
333
- remote_sni: info.sni || null,
334
- remote_session_id: info.session_id || null, // TLS 1.2 בעיקר
335
- remote_cipher_suites: info.cipher_suites || [],
336
- remote_alpns: info.alpn || [],
337
- remote_key_shares: info.key_shares || [],
338
- remote_versions: info.supported_versions || [],
339
- remote_signature_algorithms: info.signature_algorithms || [],
340
- remote_groups: info.supported_groups || [],
341
- remote_extensions: info.extensions || [],
342
- });
343
-
344
- ev.emit('hello');
345
-
346
- if(typeof context.SNICallback=='function'){
347
- context.SNICallback(context.remote_sni, function (err, creds) {
348
- if (!err && creds) {
349
- set_context({
350
- local_cert_chain: creds.certificateChain,
351
- cert_private_key: creds.privateKey
352
- });
353
- } else {
354
- //console.log('No TLS credentials for', current_params.sni);
355
- }
356
- });
357
- }
358
-
359
-
360
- } else if (message.type == wire.TLS_MESSAGE_TYPE.FINISHED) {
361
-
362
- set_context({
363
- remote_finished: message.body
364
- });
365
-
366
- }
367
-
368
- }
369
-
370
-
371
- function set_context(options){
372
- var has_changed=false;
373
-
374
- var fields=[
375
- 'local_versions',
376
- 'local_cipher_suites',
377
- 'local_alpns',
378
- 'local_groups',
379
- 'local_signature_algorithms',
380
- 'local_extensions',
381
-
382
- 'remote_versions',
383
- 'remote_cipher_suites',
384
- 'remote_alpns',
385
- 'remote_groups',
386
- 'remote_signature_algorithms',
387
- 'remote_extensions',
388
- 'remote_key_shares',
389
- 'remote_sni',
390
- 'remote_session_id',
391
- 'remote_random',
392
-
393
- 'selected_version',
394
- 'selected_cipher_suite',
395
- 'selected_alpn',
396
- 'selected_group',
397
- 'selected_signature_algorithm',
398
- 'selected_extensions',
399
- 'selected_sni',
400
- 'selected_session_id',
401
-
402
-
403
- 'local_key_share_public',
404
- 'local_key_share_private',
405
- 'ecdhe_shared_secret',
406
-
407
- 'server_handshake_traffic_secret',
408
- 'client_handshake_traffic_secret',
409
-
410
- 'server_app_traffic_secret',
411
- 'client_app_traffic_secret',
412
-
413
- 'local_cert_chain',
414
- 'remote_cert_chain',
415
-
416
- 'cert_private_key',
417
-
418
- 'remote_finished_ok',
419
- 'remote_finished',
420
- 'expected_remote_finished'
421
- ];
422
-
423
- var prev={};
424
-
425
-
426
- if (options && typeof options === 'object'){
427
-
428
- if('local_versions' in options){
429
- if(arraysEqual(options.local_versions,context.local_versions)==false){
430
- prev['local_versions']=context['local_versions'];
431
- context.local_versions=options.local_versions;
432
- has_changed=true;
433
- }
434
- }
435
-
436
- if('local_cipher_suites' in options){
437
- if(arraysEqual(options.local_cipher_suites,context.local_cipher_suites)==false){
438
- prev['local_cipher_suites']=context['local_cipher_suites'];
439
- context.local_cipher_suites=options.local_cipher_suites;
440
- has_changed=true;
441
- }
442
- }
443
-
444
- if('local_alpns' in options){
445
- if(arraysEqual(options.local_alpns,context.local_alpns)==false){
446
- prev['local_alpns']=context['local_alpns'];
447
- context.local_alpns=options.local_alpns;
448
- has_changed=true;
449
- }
450
- }
451
-
452
- if('local_groups' in options){
453
- if(arraysEqual(options.local_groups,context.local_groups)==false){
454
- prev['local_groups']=context['local_groups'];
455
- context.local_groups=options.local_groups;
456
- has_changed=true;
457
- }
458
- }
459
-
460
- if('local_signature_algorithms' in options){
461
- if(arraysEqual(options.local_signature_algorithms,context.local_signature_algorithms)==false){
462
- prev['local_signature_algorithms']=context['local_signature_algorithms'];
463
- context.local_signature_algorithms=options.local_signature_algorithms;
464
- has_changed=true;
465
- }
466
- }
467
-
468
- if('local_extensions' in options){
469
- if(arraysEqual(options.local_extensions,context.local_extensions)==false){
470
- prev['local_extensions']=context['local_extensions'];
471
- context.local_extensions=options.local_extensions;
472
- has_changed=true;
473
- }
474
- }
475
-
476
- if('local_key_share_public' in options){
477
- if((context.local_key_share_public==null && options.local_key_share_public!==null) || !arraybufferEqual(options.local_key_share_public.buffer,context.local_key_share_public.buffer)){
478
- prev['local_key_share_public']=context['local_key_share_public'];
479
- context.local_key_share_public=options.local_key_share_public;
480
- has_changed=true;
481
- }
482
- }
483
-
484
- if('local_key_share_private' in options){
485
- if((context.local_key_share_private==null && options.local_key_share_private!==null) || !arraybufferEqual(options.local_key_share_private.buffer,context.local_key_share_private.buffer)){
486
- prev['local_key_share_private']=context['local_key_share_private'];
487
- context.local_key_share_private=options.local_key_share_private;
488
- has_changed=true;
489
- }
490
- }
491
-
492
- if('remote_versions' in options){
493
- if(arraysEqual(options.remote_versions,context.remote_versions)==false){
494
- prev['remote_versions']=context['remote_versions'];
495
- context.remote_versions=options.remote_versions;
496
- has_changed=true;
497
- }
498
- }
499
-
500
- if('remote_cipher_suites' in options){
501
- if(arraysEqual(options.remote_cipher_suites,context.remote_cipher_suites)==false){
502
- prev['remote_cipher_suites']=context['remote_cipher_suites'];
503
- context.remote_cipher_suites=options.remote_cipher_suites;
504
- has_changed=true;
505
- }
506
- }
507
-
508
- if('remote_alpns' in options){
509
- if(arraysEqual(options.remote_alpns,context.remote_alpns)==false){
510
- prev['remote_alpns']=context['remote_alpns'];
511
- context.remote_alpns=options.remote_alpns;
512
- has_changed=true;
513
- }
514
- }
515
-
516
- if('remote_groups' in options){
517
- if(arraysEqual(options.remote_groups,context.remote_groups)==false){
518
- prev['remote_groups']=context['remote_groups'];
519
- context.remote_groups=options.remote_groups;
520
- has_changed=true;
521
- }
522
- }
523
-
524
- if('remote_signature_algorithms' in options){
525
- if(arraysEqual(options.remote_signature_algorithms,context.remote_signature_algorithms)==false){
526
- prev['remote_signature_algorithms']=context['remote_signature_algorithms'];
527
- context.remote_signature_algorithms=options.remote_signature_algorithms;
528
- has_changed=true;
529
- }
530
- }
531
-
532
- if('remote_extensions' in options){
533
- if(arraysEqual(options.remote_extensions,context.remote_extensions)==false){
534
- prev['remote_extensions']=context['remote_extensions'];
535
- context.remote_extensions=options.remote_extensions;
536
- has_changed=true;
537
- }
538
- }
539
-
540
- if('remote_key_shares' in options){
541
- if(arraysEqual(options.remote_key_shares,context.remote_key_shares)==false){
542
- prev['remote_key_shares']=context['remote_key_shares'];
543
- context.remote_key_shares=options.remote_key_shares;
544
- has_changed=true;
545
- }
546
- }
547
-
548
- if('remote_sni' in options){
549
- if(options.remote_sni!==context.remote_sni){
550
- prev['remote_sni']=context['remote_sni'];
551
- context.remote_sni=options.remote_sni;
552
- has_changed=true;
553
- }
554
- }
555
-
556
- if('remote_session_id' in options){
557
- if((context.remote_session_id==null && options.remote_session_id!==null) || !arraybufferEqual(options.remote_session_id.buffer,context.remote_session_id.buffer)){
558
- prev['remote_session_id']=context['remote_session_id'];
559
- context.remote_session_id=options.remote_session_id;
560
- has_changed=true;
561
- }
562
- }
563
-
564
- if('remote_random' in options){
565
- if((context.remote_random==null && options.remote_random!==null) || !arraybufferEqual(options.remote_random.buffer,context.remote_random.buffer)){
566
- prev['remote_random']=context['remote_random'];
567
- context.remote_random=options.remote_random;
568
- has_changed=true;
569
- }
570
- }
571
-
572
- if('selected_version' in options){
573
- if(options.selected_version!==context.selected_version){
574
- prev['selected_version']=context['selected_version'];
575
- context.selected_version=options.selected_version;
576
- has_changed=true;
577
- }
578
- }
579
-
580
- if('selected_cipher_suite' in options){
581
- if(options.selected_cipher_suite!==context.selected_cipher_suite){
582
- prev['selected_cipher_suite']=context['selected_cipher_suite'];
583
- context.selected_cipher_suite=options.selected_cipher_suite;
584
- has_changed=true;
585
- }
586
- }
587
-
588
- if('selected_alpn' in options){
589
- if(options.selected_alpn!==context.selected_alpn){
590
- prev['selected_alpn']=context['selected_alpn'];
591
- context.selected_alpn=options.selected_alpn;
592
- has_changed=true;
593
- }
594
- }
595
-
596
- if('selected_group' in options){
597
- if(options.selected_group!==context.selected_group){
598
- prev['selected_group']=context['selected_group'];
599
- context.selected_group=options.selected_group;
600
- has_changed=true;
601
- }
602
- }
603
-
604
- if('selected_signature_algorithm' in options){
605
- if(options.selected_signature_algorithm!==context.selected_signature_algorithm){
606
- prev['selected_signature_algorithm']=context['selected_signature_algorithm'];
607
- context.selected_signature_algorithm=options.selected_signature_algorithm;
608
- has_changed=true;
609
- }
610
- }
611
-
612
- if('selected_extensions' in options){
613
- if(arraysEqual(options.selected_extensions,context.selected_extensions)==false){
614
- prev['selected_extensions']=context['selected_extensions'];
615
- context.selected_extensions=options.selected_extensions;
616
- has_changed=true;
617
- }
618
- }
619
-
620
- if('selected_sni' in options){
621
- if(options.selected_sni!==context.selected_sni){
622
- prev['selected_sni']=context['selected_sni'];
623
- context.selected_sni=options.selected_sni;
624
- has_changed=true;
625
- }
626
- }
627
-
628
- if('selected_session_id' in options){
629
- if((context.selected_session_id==null && options.selected_session_id!==null) || !arraybufferEqual(options.selected_session_id.buffer,context.selected_session_id.buffer)){
630
- prev['selected_session_id']=context['selected_session_id'];
631
- context.selected_session_id=options.selected_session_id;
632
- has_changed=true;
633
- }
634
- }
635
-
636
-
637
-
638
-
639
- if('ecdhe_shared_secret' in options){
640
- if(context.ecdhe_shared_secret==null && options.ecdhe_shared_secret!==null){
641
- prev['ecdhe_shared_secret']=context['ecdhe_shared_secret'];
642
- context.ecdhe_shared_secret=options.ecdhe_shared_secret;
643
- has_changed=true;
644
- }
645
- }
646
-
647
- if('handshake_secret' in options){
648
- if(context.handshake_secret==null && options.handshake_secret!==null){
649
- prev['handshake_secret']=context['handshake_secret'];
650
- context.handshake_secret=options.handshake_secret;
651
- has_changed=true;
652
- }
653
- }
654
-
655
-
656
- if('client_handshake_traffic_secret' in options){
657
- if(context.client_handshake_traffic_secret==null && options.client_handshake_traffic_secret!==null){
658
- prev['client_handshake_traffic_secret']=context['client_handshake_traffic_secret'];
659
- context.client_handshake_traffic_secret=options.client_handshake_traffic_secret;
660
- has_changed=true;
661
- }
662
- }
663
-
664
- if('server_handshake_traffic_secret' in options){
665
- if(context.server_handshake_traffic_secret==null && options.server_handshake_traffic_secret!==null){
666
- prev['server_handshake_traffic_secret']=context['server_handshake_traffic_secret'];
667
- context.server_handshake_traffic_secret=options.server_handshake_traffic_secret;
668
- has_changed=true;
669
- }
670
- }
671
-
672
- if('client_app_traffic_secret' in options){
673
- if(context.client_app_traffic_secret==null && options.client_app_traffic_secret!==null){
674
- prev['client_app_traffic_secret']=context['client_app_traffic_secret'];
675
- context.client_app_traffic_secret=options.client_app_traffic_secret;
676
- has_changed=true;
677
- }
678
- }
679
-
680
- if('server_app_traffic_secret' in options){
681
- if(context.server_app_traffic_secret==null && options.server_app_traffic_secret!==null){
682
- prev['server_app_traffic_secret']=context['server_app_traffic_secret'];
683
- context.server_app_traffic_secret=options.server_app_traffic_secret;
684
- has_changed=true;
685
- }
686
- }
687
-
688
-
689
-
690
- if('local_cert_chain' in options){
691
- if(context.local_cert_chain==null && options.local_cert_chain!==null){
692
- prev['local_cert_chain']=context['local_cert_chain'];
693
- context.local_cert_chain=options.local_cert_chain;
694
- has_changed=true;
695
- }
696
- }
697
-
698
- if('cert_private_key' in options){
699
- if(context.cert_private_key==null && options.cert_private_key!==null){
700
- prev['cert_private_key']=context['cert_private_key'];
701
- context.cert_private_key=options.cert_private_key;
702
- has_changed=true;
703
- }
704
- }
705
-
706
- if('expected_remote_finished' in options){
707
- if(context.expected_remote_finished==null && options.expected_remote_finished!==null){
708
- prev['expected_remote_finished']=context['expected_remote_finished'];
709
- context.expected_remote_finished=options.expected_remote_finished;
710
- has_changed=true;
711
- }
712
- }
713
-
714
- if('remote_finished' in options){
715
- if(context.remote_finished==null && options.remote_finished!==null){
716
- prev['remote_finished']=context['remote_finished'];
717
- context.remote_finished=options.remote_finished;
718
- has_changed=true;
719
- }
720
- }
721
-
722
- if('remote_finished_ok' in options){
723
- if(context.remote_finished_ok!==options.remote_finished_ok){
724
- prev['remote_finished_ok']=context['remote_finished_ok'];
725
- context.remote_finished_ok=options.remote_finished_ok;
726
- has_changed=true;
727
- }
728
- }
729
-
730
-
731
-
732
-
733
- }
734
-
735
-
736
- if(has_changed==true){
737
-
738
- var params_to_set = {};
739
-
740
- if (
741
- !arraysEqual(context.local_versions, prev.local_versions) ||
742
- !arraysEqual(context.remote_versions, prev.remote_versions) ||
743
-
744
- !arraysEqual(context.local_cipher_suites, prev.local_cipher_suites) ||
745
- !arraysEqual(context.remote_cipher_suites, prev.remote_cipher_suites) ||
746
-
747
- !arraysEqual(context.local_alpns, prev.local_alpns) ||
748
- !arraysEqual(context.remote_alpns, prev.remote_alpns) ||
749
-
750
- !arraysEqual(context.local_groups, prev.local_groups) ||
751
- !arraysEqual(context.remote_groups, prev.remote_groups) ||
752
-
753
- !arraysEqual(context.local_signature_algorithms, prev.local_signature_algorithms) ||
754
- !arraysEqual(context.remote_signature_algorithms, prev.remote_signature_algorithms) ||
755
-
756
- // הרחבות כלליות
757
- !arraysEqual(context.local_extensions, prev.local_extensions) ||
758
- //!arraysEqual(context.local_ee_extensions, prev.local_ee_extensions) || // TLS 1.3 EE
759
- //!arraysEqual(context.remote_extensions_all, prev.remote_extensions_all) ||
760
- //!arraysEqual(context.remote_extensions_unknown, prev.remote_extensions_unknown) ||
761
-
762
- // key_shares הם מערך של אובייקטים {group, pubkey} → deep compare
763
- !arraysEqual(context.remote_key_shares, prev.remote_key_shares) ||
764
-
765
- // session_id הוא Uint8Array → בדיקה ייעודית
766
- !arraybufferEqual(context.remote_session_id.buffer, prev.remote_session_id.buffer) ||
767
-
768
- // סניפים/מחרוזות פשוט
769
- context.remote_sni !== prev.remote_sni ||
770
- 1==1
771
- ) {
772
-
773
-
774
-
775
- // === גרסה ===
776
- if (context.selected_version == null && context.local_versions.length > 0 && context.remote_versions.length > 0) {
777
- for (var i = 0; i < context.local_versions.length; i++) {
778
- var v = context.local_versions[i] | 0;
779
- for (var j = 0; j < context.remote_versions.length; j++) {
780
- if ((context.remote_versions[j] | 0) == v) {
781
- params_to_set['selected_version'] = v;
782
- break;
783
- }
784
- }
785
- if ('selected_version' in params_to_set==true && params_to_set.selected_version !== null) break;
786
- }
787
-
788
- if('selected_version' in params_to_set==false || params_to_set.selected_version==null){
789
- //console.log('no match version...');
790
- }
791
- }
792
-
793
- // === Cipher Suite ===
794
- if (context.selected_cipher_suite == null && context.local_cipher_suites.length > 0 && context.remote_cipher_suites.length > 0) {
795
-
796
- for (var i2 = 0; i2 < context.local_cipher_suites.length; i2++) {
797
- var cs = context.local_cipher_suites[i2] | 0;
798
- for (var j2 = 0; j2 < context.remote_cipher_suites.length; j2++) {
799
-
800
- if ((context.remote_cipher_suites[j2] | 0) == cs) {
801
- params_to_set['selected_cipher_suite'] = cs;
802
- break;
803
- }
804
- }
805
- if ('selected_cipher_suite' in params_to_set==true && params_to_set.selected_cipher_suite !== null) break;
806
- }
807
-
808
- if('selected_cipher_suite' in params_to_set==false || params_to_set.selected_cipher_suite==null){
809
- //console.log('no match cipher_suites...');
810
- }
811
- }
812
-
813
- // === ALPN ===
814
- if (context.selected_alpn == null && context.local_alpns && context.remote_alpns) {
815
- // עבור על הרשימה המקומית לפי סדר עדיפויות
816
- for (var a = 0; a < context.local_alpns.length; a++) {
817
- var cand = context.local_alpns[a];
818
- for (var b = 0; b < context.remote_alpns.length; b++) {
819
- if (context.remote_alpns[b] === cand) {
820
- params_to_set['selected_alpn'] = cand;
821
- break;
822
- }
823
- }
824
- if ('selected_alpn' in params_to_set==true && params_to_set.selected_alpn !== null) break;
825
- }
826
- }
827
-
828
- // === Group (ECDHE) ===
829
- if (context.selected_group == null){
830
- if (context.selected_version == wire.TLS_VERSION.TLS1_3) {
831
- if(context.local_groups.length > 0 && context.remote_key_shares.length > 0) {
832
- for (var g = 0; g < context.local_groups.length; g++) {
833
- var grp = context.local_groups[g] | 0;
834
- for (var k = 0; k < context.remote_key_shares.length; k++) {
835
- var ent = context.remote_key_shares[k];
836
- if ((ent.group | 0) === grp) {
837
- params_to_set['selected_group'] = grp;
838
- params_to_set['remote_key_share_selected_public'] = ent.pubkey || ent.key_exchange || null;
839
- break;
840
- }
841
- }
842
- if ('selected_group' in params_to_set==true && params_to_set.selected_group !== null) break;
843
- }
844
- if (!params_to_set.selected_group && context.selected_version === wire.TLS_VERSION.TLS1_3) {
845
- params_to_set['need_hrr'] = true; // HelloRetryRequest אם לא נמצא group
846
- }
847
-
848
- if('selected_group' in params_to_set==false || params_to_set.selected_group==null){
849
- //console.log('no match selected_group...');
850
- }
851
- }
852
- }else if(context.selected_version == wire.TLS_VERSION.TLS1_2){
853
- //console.log('...remote_groups...');
854
-
855
- // 1.2 – לבחור עקום מתוך supported_groups של הלקוח (אין key_share)
856
- if (context.local_groups.length > 0 && context.remote_groups.length > 0) {
857
- for (let grp of context.local_groups) {
858
- if (context.remote_groups.some(g => (g|0) === (grp|0))) {
859
- params_to_set.selected_group = grp|0;
860
- break;
861
- }
862
- }
863
-
864
- if('selected_group' in params_to_set==false || params_to_set.selected_group==null){
865
- //console.log('no match selected_group...');
866
- }
867
- }
868
-
869
- }
870
-
871
- }
872
-
873
- // === Signature Algorithm ===
874
- if (context.selected_signature_algorithm == null && context.local_signature_algorithms.length > 0 && context.remote_signature_algorithms.length > 0) {
875
- for (var s = 0; s < context.local_signature_algorithms.length; s++) {
876
- var sa = context.local_signature_algorithms[s] | 0;
877
- for (var t = 0; t < context.remote_signature_algorithms.length; t++) {
878
- if ((context.remote_signature_algorithms[t] | 0) === sa) {
879
- params_to_set['selected_signature_algorithm'] = sa;
880
- break;
881
- }
882
- }
883
- if ('selected_signature_algorithm' in params_to_set==true && params_to_set.selected_signature_algorithm != null) break;
884
- }
885
-
886
- if('selected_signature_algorithm' in params_to_set==false || params_to_set.selected_signature_algorithm==null){
887
- //console.log('no match selected_signature_algorithm...');
888
- }
889
- }
890
-
891
- // === SNI ===
892
- if (context.selected_sni == null) {
893
- params_to_set['selected_sni'] = context.remote_sni || null;
894
- }
895
-
896
- // === Session ID (TLS 1.2 בלבד) ===
897
- if (context.selected_session_id == null) {
898
- params_to_set['selected_session_id'] = context.remote_session_id || new Uint8Array(0);
899
- }
900
-
901
- // === Extensions ===
902
- if (context.selected_extensions == null && 1==2) {
903
- var sel = [];
904
- var allowed = {};
905
- if (context.local_extensions) {
906
- for (var lx = 0; lx < context.local_extensions.length; lx++) {
907
- var lt = context.local_extensions[lx] && context.local_extensions[lx].type;
908
- if (typeof lt === 'number') allowed[lt | 0] = true;
909
- }
910
- }
911
- if (context.local_ee_extensions) {
912
- for (var ex = 0; ex < context.local_ee_extensions.length; ex++) {
913
- var et = context.local_ee_extensions[ex] && context.local_ee_extensions[ex].type;
914
- if (typeof et === 'number') allowed[et | 0] = true;
915
- }
916
- }
917
- if (context.remote_extensions_all) {
918
- for (var rx = 0; rx < context.remote_extensions_all.length; rx++) {
919
- var rt = context.remote_extensions_all[rx] && context.remote_extensions_all[rx].type;
920
- if (typeof rt === 'number' && allowed[rt | 0]) {
921
- sel.push(rt | 0);
922
- }
923
- }
924
- }
925
- if (params_to_set.selected_version === wire.TLS_VERSION.TLS1_3) {
926
- if (sel.indexOf(0x002b) === -1) sel.push(0x002b); // supported_versions
927
- if (sel.indexOf(0x0033) === -1) sel.push(0x0033); // key_share
928
- }
929
- params_to_set['selected_extensions'] = sel;
930
- }
931
-
932
-
933
- //console.log(params_to_set);
934
-
935
- }
936
-
937
- //יצירת מפתח תלוי ב GROUP
938
- if(context.selected_group !== null && context.local_key_share_private === null && context.local_key_share_public === null) {
939
-
940
- if (context.selected_version === wire.TLS_VERSION.TLS1_3) {
941
- var client_public_key = null;
942
- for (var i=0; i<context.remote_key_shares.length; i++){
943
- if ((context.remote_key_shares[i].group|0) === (context.selected_group|0)){
944
- client_public_key = context.remote_key_shares[i].pubkey || context.remote_key_shares[i].key_exchange || null;
945
- break;
946
- }
947
- }
948
-
949
- if(client_public_key!==null){
950
- // כאן ליצור את זוג המפתחות (priv/pub) בהתאם לקבוצה
951
-
952
- if (context.selected_group === 0x001d) { // X25519
953
-
954
- // דרישות פורמט: client_public_key צריך להיות באורך 32 בייטים
955
- // (נמנעים כאן מטיפול שגיאות כרגע)
956
- var local_key_share_private = new Uint8Array(crypto.randomBytes(32));
957
- var local_key_share_public = x25519.getPublicKey(local_key_share_private);
958
- var ecdhe_shared_secret = x25519.getSharedSecret(local_key_share_private, client_public_key);
959
- // אפשר לבצע strip של ה־first byte אם הספרייה מחזירה 32/33 — תלוי במימוש.
960
-
961
- params_to_set['local_key_share_private']=local_key_share_private;
962
- params_to_set['local_key_share_public']=local_key_share_public;
963
- params_to_set['ecdhe_shared_secret']=ecdhe_shared_secret;
964
-
965
-
966
-
967
- } else if (context.selected_group === 0x0017) { // secp256r1 (P-256)
968
- //console.log('P-256');
969
-
970
- var local_key_share_private = p256.utils.randomPrivateKey();
971
- var local_key_share_public = p256.getPublicKey(priv, false); // uncompressed 65B
972
-
973
- var clientPoint = p256.ProjectivePoint.fromHex(client_public_key);
974
- // נקודת השיתוף = priv * clientPoint
975
- var sharedPoint = clientPoint.multiply(BigInt('0x' + Buffer.from(priv).toString('hex')));
976
- // שליפת הקואורדינטה X כ-32 בתים big-endian:
977
- var affine = sharedPoint.toAffine(); // { x: bigint, y: bigint }
978
- var xHex = affine.x.toString(16).padStart(64, '0'); // 32B hex
979
- var ecdhe_shared_secret = Uint8Array.from(Buffer.from(xHex, 'hex')); // ← הסוד ל-TLS הוא X בלבד
980
-
981
- params_to_set['local_key_share_private']=local_key_share_private;
982
- params_to_set['local_key_share_public']=local_key_share_public;
983
- params_to_set['ecdhe_shared_secret']=ecdhe_shared_secret;
984
- }
985
-
986
- }
987
- }else if(context.selected_version === wire.TLS_VERSION.TLS1_2){
988
-
989
- //console.log('@@@ 2');
990
- // רק ליצור (priv/pub) עבור ServerKeyExchange
991
- if (context.selected_group === 0x001d) { // X25519
992
- const priv = new Uint8Array(crypto.randomBytes(32));
993
- const pub = x25519.getPublicKey(priv);
994
- params_to_set.local_key_share_private = priv;
995
- params_to_set.local_key_share_public = pub;
996
- // אל תחשב shared כאן; תחכה ל-ClientKeyExchange
997
- } else if (context.selected_group === 0x0017) { // P-256
998
- const priv = p256.utils.randomPrivateKey();
999
- const pub = p256.getPublicKey(priv, false); // 65B uncompressed
1000
- params_to_set.local_key_share_private = priv;
1001
- params_to_set.local_key_share_public = pub;
1002
- }
1003
- }
1004
-
1005
- }
1006
-
1007
-
1008
-
1009
-
1010
-
1011
-
1012
- if (context.selected_version !== prev.selected_version || context.selected_cipher_suite !== prev.selected_cipher_suite || context.selected_session_id !== prev.selected_session_id || context.selected_group !== prev.selected_group || context.local_key_share_public !== prev.local_key_share_public){
1013
- // build_server_hello... 1.3...
1014
-
1015
- var can_send_hello=false;
1016
- if(context.hello_sent==false){
1017
- if(context.selected_version!==null && context.selected_cipher_suite!==null && context.selected_session_id!==null){
1018
- if(context.selected_version === wire.TLS_VERSION.TLS1_3){
1019
- if(context.local_key_share_public!==null && context.selected_group !== null){
1020
- can_send_hello=true;
1021
- }
1022
- }else if(context.selected_version === wire.TLS_VERSION.TLS1_2){
1023
- can_send_hello=true;
1024
- }
1025
- }
1026
- }
1027
-
1028
- if(can_send_hello==true){
1029
- if(context.local_random==null){
1030
- context.local_random=new Uint8Array(crypto.randomBytes(32));
1031
- }
1032
-
1033
- var build_message_params=null;
1034
-
1035
- if(context.selected_version==wire.TLS_VERSION.TLS1_3){
1036
-
1037
- build_message_params={
1038
- type: 'server_hello',
1039
- version: context.selected_version,
1040
- random: context.local_random,
1041
- session_id: context.remote_session_id,
1042
- cipher_suite: context.selected_cipher_suite, // TLS_AES_128_GCM_SHA256
1043
- extensions: [
1044
- {
1045
- type: 'SUPPORTED_VERSIONS',
1046
- value: wire.TLS_VERSION.TLS1_3
1047
- },
1048
- {
1049
- type: 'KEY_SHARE',
1050
- value: {
1051
- group: context.selected_group,
1052
- key_exchange: context.local_key_share_public
1053
- }
1054
- }
1055
- ]
1056
- };
1057
-
1058
-
1059
- }else if(context.selected_version==wire.TLS_VERSION.TLS1_2){
1060
-
1061
- // ⚠️ אין SUPPORTED_VERSIONS/KEY_SHARE בתוך ServerHello של TLS 1.2.
1062
- // מומלץ לכלול renegotiation_info (ריק בהנדשייק ראשון) ו-extended_master_secret (type=23).
1063
- // ALPN (type=16) – אופציונלי: אם נבחר למשל 'http/1.1' או 'h2'.
1064
-
1065
- var ext_list = [
1066
- // RFC 5746 – initial handshake: value ריק (vec<1> באורך 0)
1067
- { type: 'RENEGOTIATION_INFO', value: new Uint8Array(0) },
1068
-
1069
- // RFC 7627 – extended_master_secret (type 23) – ערך ריק.
1070
- // מאחר ואין encoder רשום אצלנו ל-23, נשתמש ישירות ב-data ריק:
1071
- { type: 23, data: new Uint8Array(0) }
1072
- ];
1073
-
1074
- if (context.alpn_selected) {
1075
- // RFC 7301 – ב-ServerHello מוחזר פרוטוקול אחד
1076
- ext_list.push({ type: 'ALPN', value: [ String(context.alpn_selected) ] });
1077
- }
1078
-
1079
- build_message_params = {
1080
- type: 'server_hello',
1081
- version: context.selected_version,
1082
- random: context.local_random,
1083
- session_id: context.remote_session_id || new Uint8Array(0), // מקובל להדהד את ה-session_id של הלקוח
1084
- cipher_suite: context.selected_cipher_suite, // למשל 0xC02F (ECDHE_RSA_WITH_AES_128_GCM_SHA256)
1085
- // compression_method תמיד 0 ב-1.2 אצלנו; ה-builder כבר כותב 0.
1086
- extensions: ext_list
1087
- };
1088
-
1089
- }
1090
-
1091
- if(build_message_params!==null){
1092
-
1093
- //console.log('sent server hello...')
1094
- var message_data = wire.build_message(build_message_params);
1095
-
1096
- context.transcript.push(message_data);
1097
-
1098
- context.hello_sent=true;
1099
-
1100
- ev.emit('message',0,context.message_sent_seq,'hello',message_data);
1101
-
1102
- context.message_sent_seq++;
1103
- }
1104
- }
1105
-
1106
- }
1107
-
1108
-
1109
-
1110
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1111
- if(context.selected_cipher_suite !== null && (context.ecdhe_shared_secret !== null)){// || context.selected_psk !== null
1112
-
1113
- var d = derive_handshake_traffic_secrets(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash, context.ecdhe_shared_secret, concatUint8Arrays(context.transcript));
1114
-
1115
- params_to_set['handshake_secret']=d.handshake_secret;
1116
-
1117
- params_to_set['client_handshake_traffic_secret']=d.client_handshake_traffic_secret;
1118
- params_to_set['server_handshake_traffic_secret']=d.server_handshake_traffic_secret;
1119
-
1120
-
1121
- }
1122
- }
1123
-
1124
-
1125
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1126
- if(context.encrypted_exts_sent==false && context.hello_sent==true && context.server_handshake_traffic_secret!==null){
1127
-
1128
- var extensions=[];
1129
- if(context.selected_alpn!==null){
1130
- extensions.push({ type: 'ALPN', value: [context.selected_alpn] });
1131
- }
1132
-
1133
- //console.log('extensions:');
1134
- //console.log(extensions);
1135
-
1136
- for(var i in context.local_extensions){
1137
- extensions.push(context.local_extensions[i]);
1138
- }
1139
-
1140
- var message_data = wire.build_message({
1141
- type: 'encrypted_extensions',
1142
- extensions: extensions
1143
- });
1144
-
1145
- //console.log('message_data:');
1146
- //console.log(message_data);
1147
-
1148
- context.transcript.push(message_data);
1149
-
1150
- context.encrypted_exts_sent=true;
1151
-
1152
- ev.emit('message',1,context.message_sent_seq,'encrypted_extensions',message_data);
1153
-
1154
- context.message_sent_seq++;
1155
-
1156
- }
1157
- }
1158
-
1159
-
1160
- if(context.cert_sent==false && context.local_cert_chain!==null){
1161
- if((context.selected_version === wire.TLS_VERSION.TLS1_3 && context.encrypted_exts_sent==true && context.server_handshake_traffic_secret!==null) || (context.selected_version === wire.TLS_VERSION.TLS1_2 && context.hello_sent==true)){
1162
-
1163
- var message_data = wire.build_message({
1164
- type: 'certificate',
1165
- version: context.selected_version,
1166
- entries: context.local_cert_chain
1167
- });
1168
- context.transcript.push(message_data);
1169
-
1170
- context.cert_sent=true;
1171
-
1172
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1173
- ev.emit('message',1,context.message_sent_seq,'certificate',message_data);
1174
- }else{
1175
- ev.emit('message',0,context.message_sent_seq,'certificate',message_data);
1176
- }
1177
-
1178
- context.message_sent_seq++;
1179
-
1180
-
1181
- }
1182
- }
1183
-
1184
-
1185
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1186
- if(context.cert_sent==true && context.cert_verify_sent==false && context.local_cert_chain!==null && context.server_handshake_traffic_secret!==null){
1187
-
1188
- var tbs_data = build_cert_verify_tbs(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash,true,concatUint8Arrays(context.transcript));
1189
-
1190
- var cert_private_key_obj = crypto.createPrivateKey({
1191
- key: Buffer.from(context.cert_private_key),
1192
- format: 'der',
1193
- type: 'pkcs8',
1194
- });
1195
-
1196
- var SIG = {
1197
- ECDSA_P256_SHA256: 0x0403,
1198
- ECDSA_P384_SHA384: 0x0503,
1199
- ECDSA_P521_SHA512: 0x0603,
1200
- RSA_PSS_SHA256: 0x0804,
1201
- RSA_PSS_SHA384: 0x0805,
1202
- RSA_PSS_SHA512: 0x0806,
1203
- ED25519: 0x0807,
1204
- ED448: 0x0808
1205
- };
1206
-
1207
- var candidates=[];
1208
- if (cert_private_key_obj.asymmetricKeyType === 'ed25519') candidates.push(SIG.ED25519);
1209
- if (cert_private_key_obj.asymmetricKeyType === 'ed448') candidates.push(SIG.ED448);
1210
- if (cert_private_key_obj.asymmetricKeyType === 'rsa') candidates.push(SIG.RSA_PSS_SHA256, SIG.RSA_PSS_SHA384, SIG.RSA_PSS_SHA512); // TLS 1.3 → רק PSS
1211
-
1212
- if (cert_private_key_obj.asymmetricKeyType === 'ec') {
1213
- var c = (cert_private_key_obj.asymmetricKeyDetails && cert_private_key_obj.asymmetricKeyDetails && cert_private_key_obj.asymmetricKeyDetails.namedCurve) || '';
1214
- if (c === 'prime256v1') candidates.push(SIG.ECDSA_P256_SHA256);
1215
- if (c === 'secp384r1') candidates.push(SIG.ECDSA_P384_SHA384);
1216
- if (c === 'secp521r1') candidates.push(SIG.ECDSA_P521_SHA512);
1217
- }
1218
-
1219
- //console.log(candidates);
1220
-
1221
- var preference_order = [
1222
- SIG.ED25519,
1223
- SIG.ED448,
1224
- SIG.ECDSA_P256_SHA256,
1225
- SIG.ECDSA_P384_SHA384,
1226
- SIG.ECDSA_P521_SHA512,
1227
- SIG.RSA_PSS_SHA256,
1228
- SIG.RSA_PSS_SHA384,
1229
- SIG.RSA_PSS_SHA512
1230
- ];
1231
-
1232
- var selected_scheme = null;
1233
- for (var s of preference_order) {
1234
- if (context.remote_signature_algorithms.includes(s)==true && candidates.includes(s)==true) {
1235
- selected_scheme = s;
1236
- break;
1237
- }
1238
- }
1239
-
1240
- var sig_data=null;
1241
-
1242
- switch (selected_scheme) {
1243
- case SIG.ED25519:
1244
- sig_data = new Uint8Array(crypto.sign(null, tbs_data, cert_private_key_obj));
1245
- break;
1246
-
1247
- case SIG.ECDSA_P256_SHA256:
1248
- sig_data = new Uint8Array(crypto.sign('sha256', tbs_data, cert_private_key_obj));
1249
- break;
1250
-
1251
- case SIG.ECDSA_P384_SHA384:
1252
- sig_data = new Uint8Array(crypto.sign('sha384', tbs_data, cert_private_key_obj));
1253
- break;
1254
-
1255
- case SIG.ECDSA_P521_SHA512:
1256
- sig_data = new Uint8Array(crypto.sign('sha512', tbs_data, cert_private_key_obj));
1257
- break;
1258
-
1259
- case SIG.RSA_PSS_SHA256:
1260
- sig_data = new Uint8Array(crypto.sign('sha256', tbs_data, {
1261
- key: cert_private_key_obj,
1262
- padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
1263
- saltLength: 32
1264
- }));
1265
- break;
1266
-
1267
- case SIG.RSA_PSS_SHA384:
1268
- sig_data = new Uint8Array(crypto.sign('sha384', tbs_data, {
1269
- key: cert_private_key_obj,
1270
- padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
1271
- saltLength: 48
1272
- }));
1273
- break;
1274
-
1275
- case SIG.RSA_PSS_SHA512:
1276
- sig_data = new Uint8Array(crypto.sign('sha512', tbs_data, {
1277
- key: cert_private_key_obj,
1278
- padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
1279
- saltLength: 64
1280
- }));
1281
- break;
1282
- }
1283
-
1284
-
1285
- //console.log('sig_data:');
1286
- //console.log(sig_data);
1287
-
1288
- if(sig_data){
1289
-
1290
- var message_data = wire.build_message({
1291
- type: 'certificate_verify',
1292
- scheme: selected_scheme,
1293
- signature: sig_data
1294
- });
1295
-
1296
-
1297
-
1298
- //console.log(message_data);
1299
- //console.log('certificate_verify sent!');
1300
- context.transcript.push(message_data);
1301
-
1302
- context.cert_verify_sent=true;
1303
-
1304
- ev.emit('message',1,context.message_sent_seq,'certificate_verify',message_data);
1305
-
1306
- context.message_sent_seq++;
1307
- }else{
1308
-
1309
- //..
1310
- }
1311
-
1312
-
1313
-
1314
-
1315
- }
1316
- }
1317
-
1318
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1319
- if(context.cert_verify_sent==true && context.finished_sent==false && context.local_cert_chain!==null && context.server_handshake_traffic_secret!==null){
1320
-
1321
- var finished_data=get_handshake_finished(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash,context.server_handshake_traffic_secret,concatUint8Arrays(context.transcript));
1322
-
1323
- var message_data = wire.build_message({
1324
- type: 'finished',
1325
- data: finished_data
1326
- });
1327
-
1328
- context.transcript.push(message_data);
1329
-
1330
- context.finished_sent=true;
1331
-
1332
- ev.emit('message',1,context.message_sent_seq,'finished',message_data);
1333
-
1334
- context.message_sent_seq++;
1335
-
1336
-
1337
- }
1338
- }
1339
-
1340
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1341
- if(context.finished_sent==true && context.handshake_secret!==null && context.server_app_traffic_secret==null){
1342
-
1343
- var d2 = derive_app_traffic_secrets(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash, context.handshake_secret, concatUint8Arrays(context.transcript));
1344
-
1345
- params_to_set['handshake_secret']=null;
1346
-
1347
- params_to_set['client_app_traffic_secret']=d2.client_app_traffic_secret;
1348
- params_to_set['server_app_traffic_secret']=d2.server_app_traffic_secret;
1349
-
1350
- }
1351
- }
1352
-
1353
- //בניית פינישד צפוי
1354
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1355
- if(context.finished_sent==true && context.expected_remote_finished==null && context.client_handshake_traffic_secret!==null){
1356
-
1357
- params_to_set['expected_remote_finished']=get_handshake_finished(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash,context.client_handshake_traffic_secret,concatUint8Arrays(context.transcript));
1358
-
1359
- }
1360
- }
1361
-
1362
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1363
- if(context.remote_finished_ok==false && context.remote_finished!==null && context.expected_remote_finished!==null){
1364
-
1365
- if(arraybufferEqual(context.remote_finished.buffer,context.expected_remote_finished.buffer)==true){
1366
-
1367
- context.transcript.push(context.remote_finished);
1368
-
1369
- context.remote_finished_ok=true;
1370
-
1371
- context.remote_finished=null;
1372
- context.expected_remote_finished=null;
1373
-
1374
- //console.log('finished ok!!!...');
1375
-
1376
-
1377
- }else{
1378
- context.remote_finished=null;
1379
-
1380
- //console.log('finished fail...');
1381
- }
1382
-
1383
- }
1384
- }
1385
-
1386
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1387
- if(context.remote_finished_ok==true && context.server_app_traffic_secret!==null){
1388
-
1389
- ev.emit('secureConnect');
1390
-
1391
- }
1392
- }
1393
-
1394
-
1395
-
1396
- set_context(params_to_set);
1397
- }
1398
- }
1399
-
1400
-
1401
- function close(){
1402
-
1403
- }
1404
-
1405
- var api = {
1406
- context: context,
1407
-
1408
- on: function(name, fn){ ev.on(name, fn); },
1409
-
1410
- message: process_income_message,
1411
-
1412
- set_context: set_context,
1413
-
1414
-
1415
- close: close,
1416
-
1417
- //getProtocol: getProtocol,
1418
-
1419
- getCipher: function(){
1420
- // TODO: { name, standardName, keyLen, aead } אחרי נגושיאציה
1421
- return null;
1422
- },
1423
-
1424
- getPeerCertificate: function(detailed){
1425
- void detailed;
1426
- // TODO: להחזיר ch cert או null
1427
- return context.peerCert;
1428
- },
1429
-
1430
- exportKeyingMaterial: function(length, label, context){
1431
- void length; void label; void context;
1432
- // TODO: HKDF-Expand-Label על traffic secret מתאים (RFC8446)
1433
- return new Uint8Array(0);
1434
- }
1435
- };
1436
-
1437
- for (var k in api) if (Object.prototype.hasOwnProperty.call(api,k)) this[k] = api[k];
1438
- return this;
1439
- }
1440
-
1441
- module.exports = TLSSession;