lemon-tls 0.2.1 → 0.2.2

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.
@@ -108,6 +108,7 @@ function TLSSession(options){
108
108
 
109
109
 
110
110
  transcript: [],
111
+ transcriptHook: null, // DTLSSession sets this to transform transcript entries
111
112
 
112
113
 
113
114
  //both
@@ -162,6 +163,9 @@ function TLSSession(options){
162
163
  // HelloRetryRequest
163
164
  helloRetried: false, // true if HRR was sent/received
164
165
 
166
+ // DTLS cookie (set by DTLSSession via set_context)
167
+ dtls_cookie: undefined, // Uint8Array or undefined
168
+
165
169
  // TLS 1.3 resumption
166
170
  tls13_master_secret: null,
167
171
  resumption_master_secret: null,
@@ -173,6 +177,19 @@ function TLSSession(options){
173
177
  isResumed: false, // true if PSK was accepted
174
178
  };
175
179
 
180
+ /**
181
+ * Push a handshake message to the transcript.
182
+ * If a transcriptHook is set (by DTLSSession), it transforms the data first.
183
+ * This allows DTLS 1.2 to store DTLS-format entries (with reconstruction data)
184
+ * while TLS and DTLS 1.3 store standard TLS-format entries.
185
+ */
186
+ function pushTranscript(data) {
187
+ if (context.transcriptHook) {
188
+ data = context.transcriptHook(data);
189
+ }
190
+ context.transcript.push(data);
191
+ }
192
+
176
193
  function process_income_message(data){
177
194
 
178
195
  // Track handshake start time
@@ -192,7 +209,7 @@ function TLSSession(options){
192
209
 
193
210
  if((context.isServer==false && message.type=='server_hello') || (context.isServer==true && message.type=='client_hello')){
194
211
 
195
- context.transcript.push(data);
212
+ pushTranscript(data);
196
213
 
197
214
  // Save raw ClientHello + emit event (server side)
198
215
  if (context.isServer && message.type === 'client_hello') {
@@ -350,11 +367,12 @@ function TLSSession(options){
350
367
  version: 0x0303,
351
368
  random: context.local_random,
352
369
  session_id: context.local_session_id,
370
+ cookie: context.dtls_cookie,
353
371
  cipher_suite: context.local_supported_cipher_suites,
354
372
  extensions: extensions,
355
373
  });
356
374
 
357
- context.transcript.push(ch2);
375
+ pushTranscript(ch2);
358
376
  ev.emit('message', 0, context.message_sent_seq, 'hello', ch2);
359
377
  context.message_sent_seq++;
360
378
  }
@@ -368,7 +386,9 @@ function TLSSession(options){
368
386
  remote_random: message.random || null,
369
387
  remote_sni: message.sni || null,
370
388
  remote_session_id: message.session_id || null,
371
- remote_supported_versions: message.supported_versions || [],
389
+ remote_supported_versions: (message.supported_versions && message.supported_versions.length > 0)
390
+ ? message.supported_versions
391
+ : (message.legacy_version ? [message.legacy_version] : []),
372
392
  remote_supported_alpns: message.alpn || [],
373
393
  remote_supported_cipher_suites: message.cipher_suites || [],
374
394
  remote_supported_signature_algorithms: message.signature_algorithms || [],
@@ -396,21 +416,27 @@ function TLSSession(options){
396
416
 
397
417
  }else if(message.type=='client_key_exchange' || message.type=='server_key_exchange'){
398
418
 
399
- context.transcript.push(data);
419
+ pushTranscript(data);
400
420
 
401
421
  if ([0xC02F,0xC02B,0xC030,0xC02C,0xC013,0xC014,0xC009,0xC00A].includes(context.selected_cipher_suite)==true) {//ECDHE
402
422
 
403
423
  // ServerKeyExchange carries the group; ClientKeyExchange does not (server already chose it)
404
424
  let kex_group = message.group || context.selected_group;
405
425
 
406
- set_context({
426
+ let kex_updates = {
407
427
  add_remote_key_groups: [
408
428
  {
409
429
  group: kex_group,
410
430
  public_key: message.public_key
411
431
  }
412
432
  ],
413
- });
433
+ };
434
+ // TLS 1.2 client: selected_group isn't set from ServerHello (no supported_groups ext).
435
+ // Set it from the SKE group so the reactive loop can generate a keypair and build CKE.
436
+ if (context.selected_group === null && kex_group) {
437
+ kex_updates.selected_group = kex_group;
438
+ }
439
+ set_context(kex_updates);
414
440
 
415
441
  }else if ([0x009E,0x009F,0x0033,0x0039,0x0067,0x006B].includes(context.selected_cipher_suite)==true) {//DHE
416
442
 
@@ -426,7 +452,7 @@ function TLSSession(options){
426
452
 
427
453
  }else if(message.type=='server_hello_done'){
428
454
 
429
- context.transcript.push(data);
455
+ pushTranscript(data);
430
456
 
431
457
 
432
458
  set_context({
@@ -435,7 +461,7 @@ function TLSSession(options){
435
461
 
436
462
  }else if(message.type=='encrypted_extensions'){
437
463
 
438
- context.transcript.push(data);
464
+ pushTranscript(data);
439
465
 
440
466
  set_context({
441
467
  remote_supported_groups: message.supported_groups || [],
@@ -443,7 +469,7 @@ function TLSSession(options){
443
469
 
444
470
  }else if(message.type=='certificate'){
445
471
 
446
- context.transcript.push(data);
472
+ pushTranscript(data);
447
473
 
448
474
  set_context({
449
475
  remote_cert_chain: message.entries,
@@ -458,7 +484,7 @@ function TLSSession(options){
458
484
 
459
485
  }else if(message.type=='certificate_verify'){
460
486
 
461
- context.transcript.push(data);
487
+ pushTranscript(data);
462
488
 
463
489
  }else if(message.type=='finished'){
464
490
 
@@ -487,7 +513,7 @@ function TLSSession(options){
487
513
  }else if(message.type=='key_update'){
488
514
 
489
515
  // Peer is updating their traffic secret (we update our read key)
490
- if(context.state==='connected' && context.selected_version === wire.TLS_VERSION.TLS1_3){
516
+ if(context.state==='connected' && (context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
491
517
  let hashName = TLS_CIPHER_SUITES[context.selected_cipher_suite].hash;
492
518
  let hashLen = getHashLen(hashName);
493
519
  let newRemoteSecret = hkdf_expand_label(hashName, context.remote_app_traffic_secret, 'traffic upd', new Uint8Array(0), hashLen);
@@ -512,7 +538,7 @@ function TLSSession(options){
512
538
 
513
539
  // Server is requesting a client certificate (TLS 1.3)
514
540
  if(!context.isServer){
515
- context.transcript.push(data);
541
+ pushTranscript(data);
516
542
  context.certificateRequested = true;
517
543
  context.certificateRequestContext = message.certificate_request_context || new Uint8Array(0);
518
544
  context.certificateRequestSigAlgs = message.signature_algorithms || [];
@@ -871,7 +897,10 @@ function TLSSession(options){
871
897
  }
872
898
  }
873
899
 
874
-
900
+ if('dtls_cookie' in options){
901
+ context.dtls_cookie=options.dtls_cookie;
902
+ has_changed=true;
903
+ }
875
904
 
876
905
 
877
906
  }
@@ -901,6 +930,16 @@ function TLSSession(options){
901
930
 
902
931
  if('selected_version' in params_to_set==false || params_to_set.selected_version==null){
903
932
  }
933
+
934
+ // TLS 1.2: clear key_share groups from ClientHello.
935
+ // key_share is a TLS 1.3 extension; in TLS 1.2, keys come from CKE/SKE.
936
+ // Without this, the server would compute the shared secret too early
937
+ // (using CH key_share instead of waiting for CKE).
938
+ if (context.isServer && params_to_set.selected_version !== null &&
939
+ params_to_set.selected_version !== wire.TLS_VERSION.TLS1_3 &&
940
+ params_to_set.selected_version !== wire.DTLS_VERSION.DTLS1_3) {
941
+ context.remote_key_groups = {};
942
+ }
904
943
  }
905
944
 
906
945
  //select selected_cipher...
@@ -1050,7 +1089,7 @@ function TLSSession(options){
1050
1089
  if(context.isServer==true){
1051
1090
 
1052
1091
  // HelloRetryRequest: if we selected a group but client didn't send a key_share for it
1053
- if(context.hello_sent==false && !context.helloRetried && context.selected_version === wire.TLS_VERSION.TLS1_3 &&
1092
+ if(context.hello_sent==false && !context.helloRetried && (context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) &&
1054
1093
  context.selected_group !== null && context.selected_cipher_suite !== null &&
1055
1094
  !(context.selected_group in context.remote_key_groups)){
1056
1095
 
@@ -1065,12 +1104,12 @@ function TLSSession(options){
1065
1104
  // Build and send HRR (it's a ServerHello with magic random)
1066
1105
  let hrr_body = wire.build_hello_retry_request({
1067
1106
  cipher_suite: context.selected_cipher_suite,
1068
- selected_version: wire.TLS_VERSION.TLS1_3,
1107
+ selected_version: context.selected_version,
1069
1108
  selected_group: context.selected_group,
1070
1109
  session_id: context.remote_session_id,
1071
1110
  });
1072
1111
  let hrr_data = wire.build_message(wire.TLS_MESSAGE_TYPE.SERVER_HELLO, hrr_body);
1073
- context.transcript.push(hrr_data);
1112
+ pushTranscript(hrr_data);
1074
1113
 
1075
1114
  ev.emit('message', 0, context.message_sent_seq, 'hello_retry_request', hrr_data);
1076
1115
  context.message_sent_seq++;
@@ -1090,14 +1129,14 @@ function TLSSession(options){
1090
1129
  if(context.hello_sent==false){
1091
1130
 
1092
1131
  if(context.selected_version!==null && context.selected_cipher_suite!==null && context.selected_session_id!==null){
1093
- if(context.selected_version === wire.TLS_VERSION.TLS1_3){
1132
+ if((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
1094
1133
  if(context.selected_group in context.local_key_groups==true && context.local_key_groups[context.selected_group].public_key!==null){
1095
1134
  // After HRR, don't send ServerHello until CH2 provides the requested key_share
1096
1135
  if (!context.helloRetried || (context.selected_group in context.remote_key_groups)) {
1097
1136
  can_send_hello=true;
1098
1137
  }
1099
1138
  }
1100
- }else if(context.selected_version === wire.TLS_VERSION.TLS1_2){
1139
+ }else if((context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2)){
1101
1140
  can_send_hello=true;
1102
1141
  }
1103
1142
  }
@@ -1111,12 +1150,12 @@ function TLSSession(options){
1111
1150
 
1112
1151
  let build_message_params=null;
1113
1152
 
1114
- if(context.selected_version==wire.TLS_VERSION.TLS1_3){
1153
+ if((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
1115
1154
 
1116
1155
  let shExtensions = [
1117
1156
  {
1118
1157
  type: 'SUPPORTED_VERSIONS',
1119
- value: wire.TLS_VERSION.TLS1_3
1158
+ value: context.selected_version
1120
1159
  },
1121
1160
  {
1122
1161
  type: 'KEY_SHARE',
@@ -1142,7 +1181,7 @@ function TLSSession(options){
1142
1181
  };
1143
1182
 
1144
1183
 
1145
- }else if(context.selected_version==wire.TLS_VERSION.TLS1_2){
1184
+ }else if((context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2)){
1146
1185
 
1147
1186
 
1148
1187
  // TLS 1.2 ServerHello: no SUPPORTED_VERSIONS or KEY_SHARE.
@@ -1184,7 +1223,7 @@ function TLSSession(options){
1184
1223
 
1185
1224
  let message_data = build_tls_message(build_message_params);
1186
1225
 
1187
- context.transcript.push(message_data);
1226
+ pushTranscript(message_data);
1188
1227
 
1189
1228
  context.hello_sent=true;
1190
1229
 
@@ -1204,7 +1243,7 @@ function TLSSession(options){
1204
1243
 
1205
1244
  //get base_secret
1206
1245
  if (context.base_secret==null && context.selected_cipher_suite !== null){
1207
- if(context.selected_version == wire.TLS_VERSION.TLS1_3 && (context.ecdhe_shared_secret !== null)){
1246
+ if((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && (context.ecdhe_shared_secret !== null)){
1208
1247
 
1209
1248
  let hashName = TLS_CIPHER_SUITES[context.selected_cipher_suite].hash;
1210
1249
  let result;
@@ -1226,7 +1265,7 @@ function TLSSession(options){
1226
1265
  params_to_set['remote_handshake_traffic_secret']=result.server_handshake_traffic_secret;
1227
1266
  }
1228
1267
 
1229
- }else if(context.selected_version === wire.TLS_VERSION.TLS1_2 && context.local_random!==null && context.remote_random!==null){
1268
+ }else if((context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2) && context.local_random!==null && context.remote_random!==null){
1230
1269
  if(context.ecdhe_shared_secret !== null){
1231
1270
 
1232
1271
 
@@ -1246,7 +1285,11 @@ function TLSSession(options){
1246
1285
  if(context.isServer || context.key_exchange_sent){
1247
1286
  let hashFn = getHashFn(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash);
1248
1287
 
1249
- let transcript_hash = hashFn(concatUint8Arrays(context.transcript));
1288
+ // Use snapshot up to CKE if available (excludes CertificateVerify)
1289
+ let emsTranscript = context._emsTranscriptLen
1290
+ ? context.transcript.slice(0, context._emsTranscriptLen)
1291
+ : context.transcript;
1292
+ let transcript_hash = hashFn(concatUint8Arrays(emsTranscript));
1250
1293
 
1251
1294
  let master_secret = tls12_prf(context.ecdhe_shared_secret, "extended master secret", transcript_hash, 48, TLS_CIPHER_SUITES[context.selected_cipher_suite].hash);
1252
1295
 
@@ -1270,7 +1313,7 @@ function TLSSession(options){
1270
1313
 
1271
1314
 
1272
1315
  //send encrypted_extensions...
1273
- if (context.isServer==true && context.selected_version === wire.TLS_VERSION.TLS1_3){
1316
+ if (context.isServer==true && (context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
1274
1317
  if(context.encrypted_exts_sent==false && context.hello_sent==true && context.local_handshake_traffic_secret!==null){
1275
1318
 
1276
1319
  let extensions=[];
@@ -1288,7 +1331,7 @@ function TLSSession(options){
1288
1331
  extensions: extensions
1289
1332
  });
1290
1333
 
1291
- context.transcript.push(message_data);
1334
+ pushTranscript(message_data);
1292
1335
 
1293
1336
  context.encrypted_exts_sent=true;
1294
1337
 
@@ -1302,31 +1345,31 @@ function TLSSession(options){
1302
1345
 
1303
1346
  //send certificate... (skip for PSK resumption — no cert needed)
1304
1347
  // But first: send CertificateRequest if requestCert is set (TLS 1.3 only, between EE and Cert)
1305
- if(context.isServer==true && context.requestCert==true && !context.certificateRequestSent && context.encrypted_exts_sent==true && context.local_handshake_traffic_secret!==null && context.selected_version === wire.TLS_VERSION.TLS1_3 && !context.psk_accepted){
1348
+ if(context.isServer==true && context.requestCert==true && !context.certificateRequestSent && context.encrypted_exts_sent==true && context.local_handshake_traffic_secret!==null && (context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && !context.psk_accepted){
1306
1349
  let cr_data = build_tls_message({
1307
1350
  type: 'certificate_request',
1308
1351
  certificate_request_context: new Uint8Array(0),
1309
1352
  signature_algorithms: context.local_supported_signature_algorithms,
1310
1353
  });
1311
- context.transcript.push(cr_data);
1354
+ pushTranscript(cr_data);
1312
1355
  context.certificateRequestSent = true;
1313
1356
  ev.emit('message', 1, context.message_sent_seq, 'certificate_request', cr_data);
1314
1357
  context.message_sent_seq++;
1315
1358
  }
1316
1359
 
1317
1360
  if(context.isServer==true && context.cert_sent==false && context.local_cert_chain!==null && !context.psk_accepted){
1318
- if((context.selected_version === wire.TLS_VERSION.TLS1_3 && context.encrypted_exts_sent==true && context.local_handshake_traffic_secret!==null) || (context.selected_version === wire.TLS_VERSION.TLS1_2 && context.hello_sent==true)){
1361
+ if(((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && context.encrypted_exts_sent==true && context.local_handshake_traffic_secret!==null) || ((context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2) && context.hello_sent==true)){
1319
1362
 
1320
1363
  let message_data = build_tls_message({
1321
1364
  type: 'certificate',
1322
1365
  version: context.selected_version,
1323
1366
  entries: context.local_cert_chain
1324
1367
  });
1325
- context.transcript.push(message_data);
1368
+ pushTranscript(message_data);
1326
1369
 
1327
1370
  context.cert_sent=true;
1328
1371
 
1329
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1372
+ if ((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
1330
1373
  ev.emit('message',1,context.message_sent_seq,'certificate',message_data);
1331
1374
  }else{
1332
1375
  ev.emit('message',0,context.message_sent_seq,'certificate',message_data);
@@ -1344,7 +1387,7 @@ function TLSSession(options){
1344
1387
 
1345
1388
 
1346
1389
  //send certificate verify...
1347
- if (context.isServer==true && context.selected_version === wire.TLS_VERSION.TLS1_3){
1390
+ if (context.isServer==true && (context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
1348
1391
  if(context.cert_sent==true && context.cert_verify_sent==false && context.local_cert_chain!==null && context.local_handshake_traffic_secret!==null && context.selected_cipher_suite!==null){
1349
1392
 
1350
1393
  let tbs_data = build_cert_verify_tbs(TLS_CIPHER_SUITES[context.selected_cipher_suite].hash,true,concatUint8Arrays(context.transcript));
@@ -1454,7 +1497,7 @@ function TLSSession(options){
1454
1497
 
1455
1498
 
1456
1499
 
1457
- context.transcript.push(message_data);
1500
+ pushTranscript(message_data);
1458
1501
 
1459
1502
  context.cert_verify_sent=true;
1460
1503
 
@@ -1477,26 +1520,90 @@ function TLSSession(options){
1477
1520
 
1478
1521
 
1479
1522
  // client/server key exchange - 1.2 only...
1480
- if (context.key_exchange_sent == false && context.selected_version == wire.TLS_VERSION.TLS1_2) {
1523
+ if (context.key_exchange_sent == false && (context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2)) {
1481
1524
  if(context.selected_group!==null && context.selected_group in context.local_key_groups==true && context.local_key_groups[context.selected_group].public_key!==null){
1482
1525
 
1483
1526
  if (context.isServer==false && context.remote_hello_done==true) {
1484
1527
 
1528
+ // TLS 1.2: send Certificate before CKE if server requested client auth
1529
+ if (context.certificateRequested && !context.clientCertSent) {
1530
+ context.clientCertSent = true;
1531
+
1532
+ // Build TLS 1.2 Certificate message
1533
+ let certEntries = [];
1534
+ if (context.local_cert_chain && context.local_cert_chain.length > 0) {
1535
+ certEntries = context.local_cert_chain;
1536
+ }
1537
+ // TLS 1.2 Certificate: certificate_list<0..2^24-1>
1538
+ // Each entry: cert_length<3> + cert_der
1539
+ let totalLen = 0;
1540
+ for (let ci = 0; ci < certEntries.length; ci++) {
1541
+ totalLen += 3 + certEntries[ci].cert.length;
1542
+ }
1543
+ let certBody = new Uint8Array(3 + totalLen);
1544
+ certBody[0] = (totalLen >> 16) & 0xff;
1545
+ certBody[1] = (totalLen >> 8) & 0xff;
1546
+ certBody[2] = totalLen & 0xff;
1547
+ let off = 3;
1548
+ for (let ci = 0; ci < certEntries.length; ci++) {
1549
+ let der = certEntries[ci].cert;
1550
+ certBody[off] = (der.length >> 16) & 0xff;
1551
+ certBody[off+1] = (der.length >> 8) & 0xff;
1552
+ certBody[off+2] = der.length & 0xff;
1553
+ certBody.set(der, off + 3);
1554
+ off += 3 + der.length;
1555
+ }
1556
+ let cert_data = wire.build_message(wire.TLS_MESSAGE_TYPE.CERTIFICATE, certBody);
1557
+ pushTranscript(cert_data);
1558
+ ev.emit('message', 0, context.message_sent_seq, 'certificate', cert_data);
1559
+ context.message_sent_seq++;
1560
+ }
1561
+
1485
1562
  let public_key = context.local_key_groups[context.selected_group].public_key;
1486
1563
 
1487
1564
  let message_data = build_tls_message({
1488
1565
  type: 'client_key_exchange',
1489
1566
  public_key: public_key,
1490
1567
  });
1491
- context.transcript.push(message_data);
1568
+ pushTranscript(message_data);
1492
1569
 
1493
1570
  // Set via params_to_set to trigger re-evaluation (EMS needs this)
1494
1571
  params_to_set['key_exchange_sent'] = true;
1572
+
1573
+ // Save transcript length for EMS: session_hash includes up to CKE only (RFC 7627)
1574
+ context._emsTranscriptLen = context.transcript.length;
1495
1575
 
1496
1576
  ev.emit('message', 0, context.message_sent_seq, 'client_key_exchange', message_data);
1497
1577
 
1498
1578
  context.message_sent_seq++;
1499
1579
 
1580
+ // TLS 1.2 CertificateVerify: if we sent a non-empty Certificate, prove we own the private key
1581
+ if (context.certificateRequested && context.cert_private_key && context.local_cert_chain && context.local_cert_chain.length > 0) {
1582
+ // sign_with_scheme hashes internally, so pass RAW transcript (not pre-hashed)
1583
+ let transcript_data = concatUint8Arrays(context.transcript);
1584
+
1585
+ // Pick scheme matching our cert + server's requested algorithms
1586
+ let cert_key_obj = crypto.createPrivateKey({ key: Buffer.from(context.cert_private_key), format: 'der', type: 'pkcs8' });
1587
+ let reqAlgs = context.certificateRequestSigAlgs.length > 0
1588
+ ? context.certificateRequestSigAlgs
1589
+ : context.local_supported_signature_algorithms;
1590
+ let scheme = pick_scheme(wire.TLS_VERSION.TLS1_2, cert_key_obj, reqAlgs);
1591
+ let signature = sign_with_scheme(wire.TLS_VERSION.TLS1_2, scheme, transcript_data, cert_key_obj);
1592
+
1593
+ // Build CertificateVerify: scheme(2) + sig_length(2) + sig
1594
+ let cvBody = new Uint8Array(2 + 2 + signature.length);
1595
+ cvBody[0] = (scheme >> 8) & 0xff;
1596
+ cvBody[1] = scheme & 0xff;
1597
+ cvBody[2] = (signature.length >> 8) & 0xff;
1598
+ cvBody[3] = signature.length & 0xff;
1599
+ cvBody.set(signature, 4);
1600
+
1601
+ let cv_data = wire.build_message(wire.TLS_MESSAGE_TYPE.CERTIFICATE_VERIFY, cvBody);
1602
+ pushTranscript(cv_data);
1603
+ ev.emit('message', 0, context.message_sent_seq, 'certificate_verify', cv_data);
1604
+ context.message_sent_seq++;
1605
+ }
1606
+
1500
1607
 
1501
1608
  }else if (context.isServer==true && context.cert_sent == true) {
1502
1609
 
@@ -1528,7 +1635,7 @@ function TLSSession(options){
1528
1635
  sig_alg: scheme12,
1529
1636
  signature: sig_data
1530
1637
  });
1531
- context.transcript.push(message_data);
1638
+ pushTranscript(message_data);
1532
1639
 
1533
1640
  context.key_exchange_sent = true;
1534
1641
 
@@ -1541,16 +1648,16 @@ function TLSSession(options){
1541
1648
  }
1542
1649
 
1543
1650
  //server hello done - 1.2 only...
1544
- if(context.isServer==true && context.selected_version == wire.TLS_VERSION.TLS1_2){
1651
+ if(context.isServer==true && (context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2)){
1545
1652
  if(context.hello_done_sent==false && context.key_exchange_sent==true){
1546
1653
 
1547
1654
  let message_data = build_tls_message({
1548
1655
  type: 'server_hello_done'});
1549
- context.transcript.push(message_data);
1656
+ pushTranscript(message_data);
1550
1657
 
1551
1658
  context.hello_done_sent=true;
1552
1659
 
1553
- ev.emit('message',0,context.message_sent_seq,'certificate',message_data);
1660
+ ev.emit('message',0,context.message_sent_seq,'server_hello_done',message_data);
1554
1661
 
1555
1662
  context.message_sent_seq++;
1556
1663
 
@@ -1574,7 +1681,7 @@ function TLSSession(options){
1574
1681
  entries: certCtx.certificateChain,
1575
1682
  certificate_request_context: context.certificateRequestContext || new Uint8Array(0),
1576
1683
  });
1577
- context.transcript.push(cert_data);
1684
+ pushTranscript(cert_data);
1578
1685
  ev.emit('message', 1, context.message_sent_seq, 'certificate', cert_data);
1579
1686
  context.message_sent_seq++;
1580
1687
 
@@ -1588,7 +1695,7 @@ function TLSSession(options){
1588
1695
  scheme: scheme,
1589
1696
  signature: signature,
1590
1697
  });
1591
- context.transcript.push(cv_data);
1698
+ pushTranscript(cv_data);
1592
1699
  ev.emit('message', 1, context.message_sent_seq, 'certificate_verify', cv_data);
1593
1700
  context.message_sent_seq++;
1594
1701
  } else {
@@ -1599,7 +1706,7 @@ function TLSSession(options){
1599
1706
  entries: [],
1600
1707
  certificate_request_context: context.certificateRequestContext || new Uint8Array(0),
1601
1708
  });
1602
- context.transcript.push(cert_data);
1709
+ pushTranscript(cert_data);
1603
1710
  ev.emit('message', 1, context.message_sent_seq, 'certificate', cert_data);
1604
1711
  context.message_sent_seq++;
1605
1712
  }
@@ -1609,7 +1716,7 @@ function TLSSession(options){
1609
1716
  // base_secret may be null after app secrets are derived, so we also check handshake secret.
1610
1717
  if (context.finished_sent==false && context.selected_cipher_suite!==null && (context.base_secret!==null || context.local_handshake_traffic_secret!==null)){
1611
1718
 
1612
- if(context.selected_version === wire.TLS_VERSION.TLS1_3 && context.local_handshake_traffic_secret!==null){
1719
+ if((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && context.local_handshake_traffic_secret!==null){
1613
1720
 
1614
1721
  if((context.isServer==false && context.remote_finished_ok==true && context.local_app_traffic_secret!==null && context.remote_app_traffic_secret!==null) || (context.isServer==true && context.cert_verify_sent==true && context.local_cert_chain!==null) || (context.isServer==true && context.psk_accepted==true && context.encrypted_exts_sent==true)){
1615
1722
 
@@ -1621,7 +1728,7 @@ function TLSSession(options){
1621
1728
  data: finished_data
1622
1729
  });
1623
1730
 
1624
- context.transcript.push(message_data);
1731
+ pushTranscript(message_data);
1625
1732
 
1626
1733
  context.finished_sent=true;
1627
1734
 
@@ -1631,7 +1738,7 @@ function TLSSession(options){
1631
1738
 
1632
1739
  }
1633
1740
 
1634
- }else if(context.selected_version === wire.TLS_VERSION.TLS1_2){
1741
+ }else if((context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2)){
1635
1742
 
1636
1743
  if((context.isServer==true && context.remote_finished_ok==true) || (context.isServer==false && context.key_exchange_sent==true)){
1637
1744
 
@@ -1651,7 +1758,7 @@ function TLSSession(options){
1651
1758
  data: finished_data
1652
1759
  });
1653
1760
 
1654
- context.transcript.push(message_data);
1761
+ pushTranscript(message_data);
1655
1762
 
1656
1763
  context.finished_sent=true;
1657
1764
 
@@ -1666,7 +1773,7 @@ function TLSSession(options){
1666
1773
  }
1667
1774
 
1668
1775
  //get app traffic secret...
1669
- if (context.selected_version === wire.TLS_VERSION.TLS1_3){
1776
+ if ((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3)){
1670
1777
  if(context.base_secret!==null && context.local_app_traffic_secret==null && context.remote_app_traffic_secret==null){
1671
1778
 
1672
1779
  if((context.isServer==true && context.finished_sent==true && context.remote_finished_ok==false) || (context.isServer==false && context.finished_sent==false && context.remote_finished_ok==true)){
@@ -1692,7 +1799,7 @@ function TLSSession(options){
1692
1799
  //expected_remote_finished...
1693
1800
  if (context.expected_remote_finished==null && context.selected_cipher_suite!==null){
1694
1801
 
1695
- if(context.selected_version == wire.TLS_VERSION.TLS1_3 && context.remote_handshake_traffic_secret!==null){
1802
+ if((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && context.remote_handshake_traffic_secret!==null){
1696
1803
 
1697
1804
  if((context.isServer==true && context.finished_sent==true) || (context.isServer==false && context.remote_finished !== null)){
1698
1805
 
@@ -1700,7 +1807,7 @@ function TLSSession(options){
1700
1807
 
1701
1808
  }
1702
1809
 
1703
- }else if(context.selected_version === wire.TLS_VERSION.TLS1_2 && context.base_secret!==null){
1810
+ }else if((context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2) && context.base_secret!==null){
1704
1811
 
1705
1812
  if(context.remote_finished!==null){
1706
1813
 
@@ -1736,7 +1843,7 @@ function TLSSession(options){
1736
1843
  data: context.remote_finished
1737
1844
  });
1738
1845
 
1739
- context.transcript.push(message_data);
1846
+ pushTranscript(message_data);
1740
1847
 
1741
1848
  params_to_set['remote_finished_ok']=true;
1742
1849
 
@@ -1755,13 +1862,13 @@ function TLSSession(options){
1755
1862
 
1756
1863
 
1757
1864
 
1758
- if(context.state!=='connected' && context.remote_finished_ok==true && ((context.selected_version === wire.TLS_VERSION.TLS1_3 && context.local_app_traffic_secret!==null && context.remote_app_traffic_secret!==null) || context.selected_version === wire.TLS_VERSION.TLS1_2)){
1865
+ if(context.state!=='connected' && context.remote_finished_ok==true && (((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && context.local_app_traffic_secret!==null && context.remote_app_traffic_secret!==null) || (context.selected_version === wire.TLS_VERSION.TLS1_2 || context.selected_version === wire.DTLS_VERSION.DTLS1_2))){
1759
1866
  context.state='connected';
1760
1867
  context.handshakeEndTime = Date.now();
1761
1868
  ev.emit('secureConnect');
1762
1869
 
1763
1870
  // TLS 1.3: compute resumption_master_secret (both client and server need it)
1764
- if (context.selected_version === wire.TLS_VERSION.TLS1_3 && context.tls13_master_secret && !context.resumption_master_secret) {
1871
+ if ((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && context.tls13_master_secret && !context.resumption_master_secret) {
1765
1872
  let hashName = TLS_CIPHER_SUITES[context.selected_cipher_suite].hash;
1766
1873
  context.resumption_master_secret = derive_resumption_master_secret(
1767
1874
  hashName, context.tls13_master_secret, concatUint8Arrays(context.transcript)
@@ -1769,7 +1876,7 @@ function TLSSession(options){
1769
1876
  }
1770
1877
 
1771
1878
  // TLS 1.3 server: send NewSessionTicket
1772
- if (context.selected_version === wire.TLS_VERSION.TLS1_3 && context.isServer && !context.session_ticket_sent && !context.noTickets && context.resumption_master_secret) {
1879
+ if ((context.selected_version === wire.TLS_VERSION.TLS1_3 || context.selected_version === wire.DTLS_VERSION.DTLS1_3) && context.isServer && !context.session_ticket_sent && !context.noTickets && context.resumption_master_secret) {
1773
1880
  context.session_ticket_sent = true;
1774
1881
 
1775
1882
  let hashName = TLS_CIPHER_SUITES[context.selected_cipher_suite].hash;
@@ -2044,6 +2151,7 @@ function TLSSession(options){
2044
2151
  version: 0x0303,
2045
2152
  random: context.local_random,
2046
2153
  session_id: context.local_session_id,
2154
+ cookie: context.dtls_cookie,
2047
2155
  cipher_suite: context.local_supported_cipher_suites,
2048
2156
  extensions: extensions
2049
2157
  };
@@ -2068,13 +2176,14 @@ function TLSSession(options){
2068
2176
  version: 0x0303,
2069
2177
  random: context.local_random,
2070
2178
  session_id: context.local_session_id,
2179
+ cookie: context.dtls_cookie,
2071
2180
  cipher_suite: context.local_supported_cipher_suites,
2072
2181
  extensions: extensions
2073
2182
  };
2074
2183
  message_data = build_tls_message(build_message_params);
2075
2184
  }
2076
2185
 
2077
- context.transcript.push(message_data);
2186
+ pushTranscript(message_data);
2078
2187
 
2079
2188
  context.hello_sent=true;
2080
2189
 
@@ -2218,7 +2327,7 @@ function TLSSession(options){
2218
2327
  let cipherInfo = context.selected_cipher_suite ? TLS_CIPHER_SUITES[context.selected_cipher_suite] : null;
2219
2328
  return {
2220
2329
  version: context.selected_version,
2221
- versionName: context.selected_version === 0x0304 ? 'TLSv1.3' : context.selected_version === 0x0303 ? 'TLSv1.2' : null,
2330
+ versionName: context.selected_version === 0x0304 ? 'TLSv1.3' : context.selected_version === 0xFEFC ? 'DTLSv1.3' : context.selected_version === 0x0303 ? 'TLSv1.2' : context.selected_version === 0xFEFD ? 'DTLSv1.2' : null,
2222
2331
  cipher: context.selected_cipher_suite,
2223
2332
  cipherName: cipherInfo ? cipherInfo.name : null,
2224
2333
  group: context.selected_group,
@@ -2255,7 +2364,7 @@ function TLSSession(options){
2255
2364
 
2256
2365
  /** Request a TLS 1.3 Key Update. requestPeer=true means ask the other side to update too. */
2257
2366
  requestKeyUpdate: function(requestPeer){
2258
- if (context.state !== 'connected' || context.selected_version !== wire.TLS_VERSION.TLS1_3) return;
2367
+ if (context.state !== 'connected' || (context.selected_version !== wire.TLS_VERSION.TLS1_3 && context.selected_version !== wire.DTLS_VERSION.DTLS1_3)) return;
2259
2368
  let hashName = TLS_CIPHER_SUITES[context.selected_cipher_suite].hash;
2260
2369
  let hashLen = getHashLen(hashName);
2261
2370