summaryrefslogtreecommitdiffstats
path: root/security/nss/gtests/ssl_gtest/ssl_keyupdate_unittest.cc
blob: 00c755be6372571ef9c33745631200a80d102ffb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"

extern "C" {
// This is not something that should make you happy.
#include "libssl_internals.h"
}

#include "gtest_utils.h"
#include "nss_scoped_ptrs.h"
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"

namespace nss_test {

TEST_F(TlsConnectTest, KeyUpdateClient) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  SendReceive(50);
  SendReceive(60);
  CheckEpochs(4, 3);
}

TEST_F(TlsConnectStreamTls13, KeyUpdateTooEarly_Client) {
  StartConnect();
  auto filter = MakeTlsFilter<TlsEncryptedHandshakeMessageReplacer>(
      server_, kTlsHandshakeFinished, kTlsHandshakeKeyUpdate);
  filter->EnableDecryption();

  client_->Handshake();
  server_->Handshake();
  ExpectAlert(client_, kTlsAlertUnexpectedMessage);
  client_->Handshake();
  client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE);
  server_->Handshake();
  server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
}

TEST_F(TlsConnectStreamTls13, KeyUpdateTooEarly_Server) {
  StartConnect();
  auto filter = MakeTlsFilter<TlsEncryptedHandshakeMessageReplacer>(
      client_, kTlsHandshakeFinished, kTlsHandshakeKeyUpdate);
  filter->EnableDecryption();

  client_->Handshake();
  server_->Handshake();
  client_->Handshake();
  ExpectAlert(server_, kTlsAlertUnexpectedMessage);
  server_->Handshake();
  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE);
  client_->Handshake();
  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
}

TEST_F(TlsConnectTest, KeyUpdateClientRequestUpdate) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
  // SendReceive() only gives each peer one chance to read.  This isn't enough
  // when the read on one side generates another handshake message.  A second
  // read gives each peer an extra chance to consume the KeyUpdate.
  SendReceive(50);
  SendReceive(60);  // Cumulative count.
  CheckEpochs(4, 4);
}

TEST_F(TlsConnectTest, KeyUpdateServer) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
  SendReceive(50);
  SendReceive(60);
  CheckEpochs(3, 4);
}

TEST_F(TlsConnectTest, KeyUpdateServerRequestUpdate) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  SendReceive(50);
  SendReceive(60);
  CheckEpochs(4, 4);
}

TEST_F(TlsConnectTest, KeyUpdateConsecutiveRequests) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  SendReceive(50);
  SendReceive(60);
  // The server should have updated twice, but the client should have declined
  // to respond to the second request from the server, since it doesn't send
  // anything in between those two requests.
  CheckEpochs(4, 5);
}

// Check that a local update can be immediately followed by a remotely triggered
// update even if there is no use of the keys.
TEST_F(TlsConnectTest, KeyUpdateLocalUpdateThenConsecutiveRequests) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  // This should trigger an update on the client.
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // The client should update for the first request.
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  // ...but not the second.
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  SendReceive(50);
  SendReceive(60);
  // Both should have updated twice.
  CheckEpochs(5, 5);
}

TEST_F(TlsConnectTest, KeyUpdateMultiple) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  SendReceive(50);
  SendReceive(60);
  CheckEpochs(5, 6);
}

// Both ask the other for an update, and both should react.
TEST_F(TlsConnectTest, KeyUpdateBothRequest) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  Connect();
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  SendReceive(50);
  SendReceive(60);
  CheckEpochs(5, 5);
}

// If the sequence number exceeds the number of writes before an automatic
// update (currently 3/4 of the max records for the cipher suite), then the
// stack should send an update automatically (but not request one).
TEST_F(TlsConnectTest, KeyUpdateAutomaticOnWrite) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);

  // Set this to one below the write threshold.
  uint64_t threshold = (0x5aULL << 28) * 3 / 4;
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));

  // This should be OK.
  client_->SendData(10);
  server_->ReadBytes();

  // This should cause the client to update.
  client_->SendData(20);
  server_->ReadBytes();

  SendReceive(100);
  CheckEpochs(4, 3);
}

// If the sequence number exceeds a certain number of reads (currently 7/8 of
// the max records for the cipher suite), then the stack should send AND request
// an update automatically.  However, the sender (client) will be above its
// automatic update threshold, so the KeyUpdate - that it sends with the old
// cipher spec - will exceed the receiver (server) automatic update threshold.
// The receiver gets a packet with a sequence number over its automatic read
// update threshold.  Even though the sender has updated, the code that checks
// the sequence numbers at the receiver doesn't know this and it will request an
// update.  This causes two updates: one from the sender (without requesting a
// response) and one from the receiver (which does request a response).
TEST_F(TlsConnectTest, KeyUpdateAutomaticOnRead) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);

  // Move to right at the read threshold.  Unlike the write test, we can't send
  // packets because that would cause the client to update, which would spoil
  // the test.
  uint64_t threshold = ((0x5aULL << 28) * 7 / 8) + 1;
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));

  // This should cause the client to update, but not early enough to prevent the
  // server from updating also.
  client_->SendData(10);
  server_->ReadBytes();

  // Need two SendReceive() calls to ensure that the update that the server
  // requested is properly generated and consumed.
  SendReceive(70);
  SendReceive(80);
  CheckEpochs(5, 4);
}

// Filter to modify KeyUpdate message. Takes as an input which byte and what
// value to install.
class TLSKeyUpdateDamager : public TlsRecordFilter {
 public:
  TLSKeyUpdateDamager(const std::shared_ptr<TlsAgent>& a, size_t byte,
                      uint8_t val)
      : TlsRecordFilter(a), offset_(byte), value_(val) {}

 protected:
  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& record, size_t* offset,
                                    DataBuffer* output) override {
    if (!header.is_protected()) {
      return KEEP;
    }
    uint16_t protection_epoch;
    uint8_t inner_content_type;
    DataBuffer plaintext;
    TlsRecordHeader out_header;

    if (!Unprotect(header, record, &protection_epoch, &inner_content_type,
                   &plaintext, &out_header)) {
      return KEEP;
    }

    if (inner_content_type != ssl_ct_handshake) {
      return KEEP;
    }

    if (plaintext.data()[0] != ssl_hs_key_update) {
      return KEEP;
    }

    if (offset_ >= plaintext.len()) {
      ADD_FAILURE() << "TLSKeyUpdateDamager: the input (offset_) is out "
                       "of the range (the expected len is equal to "
                    << plaintext.len() << ")." << std::endl;
      return KEEP;
    }

    plaintext.data()[offset_] = value_;
    DataBuffer ciphertext;
    bool ok = Protect(spec(protection_epoch), out_header, inner_content_type,
                      plaintext, &ciphertext, &out_header);
    if (!ok) {
      ADD_FAILURE() << "Unable to protect the plaintext using  "
                    << protection_epoch << "epoch. " << std::endl;
      return KEEP;
    }
    *offset = out_header.Write(output, *offset, ciphertext);
    return CHANGE;
  }

 protected:
  size_t offset_;
  uint8_t value_;
};

// The next tests check the behaviour in case of malformed KeyUpdate.
// The first test, TLSKeyUpdateWrongValueForUpdateRequested,
// modifies the 4th byte (KeyUpdate) to have the incorrect value.
// The last tests check the incorrect values of the length.

// RFC 8446: 4.  Handshake Protocol
//    struct {
//          HandshakeType msg_type;     handshake type
//          uint24 length;              remaining bytes in message
//          select (Handshake.msg_type) {
//              case key_update:            KeyUpdate; (4th byte)
//          };
//      } Handshake;

TEST_F(TlsConnectStreamTls13, TLSKeyUpdateWrongValueForUpdateRequested) {
  EnsureTlsSetup();
  // This test is setting the update_requested to be equal to 2
  // Whereas the allowed values are [0, 1].
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 4, 2);
  filter->EnableDecryption();
  filter->Disable();
  Connect();

  filter->Enable();
  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();

  ExpectAlert(server_, kTlsAlertDecodeError);
  client_->ExpectReceiveAlert(kTlsAlertDecodeError);

  server_->ExpectReadWriteError();
  client_->ExpectReadWriteError();
  server_->ReadBytes();
  client_->ReadBytes();

  server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_KEY_UPDATE);
  client_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT);

  // Even if the client has updated his writing key,
  client_->CheckEpochs(3, 4);
  // the server has not.
  server_->CheckEpochs(3, 3);
}

TEST_F(TlsConnectStreamTls13, TLSKeyUpdateWrongValueForLength_MessageTooLong) {
  EnsureTlsSetup();
  // the first byte of the length was replaced with 0xff.
  // The message now is too long.
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 1, 0xff);
  filter->EnableDecryption();
  filter->Disable();
  Connect();

  filter->Enable();
  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();

  ExpectAlert(server_, kTlsAlertDecodeError);
  client_->ExpectReceiveAlert(kTlsAlertDecodeError);

  server_->ExpectReadWriteError();
  client_->ExpectReadWriteError();
  server_->ReadBytes();
  client_->ReadBytes();

  server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
  client_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT);

  // Even if the client has updated his writing key,
  client_->CheckEpochs(3, 4);
  // the server has not.
  server_->CheckEpochs(3, 3);
}

TEST_F(TlsConnectStreamTls13, TLSKeyUpdateWrongValueForLength_MessageTooShort) {
  EnsureTlsSetup();
  // Changing the value of length of the KU message to be shorter than the
  // correct one.
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 0x3, 0x00);
  filter->EnableDecryption();
  filter->Disable();
  Connect();

  filter->Enable();
  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();

  ExpectAlert(server_, kTlsAlertDecodeError);
  client_->ExpectReceiveAlert(kTlsAlertCloseNotify);

  client_->SendData(10);
  server_->ReadBytes();
}

// DTLS1.3 tests

// The KeyUpdate in DTLS1.3 workflow (with the update_requested set):

// Client(P1) is asking for KeyUpdate
// Here the second parameter states whether the P1 requires update_requested
// (RFC9147, Section 8).
// EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(),
// PR_FALSE));

// The server (P2) receives the KeyUpdate request and processes it.
// server_->ReadBytes();

// P2 sends ACK.
// SSLInt_SendImmediateACK(server_->ssl_fd());

// P1 receives ACK and finished the KeyUpdate:
// client_->ReadBytes();

// This function sends and proceeds KeyUpdate explained above (assuming
// updateRequested == PR_FALSE) For the explantation of the updateRequested look
// at the test DTLSKeyUpdateClientUpdateRequestedSucceed.*/
static void SendAndProcessKU(const std::shared_ptr<TlsAgent>& sender,
                             const std::shared_ptr<TlsAgent>& receiver,
                             bool updateRequested) {
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(sender->ssl_fd(), updateRequested));
  receiver->ReadBytes();
  // It takes some time to send an ack message, so here we send it immediately
  SSLInt_SendImmediateACK(receiver->ssl_fd());
  sender->ReadBytes();
  if (updateRequested) {
    SSLInt_SendImmediateACK(sender->ssl_fd());
    receiver->ReadBytes();
  }
}

// This test checks that after the execution of KeyUpdate started by the client,
// the writing client/reading server key epoch was incremented.
// RFC 9147. Section 4.
// However, this value is set [...] of the connection epoch,
// which is an [...] counter incremented on every KeyUpdate.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientKUSucceed) {
  Connect();
  CheckEpochs(3, 3);
  //  Client starts KeyUpdate
  //  The updateRequested is not requested.
  SendAndProcessKU(client_, server_, PR_FALSE);
  //  The KeyUpdate is finished, and the client writing spec/the server reading
  //  spec is incremented.
  CheckEpochs(4, 3);
  //  Check that we can send/receive data after KeyUpdate.
  SendReceive(50);
}

// This test checks that only one KeyUpdate is possible at the same time.
// RFC 9147 Section 5.8.4
// In contrast, implementations MUST NOT send KeyUpdate, NewConnectionId, or
// RequestConnectionId messages if an earlier message of the same type has not
// yet been acknowledged.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientKUTwiceOnceIgnored) {
  Connect();
  CheckEpochs(3, 3);
  //  Client sends a key update message.
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // The second key update message will be ignored as there is KeyUpdate in
  //  progress.
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  //  For the workflow see ssl_KeyUpdate_unittest.cc:SendAndProcessKU.
  server_->ReadBytes();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  //  As only one KeyUpdate was executed, the key epoch was incremented only
  //  once.
  CheckEpochs(4, 3);
  SendReceive(50);
}

// This test checks the same as the test DTLSKeyUpdateClientKeyUpdateSucceed,
// except that the server sends KeyUpdate.
TEST_F(TlsConnectDatagram13, DTLSKU_ServerKUSucceed) {
  Connect();
  CheckEpochs(3, 3);
  SendAndProcessKU(server_, client_, PR_FALSE);
  CheckEpochs(3, 4);
  SendReceive(50);
}

// This test checks the same as the test
// DTLSKeyUpdateClientKeyUpdateTwiceOnceIgnored, except that the server sends
// KeyUpdate.
TEST_F(TlsConnectDatagram13, DTLSKU_PreviousKUNotYetACKed) {
  Connect();
  CheckEpochs(3, 3);
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
  // The second key update message will be ignored
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));

  client_->ReadBytes();
  SSLInt_SendImmediateACK(client_->ssl_fd());
  server_->ReadBytes();

  CheckEpochs(3, 4);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks that if we receive two KeyUpdates, one will be ignored
TEST_F(TlsConnectDatagram13, DTLSKU_TwiceReceivedOnceIgnored) {
  Connect();
  CheckEpochs(3, 3);
  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(server_);
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));

  // Here we check that there was no KeyUpdate happened
  client_->ReadBytes();
  SSLInt_SendImmediateACK(client_->ssl_fd());
  server_->ReadBytes();
  CheckEpochs(3, 3);

  DataBuffer d = filter->ReturnRecorded();
  // Sending the recorded KeyUpdate
  server_->SendDirect(d);
  // Sending the KeyUpdate again
  server_->SendDirect(d);

  client_->ReadBytes();
  SSLInt_SendImmediateACK(client_->ssl_fd());
  server_->ReadBytes();

  // We observe that only one KeyUpdate has happened
  CheckEpochs(3, 4);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// The KeyUpdate in DTLS1.3 workflow (with the update_requested set):

// Client(P1) is asking for KeyUpdate
// EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));

// The server (P2) receives and processes the KeyUpdate request
// At the same time, P2 sends its own KeyUpdate request (due to update_requested
// was set)
// server_->ReadBytes();

// P1 receives the ACK and finalizes the KeyUpdate.
// SSLInt_SendImmediateACK(server_->ssl_fd());

// P1 receives the KeyUpdate request and processes it.
// client_->ReadBytes();

// P2 receives the ACK and finalizes the KeyUpdate.
// SSLInt_SendImmediateACK(client_->ssl_fd());
// server_->ReadBytes();

// This test checks that after the KeyUpdate (with update requested set)
// both client w/r and server w/r key epochs were incremented.
TEST_F(TlsConnectDatagram13, DTLSKU_UpdateRequestedSucceed) {
  Connect();
  CheckEpochs(3, 3);
  // Here the second parameter sets the update_requested to true.
  SendAndProcessKU(client_, server_, PR_TRUE);
  // As there were two KeyUpdates executed (one by a client, another one by a
  // server) Both of the keys were modified.
  CheckEpochs(4, 4);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks that after two KeyUpdates (with update requested set)
// the keys epochs were incremented twice.
TEST_F(TlsConnectDatagram13, DTLSKU_UpdateRequestedTwiceSucceed) {
  Connect();
  CheckEpochs(3, 3);
  SendAndProcessKU(client_, server_, PR_TRUE);
  // The KeyUpdate is finished, so both of the epochs got incremented.
  CheckEpochs(4, 4);
  SendAndProcessKU(client_, server_, PR_TRUE);
  // The second KeyUpdate is finished, so finally the epochs were incremented
  // twice.
  CheckEpochs(5, 5);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks the same as the test DTLSKeyUpdateUpdateRequestedSucceed,
// except that the server sends KeyUpdate.
TEST_F(TlsConnectDatagram13, DTLSKU_ServerUpdateRequestedSucceed) {
  Connect();
  CheckEpochs(3, 3);
  SendAndProcessKU(server_, client_, PR_TRUE);
  CheckEpochs(4, 4);
  SendReceive(50);
}

// This test checks that after two KeyUpdates (with update requested set)
// the keys epochs were incremented twice.
TEST_F(TlsConnectDatagram13, DTLSKU_ServerUpdateRequestedTwiceSucceed) {
  Connect();
  CheckEpochs(3, 3);
  SendAndProcessKU(server_, client_, PR_TRUE);
  // The KeyUpdate is finished, so both of the epochs got incremented.
  CheckEpochs(4, 4);

  // Server sends another KeyUpdate
  SendAndProcessKU(server_, client_, PR_TRUE);
  // The second KeyUpdate is finished, so finally the epochs were incremented
  // twice.
  CheckEpochs(5, 5);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks that both client and server can send the KeyUpdate in
// consequence.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientServerConseqSucceed) {
  Connect();
  CheckEpochs(3, 3);
  SendAndProcessKU(client_, server_, PR_FALSE);
  // As the server initiated KeyUpdate and did not request an update_request,
  // Only the server writing/client reading key epoch was incremented.
  CheckEpochs(4, 3);
  SendAndProcessKU(server_, client_, PR_FALSE);
  // Now the client initiated KeyUpdate and did not request an update_request,
  // so now both of epochs got incremented.
  CheckEpochs(4, 4);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks that both client and server can send the KeyUpdate in
// consequence. Compared to the DTLSKeyUpdateClientServerConseqSucceed TV, this
// time both parties set update_requested to be true.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientServerUpdateRequestedBothSucceed) {
  Connect();
  CheckEpochs(3, 3);
  SendAndProcessKU(client_, server_, PR_TRUE);
  SendAndProcessKU(server_, client_, PR_TRUE);
  // The second KeyUpdate (update_request = True) increments again the epochs
  // of both keys.
  CheckEpochs(5, 5);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks that if there is an ongoing KeyUpdate, the one started
// durint the KU is not going to be executed.
TEST_F(TlsConnectDatagram13, DTLSKU_KUInTheMiddleIsRejected) {
  Connect();
  CheckEpochs(3, 3);
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  client_->ReadBytes();
  SSLInt_SendImmediateACK(client_->ssl_fd());
  // Here a client starts KeyUpdate at the same time as the ongoing KeyUpdate
  // This KeyUpdate will not execute
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
  server_->ReadBytes();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  // As there was only one KeyUpdate executed, both keys got incremented only
  // once.
  CheckEpochs(4, 4);
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// DTLS1.3 KeyUpdate - Immediate Send Tests.

// The expected behaviour of the protocol:
// P1 starts initiates KeyUpdate
// P2 receives KeyUpdate
// And this moment, P2 will update the reading key to n
// But P2 will be accepting the keys from the previous epoch until a new message
// encrypted with the epoch n arrives.

// This test checks that when a client sent KeyUpdate, but the KeyUpdate message
// was not yet received, client can still send data.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientImmediateSend) {
  Connect();
  // Client has initiated KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // Server has not yet received it, client is trying to send some additional
  // data.
  CheckEpochs(3, 3);
  client_->SendData(10);
  // Server successfully receives it.
  WAIT_(server_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, server_->received_bytes());
  SendReceive(50);
}

// This test checks that when a client sent KeyUpdate, but the KeyUpdate message
// was not yet received, it can still receive data.
TEST_F(TlsConnectDatagram13, DTLSKU_ServerImmediateSend) {
  Connect();
  // Client has initiated KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // The server can successfully send data.
  CheckEpochs(3, 3);
  server_->SendData(10);
  WAIT_(client_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, client_->received_bytes());
  SendReceive(50);
}

// This test checks that when a client sent KeyUpdate,
// the server has not yet sent an ACK and the client has not yet ACKed
// KeyUpdate, both parties can exchange data.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientImmediateSendAfterServerRead) {
  Connect();
  // Client has initiated KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // Server receives KeyUpdate
  server_->ReadBytes();
  // Client can send data before the server sending ACK and client receiving
  // * ACK messages
  // Only server keys got updated.
  server_->CheckEpochs(4, 3);
  client_->CheckEpochs(3, 3);
  client_->SendData(10);
  WAIT_(server_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, server_->received_bytes());
  // Server can send data
  server_->SendData(10);
  WAIT_(client_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, client_->received_bytes());
  SendReceive(50);
}

// This test checks that when a client sent KeyUpdate, but has not yet ACKed it,
// both parties can exchange data.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientImmediateSendAfterServerReadAndACK) {
  Connect();
  CheckEpochs(3, 3);
  // Client has initiated KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // Server receives KeyUpdate
  server_->ReadBytes();
  // Server sends ACK
  SSLInt_SendImmediateACK(server_->ssl_fd());
  // Client can send data before he has received KeyUpdate
  // Only server keys got updated.
  server_->CheckEpochs(4, 3);
  client_->CheckEpochs(3, 3);
  client_->SendData(10);
  WAIT_(server_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, server_->received_bytes());
  // Server can send data
  server_->SendData(10);
  WAIT_(client_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, client_->received_bytes());
  SendReceive(50);
}

// This test checks that the client writing epoch is updated only
// when the client has received the ACK.
// RFC 9147. Section 8
// As with other handshake messages with no built-in response, KeyUpdates MUST
// be acknowledged.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientWritingEpochUpdatedAfterReceivedACK) {
  Connect();
  // Previous epoch
  CheckEpochs(3, 3);
  // Client sends a KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // Server updates his reading key
  server_->ReadBytes();
  // Now the server has a reading key = 4
  server_->CheckEpochs(4, 3);
  // But the client has a writing key = 3
  client_->CheckEpochs(3, 3);

  // Client sends a data, but using the old (3) keys
  client_->SendData(10);
  WAIT_(server_->received_bytes() == 10, 2000);
  ASSERT_EQ((size_t)10, server_->received_bytes());

  server_->CheckEpochs(4, 3);
  client_->CheckEpochs(3, 3);

  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();

  CheckEpochs(4, 3);
  SendReceive(50);
}

// DTLS1.3 KeyUpdate - Testing the border conditions
// (i.e. the cases where we reached the highest epoch).

// This test checks that the maximum epoch will not be exceeded on KeyUpdate.
// RFC 9147. Section 8.
// In order to provide an extra margin of security,
// sending implementations MUST NOT allow the epoch to exceed 2^48-1.

// Here we use the maximum as 2^16,
// See bug https://bugzilla.mozilla.org/show_bug.cgi?id=1809872
// When the bug is solved, the constant is to be replaced with 2^48 as
// required by RFC.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientMaxEpochReached) {
  Connect();
  CheckEpochs(3, 3);
  PRUint64 max_epoch_type = (0x1ULL << 16) - 1;

  // We assign the maximum possible epochs
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteEpochNum(client_->ssl_fd(), max_epoch_type));
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceReadEpochNum(server_->ssl_fd(), max_epoch_type));
  CheckEpochs(max_epoch_type, 3);
  // Upon trying to execute KeyUpdate, we return a SECFailure.
  EXPECT_EQ(SECFailure, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  SendReceive(50);
}

// This test checks the compliance with the RFC 9147 stating the behaviour
// reaching the max epoch: RFC 9147 Section 8. If a sending implementation
// receives a KeyUpdate with request_update set to "update_requested", it MUST
// NOT send its own KeyUpdate if that would cause it to exceed these limits and
// SHOULD instead ignore the "update_requested" flag.
TEST_F(TlsConnectDatagram13, DTLSKU_ClientMaxEpochReachedUpdateRequested) {
  Connect();
  CheckEpochs(3, 3);

  PRUint64 max_epoch_type = (0x1ULL << 16) - 1;

  // We assign the maximum possible epochs - 1.
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteEpochNum(client_->ssl_fd(), max_epoch_type));
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceReadEpochNum(server_->ssl_fd(), max_epoch_type));

  CheckEpochs(max_epoch_type, 3);
  // Once we call KeyUpdate with update requested
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
  client_->ReadBytes();
  SSLInt_SendImmediateACK(client_->ssl_fd());
  server_->ReadBytes();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  // Only one key (that has not reached the maximum epoch) was updated.
  CheckEpochs(max_epoch_type, 4);
  SendReceive(50);
}

// DTLS1.3 KeyUpdate - Automatic update tests

// RFC 9147 Section 4.5.3.
// Implementations SHOULD NOT protect more records than allowed by the limit
// specified for the negotiated AEAD.
// Implementations SHOULD initiate a key update before reaching this limit.

// These two tests check that the KeyUpdate is automatically called upon
// reaching the reading/writing limit.
TEST_F(TlsConnectDatagram13, DTLSKU_AutomaticOnWrite) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);
  CheckEpochs(3, 3);

  // Set this to one below the write threshold.
  uint64_t threshold = 0x438000000;
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));

  // This should be OK.
  client_->SendData(10);
  server_->ReadBytes();

  // This should cause the client to update.
  client_->SendData(15);
  server_->ReadBytes();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();

  // The client key epoch was incremented.
  CheckEpochs(4, 3);
  // Checking that we still can send/receive data.
  SendReceive(100);
}

TEST_F(TlsConnectDatagram13, DTLSKU_AutomaticOnRead) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);
  CheckEpochs(3, 3);

  // Set this to one below the read threshold.
  uint64_t threshold = 0x4ec000000 - 1;
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));

  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(client_);
  client_->SendData(10);
  DataBuffer d = filter->ReturnRecorded();

  client_->SendDirect(d);
  // This message will cause the server to start KeyUpdate with updateRequested
  // = 1.
  server_->ReadBytes();

  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  SSLInt_SendImmediateACK(client_->ssl_fd());
  server_->ReadBytes();

  // Both keys got updated.
  CheckEpochs(4, 4);
  // Checking that we still can send/receive data.
  SendReceive(100);
}

// The test describes the situation when there was a request
// to execute an automatic KU, but the server has not responded.
TEST_F(TlsConnectDatagram13, DTLSKU_CanSendBeforeThreshold) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);
  CheckEpochs(3, 3);

  uint64_t threshold = 0x5a0000000 - 2;
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));

  size_t received_bytes = server_->received_bytes();
  // We still can send a message
  client_->SendData(15);

  // We can not send a message anymore
  client_->ExpectReadWriteError();
  client_->SendData(105);

  server_->ReadBytes();
  // And it was not received.
  ASSERT_EQ((size_t)received_bytes + 15, server_->received_bytes());
}

TEST_F(TlsConnectDatagram13, DTLSKU_DiscardAfterThreshold) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
  ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);
  CheckEpochs(3, 3);

  uint64_t threshold = 0x5a0000000 - 3;
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));

  size_t received_bytes = server_->received_bytes();

  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(client_);
  client_->SendData(30);
  DataBuffer d = filter->ReturnRecorded();

  client_->SendDirect(d);
  client_->SendDirect(d);

  server_->ReadBytes();
  // Only one message was received.
  ASSERT_EQ((size_t)received_bytes + 30, server_->received_bytes());
}

// DTLS1.3 KeyUpdate - Managing previous epoch messages
// RFC 9147 Section 8.
// Due to the possibility of an ACK message for a KeyUpdate being lost
// and thereby preventing the sender of the KeyUpdate from updating its
// keying material, receivers MUST retain the pre-update keying material
// until receipt and successful decryption of a message using the new
// keys.

// This test checks that message encrypted with the key n-1 will be accepted
// after KeyUpdate is executed, but before the message n has arrived.
TEST_F(TlsConnectDatagram13, DTLSKU_PreviousEpochIsAcceptedBeforeNew) {
  size_t len = 10;

  Connect();
  // Client starts KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // Server receives KeyUpdate and sends ACK
  server_->ReadBytes();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  // Client has not yet received the ACK, so the writing key epoch has not
  // changed
  client_->CheckEpochs(3, 3);
  server_->CheckEpochs(4, 3);

  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(client_);

  // Here the message previousEpochMessageBuffer contains a message
  // encrypted with the client 3rd epoch key, m1 = enc(message, key_3)
  client_->SendData(len);
  DataBuffer d = filter->ReturnRecorded();

  // Client has received the ACK
  client_->ReadBytes();
  // Now he updates the writing Key to 4
  client_->CheckEpochs(3, 4);
  server_->CheckEpochs(4, 3);

  // And now we resend the message m1 and successfully receive it
  client_->SendDirect(d);
  WAIT_(server_->received_bytes() == len, 2000);
  ASSERT_EQ(len, server_->received_bytes());
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// This test checks that message encrypted with the key n-2 will not be accepted
// after KeyUpdate is executed, but before the message n has arrived.
TEST_F(TlsConnectDatagram13, DTLSKU_2EpochsAgoIsRejected) {
  size_t len = 10;

  Connect();
  CheckEpochs(3, 3);
  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(client_);
  client_->SendData(len);
  DataBuffer d = filter->ReturnRecorded();
  client_->ResetSentBytes();

  SendAndProcessKU(client_, server_, PR_FALSE);
  SendAndProcessKU(client_, server_, PR_FALSE);

  // Executing 2 KeyUpdates, so the client writing key is equal to 5 now
  CheckEpochs(5, 3);
  // And now we resend the message m1 encrypted with the key n-2 (3)
  client_->SendDirect(d);
  server_->ReadBytes();
  // Server has still received just legal_message_len of bytes (not the
  // previousEpochLen + legal_message_len)
  ASSERT_EQ((size_t)0, server_->received_bytes());
  // Checking that we still can send/receive data.
  SendReceive(60);
}

// This test checks that that message encrypted with the key n-1 will be
// rejected after KeyUpdate is executed, and after the message n has arrived.
TEST_F(TlsConnectDatagram13, DTLSKU_PreviousEpochIsAcceptedAfterNew) {
  size_t len = 30;
  size_t legal_message_len = 20;

  Connect();
  // Client starts KeyUpdate
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  // Server receives KeyUpdate and sends ACK
  server_->ReadBytes();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  // Client has not yet received the ACK, so the writing key epoch has not
  // changed
  client_->CheckEpochs(3, 3);
  server_->CheckEpochs(4, 3);

  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(client_);

  // Here the message previousEpochMessageBuffer contains a message
  // encrypted with the client 3rd epoch key, m1 = enc(message, key_3)
  client_->SendData(len);
  DataBuffer d = filter->ReturnRecorded();
  client_->ResetSentBytes();

  // Client has received the ACK
  client_->ReadBytes();
  client_->CheckEpochs(3, 4);
  server_->CheckEpochs(4, 3);

  // At this moment, a client will send a message with the new key
  SendReceive(legal_message_len);
  // As soon as it's received, the server will forbid the messaged from the
  // previous epochs
  server_->ReadBytes();

  // If a message from the previous epoch arrives to the server (m1, the key_3
  // was used to encrypt it)
  client_->SendDirect(d);
  // it will be silently dropped
  server_->ReadBytes();
  //  Server has still received just legal_message_len of bytes (not the
  // previousEpochLen + legal_message_len)
  ASSERT_EQ((size_t)legal_message_len, server_->received_bytes());
  // Checking that we still can send/receive data.
  SendReceive(50);
}

// DTLS Epoch reconstruction test
// RFC 9147 Section 8. 4.2.2. Reconstructing the Sequence Number and Epoch

// This test checks that the epoch reconstruction is correct.
// The function under testing is dtlscon.c::dtls_ReadEpoch.
// We only consider the case when dtls_IsDtls13Ciphertext is true.

typedef struct sslKeyUpdateReadEpochTVStr {
  // The current epoch
  DTLSEpoch epoch;
  // Only two-bit epoch here
  PRUint8 header;
  DTLSEpoch expected_reconstructed_epoch;
} sslKeyUpdateReadEpochTV_t;

static const sslKeyUpdateReadEpochTV_t sslKeyUpdateReadEpochTV[26] = {
    {0x1, 0x1, 0x1},

    {0x2, 0x1, 0x1},
    {0x2, 0x2, 0x2},

    {0x3, 0x3, 0x3},
    {0x3, 0x2, 0x2},
    {0x3, 0x1, 0x1},

    {0x4, 0x0, 0x4},  // the difference (diff) between the reconstructed and
                      // the current epoch is equal to 0
    {0x4, 0x1, 0x1},  // diff == 3
    {0x4, 0x2, 0x2},  // diff == 2
    {0x4, 0x3, 0x3},  // diff == 1

    {0x5, 0x0, 0x4},  // diff == 1
    {0x5, 0x1, 0x5},  // diff == 0
    {0x5, 0x2, 0x2},  // diff == 3
    {0x5, 0x3, 0x3},  // diff == 2

    {0x6, 0x0, 0x4},
    {0x6, 0x1, 0x5},
    {0x6, 0x2, 0x6},
    {0x6, 0x3, 0x3},

    {0x7, 0x0, 0x4},
    {0x7, 0x1, 0x5},
    {0x7, 0x2, 0x6},
    {0x7, 0x3, 0x7},

    {0x8, 0x0, 0x8},
    {0x8, 0x1, 0x5},
    {0x8, 0x2, 0x6},
    {0x8, 0x3, 0x7},

    // Starting from here the pattern (starting from 4) repeats:
    // if a current epoch is equal to n,
    // the difference will behave as for n % 4 + 4.
    // For example, if the current epoch is equal to 9, then
    // the difference between the reconstructed epoch and the current one
    // will be the same as for the 5th epoch.
};

TEST_F(TlsConnectDatagram13, DTLS_EpochReconstruction) {
  PRUint8 header[5] = {0};
  header[0] = 0x20;
  DTLSEpoch epoch;

  for (size_t i = 0; i < 26; i++) {
    epoch = sslKeyUpdateReadEpochTV[i].epoch;
    header[0] = (header[0] & 0xfc) | (sslKeyUpdateReadEpochTV[i].header & 0x3);
    // ReadEpoch (dtlscon.c#1339) uses only spec->version and spec->epoch.
    ASSERT_EQ(sslKeyUpdateReadEpochTV[i].expected_reconstructed_epoch,
              dtls_ReadEpoch(SSL_LIBRARY_VERSION_TLS_1_3, epoch, header));
  }
}

// RFC 9147. A.2. Handshake Protocol
// struct {
//  HandshakeType msg_type;    -- handshake type
//  uint24 length;             -- bytes in message
//  uint16 message_seq;        -- DTLS-required field
//  uint24 fragment_offset;    -- DTLS-required field
//  uint24 fragment_length;    -- DTLS-required field
//  select (msg_type) {
//  ...
//  case key_update:            KeyUpdate;
//  } body;
// } Handshake;
//
// enum {
// update_not_requested(0), update_requested(1), (255)
// } KeyUpdateRequest;

// The next tests send malformed KeyUpdate messages.
// A remainder: TLSKeyUpdateDamager filter takes as an input an agent,
// a byte index and a value that the existing value of the byte with the byte
// index will be replaced with. The filter catchs only the KeyUpdate messages,
// keeping unchanged all the rest.

// The first test, DTLSKeyUpdateDamagerFilterTestingNoModification,
// checks the correctness of the filter itself. It replaces the value of 12th
// byte with 0: The 12th byte is used to specify KeyUpdateRequest. Thus, the
// modification done in the test will still result in the correct KeyUpdate
// request.

// The test DTLSKU_WrongValueForUpdateRequested is modifying
// KeyUpdateRequest byte to have an not-allowed value.

// The test DTLSKeyUpdateDamagedLength modifies the 3rd byte (one of the length
// bytes).

// The test DTLSKeyUpdateDamagedLengthLongMessage changes the length of the
// message as well.

// The test DTLSKeyUpdateDamagedFragmentLength modifies the 10th byte (one of
// the fragment_length bytes)

TEST_F(TlsConnectDatagram13, DTLSKU_WrongValueForUpdateRequested) {
  EnsureTlsSetup();
  // Filter replacing the update_requested with an unexpected value.
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 12, 2);
  filter->EnableDecryption();
  filter->Disable();
  Connect();
  filter->Enable();
  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();

  ExpectAlert(server_, kTlsAlertDecodeError);
  client_->ExpectReceiveAlert(kTlsAlertDecodeError);

  server_->ExpectReadWriteError();
  client_->ExpectReadWriteError();

  server_->ReadBytes();
  client_->ReadBytes();

  server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_KEY_UPDATE);
  client_->CheckErrorCode(SSL_ERROR_DECODE_ERROR_ALERT);

  // No KeyUpdate happened.
  CheckEpochs(3, 3);
}

TEST_F(TlsConnectDatagram13, DTLSKU_DamagedLength) {
  EnsureTlsSetup();
  // Filter replacing the length value with 0.
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 3, 0);
  filter->EnableDecryption();
  filter->Disable();
  Connect();
  filter->Enable();

  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  // No KeyUpdate happened.
  CheckEpochs(3, 3);
  SendReceive(50);
}

TEST_F(TlsConnectDatagram13, DTLSKU_DamagedLengthTooLong) {
  EnsureTlsSetup();
  // Filter replacing the second byte of length with one
  // The message length is increased by 2 ^ 8
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 2, 2);
  filter->EnableDecryption();
  filter->Disable();
  Connect();
  filter->Enable();

  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  // No KeyUpdate happened.
  CheckEpochs(3, 3);
  SendReceive(50);
}

TEST_F(TlsConnectDatagram13, DTLSKU_DamagedFragmentLength) {
  EnsureTlsSetup();
  // Filter replacing the fragment length with 1.
  auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 10, 1);
  filter->EnableDecryption();
  filter->Disable();
  Connect();
  filter->Enable();

  SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE);
  filter->Disable();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  client_->ReadBytes();
  // No KeyUpdate happened.
  CheckEpochs(3, 3);
  SendReceive(50);
}

// This filter is used in order to modify an ACK message.
// As it's possible that one record contains several ACKs,
// we fault all of them.

class TLSACKDamager : public TlsRecordFilter {
 public:
  TLSACKDamager(const std::shared_ptr<TlsAgent>& a, size_t byte, uint8_t val)
      : TlsRecordFilter(a), offset_(byte), value_(val) {}

 protected:
  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& record, size_t* offset,
                                    DataBuffer* output) override {
    if (!header.is_protected()) {
      return KEEP;
    }

    uint16_t protection_epoch;
    uint8_t inner_content_type;
    DataBuffer plaintext;
    TlsRecordHeader out_header;

    if (!Unprotect(header, record, &protection_epoch, &inner_content_type,
                   &plaintext, &out_header)) {
      return KEEP;
    }

    if (plaintext.data() == NULL || plaintext.len() == 0) {
      return KEEP;
    }

    if (decrypting() && inner_content_type != ssl_ct_ack) {
      return KEEP;
    }

    // We compute the number of ACKS in the message
    // As we keep processing the ACK even if one message is incorrent,
    // we fault all the found ACKs.

    uint8_t ack_message_header_len = 2;
    uint8_t ack_message_len_one_ACK = 16;
    uint64_t acks = plaintext.len() - ack_message_header_len;
    EXPECT_EQ((uint64_t)0, acks % ack_message_len_one_ACK);
    acks = acks / ack_message_len_one_ACK;

    if (plaintext.len() <= ack_message_header_len + offset_ +
                               (acks - 1) * ack_message_len_one_ACK) {
      return KEEP;
    }

    for (size_t i = 0; i < acks; i++) {
      // Here we replace the offset_-th byte after the header
      // i.e. headerAck + ACK(0) + ACK(1) <-- the offset_-th byte
      // of ACK(0), ACK(1), etc
      plaintext.data()[ack_message_header_len + offset_ +
                       i * ack_message_len_one_ACK] = value_;
    }

    DataBuffer ciphertext;
    bool ok = Protect(spec(protection_epoch), out_header, inner_content_type,
                      plaintext, &ciphertext, &out_header);
    if (!ok) {
      return KEEP;
    }
    *offset = out_header.Write(output, *offset, ciphertext);
    return CHANGE;
  }

 protected:
  size_t offset_;
  uint8_t value_;
};

// The next two tests are modifying the ACK message:

// First, we call KeyUpdate on the client side. The server successfully
// processes it, and it's sending an ACK message. At this moment, the filter
// modifies the content of the ACK message by changing the seqNum or epoch and
// sends it back to the client.
//
// struct {
//  uint64 epoch;
//  uint64 sequence_number;
// } RecordNumber;

// struct {
//  RecordNumber record_numbers<0..2^16-1>;
// } ACK;

TEST_F(TlsConnectDatagram13, DTLSKU_ModifACKEpoch) {
  EnsureTlsSetup();
  uint8_t byte = 3;
  uint8_t v = 1;
  // The filter will replace value-th byte of each ACK with one
  // The epoch will be more than v * 2 ^ ((byte - 1) * 8).
  // HandleACK function allows the epochs such that (epoch > RECORD_EPOCH_MAX)
  // where RECORD_EPOCH_MAX == ((0x1ULL << 16) - 1)
  auto filter = MakeTlsFilter<TLSACKDamager>(server_, byte, v);
  filter->EnableDecryption();
  filter->Disable();
  Connect();
  CheckEpochs(3, 3);
  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  server_->ReadBytes();

  filter->Enable();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  filter->Disable();

  client_->ReadBytes();
  server_->CheckEpochs(4, 3);
  // The client has not received the ACK, so it will not update the key.
  client_->CheckEpochs(3, 3);

  // The communication still continues.
  SendReceive(50);
}

TEST_F(TlsConnectDatagram13, DTLSKU_ModifACKSeqNum) {
  EnsureTlsSetup();
  uint8_t byte = 7;
  uint8_t v = 1;
  // The filter will replace value byte  of each ACK with one
  // The seqNum will be more than v * 2 ^ ((byte - 1) * 8).
  // HandleACK function allows the epochs such that (seq > RECORD_SEQ_MAX)
  // where RECORD_SEQ_MAX == ((0x1ULL << 48) - 1)

  // here byte + 8 means that we modify not epoch, but sequenceNum
  auto filter = MakeTlsFilter<TLSACKDamager>(server_, byte + 8, v);
  filter->EnableDecryption();
  filter->Disable();
  Connect();

  EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
  server_->ReadBytes();

  filter->Enable();
  SSLInt_SendImmediateACK(server_->ssl_fd());
  filter->Disable();

  client_->ReadBytes();

  client_->ReadBytes();
  server_->CheckEpochs(4, 3);
  // The client has not received the ACK, so it will not update the key.
  client_->CheckEpochs(3, 3);

  // The communication still continues.
  SendReceive(50);
}

TEST_F(TlsConnectDatagram13, DTLSKU_TooEarly_ClientCannotSendKeyUpdate) {
  StartConnect();
  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(server_);
  filter->EnableDecryption();

  client_->Handshake();
  server_->Handshake();

  EXPECT_EQ(SECFailure, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
}

TEST_F(TlsConnectDatagram13, DTLSKeyUpdateTooEarly_ServerCannotSendKeyUpdate) {
  StartConnect();
  auto filter = MakeTlsFilter<TLSRecordSaveAndDropNext>(server_);
  filter->EnableDecryption();

  client_->Handshake();
  server_->Handshake();

  EXPECT_EQ(SECFailure, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
}

class DTlsEncryptedHandshakeHeaderReplacer : public TlsRecordFilter {
 public:
  DTlsEncryptedHandshakeHeaderReplacer(const std::shared_ptr<TlsAgent>& a,
                                       uint8_t old_ct, uint8_t new_ct)
      : TlsRecordFilter(a),
        old_ct_(old_ct),
        new_ct_(new_ct),
        replaced_(false) {}

 protected:
  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& record, size_t* offset,
                                    DataBuffer* output) override {
    if (replaced_) return KEEP;

    uint8_t inner_content_type;
    DataBuffer plaintext;
    uint16_t protection_epoch = 0;
    TlsRecordHeader out_header(header);

    if (!Unprotect(header, record, &protection_epoch, &inner_content_type,
                   &plaintext, &out_header)) {
      return KEEP;
    }

    auto& protection_spec = spec(protection_epoch);
    uint32_t msg_type = 256;  // Not a real message
    if (!plaintext.Read(0, 1, &msg_type) || msg_type == old_ct_) {
      replaced_ = true;
      plaintext.Write(0, new_ct_, 1);
    }

    uint64_t seq_num = protection_spec.next_out_seqno();
    if (out_header.is_dtls()) {
      seq_num |= out_header.sequence_number() & (0xffffULL << 48);
    }
    out_header.sequence_number(seq_num);

    DataBuffer ciphertext;
    bool rv = Protect(protection_spec, out_header, inner_content_type,
                      plaintext, &ciphertext, &out_header);
    if (!rv) {
      return KEEP;
    }
    *offset = out_header.Write(output, *offset, ciphertext);
    return CHANGE;
  }

 private:
  uint8_t old_ct_;
  uint8_t new_ct_;
  bool replaced_;
};

// The next tests check the behaviour of KU before the handshake is finished.
TEST_F(TlsConnectDatagram13, DTLSKU_TooEarly_Client) {
  StartConnect();
  // This filter takes the record and if it finds kTlsHandshakeFinished
  // it replaces it with kTlsHandshakeKeyUpdate
  // Then, the KeyUpdate will be started when the handshake is not yet finished
  // This handshake will be cancelled.
  auto filter = MakeTlsFilter<DTlsEncryptedHandshakeHeaderReplacer>(
      server_, kTlsHandshakeFinished, kTlsHandshakeKeyUpdate);
  filter->EnableDecryption();

  client_->Handshake();
  server_->Handshake();
  ExpectAlert(client_, kTlsAlertUnexpectedMessage);
  client_->Handshake();
  client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE);
  server_->Handshake();
  server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
}

TEST_F(TlsConnectDatagram13, DTLSKU_TooEarly_Server) {
  StartConnect();
  // This filter takes the record and if it finds kTlsHandshakeFinished
  // it replaces it with kTlsHandshakeKeyUpdate
  auto filter = MakeTlsFilter<DTlsEncryptedHandshakeHeaderReplacer>(
      client_, kTlsHandshakeFinished, kTlsHandshakeKeyUpdate);
  filter->EnableDecryption();

  client_->Handshake();
  server_->Handshake();
  client_->Handshake();
  ExpectAlert(server_, kTlsAlertUnexpectedMessage);
  server_->Handshake();
  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE);
  client_->Handshake();
  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
}

}  // namespace nss_test