lemon-tls 0.1.1 → 0.2.1

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