• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.35
/src/tests/test_tls_cipher_state.cpp
1
/*
2
* (C) 2021 Jack Lloyd
3
* (C) 2021 Hannes Rantzsch, René Meusel - neXenio
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include "tests.h"
9

10
#if defined(BOTAN_HAS_TLS_13)
11

12
   #include <botan/secmem.h>
13
   #include <botan/tls_ciphersuite.h>
14

15
   #include <botan/internal/tls_cipher_state.h>
16

17
namespace {
18

19
using Test = Botan_Tests::Test;
20
using namespace Botan;
21
using namespace Botan::TLS;
22

23
decltype(auto) make_CHECK_both(Cipher_State* cs_client, Cipher_State* cs_server) {
2✔
24
   using namespace std::placeholders;
2✔
25
   return [=](const std::string& name, auto lambda) -> std::vector<Test::Result> {
14✔
26
      return {Botan_Tests::CHECK(std::string(name + " (client)").c_str(),
×
27
                                 std::bind(lambda, cs_client, Connection_Side::Client, _1)),
12✔
28
              Botan_Tests::CHECK(std::string(name + " (server)").c_str(),
12✔
29
                                 std::bind(lambda, cs_server, Connection_Side::Server, _1))};
58✔
30
   };
31
}
32

33
class RFC8448_TestData {
34
   private:
35
      const std::string name;
36
      const Connection_Side emitter;
37
      const std::vector<uint8_t> record_header;
38
      const secure_vector<uint8_t> encrypted_fragment;
39
      const secure_vector<uint8_t> plaintext_fragment;
40

41
   public:
42
      RFC8448_TestData(std::string n,
9✔
43
                       Connection_Side em,
44
                       std::vector<uint8_t> rh,
45
                       secure_vector<uint8_t> ef,
46
                       secure_vector<uint8_t> pf) :
9✔
47
            name(std::move(n)),
9✔
48
            emitter(em),
9✔
49
            record_header(std::move(rh)),
9✔
50
            encrypted_fragment(std::move(ef)),
9✔
51
            plaintext_fragment(std::move(pf)) {}
9✔
52

53
      void encrypt(Test::Result& result, Cipher_State* cs) const {
9✔
54
         auto plaintext_fragment_copy = plaintext_fragment;
9✔
55
         result.test_no_throw("encryption is successful for " + name,
18✔
56
                              [&] { cs->encrypt_record_fragment(record_header, plaintext_fragment_copy); });
9✔
57

58
         result.test_eq("encrypted payload for " + name, plaintext_fragment_copy, encrypted_fragment);
18✔
59
      }
9✔
60

61
      void decrypt(Test::Result& result, Cipher_State* cs) const {
9✔
62
         auto encrypted_fragment_copy = encrypted_fragment;
9✔
63
         result.test_no_throw("decryption is successful for " + name,
18✔
64
                              [&] { cs->decrypt_record_fragment(record_header, encrypted_fragment_copy); });
9✔
65

66
         result.test_eq("plaintext for " + name, encrypted_fragment_copy, plaintext_fragment);
18✔
67
      }
9✔
68

69
      void xxcrypt(Test::Result& result, Cipher_State* cs, Connection_Side side) const {
18✔
70
         if(emitter == side) {
18✔
71
            encrypt(result, cs);
9✔
72
         } else {
73
            decrypt(result, cs);
9✔
74
         }
75
      }
18✔
76
};
77

78
std::vector<Test::Result> test_secret_derivation_rfc8448_rtt1() {
1✔
79
   // shared secret
80
   const auto shared_secret = Botan::hex_decode_locked(
1✔
81
      "8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d"
82
      "35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d");
1✔
83

84
   const auto expected_psk = Botan::hex_decode_locked(
1✔
85
      "4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c a4 c5"
86
      "85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3");
1✔
87

88
   // this is not part of RFC 8448
89
   const std::string export_label = "export_test_label";
1✔
90
   const std::string export_context = "rfc8448_rtt1";
1✔
91
   const auto expected_key_export = Botan::hex_decode_locked("f2 00 58 a6 5c e0 43 0a 19 79 44 c8 12 43 1c 2d");
1✔
92

93
   // transcript hash from client hello and server hello
94
   const auto th_server_hello = Botan::hex_decode(
1✔
95
      "86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed"
96
      "d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8");
1✔
97

98
   // transcript hash from client hello up to (excluding) server finished
99
   const auto th_pre_server_finished = Botan::hex_decode(
1✔
100
      "ed b7 72 5f a7 a3 47 3b 03 1e c8 ef 65 a2 48 54"
101
      "93 90 01 38 a2 b9 12 91 40 7d 79 51 a0 61 10 ed");
1✔
102

103
   // transcript hash from client hello up to (including) server finished
104
   const auto th_server_finished = Botan::hex_decode(
1✔
105
      "96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a"
106
      "00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13");
1✔
107

108
   // transcript hash from client hello up to (including) client finished
109
   const auto th_client_finished = Botan::hex_decode(
1✔
110
      "20 91 45 a9 6e e8 e2 a1 22 ff 81 00 47 cc 95 26"
111
      "84 65 8d 60 49 e8 64 29 42 6d b8 7c 54 ad 14 3d");
1✔
112

113
   // encrypted with server_handshake_traffic_secret
114
   const auto encrypted_extensions =
1✔
115
      RFC8448_TestData("encrypted_extensions",
116
                       Connection_Side::Server,
117
                       Botan::hex_decode("17 03 03 02 a2"),
2✔
118
                       Botan::hex_decode_locked("d1 ff 33 4a 56 f5 bf"
2✔
119
                                                "f6 59 4a 07 cc 87 b5 80 23 3f 50 0f 45 e4 89 e7 f3 3a f3 5e df"
120
                                                "78 69 fc f4 0a a4 0a a2 b8 ea 73 f8 48 a7 ca 07 61 2e f9 f9 45"
121
                                                "cb 96 0b 40 68 90 51 23 ea 78 b1 11 b4 29 ba 91 91 cd 05 d2 a3"
122
                                                "89 28 0f 52 61 34 aa dc 7f c7 8c 4b 72 9d f8 28 b5 ec f7 b1 3b"
123
                                                "d9 ae fb 0e 57 f2 71 58 5b 8e a9 bb 35 5c 7c 79 02 07 16 cf b9"
124
                                                "b1 18 3e f3 ab 20 e3 7d 57 a6 b9 d7 47 76 09 ae e6 e1 22 a4 cf"
125
                                                "51 42 73 25 25 0c 7d 0e 50 92 89 44 4c 9b 3a 64 8f 1d 71 03 5d"
126
                                                "2e d6 5b 0e 3c dd 0c ba e8 bf 2d 0b 22 78 12 cb b3 60 98 72 55"
127
                                                "cc 74 41 10 c4 53 ba a4 fc d6 10 92 8d 80 98 10 e4 b7 ed 1a 8f"
128
                                                "d9 91 f0 6a a6 24 82 04 79 7e 36 a6 a7 3b 70 a2 55 9c 09 ea d6"
129
                                                "86 94 5b a2 46 ab 66 e5 ed d8 04 4b 4c 6d e3 fc f2 a8 94 41 ac"
130
                                                "66 27 2f d8 fb 33 0e f8 19 05 79 b3 68 45 96 c9 60 bd 59 6e ea"
131
                                                "52 0a 56 a8 d6 50 f5 63 aa d2 74 09 96 0d ca 63 d3 e6 88 61 1e"
132
                                                "a5 e2 2f 44 15 cf 95 38 d5 1a 20 0c 27 03 42 72 96 8a 26 4e d6"
133
                                                "54 0c 84 83 8d 89 f7 2c 24 46 1a ad 6d 26 f5 9e ca ba 9a cb bb"
134
                                                "31 7b 66 d9 02 f4 f2 92 a3 6a c1 b6 39 c6 37 ce 34 31 17 b6 59"
135
                                                "62 22 45 31 7b 49 ee da 0c 62 58 f1 00 d7 d9 61 ff b1 38 64 7e"
136
                                                "92 ea 33 0f ae ea 6d fa 31 c7 a8 4d c3 bd 7e 1b 7a 6c 71 78 af"
137
                                                "36 87 90 18 e3 f2 52 10 7f 24 3d 24 3d c7 33 9d 56 84 c8 b0 37"
138
                                                "8b f3 02 44 da 8c 87 c8 43 f5 e5 6e b4 c5 e8 28 0a 2b 48 05 2c"
139
                                                "f9 3b 16 49 9a 66 db 7c ca 71 e4 59 94 26 f7 d4 61 e6 6f 99 88"
140
                                                "2b d8 9f c5 08 00 be cc a6 2d 6c 74 11 6d bd 29 72 fd a1 fa 80"
141
                                                "f8 5d f8 81 ed be 5a 37 66 89 36 b3 35 58 3b 59 91 86 dc 5c 69"
142
                                                "18 a3 96 fa 48 a1 81 d6 b6 fa 4f 9d 62 d5 13 af bb 99 2f 2b 99"
143
                                                "2f 67 f8 af e6 7f 76 91 3f a3 88 cb 56 30 c8 ca 01 e0 c6 5d 11"
144
                                                "c6 6a 1e 2a c4 c8 59 77 b7 c7 a6 99 9b bf 10 dc 35 ae 69 f5 51"
145
                                                "56 14 63 6c 0b 9b 68 c1 9e d2 e3 1c 0b 3b 66 76 30 38 eb ba 42"
146
                                                "f3 b3 8e dc 03 99 f3 a9 f2 3f aa 63 97 8c 31 7f c9 fa 66 a7 3f"
147
                                                "60 f0 50 4d e9 3b 5b 84 5e 27 55 92 c1 23 35 ee 34 0b bc 4f dd"
148
                                                "d5 02 78 40 16 e4 b3 be 7e f0 4d da 49 f4 b4 40 a3 0c b5 d2 af"
149
                                                "93 98 28 fd 4a e3 79 4e 44 f9 4d f5 a6 31 ed e4 2c 17 19 bf da"
150
                                                "bf 02 53 fe 51 75 be 89 8e 75 0e dc 53 37 0d 2b"),
151
                       Botan::hex_decode_locked("08 00 00 24 00 22 00 0a 00 14 00 12 00 1d"
1✔
152
                                                "00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c 00 02 40"
153
                                                "01 00 00 00 00 0b 00 01 b9 00 00 01 b5 00 01 b0 30 82 01 ac 30"
154
                                                "82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48 86 f7 0d"
155
                                                "01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03 72 73 61"
156
                                                "30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17 0d 32 36"
157
                                                "30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06 03 55 04"
158
                                                "03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01"
159
                                                "01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f 82 79 30"
160
                                                "3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26 d3 90 1a"
161
                                                "24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c 1a f1 9e"
162
                                                "aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52 4b 1b 01"
163
                                                "8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74 80 30 53"
164
                                                "0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93 ef f0 ab"
165
                                                "9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03 01 00 01"
166
                                                "a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06 03 55 1d"
167
                                                "0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05"
168
                                                "00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a 72 67 17"
169
                                                "06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea e8 f8 a5"
170
                                                "8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01 51 56 72"
171
                                                "60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be c1 fc 63"
172
                                                "a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b 1c 3b 84"
173
                                                "e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8 96 12 29"
174
                                                "ac 91 87 b4 2b 4d e1 00 00 0f 00 00 84 08 04 00 80 5a 74 7c 5d"
175
                                                "88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a b3"
176
                                                "ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07 86"
177
                                                "53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b be"
178
                                                "8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44 5c"
179
                                                "9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a 3d"
180
                                                "a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3 14 00"
181
                                                "00 20 9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4 de da 4a b4 2c"
182
                                                "30 95 72 cb 7f ff ee 54 54 b7 8f 07 18"
183
                                                "16" /* to-be-encrypted content type */));
1✔
184

185
   // encrypted with client_handshake_traffic_secret
186
   const auto encrypted_client_finished_message =
1✔
187
      RFC8448_TestData("encrypted_client_finished_message",
188
                       Connection_Side::Client,
189
                       Botan::hex_decode("17 03 03 00 35"),
2✔
190
                       Botan::hex_decode_locked("75 ec 4d c2 38 cc e6"
2✔
191
                                                "0b 29 80 44 a7 1e 21 9c 56 cc 77 b0 51 7f e9 b9 3c 7a 4b fc 44"
192
                                                "d8 7f 38 f8 03 38 ac 98 fc 46 de b3 84 bd 1c ae ac ab 68 67 d7"
193
                                                "26 c4 05 46"),
194
                       Botan::hex_decode_locked("14 00 00 20 a8 ec 43 6d 67 76 34 ae 52 5a c1"
1✔
195
                                                "fc eb e1 1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce 61"
196
                                                "16" /* to-be-encrypted content type */));
1✔
197

198
   // encrypted with server_application_traffic_secret
199
   const auto encrypted_new_session_ticket =
1✔
200
      RFC8448_TestData("encrypted_new_session_ticket",
201
                       Connection_Side::Server,
202
                       Botan::hex_decode("17 03 03 00 de"),
2✔
203
                       Botan::hex_decode_locked("3a 6b 8f 90 41 4a 97"
2✔
204
                                                "d6 95 9c 34 87 68 0d e5 13 4a 2b 24 0e 6c ff ac 11 6e 95 d4 1d"
205
                                                "6a f8 f6 b5 80 dc f3 d1 1d 63 c7 58 db 28 9a 01 59 40 25 2f 55"
206
                                                "71 3e 06 1d c1 3e 07 88 91 a3 8e fb cf 57 53 ad 8e f1 70 ad 3c"
207
                                                "73 53 d1 6d 9d a7 73 b9 ca 7f 2b 9f a1 b6 c0 d4 a3 d0 3f 75 e0"
208
                                                "9c 30 ba 1e 62 97 2a c4 6f 75 f7 b9 81 be 63 43 9b 29 99 ce 13"
209
                                                "06 46 15 13 98 91 d5 e4 c5 b4 06 f1 6e 3f c1 81 a7 7c a4 75 84"
210
                                                "00 25 db 2f 0a 77 f8 1b 5a b0 5b 94 c0 13 46 75 5f 69 23 2c 86"
211
                                                "51 9d 86 cb ee ac 87 aa c3 47 d1 43 f9 60 5d 64 f6 50 db 4d 02"
212
                                                "3e 70 e9 52 ca 49 fe 51 37 12 1c 74 bc 26 97 68 7e 24 87 46 d6"
213
                                                "df 35 30 05 f3 bc e1 86 96 12 9c 81 53 55 6b 3b 6c 67 79 b3 7b"
214
                                                "f1 59 85 68 4f"),
215
                       Botan::hex_decode_locked("04 00 00 c9 00 00 00 1e fa d6 aa c5 02 00"
1✔
216
                                                "00 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9 00 00 00 00 26 2a"
217
                                                "64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00 70 ad 3c 49 88 83"
218
                                                "c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9 82 11 72 83 f8"
219
                                                "2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f d6 1d 28 27 db 27"
220
                                                "9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e e0 37 25 a6 a4 da"
221
                                                "fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5 90 6c 5b 3f 7d"
222
                                                "8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97 b5 ae a6 17 64 6f"
223
                                                "ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f 7d e6 50 5e 5b fb"
224
                                                "c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 00 08 00 2a 00 04 00 00"
225
                                                "04 00"
226
                                                "16" /* to-be-encrypted content type */));
1✔
227

228
   // encrypted with client_application_traffic_secret
229
   const auto encrypted_application_data_client =
1✔
230
      RFC8448_TestData("encrypted_application_data_client",
231
                       Connection_Side::Client,
232
                       Botan::hex_decode("17 03 03 00 43"),
2✔
233
                       Botan::hex_decode_locked("a2 3f 70 54 b6 2c 94"
2✔
234
                                                "d0 af fa fe 82 28 ba 55 cb ef ac ea 42 f9 14 aa 66 bc ab 3f 2b"
235
                                                "98 19 a8 a5 b4 6b 39 5b d5 4a 9a 20 44 1e 2b 62 97 4e 1f 5a 62"
236
                                                "92 a2 97 70 14 bd 1e 3d ea e6 3a ee bb 21 69 49 15 e4"),
237
                       Botan::hex_decode_locked("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e"
1✔
238
                                                "0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23"
239
                                                "24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31"
240
                                                "17" /* to-be-encrypted content type */));
1✔
241

242
   // encrypted with server_application_traffic_secret
243
   const auto encrypted_application_data_server =
1✔
244
      RFC8448_TestData("encrypted_application_data_server",
245
                       Connection_Side::Server,
246
                       Botan::hex_decode("17 03 03 00 43"),
2✔
247
                       Botan::hex_decode_locked("2e 93 7e 11 ef 4a c7"
2✔
248
                                                "40 e5 38 ad 36 00 5f c4 a4 69 32 fc 32 25 d0 5f 82 aa 1b 36 e3"
249
                                                "0e fa f9 7d 90 e6 df fc 60 2d cb 50 1a 59 a8 fc c4 9c 4b f2 e5"
250
                                                "f0 a2 1c 00 47 c2 ab f3 32 54 0d d0 32 e1 67 c2 95 5d"),
251
                       Botan::hex_decode_locked("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e"
1✔
252
                                                "0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23"
253
                                                "24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31"
254
                                                "17" /* to-be-encrypted content type */));
1✔
255

256
   auto cipher = Ciphersuite::from_name("AES_128_GCM_SHA256").value();
1✔
257

258
   // initialize Cipher_State with client_hello...server_hello
259
   auto cs_client = Cipher_State::init_with_server_hello(
1✔
260
      Connection_Side::Client, secure_vector<uint8_t>(shared_secret), cipher, th_server_hello);
1✔
261
   auto cs_server = Cipher_State::init_with_server_hello(
1✔
262
      Connection_Side::Server, secure_vector<uint8_t>(shared_secret), cipher, th_server_hello);
1✔
263

264
   auto CHECK_both = make_CHECK_both(cs_client.get(), cs_server.get());
1✔
265

266
   return Test::flatten_result_lists(
7✔
267
      {CHECK_both("ciphersuite compatibility",
268
                  [&](Cipher_State* cs, Connection_Side side, Test::Result& result) {
2✔
269
                     result.confirm("self-compatibility", cs->is_compatible_with(cipher));
4✔
270
                     result.confirm(
4✔
271
                        "fully defined state is not compatible to other suites",
272
                        !cs->is_compatible_with(Ciphersuite::from_name("CHACHA20_POLY1305_SHA256").value()) &&
6✔
273
                           !cs->is_compatible_with(Ciphersuite::from_name("AES_128_CCM_SHA256").value()) &&
6✔
274
                           !cs->is_compatible_with(Ciphersuite::from_name("PSK_WITH_AES_128_GCM_SHA256").value()));
4✔
275
                     if(side == Connection_Side::Client) {
2✔
276
                        result.confirm("Clients don't expect unprotected alerts after server hello",
2✔
277
                                       !cs->must_expect_unprotected_alert_traffic());
1✔
278
                     } else {
279
                        result.confirm("Servers must expect unprotected alerts in response to their server hello",
3✔
280
                                       cs->must_expect_unprotected_alert_traffic());
1✔
281
                     }
282
                  }),
2✔
283

284
       CHECK_both("ticket nonce counter is not yet available",
285
                  [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
286
                     result.test_throws<Botan::Invalid_State>("nonce counter is disabled",
4✔
287
                                                              [&] { cs->next_ticket_nonce(); });
2✔
288
                  }),
2✔
289

290
       CHECK_both("handshake traffic without PSK",
291
                  [&](Cipher_State* cs, Connection_Side side, Test::Result& result) {
2✔
292
                     result.confirm("can not yet write application data", !cs->can_encrypt_application_traffic());
4✔
293
                     result.confirm("can not yet export key material", !cs->can_export_keys());
6✔
294

295
                     // decrypt encrypted extensions from server
296
                     encrypted_extensions.xxcrypt(result, cs, side);
2✔
297

298
                     // validate the MAC we receive in server Finished message
299
                     const auto expected_server_mac = Botan::hex_decode(
2✔
300
                        "9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4"
301
                        "de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18");
2✔
302
                     if(side == Connection_Side::Client) {
2✔
303
                        result.confirm("expecting the correct MAC for server finished",
3✔
304
                                       cs->verify_peer_finished_mac(th_pre_server_finished, expected_server_mac));
1✔
305
                     } else {
306
                        result.test_eq("expecting the correct MAC for server finished",
2✔
307
                                       cs->finished_mac(th_pre_server_finished),
2✔
308
                                       expected_server_mac);
309
                     }
310

311
                     // advance Cipher_State with client_hello...server_Finished
312
                     // (allows receiving of application data, but does not yet allow such sending)
313
                     result.test_no_throw("state advancement is legal",
4✔
314
                                          [&] { cs->advance_with_server_finished(th_server_finished); });
4✔
315

316
                     if(side == Connection_Side::Client) {
2✔
317
                        result.confirm("can read application data", cs->can_decrypt_application_traffic());
2✔
318
                        result.confirm("can not yet write application data", !cs->can_encrypt_application_traffic());
2✔
319
                        result.confirm("Clients don't expect unprotected alerts after server hello",
2✔
320
                                       !cs->must_expect_unprotected_alert_traffic());
1✔
321
                     } else {
322
                        result.confirm("can not yet read application data", !cs->can_decrypt_application_traffic());
2✔
323
                        result.confirm("can write application data", cs->can_encrypt_application_traffic());
2✔
324
                        result.confirm("Servers must expect unprotected alerts in response to their first flight",
3✔
325
                                       cs->must_expect_unprotected_alert_traffic());
1✔
326
                     }
327

328
                     // generate the MAC for the client Finished message
329
                     const auto expected_client_mac = Botan::hex_decode(
2✔
330
                        "a8 ec 43 6d 67 76 34 ae 52 5a c1 fc eb e1 1a 03"
331
                        "9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce 61");
2✔
332
                     if(side == Connection_Side::Client) {
2✔
333
                        result.test_eq("generating the correct MAC for client finished",
2✔
334
                                       cs->finished_mac(th_server_finished),
2✔
335
                                       expected_client_mac);
336
                     } else {
337
                        result.confirm("verify the correct MAC for client finished",
3✔
338
                                       cs->verify_peer_finished_mac(th_server_finished, expected_client_mac));
1✔
339
                     }
340

341
                     // encrypt client Finished message by client
342
                     // (under the client handshake traffic secret)
343
                     encrypted_client_finished_message.xxcrypt(result, cs, side);
2✔
344

345
                     // advance Cipher_State with client_hello...client_Finished
346
                     // (allows generation of resumption PSKs)
347
                     result.test_no_throw("state advancement is legal",
4✔
348
                                          [&] { cs->advance_with_client_finished(th_client_finished); });
4✔
349

350
                     result.confirm("can write application data", cs->can_encrypt_application_traffic());
4✔
351
                     result.confirm("can read application data", cs->can_decrypt_application_traffic());
4✔
352
                     result.confirm("doesn't need to expect unprotected alerts",
2✔
353
                                    !cs->must_expect_unprotected_alert_traffic());
2✔
354
                     result.confirm("can export key material", cs->can_export_keys());
6✔
355
                     result.test_eq("key export produces expected result",
4✔
356
                                    cs->export_key(export_label, export_context, 16),
×
357
                                    expected_key_export);
2✔
358

359
                     // decrypt "new session ticket" post-handshake message from server
360
                     // (encrypted under the application traffic secret)
361
                     encrypted_new_session_ticket.xxcrypt(result, cs, side);
2✔
362

363
                     // encrypt application data by client
364
                     encrypted_application_data_client.xxcrypt(result, cs, side);
2✔
365

366
                     // decrypt application data from server
367
                     // (encrypted under the application traffic secret -- and a new sequence number)
368
                     encrypted_application_data_server.xxcrypt(result, cs, side);
2✔
369

370
                     result.confirm("can export key material still", cs->can_export_keys());
6✔
371
                     result.test_eq("key export result did not change",
4✔
372
                                    cs->export_key(export_label, export_context, 16),
4✔
373
                                    expected_key_export);
374
                  }),
4✔
375

376
       CHECK_both("ticket nonce counter counts",
377
                  [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
378
                     result.test_is_eq("nonce is 0x00, 0x00",
4✔
379
                                       cs->next_ticket_nonce(),
2✔
380
                                       Botan::TLS::Ticket_Nonce(std::vector<uint8_t>{0x00, 0x00}));
4✔
381
                     result.test_is_eq("nonce is 0x00, 0x01",
4✔
382
                                       cs->next_ticket_nonce(),
2✔
383
                                       Botan::TLS::Ticket_Nonce(std::vector<uint8_t>{0x00, 0x01}));
4✔
384
                     result.test_is_eq("nonce is 0x00, 0x02",
4✔
385
                                       cs->next_ticket_nonce(),
2✔
386
                                       Botan::TLS::Ticket_Nonce(std::vector<uint8_t>{0x00, 0x02}));
4✔
387

388
                     for(uint32_t i = 3; i < std::numeric_limits<uint16_t>::max(); ++i) {
131,066✔
389
                        cs->next_ticket_nonce();
262,128✔
390
                     }
391

392
                     // Cannot generate more than 2^16 ticket nonces
393
                     result.test_throws<Botan::Invalid_State>("nonces are depleted", [&] { cs->next_ticket_nonce(); });
6✔
394
                  }),
2✔
395

396
       CHECK_both("PSK",
397
                  [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
398
                     // derive PSK for resumption
399
                     const auto psk = cs->psk(Botan::TLS::Ticket_Nonce(
2✔
400
                        std::vector<uint8_t>{0x00, 0x00}) /* ticket_nonce as defined in RFC 8448 */);
2✔
401
                     result.test_eq("PSK matches", psk, expected_psk);
4✔
402
                  }),
2✔
403

404
       CHECK_both("key update",
405
                  [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
406
                     cs->update_read_keys();
2✔
407
                     cs->update_write_keys();
2✔
408

409
                     result.confirm("can encrypt application traffic", cs->can_encrypt_application_traffic());
4✔
410
                  }),
2✔
411

412
       CHECK_both("cleanup", [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
413
          // cleanup
414
          cs->clear_write_keys();
2✔
415
          result.confirm("can no longer write application data", !cs->can_encrypt_application_traffic());
4✔
416
          result.confirm("can still read application data", cs->can_decrypt_application_traffic());
4✔
417

418
          cs->clear_read_keys();
2✔
419
          result.confirm("can no longer write application data", !cs->can_encrypt_application_traffic());
4✔
420
          result.confirm("can no longer read application data", !cs->can_decrypt_application_traffic());
4✔
421
       })});
13✔
422
}
9✔
423

424
std::vector<Test::Result> test_secret_derivation_rfc8448_rtt0() {
1✔
425
   // this is the PSK that was negotiated for session resumption in RFC 8448 (see test case above)
426
   const auto psk = Botan::hex_decode_locked(
1✔
427
      "4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c a4 c5"
428
      "85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3");
1✔
429

430
   // this shared secret is obtained by a key exchange performed additionally to
431
   // the pre-shared-key.
432
   const auto shared_secret = Botan::hex_decode_locked(
1✔
433
      "f4 41 94 75 6f f9 ec 9d 25 18 06 35 d6 6e a6 82"
434
      "4c 6a b3 bf 17 99 77 be 37 f7 23 57 0e 7c cb 2e");
1✔
435

436
   // transcript hash of the client hello up to (including) the PSK modes
437
   // (used to calculate the PSK binder)
438
   const auto th_client_hello_prefix = Botan::hex_decode(
1✔
439
      "63 22 4b 2e 45 73 f2 d3 45 4c a8 4b 9d 00 9a 04"
440
      "f6 be 9e 05 71 1a 83 96 47 3a ef a0 1e 92 4a 14");
1✔
441

442
   // transcript hash of the client hello including the PSK identity and binders
443
   const auto th_client_hello = Botan::hex_decode(
1✔
444
      "08 ad 0f a0 5d 7c 72 33 b1 77 5b a2 ff 9f 4c 5b"
445
      "8b 59 27 6b 7f 22 7f 13 a9 76 24 5f 5d 96 09 13");
1✔
446

447
   const auto th_server_hello = Botan::hex_decode(
1✔
448
      "f7 36 cb 34 fe 25 e7 01 55 1b ee 6f d2 4c 1c c7"
449
      "10 2a 7d af 94 05 cb 15 d9 7a af e1 6f 75 7d 03");
1✔
450

451
   // this is not directly exposed in RFC 8448 but calculated as
452
   // SHA-256(ClientHello..EncryptedExtensions)
453
   const auto th_pre_server_finished = Botan::hex_decode(
1✔
454
      "04 05 54 55 ef 74 b2 32 2b a3 66 cb c4 cf e0 27"
455
      "23 43 4b 37 b9 b3 67 1b b5 a3 00 60 56 d8 f0 2f");
1✔
456

457
   const auto th_server_finished = Botan::hex_decode(
1✔
458
      "b0 ae ff c4 6a 2c fe 33 11 4e 6f d7 d5 1f 9f 04"
459
      "b1 ca 3c 49 7d ab 08 93 4a 77 4a 9d 9a d7 db f3");
1✔
460

461
   // this is not directly exposed in RFC 8448 but calculated as
462
   // SHA-256(ClientHello..EndOfEarlyData)
463
   const auto th_end_of_early_data = Botan::hex_decode(
1✔
464
      "9f 23 a0 0c 1f 08 fc 18 80 7b 8b 68 23 7b 56 5d"
465
      "f2 0d 4c 50 dd 8e 49 ef 61 2e 1a 5b b1 6c 58 67");
1✔
466

467
   const auto th_client_finished = Botan::hex_decode(
1✔
468
      "c3 c1 22 e0 bd 90 7a 4a 3f f6 11 2d 8f d5 3d bf"
469
      "89 c7 73 d9 55 2e 8b 6b 9d 56 d3 61 b3 a9 7b f6");
1✔
470

471
   const auto expected_psk_binder = Botan::hex_decode(
1✔
472
      "3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e f5 e8"
473
      "8d ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d");
1✔
474

475
   // this is not part of RFC 8448
476
   const std::string export_label = "export_test_label";
1✔
477
   const std::string export_context = "rfc8448_psk";
1✔
478
   const auto expected_key_export = Botan::hex_decode_locked("b5 89 bc b4 0b 7f 94 d7 6f 2d d6 fc f9 e5 87 8e");
1✔
479

480
   // this is not part of RFC 8448
481
   const std::string early_export_label = "export_test_label_early";
1✔
482
   const std::string early_export_context = "rfc8448_psk_early";
1✔
483
   const auto early_expected_key_export = Botan::hex_decode_locked("b6 fb 7d 9e b5 4e 97 59 6f e4 ed 93 cc b0 bf 0c");
1✔
484

485
   // encrypted with server_handshake_traffic_secret
486
   const auto encrypted_extensions =
1✔
487
      RFC8448_TestData("encrypted_extensions",
488
                       Connection_Side::Server,
489
                       Botan::hex_decode("17 03 03 00 61"),
2✔
490
                       Botan::hex_decode_locked("dc 48 23 7b 4b 87 9f"
2✔
491
                                                "50 d0 d4 d2 62 ea 8b 47 16 eb 40 dd c1 eb 95 7e 11 12 6e 8a 71"
492
                                                "49 c2 d0 12 d3 7a 71 15 95 7e 64 ce 30 00 8b 9e 03 23 f2 c0 5a"
493
                                                "9c 1c 77 b4 f3 78 49 a6 95 ab 25 50 60 a3 3f ee 77 0c a9 5c b8"
494
                                                "48 6b fd 08 43 b8 70 24 86 5c a3 5c c4 1c 4e 51 5c 64 dc b1 36"
495
                                                "9f 98 63 5b c7 a5"),
496
                       Botan::hex_decode_locked("08 00 00 28 00 26 00 0a 00 14 00 12 00 1d 00"
1✔
497
                                                "17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c 00 02 40 01"
498
                                                "00 00 00 00 00 2a 00 00 14 00 00 20 48 d3 e0 e1 b3 d9 07 c6 ac"
499
                                                "ff 14 5e 16 09 03 88 c7 7b 05 c0 50 b6 34 ab 1a 88 bb d0 dd 1a"
500
                                                "34 b2"
501
                                                "16" /* to-be-encrypted content type */));
1✔
502

503
   // encrypted with client_handshake_traffic_secret
504
   const auto encrypted_client_finished_message =
1✔
505
      RFC8448_TestData("encrypted_client_finished_message",
506
                       Connection_Side::Client,
507
                       Botan::hex_decode("17 03 03 00 35"),
2✔
508
                       Botan::hex_decode_locked("00 f8 b4 67 d1 4c f2"
2✔
509
                                                "2a 4b 3f 0b 6a e0 d8 e6 cc 8d 08 e0 db 35 15 ef 5c 2b df 19 22"
510
                                                "ea fb b7 00 09 96 47 16 d8 34 fb 70 c3 d2 a5 6c 5b 1f 5f 6b db"
511
                                                "a6 c3 33 cf"),
512
                       Botan::hex_decode_locked("14 00 00 20 72 30 a9 c9 52 c2 5c d6 13 8f"
1✔
513
                                                "c5 e6 62 83 08 c4 1c 53 35 dd 81 b9 f9 6b ce a5 0f d3 2b da 41 6d"
514
                                                "16" /* to-be-encrypted content type */));
1✔
515

516
   // encrypted with client_application_traffic_secret
517
   const auto encrypted_application_data_client =
1✔
518
      RFC8448_TestData("encrypted_application_data_client",
519
                       Connection_Side::Client,
520
                       Botan::hex_decode("17 03 03 00 43"),
2✔
521
                       Botan::hex_decode_locked("b1 ce bc e2 42 aa 20"
2✔
522
                                                "1b e9 ae 5e 1c b2 a9 aa 4b 33 d4 e8 66 af 1e db 06 89 19 23 77"
523
                                                "41 aa 03 1d 7a 74 d4 91 c9 9b 9d 4e 23 2b 74 20 6b c6 fb aa 04"
524
                                                "fe 78 be 44 a9 b4 f5 43 20 a1 7e b7 69 92 af ac 31 03"),
525
                       Botan::hex_decode_locked("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e"
1✔
526
                                                "0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23"
527
                                                "24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31"
528
                                                "17" /* to-be-encrypted content type */));
1✔
529

530
   // encrypted with server_application_traffic_secret
531
   const auto encrypted_application_data_server =
1✔
532
      RFC8448_TestData("encrypted_application_data_server",
533
                       Connection_Side::Server,
534
                       Botan::hex_decode("17 03 03 00 43"),
2✔
535
                       Botan::hex_decode_locked("27 5e 9f 20 ac ff 57"
2✔
536
                                                "bc 00 06 57 d3 86 7d f0 39 cc cf 79 04 78 84 cf 75 77 17 46 f7"
537
                                                "40 b5 a8 3f 46 2a 09 54 c3 58 13 93 a2 03 a2 5a 7d d1 41 41 ef"
538
                                                "1a 37 90 0c db 62 ff 62 de e1 ba 39 ab 25 90 cb f1 94"),
539
                       Botan::hex_decode_locked("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e"
1✔
540
                                                "0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23"
541
                                                "24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31"
542
                                                "17" /* to-be-encrypted content type */));
1✔
543

544
   auto cipher = Ciphersuite::from_name("AES_128_GCM_SHA256").value();
1✔
545

546
   auto cs_client = Cipher_State::init_with_psk(Connection_Side::Client,
1✔
547
                                                Cipher_State::PSK_Type::Resumption,
548
                                                secure_vector<uint8_t>(psk.begin(), psk.end()),
1✔
549
                                                cipher);
1✔
550
   auto cs_server = Cipher_State::init_with_psk(Connection_Side::Server,
1✔
551
                                                Cipher_State::PSK_Type::Resumption,
552
                                                secure_vector<uint8_t>(psk.begin(), psk.end()),
1✔
553
                                                cipher);
1✔
554

555
   auto CHECK_both = make_CHECK_both(cs_client.get(), cs_server.get());
1✔
556

557
   return Test::flatten_result_lists(
5✔
558
      {CHECK_both("calculating PSK binder",
559
                  [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
560
                     const auto mac = cs->psk_binder_mac(th_client_hello_prefix);
2✔
561
                     result.test_eq("PSK binder is as expected", mac, expected_psk_binder);
4✔
562
                  }),
2✔
563

564
       CHECK_both(
565
          "ciphersuite compatibility",
566
          [&](Cipher_State* cs, Connection_Side, Test::Result& result) {
2✔
567
             result.confirm("self-compatibility", cs->is_compatible_with(cipher));
4✔
568
             result.confirm("partially defined state is compatible with suites using the same hash",
4✔
569
                            cs->is_compatible_with(Ciphersuite::from_name("CHACHA20_POLY1305_SHA256").value()) &&
6✔
570
                               cs->is_compatible_with(Ciphersuite::from_name("AES_128_CCM_SHA256").value()) &&
6✔
571
                               cs->is_compatible_with(Ciphersuite::from_name("AES_128_CCM_8_SHA256").value()));
4✔
572

573
             result.confirm("partially defined state is not compatible with other hashes or protocol versions",
4✔
574
                            !cs->is_compatible_with(Ciphersuite::from_name("PSK_WITH_AES_128_GCM_SHA256").value()) &&
6✔
575
                               !cs->is_compatible_with(Ciphersuite::from_name("AES_256_GCM_SHA384").value()));
4✔
576
          }),
2✔
577

578
       CHECK_both("calculate the early traffic secrets",
579
                  [&](Cipher_State* cs, Connection_Side side, Test::Result& result) {
2✔
580
                     cs->advance_with_client_hello(th_client_hello);
2✔
581
                     result.require("early key export is possible", cs->can_export_keys());
4✔
582
                     result.test_eq("early key export produces expected result",
4✔
583
                                    cs->export_key(early_export_label, early_export_context, 16),
2✔
584
                                    early_expected_key_export);
2✔
585

586
                     if(side == Connection_Side::Client) {
2✔
587
                        result.confirm("Clients must expect servers to respond with an unprotected alert",
3✔
588
                                       cs->must_expect_unprotected_alert_traffic());
1✔
589
                     } else {
590
                        result.confirm(
2✔
591
                           "Servers do not expect clients to send alerts protected with the early data secret",
592
                           !cs->must_expect_unprotected_alert_traffic());
1✔
593
                     }
594

595
                     // TODO: Once 0-RTT traffic is implemented this will likely allow handling of
596
                     //       application traffic in this state.
597
                     result.confirm("can not yet write application data", !cs->can_encrypt_application_traffic());
4✔
598
                     result.confirm("can not yet read application data", !cs->can_decrypt_application_traffic());
4✔
599
                  }),
2✔
600

601
       CHECK_both("handshake traffic after PSK",
602
                  [&](Cipher_State* cs, Connection_Side side, Test::Result& result) {
2✔
603
                     cs->advance_with_server_hello(cipher, secure_vector<uint8_t>(shared_secret), th_server_hello);
2✔
604

605
                     // decrypt encrypted extensions from server
606
                     encrypted_extensions.xxcrypt(result, cs, side);
2✔
607

608
                     // TODO: Handling of early traffic is left out as 0-RTT is not implemented yet.
609

610
                     // validate the MAC we receive in server Finished message
611
                     const auto expected_server_mac = Botan::hex_decode(
2✔
612
                        "48 d3 e0 e1 b3 d9 07 c6 ac ff 14 5e 16 09 03 88"
613
                        "c7 7b 05 c0 50 b6 34 ab 1a 88 bb d0 dd 1a 34 b2");
2✔
614
                     if(side == Connection_Side::Client) {
2✔
615
                        result.confirm("expecting the correct MAC for server finished",
2✔
616
                                       cs->verify_peer_finished_mac(th_pre_server_finished, expected_server_mac));
1✔
617
                        result.confirm("Clients don't expect unprotected alerts after server hello",
2✔
618
                                       !cs->must_expect_unprotected_alert_traffic());
1✔
619
                     } else {
620
                        result.test_eq("expecting the correct MAC for server finished",
2✔
621
                                       cs->finished_mac(th_pre_server_finished),
1✔
622
                                       expected_server_mac);
623
                        result.confirm("Servers must expect unprotected alerts in response to their server hello",
3✔
624
                                       cs->must_expect_unprotected_alert_traffic());
1✔
625
                     }
626

627
                     result.confirm("cannot read application data", !cs->can_decrypt_application_traffic());
4✔
628
                     result.confirm("cannot write application data", !cs->can_encrypt_application_traffic());
4✔
629

630
                     // advance Cipher_State with client_hello...server_Finished
631
                     // (allows receiving of application data, but no such sending)
632
                     result.test_no_throw("state advancement is legal",
4✔
633
                                          [&] { cs->advance_with_server_finished(th_server_finished); });
4✔
634

635
                     if(side == Connection_Side::Client) {
2✔
636
                        result.confirm("can read application data", cs->can_decrypt_application_traffic());
2✔
637
                        result.confirm("cannot write application data", !cs->can_encrypt_application_traffic());
2✔
638
                        result.confirm("Clients don't expect unprotected alerts after server hello",
2✔
639
                                       !cs->must_expect_unprotected_alert_traffic());
1✔
640
                     } else {
641
                        result.confirm("cannot read application data", !cs->can_decrypt_application_traffic());
2✔
642
                        result.confirm("can write application data", cs->can_encrypt_application_traffic());
2✔
643
                        result.confirm("Servers must expect unprotected alerts in response to their first flight",
3✔
644
                                       cs->must_expect_unprotected_alert_traffic());
1✔
645
                     }
646

647
                     // generate the MAC for the client Finished message
648
                     const auto expected_client_mac = Botan::hex_decode(
2✔
649
                        "72 30 a9 c9 52 c2 5c d6 13 8f c5 e6 62 83 08 c4"
650
                        "1c 53 35 dd 81 b9 f9 6b ce a5 0f d3 2b da 41 6d");
2✔
651
                     if(side == Connection_Side::Client) {
2✔
652
                        result.test_eq("generating the correct MAC for client finished",
2✔
653
                                       cs->finished_mac(th_end_of_early_data),
2✔
654
                                       expected_client_mac);
655
                     } else {
656
                        result.confirm("verify the correct MAC for client finished",
3✔
657
                                       cs->verify_peer_finished_mac(th_end_of_early_data, expected_client_mac));
1✔
658
                     }
659

660
                     // encrypt client Finished message by client
661
                     // (under the client handshake traffic secret)
662
                     encrypted_client_finished_message.xxcrypt(result, cs, side);
2✔
663
                  }),
4✔
664

665
       CHECK_both("application traffic after PSK", [&](Cipher_State* cs, Connection_Side side, Test::Result& result) {
2✔
666
          // advance Cipher_State with client_hello...client_Finished
667
          // (allows generation of resumption PSKs)
668
          result.test_no_throw("state advancement is legal",
4✔
669
                               [&] { cs->advance_with_client_finished(th_client_finished); });
4✔
670

671
          result.confirm("can read application data", cs->can_decrypt_application_traffic());
4✔
672
          result.confirm("can write application data", cs->can_encrypt_application_traffic());
4✔
673
          result.confirm("doesn't need to expect unprotected alerts", !cs->must_expect_unprotected_alert_traffic());
4✔
674
          result.confirm("can export key material", cs->can_export_keys());
6✔
675
          result.test_eq("key export produces expected result",
4✔
676
                         cs->export_key(export_label, export_context, 16),
2✔
677
                         expected_key_export);
2✔
678

679
          // encrypt application data by client
680
          encrypted_application_data_client.xxcrypt(result, cs, side);
2✔
681

682
          // decrypt application data from server
683
          // (encrypted under the application traffic secret -- and a new sequence number)
684
          encrypted_application_data_server.xxcrypt(result, cs, side);
2✔
685
       })});
12✔
686
}
16✔
687

688
}  // namespace
689

690
namespace Botan_Tests {
691
BOTAN_REGISTER_TEST_FN("tls",
692
                       "tls_cipher_state",
693
                       test_secret_derivation_rfc8448_rtt1,
694
                       test_secret_derivation_rfc8448_rtt0);
695
}
696

697
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc