Branch data Line data Source code
1 : : /*
2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License").
5 : : * You may not use this file except in compliance with the License.
6 : : * A copy of the License is located at
7 : : *
8 : : * http://aws.amazon.com/apache2.0
9 : : *
10 : : * or in the "license" file accompanying this file. This file is distributed
11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 : : * express or implied. See the License for the specific language governing
13 : : * permissions and limitations under the License.
14 : : */
15 : :
16 : : #include <errno.h>
17 : : #include <sys/param.h>
18 : :
19 : : #include "api/s2n.h"
20 : : #include "crypto/s2n_fips.h"
21 : : #include "error/s2n_errno.h"
22 : : #include "stuffer/s2n_stuffer.h"
23 : : #include "tls/s2n_alerts.h"
24 : : #include "tls/s2n_async_pkey.h"
25 : : #include "tls/s2n_cipher_suites.h"
26 : : #include "tls/s2n_connection.h"
27 : : #include "tls/s2n_kex.h"
28 : : #include "tls/s2n_post_handshake.h"
29 : : #include "tls/s2n_record.h"
30 : : #include "tls/s2n_resume.h"
31 : : #include "tls/s2n_tls.h"
32 : : #include "tls/s2n_tls13.h"
33 : : #include "tls/s2n_tls13_handshake.h"
34 : : #include "tls/s2n_tls13_key_schedule.h"
35 : : #include "utils/s2n_bitmap.h"
36 : : #include "utils/s2n_random.h"
37 : : #include "utils/s2n_safety.h"
38 : : #include "utils/s2n_socket.h"
39 : :
40 : : /* clang-format off */
41 : : struct s2n_handshake_action {
42 : : uint8_t record_type;
43 : : uint8_t message_type;
44 : : char writer; /* 'S' or 'C' for server or client, 'B' for both */
45 : : int (*handler[2]) (struct s2n_connection * conn);
46 : : };
47 : :
48 : : static int s2n_always_fail_send(struct s2n_connection *conn)
49 : 0 : {
50 : : /* This state should never be sending a handshake message. */
51 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_HANDSHAKE_UNREACHABLE);
52 : 0 : }
53 : :
54 : : static int s2n_always_fail_recv(struct s2n_connection *conn)
55 : 0 : {
56 : : /* This state should never have an incoming handshake message. */
57 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_HANDSHAKE_UNREACHABLE);
58 : 0 : }
59 : :
60 : : /* Client and Server handlers for each message type we support.
61 : : * See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7 for the list of handshake message types
62 : : */
63 : : static struct s2n_handshake_action state_machine[] = {
64 : : /* message_type_t = {Record type Message type Writer S2N_SERVER S2N_CLIENT } */
65 : : [CLIENT_HELLO] = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
66 : : [SERVER_HELLO] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
67 : : [SERVER_NEW_SESSION_TICKET] = {TLS_HANDSHAKE, TLS_SERVER_NEW_SESSION_TICKET,'S', {s2n_server_nst_send, s2n_server_nst_recv}},
68 : : [SERVER_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
69 : : [SERVER_CERT_STATUS] = {TLS_HANDSHAKE, TLS_SERVER_CERT_STATUS, 'S', {s2n_server_status_send, s2n_server_status_recv}},
70 : : [SERVER_KEY] = {TLS_HANDSHAKE, TLS_SERVER_KEY, 'S', {s2n_server_key_send, s2n_server_key_recv}},
71 : : [SERVER_CERT_REQ] = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_cert_req_send, s2n_cert_req_recv}},
72 : : [SERVER_HELLO_DONE] = {TLS_HANDSHAKE, TLS_SERVER_HELLO_DONE, 'S', {s2n_server_done_send, s2n_server_done_recv}},
73 : : [CLIENT_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
74 : : [CLIENT_KEY] = {TLS_HANDSHAKE, TLS_CLIENT_KEY, 'C', {s2n_client_key_recv, s2n_client_key_send}},
75 : : [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_client_cert_verify_recv, s2n_client_cert_verify_send}},
76 : : [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_client_ccs_recv, s2n_ccs_send}},
77 : : [CLIENT_NPN] = {TLS_HANDSHAKE, TLS_NPN, 'C', {s2n_next_protocol_recv, s2n_next_protocol_send}},
78 : : [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_client_finished_recv, s2n_client_finished_send}},
79 : : [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_server_ccs_recv}},
80 : : [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_server_finished_send, s2n_server_finished_recv}},
81 : : [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}},
82 : : };
83 : :
84 : : /*
85 : : * Client and Server handlers for TLS1.3.
86 : : */
87 : : static struct s2n_handshake_action tls13_state_machine[] = {
88 : : /* message_type_t = {Record type, Message type, Writer, {Server handler, client handler} } */
89 : : [CLIENT_HELLO] = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
90 : : [SERVER_HELLO] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
91 : : [HELLO_RETRY_MSG] = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_retry_send, s2n_server_hello_retry_recv}},
92 : : [ENCRYPTED_EXTENSIONS] = {TLS_HANDSHAKE, TLS_ENCRYPTED_EXTENSIONS, 'S', {s2n_encrypted_extensions_send, s2n_encrypted_extensions_recv}},
93 : : [SERVER_CERT_REQ] = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_tls13_cert_req_send, s2n_tls13_cert_req_recv}},
94 : : [SERVER_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
95 : : [SERVER_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'S', {s2n_tls13_cert_verify_send, s2n_tls13_cert_verify_recv}},
96 : : [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_tls13_server_finished_send, s2n_tls13_server_finished_recv}},
97 : :
98 : : [CLIENT_CERT] = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
99 : : [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_tls13_cert_verify_recv, s2n_tls13_cert_verify_send}},
100 : : [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_tls13_client_finished_recv, s2n_tls13_client_finished_send}},
101 : : [END_OF_EARLY_DATA] = {TLS_HANDSHAKE, TLS_END_OF_EARLY_DATA, 'C', {s2n_end_of_early_data_recv, s2n_end_of_early_data_send}},
102 : :
103 : : /* Not used by TLS1.3, except to maintain middlebox compatibility */
104 : : [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_basic_ccs_recv, s2n_ccs_send}},
105 : : [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_basic_ccs_recv}},
106 : :
107 : : [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}},
108 : : };
109 : :
110 : : #define MESSAGE_NAME_ENTRY(msg) [msg] = #msg
111 : :
112 : : static const char *message_names[] = {
113 : : MESSAGE_NAME_ENTRY(CLIENT_HELLO),
114 : : MESSAGE_NAME_ENTRY(SERVER_HELLO),
115 : : MESSAGE_NAME_ENTRY(ENCRYPTED_EXTENSIONS),
116 : : MESSAGE_NAME_ENTRY(SERVER_NEW_SESSION_TICKET),
117 : : MESSAGE_NAME_ENTRY(SERVER_CERT),
118 : : MESSAGE_NAME_ENTRY(SERVER_CERT_STATUS),
119 : : MESSAGE_NAME_ENTRY(SERVER_CERT_VERIFY),
120 : : MESSAGE_NAME_ENTRY(SERVER_KEY),
121 : : MESSAGE_NAME_ENTRY(SERVER_CERT_REQ),
122 : : MESSAGE_NAME_ENTRY(SERVER_HELLO_DONE),
123 : : MESSAGE_NAME_ENTRY(CLIENT_CERT),
124 : : MESSAGE_NAME_ENTRY(CLIENT_KEY),
125 : : MESSAGE_NAME_ENTRY(CLIENT_CERT_VERIFY),
126 : : MESSAGE_NAME_ENTRY(CLIENT_CHANGE_CIPHER_SPEC),
127 : : MESSAGE_NAME_ENTRY(CLIENT_FINISHED),
128 : : MESSAGE_NAME_ENTRY(SERVER_CHANGE_CIPHER_SPEC),
129 : : MESSAGE_NAME_ENTRY(SERVER_FINISHED),
130 : : MESSAGE_NAME_ENTRY(HELLO_RETRY_MSG),
131 : : MESSAGE_NAME_ENTRY(END_OF_EARLY_DATA),
132 : : MESSAGE_NAME_ENTRY(APPLICATION_DATA),
133 : : MESSAGE_NAME_ENTRY(CLIENT_NPN),
134 : : };
135 : :
136 : : /* We support different ordering of TLS Handshake messages, depending on what is being negotiated. There's also a dummy "INITIAL" handshake
137 : : * that everything starts out as until we know better.
138 : : */
139 : :
140 : : static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
141 : : [INITIAL] = {
142 : : CLIENT_HELLO,
143 : : SERVER_HELLO
144 : : },
145 : :
146 : : [NEGOTIATED] = {
147 : : CLIENT_HELLO,
148 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
149 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
150 : : APPLICATION_DATA
151 : : },
152 : :
153 : : [NEGOTIATED | WITH_NPN ] = {
154 : : CLIENT_HELLO,
155 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
156 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
157 : : APPLICATION_DATA
158 : : },
159 : :
160 : : [NEGOTIATED | WITH_SESSION_TICKET ] = {
161 : : CLIENT_HELLO,
162 : : SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
163 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
164 : : APPLICATION_DATA},
165 : :
166 : : [NEGOTIATED | WITH_SESSION_TICKET | WITH_NPN ] = {
167 : : CLIENT_HELLO,
168 : : SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
169 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
170 : : APPLICATION_DATA},
171 : :
172 : : [NEGOTIATED | FULL_HANDSHAKE ] = {
173 : : CLIENT_HELLO,
174 : : SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
175 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
176 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
177 : : APPLICATION_DATA
178 : : },
179 : :
180 : : [NEGOTIATED | FULL_HANDSHAKE | WITH_NPN ] = {
181 : : CLIENT_HELLO,
182 : : SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
183 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
184 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
185 : : APPLICATION_DATA
186 : : },
187 : :
188 : : [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET ] = {
189 : : CLIENT_HELLO,
190 : : SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
191 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
192 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
193 : : APPLICATION_DATA
194 : : },
195 : :
196 : : [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET | WITH_NPN ] = {
197 : : CLIENT_HELLO,
198 : : SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
199 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
200 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
201 : : APPLICATION_DATA
202 : : },
203 : :
204 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY ] = {
205 : : CLIENT_HELLO,
206 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
207 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
208 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
209 : : APPLICATION_DATA
210 : : },
211 : :
212 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_NPN ] = {
213 : : CLIENT_HELLO,
214 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
215 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
216 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
217 : : APPLICATION_DATA
218 : : },
219 : :
220 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET ] = {
221 : : CLIENT_HELLO,
222 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
223 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
224 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
225 : : APPLICATION_DATA
226 : : },
227 : :
228 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET | WITH_NPN ] = {
229 : : CLIENT_HELLO,
230 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
231 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
232 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
233 : : APPLICATION_DATA
234 : : },
235 : :
236 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS ] ={
237 : : CLIENT_HELLO,
238 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
239 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
240 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
241 : : APPLICATION_DATA
242 : : },
243 : :
244 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_NPN ] ={
245 : : CLIENT_HELLO,
246 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
247 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
248 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
249 : : APPLICATION_DATA
250 : : },
251 : :
252 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET ] = {
253 : : CLIENT_HELLO,
254 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
255 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
256 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
257 : : APPLICATION_DATA
258 : : },
259 : :
260 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET | WITH_NPN ] = {
261 : : CLIENT_HELLO,
262 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
263 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
264 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
265 : : APPLICATION_DATA
266 : : },
267 : :
268 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS ] = {
269 : : CLIENT_HELLO,
270 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
271 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
272 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
273 : : APPLICATION_DATA
274 : : },
275 : :
276 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_NPN ] = {
277 : : CLIENT_HELLO,
278 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
279 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
280 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
281 : : APPLICATION_DATA
282 : : },
283 : :
284 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET ] ={
285 : : CLIENT_HELLO,
286 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
287 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
288 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
289 : : APPLICATION_DATA
290 : : },
291 : :
292 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET | WITH_NPN ] ={
293 : : CLIENT_HELLO,
294 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
295 : : CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
296 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
297 : : APPLICATION_DATA
298 : : },
299 : :
300 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
301 : : CLIENT_HELLO,
302 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
303 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
304 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
305 : : APPLICATION_DATA
306 : : },
307 : :
308 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH| WITH_NPN ] = {
309 : : CLIENT_HELLO,
310 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
311 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
312 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
313 : : APPLICATION_DATA
314 : : },
315 : :
316 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT ] = {
317 : : CLIENT_HELLO,
318 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
319 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
320 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
321 : : APPLICATION_DATA
322 : : },
323 : :
324 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
325 : : CLIENT_HELLO,
326 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
327 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
328 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
329 : : APPLICATION_DATA
330 : : },
331 : :
332 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET] = {
333 : : CLIENT_HELLO,
334 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
335 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
336 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
337 : : APPLICATION_DATA
338 : : },
339 : :
340 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
341 : : CLIENT_HELLO,
342 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
343 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
344 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
345 : : APPLICATION_DATA
346 : : },
347 : :
348 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
349 : : CLIENT_HELLO,
350 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
351 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
352 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
353 : : APPLICATION_DATA
354 : : },
355 : :
356 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
357 : : CLIENT_HELLO,
358 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
359 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
360 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
361 : : APPLICATION_DATA
362 : : },
363 : :
364 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH] = {
365 : : CLIENT_HELLO,
366 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
367 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
368 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
369 : : APPLICATION_DATA
370 : : },
371 : :
372 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_NPN ] = {
373 : : CLIENT_HELLO,
374 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
375 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
376 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
377 : : APPLICATION_DATA
378 : : },
379 : :
380 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT ] = {
381 : : CLIENT_HELLO,
382 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
383 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
384 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
385 : : APPLICATION_DATA
386 : : },
387 : :
388 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
389 : : CLIENT_HELLO,
390 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
391 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
392 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
393 : : APPLICATION_DATA
394 : : },
395 : :
396 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET] = {
397 : : CLIENT_HELLO,
398 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
399 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
400 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
401 : : APPLICATION_DATA
402 : : },
403 : :
404 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
405 : : CLIENT_HELLO,
406 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
407 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
408 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
409 : : APPLICATION_DATA
410 : : },
411 : :
412 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
413 : : CLIENT_HELLO,
414 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
415 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
416 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
417 : : APPLICATION_DATA
418 : : },
419 : :
420 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
421 : : CLIENT_HELLO,
422 : : SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
423 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
424 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
425 : : APPLICATION_DATA
426 : : },
427 : :
428 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH] = {
429 : : CLIENT_HELLO,
430 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
431 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
432 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
433 : : APPLICATION_DATA
434 : : },
435 : :
436 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_NPN ] = {
437 : : CLIENT_HELLO,
438 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
439 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
440 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
441 : : APPLICATION_DATA
442 : : },
443 : :
444 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
445 : : CLIENT_HELLO,
446 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
447 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
448 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
449 : : APPLICATION_DATA
450 : : },
451 : :
452 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
453 : : CLIENT_HELLO,
454 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
455 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
456 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
457 : : APPLICATION_DATA
458 : : },
459 : :
460 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET] = {
461 : : CLIENT_HELLO,
462 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
463 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
464 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
465 : : APPLICATION_DATA
466 : : },
467 : :
468 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
469 : : CLIENT_HELLO,
470 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
471 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
472 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
473 : : APPLICATION_DATA
474 : : },
475 : :
476 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
477 : : CLIENT_HELLO,
478 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
479 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
480 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
481 : : APPLICATION_DATA
482 : : },
483 : :
484 : : [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
485 : : CLIENT_HELLO,
486 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
487 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
488 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
489 : : APPLICATION_DATA
490 : : },
491 : :
492 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH ] = {
493 : : CLIENT_HELLO,
494 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
495 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
496 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
497 : : APPLICATION_DATA
498 : : },
499 : :
500 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_NPN ] = {
501 : : CLIENT_HELLO,
502 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
503 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
504 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
505 : : APPLICATION_DATA
506 : : },
507 : :
508 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
509 : : CLIENT_HELLO,
510 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
511 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
512 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
513 : : APPLICATION_DATA
514 : : },
515 : :
516 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
517 : : CLIENT_HELLO,
518 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
519 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
520 : : SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
521 : : APPLICATION_DATA
522 : : },
523 : :
524 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET ] = {
525 : : CLIENT_HELLO,
526 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
527 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
528 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
529 : : APPLICATION_DATA
530 : : },
531 : :
532 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
533 : : CLIENT_HELLO,
534 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
535 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
536 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
537 : : APPLICATION_DATA
538 : : },
539 : :
540 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
541 : : CLIENT_HELLO,
542 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
543 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
544 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
545 : : APPLICATION_DATA
546 : : },
547 : :
548 : : [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
549 : : CLIENT_HELLO,
550 : : SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
551 : : CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
552 : : SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
553 : : APPLICATION_DATA
554 : : },
555 : : };
556 : :
557 : : /*
558 : : * This selection of handshakes resembles the standard set, but with changes made to support tls1.3.
559 : : *
560 : : * The CHANGE_CIPHER_SPEC messages are included only for middlebox compatibility.
561 : : * See https://tools.ietf.org/html/rfc8446#appendix-D.4
562 : : */
563 : : static message_type_t tls13_handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
564 : : [INITIAL] = {
565 : : CLIENT_HELLO,
566 : : SERVER_HELLO
567 : : },
568 : :
569 : : [INITIAL | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
570 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
571 : : SERVER_HELLO
572 : : },
573 : :
574 : : [INITIAL | HELLO_RETRY_REQUEST] = {
575 : : CLIENT_HELLO,
576 : : HELLO_RETRY_MSG
577 : : },
578 : :
579 : : [INITIAL | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
580 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
581 : : HELLO_RETRY_MSG
582 : : },
583 : :
584 : : [NEGOTIATED] = {
585 : : CLIENT_HELLO,
586 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
587 : : CLIENT_FINISHED,
588 : : APPLICATION_DATA
589 : : },
590 : :
591 : : [NEGOTIATED | WITH_EARLY_DATA] = {
592 : : CLIENT_HELLO,
593 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
594 : : END_OF_EARLY_DATA, CLIENT_FINISHED,
595 : : APPLICATION_DATA
596 : : },
597 : :
598 : : [NEGOTIATED | MIDDLEBOX_COMPAT] = {
599 : : CLIENT_HELLO,
600 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
601 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
602 : : APPLICATION_DATA
603 : : },
604 : :
605 : : [NEGOTIATED | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
606 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
607 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
608 : : CLIENT_FINISHED,
609 : : APPLICATION_DATA
610 : : },
611 : :
612 : : [NEGOTIATED | MIDDLEBOX_COMPAT | WITH_EARLY_DATA] = {
613 : : CLIENT_HELLO,
614 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
615 : : CLIENT_CHANGE_CIPHER_SPEC, END_OF_EARLY_DATA, CLIENT_FINISHED,
616 : : APPLICATION_DATA
617 : : },
618 : :
619 : : [NEGOTIATED | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS | WITH_EARLY_DATA] = {
620 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
621 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
622 : : END_OF_EARLY_DATA, CLIENT_FINISHED,
623 : : APPLICATION_DATA
624 : : },
625 : :
626 : : [NEGOTIATED | HELLO_RETRY_REQUEST] = {
627 : : CLIENT_HELLO,
628 : : HELLO_RETRY_MSG,
629 : : CLIENT_HELLO,
630 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
631 : : CLIENT_FINISHED,
632 : : APPLICATION_DATA
633 : : },
634 : :
635 : : [NEGOTIATED | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT] = {
636 : : CLIENT_HELLO,
637 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
638 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
639 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
640 : : CLIENT_FINISHED,
641 : : APPLICATION_DATA
642 : : },
643 : :
644 : : [NEGOTIATED | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
645 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
646 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
647 : : CLIENT_HELLO,
648 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
649 : : CLIENT_FINISHED,
650 : : APPLICATION_DATA
651 : : },
652 : :
653 : : [NEGOTIATED | FULL_HANDSHAKE] = {
654 : : CLIENT_HELLO,
655 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
656 : : CLIENT_FINISHED,
657 : : APPLICATION_DATA
658 : : },
659 : :
660 : : [NEGOTIATED | FULL_HANDSHAKE | MIDDLEBOX_COMPAT] = {
661 : : CLIENT_HELLO,
662 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
663 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
664 : : APPLICATION_DATA
665 : : },
666 : :
667 : : [NEGOTIATED | FULL_HANDSHAKE | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
668 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
669 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
670 : : CLIENT_FINISHED,
671 : : APPLICATION_DATA
672 : : },
673 : :
674 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST] = {
675 : : CLIENT_HELLO,
676 : : HELLO_RETRY_MSG,
677 : : CLIENT_HELLO,
678 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
679 : : CLIENT_FINISHED,
680 : : APPLICATION_DATA
681 : : },
682 : :
683 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT] = {
684 : : CLIENT_HELLO,
685 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
686 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
687 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
688 : : CLIENT_FINISHED,
689 : : APPLICATION_DATA
690 : : },
691 : :
692 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
693 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
694 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
695 : : CLIENT_HELLO,
696 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
697 : : CLIENT_FINISHED,
698 : : APPLICATION_DATA
699 : : },
700 : :
701 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH] = {
702 : : CLIENT_HELLO,
703 : : HELLO_RETRY_MSG,
704 : : CLIENT_HELLO,
705 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
706 : : CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
707 : : APPLICATION_DATA
708 : : },
709 : :
710 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
711 : : CLIENT_HELLO,
712 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
713 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
714 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
715 : : CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
716 : : APPLICATION_DATA
717 : : },
718 : :
719 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
720 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
721 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
722 : : CLIENT_HELLO,
723 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
724 : : CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
725 : : APPLICATION_DATA
726 : : },
727 : :
728 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT] = {
729 : : CLIENT_HELLO,
730 : : HELLO_RETRY_MSG,
731 : : CLIENT_HELLO,
732 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
733 : : CLIENT_CERT, CLIENT_FINISHED,
734 : : APPLICATION_DATA
735 : : },
736 : :
737 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
738 : : CLIENT_HELLO,
739 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
740 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
741 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
742 : : CLIENT_CERT, CLIENT_FINISHED,
743 : : APPLICATION_DATA
744 : : },
745 : :
746 : : [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
747 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
748 : : HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
749 : : CLIENT_HELLO,
750 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
751 : : CLIENT_CERT, CLIENT_FINISHED,
752 : : APPLICATION_DATA
753 : : },
754 : :
755 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
756 : : CLIENT_HELLO,
757 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
758 : : CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
759 : : APPLICATION_DATA
760 : : },
761 : :
762 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
763 : : CLIENT_HELLO,
764 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
765 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
766 : : APPLICATION_DATA
767 : : },
768 : :
769 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
770 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
771 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
772 : : CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
773 : : APPLICATION_DATA
774 : : },
775 : :
776 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT] = {
777 : : CLIENT_HELLO,
778 : : SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
779 : : CLIENT_CERT, CLIENT_FINISHED,
780 : : APPLICATION_DATA
781 : : },
782 : :
783 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
784 : : CLIENT_HELLO,
785 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
786 : : CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_FINISHED,
787 : : APPLICATION_DATA
788 : : },
789 : :
790 : : [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
791 : : CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
792 : : SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
793 : : CLIENT_CERT, CLIENT_FINISHED,
794 : : APPLICATION_DATA
795 : : },
796 : : };
797 : : /* clang-format on */
798 : :
799 : : #define MAX_HANDSHAKE_TYPE_LEN 142
800 : : static char handshake_type_str[S2N_HANDSHAKES_COUNT][MAX_HANDSHAKE_TYPE_LEN] = { 0 };
801 : :
802 : : static const char *tls12_handshake_type_names[] = {
803 : : "NEGOTIATED|",
804 : : "FULL_HANDSHAKE|",
805 : : "CLIENT_AUTH|",
806 : : "NO_CLIENT_CERT|",
807 : : "TLS12_PERFECT_FORWARD_SECRECY|",
808 : : "OCSP_STATUS|",
809 : : "WITH_SESSION_TICKET|",
810 : : "WITH_NPN|",
811 : : };
812 : :
813 : : static const char *tls13_handshake_type_names[] = {
814 : : "NEGOTIATED|",
815 : : "FULL_HANDSHAKE|",
816 : : "CLIENT_AUTH|",
817 : : "NO_CLIENT_CERT|",
818 : : "HELLO_RETRY_REQUEST|",
819 : : "MIDDLEBOX_COMPAT|",
820 : : "WITH_EARLY_DATA|",
821 : : "EARLY_CLIENT_CCS|",
822 : : };
823 : :
824 : 3375212 : #define IS_TLS13_HANDSHAKE(conn) ((conn)->handshake.state_machine == S2N_STATE_MACHINE_TLS13)
825 : :
826 : 1076818 : #define ACTIVE_STATE_MACHINE(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_state_machine : state_machine)
827 : 2251271 : #define ACTIVE_HANDSHAKES(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_handshakes : handshakes)
828 : :
829 : 2251271 : #define ACTIVE_MESSAGE(conn) ACTIVE_HANDSHAKES(conn)[(conn)->handshake.handshake_type][(conn)->handshake.message_number]
830 : :
831 : 1076818 : #define ACTIVE_STATE(conn) ACTIVE_STATE_MACHINE(conn)[ACTIVE_MESSAGE((conn))]
832 : :
833 : : #define CCS_STATE(conn) (((conn)->mode == S2N_CLIENT) ? \
834 : : ACTIVE_STATE_MACHINE(conn)[SERVER_CHANGE_CIPHER_SPEC] : \
835 : : ACTIVE_STATE_MACHINE(conn)[CLIENT_CHANGE_CIPHER_SPEC])
836 : :
837 : 165412 : #define EXPECTED_RECORD_TYPE(conn) ACTIVE_STATE(conn).record_type
838 : 62578 : #define EXPECTED_MESSAGE_TYPE(conn) ACTIVE_STATE(conn).message_type
839 : :
840 : 369281 : #define CONNECTION_WRITER(conn) (conn->mode == S2N_CLIENT ? 'C' : 'S')
841 : 275924 : #define CONNECTION_IS_WRITER(conn) (ACTIVE_STATE(conn).writer == CONNECTION_WRITER(conn))
842 : :
843 : : /* Only used in our test cases. */
844 : : message_type_t s2n_conn_get_current_message_type(const struct s2n_connection *conn)
845 : 832941 : {
846 [ + + ]: 832941 : return ACTIVE_MESSAGE(conn);
847 : 832941 : }
848 : :
849 : : static int s2n_advance_message(struct s2n_connection *conn)
850 : 93357 : {
851 : : /* Get the mode: 'C'lient or 'S'erver */
852 [ + + ][ + + ]: 93357 : char previous_writer = ACTIVE_STATE(conn).writer;
853 [ + + ]: 93357 : char this_mode = CONNECTION_WRITER(conn);
854 : :
855 : : /* Actually advance the message number */
856 : 93357 : conn->handshake.message_number++;
857 : :
858 : : /* When reading and using TLS1.3, skip optional change_cipher_spec states. */
859 [ + + ][ + + ]: 93357 : if (ACTIVE_STATE(conn).writer != this_mode && EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && IS_TLS13_HANDSHAKE(conn)) {
[ + + ][ + + ]
[ + + ][ + + ]
[ + + ]
860 : 7570 : conn->handshake.message_number++;
861 : 7570 : }
862 : :
863 : : /* Set TCP_QUICKACK to avoid artificial delay during the handshake */
864 [ - + ]: 93357 : POSIX_GUARD(s2n_socket_quickack(conn));
865 : :
866 : : /* If optimized io hasn't been enabled or if the caller started out with a corked socket,
867 : : * we don't mess with it
868 : : */
869 [ + + ][ - + ]: 93357 : if (!conn->corked_io || s2n_socket_was_corked(conn)) {
870 : 93017 : return S2N_SUCCESS;
871 : 93017 : }
872 : :
873 : : /* Are we changing I/O directions */
874 [ + + ][ + + ]: 340 : if (ACTIVE_STATE(conn).writer == previous_writer || ACTIVE_STATE(conn).writer == 'A') {
[ + + ][ + + ]
[ + + ][ - + ]
875 : 206 : return S2N_SUCCESS;
876 : 206 : }
877 : :
878 : : /* We're the new writer */
879 [ + + ][ + + ]: 134 : if (ACTIVE_STATE(conn).writer == this_mode) {
[ + + ]
880 [ + - ]: 62 : if (s2n_connection_is_managed_corked(conn)) {
881 : : /* Set TCP_CORK/NOPUSH */
882 [ - + ]: 62 : POSIX_GUARD(s2n_socket_write_cork(conn));
883 : 62 : }
884 : :
885 : 62 : return S2N_SUCCESS;
886 : 62 : }
887 : :
888 : : /* We're the new reader, or we reached the "B" writer stage indicating that
889 : : we're at the application data stage - uncork the data */
890 [ + - ]: 72 : if (s2n_connection_is_managed_corked(conn)) {
891 [ - + ]: 72 : POSIX_GUARD(s2n_socket_write_uncork(conn));
892 : 72 : }
893 : :
894 : 72 : return S2N_SUCCESS;
895 : 72 : }
896 : :
897 : : int s2n_generate_new_client_session_id(struct s2n_connection *conn)
898 : 4662 : {
899 [ + + ]: 4662 : if (conn->mode == S2N_SERVER) {
900 : 2370 : struct s2n_blob session_id = { 0 };
901 [ - + ]: 2370 : POSIX_GUARD(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
902 : :
903 : : /* Generate a new session id */
904 [ - + ]: 2370 : POSIX_GUARD_RESULT(s2n_get_public_random_data(&session_id));
905 : 2370 : conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
906 : 2370 : }
907 : :
908 : 4662 : return S2N_SUCCESS;
909 : 4662 : }
910 : :
911 : : /* Lets the server flag whether a HelloRetryRequest is needed while processing extensions */
912 : : int s2n_set_hello_retry_required(struct s2n_connection *conn)
913 : 1965 : {
914 [ - + ][ # # ]: 1965 : POSIX_ENSURE_REF(conn);
915 : :
916 [ + - ][ + + ]: 1965 : POSIX_ENSURE(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
917 [ - + ]: 1964 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls13_flag(conn, HELLO_RETRY_REQUEST));
918 : :
919 : : /* HelloRetryRequests also indicate rejection of early data.
920 : : *
921 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
922 : : *# A server which receives an "early_data" extension MUST behave in one
923 : : *# of three ways:
924 : : *
925 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
926 : : *# - Request that the client send another ClientHello by responding
927 : : *# with a HelloRetryRequest.
928 : : **/
929 [ + + ]: 1964 : if (conn->early_data_state == S2N_EARLY_DATA_REQUESTED) {
930 [ - + ]: 916 : POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_EARLY_DATA_REJECTED));
931 : 916 : }
932 : :
933 : 1964 : return S2N_SUCCESS;
934 : 1964 : }
935 : :
936 : : bool s2n_is_hello_retry_message(struct s2n_connection *conn)
937 : 42609 : {
938 [ + - ][ + - ]: 42609 : return (conn != NULL && s2n_result_is_ok(s2n_handshake_validate(&(conn->handshake))) && ACTIVE_MESSAGE(conn) == HELLO_RETRY_MSG);
[ + + ][ + + ]
939 : 42609 : }
940 : :
941 : : bool s2n_is_hello_retry_handshake(struct s2n_connection *conn)
942 : 86812 : {
943 : 86812 : return IS_HELLO_RETRY_HANDSHAKE(conn);
944 : 86812 : }
945 : :
946 : : static S2N_RESULT s2n_conn_set_tls13_handshake_type(struct s2n_connection *conn)
947 : 9615 : {
948 [ # # ][ - + ]: 9615 : RESULT_ENSURE_REF(conn);
949 : :
950 : : /* Most handshake type flags should be reset before we calculate the handshake type,
951 : : * in order to handle changes during retries.
952 : : * However, flags that have already affected the message order must be kept to avoid
953 : : * rewriting the past.
954 : : */
955 : 9615 : conn->handshake.handshake_type &= (HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS);
956 : :
957 : : /* A handshake type has been negotiated */
958 [ - + ]: 9615 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, NEGOTIATED));
959 : :
960 [ + + ]: 9615 : if (conn->psk_params.chosen_psk == NULL) {
961 [ - + ]: 7963 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
962 : 7963 : }
963 : :
964 [ + + ]: 9615 : if (conn->early_data_state == S2N_EARLY_DATA_ACCEPTED) {
965 : 46 : conn->handshake.handshake_type |= WITH_EARLY_DATA;
966 : 46 : }
967 : :
968 : 9615 : s2n_cert_auth_type client_cert_auth_type;
969 [ - + ]: 9615 : RESULT_GUARD_POSIX(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
970 : :
971 [ + + ][ + + ]: 9615 : if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED
972 [ + + ]: 9615 : && IS_FULL_HANDSHAKE(conn)) {
973 : : /* If we're a client, and Client Auth is REQUIRED, then the Client must expect the CLIENT_CERT_REQ Message */
974 [ - + ]: 22 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
975 [ + + ][ + + ]: 9593 : } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE
976 [ + + ]: 9593 : && IS_FULL_HANDSHAKE(conn)) {
977 : : /* If we're a server, and Client Auth is REQUIRED or OPTIONAL, then the server must send the CLIENT_CERT_REQ Message*/
978 [ - + ]: 33 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
979 : 33 : }
980 : :
981 [ + + ]: 9615 : if (s2n_is_middlebox_compat_enabled(conn)) {
982 [ - + ]: 9598 : RESULT_GUARD(s2n_handshake_type_set_tls13_flag(conn, MIDDLEBOX_COMPAT));
983 : 9598 : }
984 : :
985 : 9615 : return S2N_RESULT_OK;
986 : 9615 : }
987 : :
988 : : static S2N_RESULT s2n_validate_ems_status(struct s2n_connection *conn)
989 : 13 : {
990 [ - + ][ # # ]: 13 : RESULT_ENSURE_REF(conn);
991 : :
992 : 13 : s2n_extension_type_id ems_ext_id = 0;
993 [ - + ]: 13 : RESULT_GUARD_POSIX(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_EMS, &ems_ext_id));
994 : 13 : bool ems_extension_recv = S2N_CBIT_TEST(conn->extension_requests_received, ems_ext_id);
995 : :
996 : : /**
997 : : *= https://www.rfc-editor.org/rfc/rfc7627#section-5.3
998 : : *# If the original session used the "extended_master_secret"
999 : : *# extension but the new ClientHello does not contain it, the server
1000 : : *# MUST abort the abbreviated handshake.
1001 : : **/
1002 [ + + ]: 13 : if (conn->ems_negotiated) {
1003 [ + + ][ + - ]: 11 : RESULT_ENSURE(ems_extension_recv, S2N_ERR_MISSING_EXTENSION);
1004 : 11 : }
1005 : :
1006 : : /* Since we're discarding the resumption ticket, ignore EMS value from the ticket */
1007 : 11 : conn->ems_negotiated = ems_extension_recv;
1008 : :
1009 : 11 : return S2N_RESULT_OK;
1010 : 13 : }
1011 : :
1012 : : int s2n_conn_set_handshake_type(struct s2n_connection *conn)
1013 : 14500 : {
1014 [ # # ][ - + ]: 14500 : POSIX_ENSURE_REF(conn);
1015 [ # # ][ - + ]: 14500 : POSIX_ENSURE_REF(conn->secure);
1016 : :
1017 [ - + ]: 14500 : POSIX_GUARD_RESULT(s2n_conn_choose_state_machine(conn, conn->actual_protocol_version));
1018 : :
1019 [ + + ]: 14500 : if (IS_TLS13_HANDSHAKE(conn)) {
1020 [ - + ]: 9782 : POSIX_GUARD_RESULT(s2n_conn_set_tls13_handshake_type(conn));
1021 : 9782 : return S2N_SUCCESS;
1022 : 9782 : }
1023 : :
1024 [ - + ]: 4718 : POSIX_GUARD_RESULT(s2n_handshake_type_reset(conn));
1025 : :
1026 : : /* A handshake type has been negotiated */
1027 [ - + ]: 4718 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, NEGOTIATED));
1028 : :
1029 : 4718 : s2n_cert_auth_type client_cert_auth_type;
1030 [ - + ]: 4718 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1031 : :
1032 [ + + ][ + + ]: 4718 : if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED) {
1033 : : /* If we're a client, and Client Auth is REQUIRED, then the Client must expect the CLIENT_CERT_REQ Message */
1034 [ - + ]: 54 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
1035 [ + + ][ + + ]: 4664 : } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE) {
1036 : : /* If we're a server, and Client Auth is REQUIRED or OPTIONAL, then the server must send the CLIENT_CERT_REQ Message*/
1037 [ - + ]: 107 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
1038 : 107 : }
1039 : :
1040 [ + + ]: 4718 : if (conn->npn_negotiated) {
1041 [ - + ]: 4 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_NPN));
1042 : 4 : }
1043 : :
1044 [ + + ]: 4718 : if (conn->config->use_tickets) {
1045 [ + + ]: 122 : if (conn->session_ticket_status == S2N_DECRYPT_TICKET) {
1046 : : /* We reuse the session if a valid TLS12 ticket is provided.
1047 : : * Otherwise, we will perform a full handshake and then generate
1048 : : * a new session ticket. */
1049 [ + + ]: 29 : if (s2n_result_is_ok(s2n_resume_decrypt_session(conn, &conn->client_ticket_to_decrypt))) {
1050 : 23 : return S2N_SUCCESS;
1051 : 23 : }
1052 : :
1053 [ + + ]: 6 : POSIX_GUARD_RESULT(s2n_validate_ems_status(conn));
1054 : :
1055 : : /* Set up the handshake to send a session ticket since a valid ticket was not provided */
1056 [ + + ]: 5 : if (s2n_result_is_ok(s2n_config_is_encrypt_key_available(conn->config))) {
1057 : 3 : conn->session_ticket_status = S2N_NEW_TICKET;
1058 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
1059 : 3 : }
1060 : :
1061 : : /* If a session ticket is presented by the client, then skip lookup in Session ID server cache */
1062 : 5 : goto skip_cache_lookup;
1063 : 5 : }
1064 : :
1065 [ + + ]: 93 : if (conn->session_ticket_status == S2N_NEW_TICKET) {
1066 [ - + ]: 35 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
1067 : 35 : }
1068 : 93 : }
1069 : :
1070 : : /* If a TLS session is resumed, the Server should respond in its ServerHello with the same SessionId the
1071 : : * Client sent in the ClientHello. */
1072 [ + - ][ + + ]: 4689 : if (conn->actual_protocol_version <= S2N_TLS12 && conn->mode == S2N_SERVER && s2n_allowed_to_cache_connection(conn)) {
[ + + ]
1073 : 16 : int r = s2n_resume_from_cache(conn);
1074 [ + + ][ + - ]: 16 : if (r == S2N_SUCCESS || (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno))) {
[ + + ]
1075 : 9 : return r;
1076 : 9 : }
1077 [ + + ]: 7 : POSIX_GUARD_RESULT(s2n_validate_ems_status(conn));
1078 : 7 : }
1079 : :
1080 : 4684 : skip_cache_lookup:
1081 [ + + ][ + + ]: 4684 : if (conn->mode == S2N_CLIENT && conn->client_session_resumed == 1) {
1082 : 22 : return S2N_SUCCESS;
1083 : 22 : }
1084 : :
1085 : : /* If we're doing full handshake, generate a new session id. */
1086 [ - + ]: 4662 : POSIX_GUARD(s2n_generate_new_client_session_id(conn));
1087 : :
1088 : : /* If we get this far, it's a full handshake */
1089 [ - + ]: 4662 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
1090 : :
1091 : 4662 : bool is_ephemeral = false;
1092 [ - + ]: 4662 : POSIX_GUARD_RESULT(s2n_kex_is_ephemeral(conn->secure->cipher_suite->key_exchange_alg, &is_ephemeral));
1093 [ + + ]: 4662 : if (is_ephemeral) {
1094 [ - + ]: 1655 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, TLS12_PERFECT_FORWARD_SECRECY));
1095 : 1655 : }
1096 : :
1097 [ + - ][ + + ]: 4662 : if (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn)) {
[ + + ][ + + ]
[ + + ][ + + ]
1098 [ - + ]: 5 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, OCSP_STATUS));
1099 : 5 : }
1100 : :
1101 : 4662 : return S2N_SUCCESS;
1102 : 4662 : }
1103 : :
1104 : : int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn)
1105 : 69 : {
1106 : 69 : s2n_cert_auth_type client_cert_auth_type;
1107 [ - + ]: 69 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1108 [ + - ][ + + ]: 69 : POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_MISSING_CLIENT_CERT);
1109 : :
1110 [ - + ]: 60 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, NO_CLIENT_CERT));
1111 : :
1112 : 60 : return S2N_SUCCESS;
1113 : 60 : }
1114 : :
1115 : : S2N_RESULT s2n_conn_choose_state_machine(struct s2n_connection *conn, uint8_t protocol_version)
1116 : 31056 : {
1117 [ # # ][ - + ]: 31056 : RESULT_ENSURE_REF(conn);
1118 : :
1119 : : /* This should never be called before we know what version we're on */
1120 [ # # ][ - + ]: 31056 : RESULT_ENSURE_NE(protocol_version, S2N_UNKNOWN_PROTOCOL_VERSION);
1121 : :
1122 [ + + ]: 31056 : if (protocol_version == S2N_TLS13) {
1123 : : /* State machine should not change once set */
1124 [ - + ][ # # ]: 24585 : RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS12);
1125 : 24585 : conn->handshake.state_machine = S2N_STATE_MACHINE_TLS13;
1126 : 24585 : } else {
1127 : : /* State machine should not change once set */
1128 [ # # ][ - + ]: 6471 : RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS13);
1129 : 6471 : conn->handshake.state_machine = S2N_STATE_MACHINE_TLS12;
1130 : 6471 : }
1131 : :
1132 : 31056 : return S2N_RESULT_OK;
1133 : 31056 : }
1134 : :
1135 : : const char *s2n_connection_get_last_message_name(struct s2n_connection *conn)
1136 : 362 : {
1137 [ - + ][ # # ]: 362 : PTR_ENSURE_REF(conn);
1138 [ - + ]: 362 : PTR_GUARD_RESULT(s2n_handshake_validate(&(conn->handshake)));
1139 [ + + ]: 362 : return message_names[ACTIVE_MESSAGE(conn)];
1140 : 362 : }
1141 : :
1142 : : const char *s2n_connection_get_handshake_type_name(struct s2n_connection *conn)
1143 : 3861 : {
1144 [ # # ][ - + ]: 3861 : PTR_ENSURE_REF(conn);
1145 [ - + ][ + - ]: 3861 : PTR_PRECONDITION(s2n_handshake_validate(&(conn->handshake)));
1146 : :
1147 : 3861 : uint32_t handshake_type = conn->handshake.handshake_type;
1148 : :
1149 [ + + ]: 3861 : if (handshake_type == INITIAL) {
1150 : 88 : return "INITIAL";
1151 : 88 : }
1152 : :
1153 : 3773 : const char **handshake_type_names = tls13_handshake_type_names;
1154 : 3773 : size_t handshake_type_names_len = s2n_array_len(tls13_handshake_type_names);
1155 [ + + ]: 3773 : if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
1156 : 2810 : handshake_type_names = tls12_handshake_type_names;
1157 : 2810 : handshake_type_names_len = s2n_array_len(tls12_handshake_type_names);
1158 : 2810 : }
1159 : :
1160 : : /* Not all handshake strings will be created already. If the handshake string
1161 : : * is not null, we can just return the handshake. Otherwise we have to compute
1162 : : * it down below. */
1163 [ + + ]: 3773 : if (handshake_type_str[handshake_type][0] != '\0') {
1164 : 3690 : return handshake_type_str[handshake_type];
1165 : 3690 : }
1166 : :
1167 : : /* Compute handshake_type_str[handshake_type] by concatenating
1168 : : * each applicable handshake_type.
1169 : : *
1170 : : * Unit tests enforce that the elements of handshake_type_str are always
1171 : : * long enough to contain the longest possible valid handshake_type, but
1172 : : * for safety we still handle the case where we need to truncate.
1173 : : */
1174 : 83 : char *p = handshake_type_str[handshake_type];
1175 : 83 : size_t remaining = sizeof(handshake_type_str[0]);
1176 [ + + ]: 747 : for (size_t i = 0; i < handshake_type_names_len; i++) {
1177 [ + + ]: 664 : if (handshake_type & (1 << i)) {
1178 : 366 : size_t bytes_to_copy = MIN(remaining, strlen(handshake_type_names[i]));
1179 [ # # ][ - + ]: 366 : PTR_CHECKED_MEMCPY(p, handshake_type_names[i], bytes_to_copy);
[ + - ]
1180 : 366 : p[bytes_to_copy] = '\0';
1181 : 366 : p += bytes_to_copy;
1182 : 366 : remaining -= bytes_to_copy;
1183 : 366 : }
1184 : 664 : }
1185 : :
1186 [ + - ][ + - ]: 83 : if (p != handshake_type_str[handshake_type] && '|' == *(p - 1)) {
1187 : 83 : *(p - 1) = '\0';
1188 : 83 : }
1189 : :
1190 : 83 : return handshake_type_str[handshake_type];
1191 : 83 : }
1192 : :
1193 : : S2N_RESULT s2n_handshake_message_send(struct s2n_connection *conn, uint8_t content_type, s2n_blocked_status *blocked)
1194 : 112998 : {
1195 [ - + ][ # # ]: 112998 : RESULT_ENSURE_REF(conn);
1196 : 112998 : struct s2n_stuffer *in = &conn->handshake.io;
1197 : :
1198 : 112998 : uint32_t size = s2n_stuffer_data_available(in);
1199 [ + + ]: 112998 : if (size == 0) {
1200 : 49597 : return S2N_RESULT_OK;
1201 : 49597 : }
1202 : :
1203 [ + + ]: 63401 : if (s2n_connection_is_quic_enabled(conn)) {
1204 [ - + ]: 50 : RESULT_GUARD(s2n_quic_write_handshake_message(conn));
1205 [ + + ]: 50 : RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
1206 : 49 : return S2N_RESULT_OK;
1207 : 50 : }
1208 : :
1209 : 63351 : struct iovec iov = { 0 };
1210 : 63351 : iov.iov_len = size;
1211 : 63351 : iov.iov_base = s2n_stuffer_raw_read(in, size);
1212 [ - + ][ # # ]: 63351 : RESULT_ENSURE_REF(iov.iov_base);
1213 [ - + ]: 63351 : RESULT_GUARD_POSIX(s2n_stuffer_rewind_read(in, size));
1214 : :
1215 : 63351 : uint32_t total_bytes_written = 0;
1216 [ + + ]: 117575 : while (total_bytes_written < size) {
1217 : 64976 : int bytes_written = s2n_record_writev(conn, content_type, &iov, 1,
1218 : 64976 : total_bytes_written, size - total_bytes_written);
1219 [ - + ]: 64976 : RESULT_GUARD_POSIX(bytes_written);
1220 : 64976 : total_bytes_written += bytes_written;
1221 [ - + ]: 64976 : RESULT_GUARD_POSIX(s2n_stuffer_skip_read(in, bytes_written));
1222 [ + + ]: 64976 : RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
1223 : 64976 : }
1224 : 52599 : return S2N_RESULT_OK;
1225 : 63351 : }
1226 : :
1227 : : /* Writing is relatively straight forward, simply write each message out as a record,
1228 : : * we may fragment a message across multiple records, but we never coalesce multiple
1229 : : * messages into single records.
1230 : : * Precondition: secure outbound I/O has already been flushed
1231 : : */
1232 : : static int s2n_handshake_write_io(struct s2n_connection *conn)
1233 : 61683 : {
1234 [ + + ][ + + ]: 61683 : uint8_t record_type = EXPECTED_RECORD_TYPE(conn);
1235 : 61683 : s2n_blocked_status blocked = S2N_NOT_BLOCKED;
1236 : :
1237 : : /* Populate handshake.io with header/payload for the current state, once.
1238 : : * Check wiped instead of s2n_stuffer_data_available to differentiate between the initial call
1239 : : * to s2n_handshake_write_io and a repeated call after an EWOULDBLOCK.
1240 : : */
1241 [ + + ]: 61683 : if (s2n_stuffer_is_wiped(&conn->handshake.io)) {
1242 [ + + ]: 51905 : if (record_type == TLS_HANDSHAKE) {
1243 [ - + ][ + + ]: 41547 : POSIX_GUARD(s2n_handshake_write_header(&conn->handshake.io, ACTIVE_STATE(conn).message_type));
[ + + ]
1244 : 41547 : }
1245 [ + + ][ + + ]: 51905 : POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn));
[ + + ]
1246 [ + + ]: 51795 : if (record_type == TLS_HANDSHAKE) {
1247 [ - + ]: 41437 : POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
1248 : 41437 : }
1249 : 51795 : }
1250 : :
1251 [ + + ]: 61573 : POSIX_GUARD_RESULT(s2n_handshake_message_send(conn, record_type, &blocked));
1252 [ + + ]: 51856 : if (record_type == TLS_HANDSHAKE) {
1253 [ - + ]: 41498 : POSIX_GUARD_RESULT(s2n_handshake_transcript_update(conn));
1254 : 41498 : }
1255 : :
1256 : : /* We're done sending the last record, reset everything */
1257 [ - + ]: 51856 : POSIX_GUARD(s2n_stuffer_wipe(&conn->out));
1258 [ - + ]: 51856 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1259 : :
1260 : : /* Update the secrets, if necessary */
1261 [ - + ]: 51856 : POSIX_GUARD_RESULT(s2n_tls13_secrets_update(conn));
1262 [ - + ]: 51856 : POSIX_GUARD_RESULT(s2n_tls13_key_schedule_update(conn));
1263 : :
1264 : : /* Advance the state machine */
1265 [ - + ]: 51856 : POSIX_GUARD(s2n_advance_message(conn));
1266 : :
1267 : 51856 : return S2N_SUCCESS;
1268 : 51856 : }
1269 : :
1270 : : /*
1271 : : * Returns:
1272 : : * 1 - more data is needed to complete the handshake message.
1273 : : * 0 - we read the whole handshake message.
1274 : : * -1 - error processing the handshake message.
1275 : : */
1276 : : static int s2n_read_full_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
1277 : 48166 : {
1278 : 48166 : uint32_t current_handshake_data = s2n_stuffer_data_available(&conn->handshake.io);
1279 [ + + ]: 48166 : if (current_handshake_data < TLS_HANDSHAKE_HEADER_LENGTH) {
1280 : : /* The message may be so badly fragmented that we don't even read the full header, take
1281 : : * what we can and then continue to the next record read iteration.
1282 : : */
1283 [ + + ]: 38177 : if (s2n_stuffer_data_available(&conn->in) < (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)) {
1284 [ - + ]: 116 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1285 : 116 : return 1;
1286 : 116 : }
1287 : :
1288 : : /* Get the remainder of the header */
1289 [ - + ]: 38061 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)));
1290 : 38061 : }
1291 : :
1292 : 48050 : uint32_t handshake_message_length = 0;
1293 [ - + ]: 48050 : POSIX_GUARD_RESULT(s2n_handshake_parse_header(&conn->handshake.io, message_type, &handshake_message_length));
1294 : :
1295 [ + + ][ + - ]: 48050 : S2N_ERROR_IF(handshake_message_length > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
1296 : :
1297 : 48049 : uint32_t bytes_to_take = handshake_message_length - s2n_stuffer_data_available(&conn->handshake.io);
1298 : 48049 : bytes_to_take = MIN(bytes_to_take, s2n_stuffer_data_available(&conn->in));
1299 : :
1300 : : /* If the record is handshake data, add it to the handshake buffer */
1301 [ - + ]: 48049 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, bytes_to_take));
1302 : :
1303 : : /* If we have the whole handshake message, then success */
1304 [ + + ]: 48049 : if (s2n_stuffer_data_available(&conn->handshake.io) == handshake_message_length) {
1305 : 38098 : return 0;
1306 : 38098 : }
1307 : :
1308 : : /* We don't have the whole message, so we'll need to go again */
1309 [ - + ]: 9951 : POSIX_GUARD(s2n_stuffer_reread(&conn->handshake.io));
1310 : :
1311 : 9951 : return 1;
1312 : 9951 : }
1313 : :
1314 : : static int s2n_handshake_handle_sslv2(struct s2n_connection *conn)
1315 : 3 : {
1316 [ - + ][ - + ]: 3 : S2N_ERROR_IF(ACTIVE_MESSAGE(conn) != CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
[ # # ]
1317 : :
1318 : : /* Add the message to our handshake hashes */
1319 : 3 : struct s2n_blob hashed = { 0 };
1320 [ - + ]: 3 : POSIX_GUARD(s2n_blob_init(&hashed, conn->header_in.blob.data + 2, 3));
1321 [ - + ]: 3 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
1322 : :
1323 : 3 : hashed.data = conn->in.blob.data;
1324 : 3 : hashed.size = s2n_stuffer_data_available(&conn->in);
1325 [ - + ]: 3 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
1326 : :
1327 : : /* Handle an SSLv2 client hello */
1328 [ - + ]: 3 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1329 : 3 : conn->client_hello.sslv2 = true;
1330 : : /* Execute the state machine handler */
1331 [ - + ][ - + ]: 3 : int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
1332 [ - + ]: 3 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1333 : :
1334 : : /* We're done with the record, wipe it */
1335 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1336 : :
1337 [ - + ][ + - ]: 3 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
1338 : :
1339 : : /* Advance the state machine */
1340 [ - + ]: 3 : POSIX_GUARD(s2n_advance_message(conn));
1341 : :
1342 : 3 : return S2N_SUCCESS;
1343 : 3 : }
1344 : :
1345 : : static int s2n_try_delete_session_cache(struct s2n_connection *conn)
1346 : 2527 : {
1347 [ - + ][ # # ]: 2527 : POSIX_ENSURE_REF(conn);
1348 : :
1349 [ + + ]: 2527 : if (s2n_allowed_to_cache_connection(conn) > 0) {
1350 : 2 : conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
1351 : 2 : }
1352 : :
1353 : 2527 : return S2N_SUCCESS;
1354 : 2527 : }
1355 : :
1356 : : static S2N_RESULT s2n_finish_read(struct s2n_connection *conn)
1357 : 37978 : {
1358 [ # # ][ - + ]: 37978 : RESULT_ENSURE_REF(conn);
1359 : :
1360 [ - + ]: 37978 : RESULT_GUARD(s2n_handshake_transcript_update(conn));
1361 [ - + ]: 37978 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->handshake.io));
1362 [ - + ]: 37978 : RESULT_GUARD(s2n_tls13_secrets_update(conn));
1363 [ - + ]: 37978 : RESULT_GUARD(s2n_tls13_key_schedule_update(conn));
1364 [ - + ]: 37978 : RESULT_GUARD_POSIX(s2n_advance_message(conn));
1365 : 37978 : return S2N_RESULT_OK;
1366 : 37978 : }
1367 : :
1368 : : static S2N_RESULT s2n_handshake_app_data_recv(struct s2n_connection *conn)
1369 : 89 : {
1370 [ + + ]: 89 : if (conn->early_data_expected) {
1371 [ - + ]: 63 : RESULT_GUARD(s2n_early_data_validate_recv(conn));
1372 [ + - ]: 63 : RESULT_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
1373 : 63 : }
1374 : :
1375 [ + + ]: 26 : if (conn->handshake.renegotiation) {
1376 [ - + ]: 25 : RESULT_GUARD(s2n_renegotiate_validate(conn));
1377 : : /* During renegotiation, Application Data may only be received until
1378 : : * the server acknowledges the new handshake with a ServerHello.
1379 : : */
1380 [ + + ][ + - ]: 25 : RESULT_ENSURE(ACTIVE_MESSAGE(conn) == SERVER_HELLO, S2N_ERR_BAD_MESSAGE);
[ - + ]
1381 [ + - ]: 20 : RESULT_BAIL(S2N_ERR_APP_DATA_BLOCKED);
1382 : 20 : }
1383 : :
1384 [ + - ]: 1 : RESULT_BAIL(S2N_ERR_BAD_MESSAGE);
1385 : 1 : }
1386 : :
1387 : : /* Reading is a little more complicated than writing as the TLS RFCs allow content
1388 : : * types to be interleaved at the record layer. We may get an alert message
1389 : : * during the handshake phase, or messages of types that we don't support (e.g.
1390 : : * HEARTBEAT messages), or during renegotiations we may even get application
1391 : : * data messages that need to be handled by the application.
1392 : : */
1393 : : static int s2n_handshake_read_io(struct s2n_connection *conn)
1394 : 208981 : {
1395 : 208981 : uint8_t record_type = 0;
1396 : 208981 : uint8_t message_type = 0;
1397 : 208981 : int isSSLv2 = 0;
1398 : :
1399 : : /* Fill conn->in stuffer necessary for the handshake.
1400 : : * If using TCP, read a record. If using QUIC, read a message. */
1401 [ + + ]: 208981 : if (s2n_connection_is_quic_enabled(conn)) {
1402 : 62 : record_type = TLS_HANDSHAKE;
1403 [ + + ]: 62 : POSIX_GUARD_RESULT(s2n_quic_read_handshake_message(conn, &message_type));
1404 : 208919 : } else {
1405 : 208919 : int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
1406 : :
1407 : : /**
1408 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
1409 : : *# If the client attempts a 0-RTT handshake but the server
1410 : : *# rejects it, the server will generally not have the 0-RTT record
1411 : : *# protection keys and must instead use trial decryption (either with
1412 : : *# the 1-RTT handshake keys or by looking for a cleartext ClientHello in
1413 : : *# the case of a HelloRetryRequest) to find the first non-0-RTT message.
1414 : : *#
1415 : : *# If the server chooses to accept the "early_data" extension, then it
1416 : : *# MUST comply with the same error-handling requirements specified for
1417 : : *# all records when processing early data records. Specifically, if the
1418 : : *# server fails to decrypt a 0-RTT record following an accepted
1419 : : *# "early_data" extension, it MUST terminate the connection with a
1420 : : *# "bad_record_mac" alert as per Section 5.2.
1421 : : */
1422 [ + + ][ + + ]: 208919 : if ((r < S2N_SUCCESS) && (s2n_errno == S2N_ERR_EARLY_DATA_TRIAL_DECRYPT)) {
1423 [ - + ]: 505 : POSIX_GUARD(s2n_stuffer_reread(&conn->in));
1424 [ + + ]: 505 : POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, s2n_stuffer_data_available(&conn->in)));
1425 [ - + ]: 504 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1426 : 504 : return S2N_SUCCESS;
1427 : 504 : }
1428 [ + + ]: 208414 : POSIX_GUARD(r);
1429 : 208414 : }
1430 : :
1431 [ + + ]: 60073 : if (isSSLv2) {
1432 [ - + ][ # # ]: 3 : S2N_ERROR_IF(record_type != SSLv2_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
1433 [ - + ]: 3 : POSIX_GUARD(s2n_handshake_handle_sslv2(conn));
1434 : 3 : }
1435 : :
1436 : : /* Now we have a record, but it could be a partial fragment of a message, or it might
1437 : : * contain several messages.
1438 : : */
1439 : :
1440 [ + + ]: 60073 : if (record_type == TLS_APPLICATION_DATA) {
1441 [ + - ]: 89 : POSIX_GUARD_RESULT(s2n_handshake_app_data_recv(conn));
1442 [ + + ]: 59984 : } else if (record_type == TLS_CHANGE_CIPHER_SPEC) {
1443 : : /* TLS1.3 can receive unexpected CCS messages at any point in the handshake
1444 : : * due to a peer operating in middlebox compatibility mode.
1445 : : * However, when operating in QUIC mode, S2N should not accept ANY CCS messages,
1446 : : * including these unexpected ones.*/
1447 [ + + ][ - + ]: 10305 : if (!IS_TLS13_HANDSHAKE(conn) || s2n_connection_is_quic_enabled(conn)) {
1448 [ - + ][ # # ]: 3520 : POSIX_ENSURE(EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC, S2N_ERR_BAD_MESSAGE);
[ - + ][ - + ]
1449 [ - + ][ # # ]: 3520 : POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
[ - + ][ - + ]
[ + + ]
1450 : 3520 : }
1451 : :
1452 [ - + ][ # # ]: 10305 : S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) != 1, S2N_ERR_BAD_MESSAGE);
1453 : :
1454 [ - + ]: 10305 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1455 [ - + ][ + + ]: 10305 : POSIX_GUARD(CCS_STATE(conn).handler[conn->mode](conn));
[ + + ][ + + ]
1456 [ - + ]: 10305 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1457 : :
1458 : : /* We're done with the record, wipe it */
1459 [ - + ]: 10305 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1460 : :
1461 : : /* Advance the state machine if this was an expected message */
1462 [ + + ][ - + ]: 10305 : if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
[ - + ][ + + ]
[ + - ]
1463 [ - + ]: 3520 : POSIX_GUARD(s2n_advance_message(conn));
1464 : 3520 : }
1465 : :
1466 : 10305 : return S2N_SUCCESS;
1467 [ + + ]: 49679 : } else if (record_type != TLS_HANDSHAKE) {
1468 [ + + ]: 1517 : if (record_type == TLS_ALERT) {
1469 [ + + ]: 1511 : POSIX_GUARD(s2n_process_alert_fragment(conn));
1470 : 1511 : }
1471 : :
1472 : : /* Ignore record types that we don't support */
1473 : :
1474 : : /* We're done with the record, wipe it */
1475 [ - + ]: 11 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1476 : 11 : return S2N_SUCCESS;
1477 : 11 : }
1478 : :
1479 : : /* Record is a handshake message */
1480 [ - + ][ # # ]: 48162 : S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
1481 : :
1482 [ + + ]: 86080 : while (s2n_stuffer_data_available(&conn->in)) {
1483 : : /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */
1484 [ + + ][ - + ]: 48166 : S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
[ + + ][ # # ]
1485 : 48166 : int r = 0;
1486 [ + + ]: 48166 : POSIX_GUARD((r = s2n_read_full_handshake_message(conn, &message_type)));
1487 : :
1488 : : /* Do we need more data? This happens for message fragmentation */
1489 [ + + ]: 48165 : if (r == 1) {
1490 : : /* Break out of this inner loop, but since we're not changing the state, the
1491 : : * outer loop in s2n_handshake_io() will read another record.
1492 : : */
1493 [ - + ]: 10067 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1494 : 10067 : return S2N_SUCCESS;
1495 : 10067 : }
1496 : :
1497 [ + + ]: 38098 : if (conn->mode == S2N_CLIENT) {
1498 : 24499 : s2n_cert_auth_type client_cert_auth_type = { 0 };
1499 [ - + ]: 24499 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1500 : : /* If client auth is optional, we initially assume it will not be requested.
1501 : : * If we received a request, switch to a client auth handshake.
1502 : : */
1503 [ + + ][ + + ]: 24499 : if (client_cert_auth_type != S2N_CERT_AUTH_REQUIRED && message_type == TLS_CERT_REQ) {
1504 [ + + ][ + - ]: 57 : POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_UNEXPECTED_CERT_REQUEST);
1505 [ # # ][ - + ]: 49 : POSIX_ENSURE(IS_FULL_HANDSHAKE(conn), S2N_ERR_HANDSHAKE_STATE);
1506 [ - + ]: 49 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
1507 : 49 : }
1508 : :
1509 : : /* According to rfc6066 section 8, the server may choose not to send a "CertificateStatus"
1510 : : * message even if it has sent a "status_request" extension in the ServerHello message.
1511 : : */
1512 [ + + ][ + + ]: 24491 : if (EXPECTED_MESSAGE_TYPE(conn) == TLS_SERVER_CERT_STATUS
[ + + ]
1513 [ - + ]: 24491 : && message_type != TLS_SERVER_CERT_STATUS) {
1514 [ # # ]: 0 : POSIX_GUARD_RESULT(s2n_handshake_type_unset_tls12_flag(conn, OCSP_STATUS));
1515 : 0 : }
1516 : 24491 : }
1517 : :
1518 : : /*
1519 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4
1520 : : *# The one message that is not bound by these ordering rules
1521 : : *# is the HelloRequest message, which can be sent at any time, but which
1522 : : *# SHOULD be ignored by the client if it arrives in the middle of a handshake.
1523 : : */
1524 [ + + ]: 38090 : if (message_type == TLS_HELLO_REQUEST) {
1525 [ + + ]: 3 : POSIX_GUARD_RESULT(s2n_client_hello_request_validate(conn));
1526 [ - + ]: 2 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1527 : 2 : continue;
1528 : 2 : }
1529 : :
1530 : : /* Check for missing Certificate Requests to surface a more specific error */
1531 [ + + ][ + + ]: 38087 : if (EXPECTED_MESSAGE_TYPE(conn) == TLS_CERT_REQ) {
[ + + ]
1532 [ - + ][ # # ]: 116 : POSIX_ENSURE(message_type == TLS_CERT_REQ,
1533 : 116 : S2N_ERR_MISSING_CERT_REQUEST);
1534 : 116 : }
1535 : :
1536 [ - + ][ # # ]: 38087 : POSIX_ENSURE(record_type == EXPECTED_RECORD_TYPE(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
1537 [ + + ][ + - ]: 38087 : POSIX_ENSURE(message_type == EXPECTED_MESSAGE_TYPE(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
1538 [ - + ][ # # ]: 38084 : POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
[ + + ]
1539 : :
1540 : : /* Call the relevant handler */
1541 [ + + ][ + + ]: 38084 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn)));
[ + + ][ + - ]
1542 : :
1543 : : /* Advance the state machine */
1544 [ - + ]: 37916 : POSIX_GUARD_RESULT(s2n_finish_read(conn));
1545 : 37916 : }
1546 : :
1547 : : /* We're done with the record, wipe it */
1548 [ - + ]: 37914 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1549 : 37914 : return S2N_SUCCESS;
1550 : 37914 : }
1551 : :
1552 : : static int s2n_handle_retry_state(struct s2n_connection *conn)
1553 : 237 : {
1554 : : /* If we were blocked reading or writing a record, then the handler is waiting on
1555 : : * external data. The handler will know how to continue, so we should call the
1556 : : * handler right away. We aren't going to read more handshake data yet or proceed
1557 : : * to the next handler because the current message has not finished processing. */
1558 : 237 : s2n_errno = S2N_ERR_OK;
1559 [ + + ][ + + ]: 237 : const int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
1560 : :
1561 [ + + ][ + + ]: 237 : if (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno)) {
1562 : : /* If the handler is still waiting for data, return control to the caller. */
1563 : 103 : S2N_ERROR_PRESERVE_ERRNO();
1564 : 103 : }
1565 : :
1566 : : /* Resume the handshake */
1567 : 134 : conn->handshake.paused = false;
1568 : :
1569 [ + + ][ + + ]: 134 : if (!CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1570 : : /* We're done parsing the record, reset everything */
1571 [ - + ]: 67 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1572 : 67 : }
1573 : :
1574 [ + + ][ + + ]: 134 : if (CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1575 [ - + ]: 67 : POSIX_GUARD(r);
1576 : :
1577 : : /* If we're the writer and handler just finished, update the record header if
1578 : : * needed and let the s2n_handshake_write_io write the data to the socket */
1579 [ + - ][ + + ]: 67 : if (EXPECTED_RECORD_TYPE(conn) == TLS_HANDSHAKE) {
[ + + ]
1580 [ - + ]: 67 : POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
1581 : 67 : }
1582 : 67 : } else {
1583 [ + + ][ + - ]: 67 : if (r < S2N_SUCCESS && conn->session_id_len) {
1584 : 5 : s2n_try_delete_session_cache(conn);
1585 : 5 : }
1586 [ + + ][ + - ]: 67 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
1587 : :
1588 : : /* The read handler processed the record successfully, we are done with this
1589 : : * record. Advance the state machine. */
1590 [ - + ]: 62 : POSIX_GUARD_RESULT(s2n_finish_read(conn));
1591 : 62 : }
1592 : :
1593 : 129 : return S2N_SUCCESS;
1594 : 134 : }
1595 : :
1596 : : bool s2n_handshake_is_complete(struct s2n_connection *conn)
1597 : 318449 : {
1598 : : /* A deserialized connection implies that the handshake is complete because
1599 : : * connections cannot be serialized before completing the handshake. */
1600 [ + - ][ + + ]: 318449 : return conn && (ACTIVE_STATE(conn).writer == 'B' || conn->deserialized_conn);
[ + + ][ + + ]
[ + + ]
1601 : 318449 : }
1602 : :
1603 : : int s2n_negotiate_impl(struct s2n_connection *conn, s2n_blocked_status *blocked)
1604 : 196687 : {
1605 [ # # ][ - + ]: 196687 : POSIX_ENSURE_REF(conn);
1606 [ + + ][ + - ]: 196687 : POSIX_ENSURE_REF(blocked);
1607 : :
1608 [ + + ][ + + ]: 308609 : while (!s2n_handshake_is_complete(conn) && ACTIVE_MESSAGE(conn) != conn->handshake.end_of_messages) {
[ + + ]
1609 : 293217 : errno = 0;
1610 : 293217 : s2n_errno = S2N_ERR_OK;
1611 : :
1612 : : /* Flush any pending I/O or alert messages */
1613 [ + + ]: 293217 : POSIX_GUARD(s2n_flush(conn, blocked));
1614 : :
1615 [ + + ][ + - ]: 273766 : POSIX_ENSURE(s2n_connection_check_io_status(conn, S2N_IO_FULL_DUPLEX), S2N_ERR_CLOSED);
1616 : :
1617 : : /* If the handshake was paused, retry the current message */
1618 [ + + ]: 272262 : if (conn->handshake.paused) {
1619 : 257 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1620 [ + + ]: 257 : POSIX_GUARD(s2n_handle_retry_state(conn));
1621 : 257 : }
1622 : :
1623 [ + + ][ + + ]: 272136 : if (CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1624 : 62352 : *blocked = S2N_BLOCKED_ON_WRITE;
1625 : 62352 : const int write_result = s2n_handshake_write_io(conn);
1626 : :
1627 [ + + ]: 62352 : if (write_result < S2N_SUCCESS) {
1628 [ + + ]: 9834 : if (!S2N_ERROR_IS_BLOCKING(s2n_errno)) {
1629 : : /* Non-retryable write error. The peer might have sent an alert. Try and read it. */
1630 : 12 : const int write_errno = errno;
1631 : 12 : const int write_s2n_errno = s2n_errno;
1632 : 12 : struct s2n_debug_info write_s2n_debug_info = _s2n_debug_info;
1633 : :
1634 [ + - ][ + + ]: 12 : if (s2n_handshake_read_io(conn) < 0 && s2n_errno == S2N_ERR_ALERT) {
1635 : : /* s2n_handshake_read_io has set s2n_errno */
1636 : 1 : S2N_ERROR_PRESERVE_ERRNO();
1637 : 11 : } else {
1638 : : /* Let the write error take precedence if we didn't read an alert. */
1639 : 11 : errno = write_errno;
1640 : 11 : s2n_errno = write_s2n_errno;
1641 : 11 : _s2n_debug_info = write_s2n_debug_info;
1642 : 11 : S2N_ERROR_PRESERVE_ERRNO();
1643 : 11 : }
1644 : 12 : }
1645 : :
1646 [ + + ]: 9822 : if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
1647 : 70 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1648 : 70 : conn->handshake.paused = true;
1649 [ + + ]: 9752 : } else if (s2n_errno == S2N_ERR_EARLY_DATA_BLOCKED) {
1650 : 40 : *blocked = S2N_BLOCKED_ON_EARLY_DATA;
1651 : 40 : }
1652 : :
1653 : 9822 : S2N_ERROR_PRESERVE_ERRNO();
1654 : 9822 : }
1655 : 209784 : } else {
1656 : 209784 : *blocked = S2N_BLOCKED_ON_READ;
1657 : 209784 : const int read_result = s2n_handshake_read_io(conn);
1658 : :
1659 [ + + ]: 209784 : if (read_result < S2N_SUCCESS) {
1660 : : /* One blocking condition is waiting on the session resumption cache. */
1661 : : /* So we don't want to delete anything if we are blocked. */
1662 [ + + ][ + + ]: 150379 : if (!S2N_ERROR_IS_BLOCKING(s2n_errno) && conn->session_id_len) {
1663 : 2544 : s2n_try_delete_session_cache(conn);
1664 : 2544 : }
1665 : :
1666 [ + + ]: 150379 : if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
1667 : 70 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1668 : 70 : conn->handshake.paused = true;
1669 [ + + ]: 150309 : } else if (s2n_errno == S2N_ERR_EARLY_DATA_BLOCKED) {
1670 : 63 : *blocked = S2N_BLOCKED_ON_EARLY_DATA;
1671 : 63 : }
1672 : :
1673 : 150379 : S2N_ERROR_PRESERVE_ERRNO();
1674 : 150379 : }
1675 : 209784 : }
1676 : :
1677 [ + + ][ + + ]: 111923 : if (ACTIVE_STATE(conn).writer == 'B') {
[ + + ]
1678 : : /* Clean up handshake secrets */
1679 [ - + ]: 7940 : POSIX_GUARD_RESULT(s2n_tls13_secrets_clean(conn));
1680 : :
1681 : : /* Send any pending post-handshake messages */
1682 [ - + ]: 7940 : POSIX_GUARD(s2n_post_handshake_send(conn, blocked));
1683 : :
1684 : : /* If the handshake has just ended, free up memory */
1685 [ - + ]: 7940 : POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
1686 : 7940 : }
1687 : 111923 : }
1688 : :
1689 : 15392 : *blocked = S2N_NOT_BLOCKED;
1690 : :
1691 : 15392 : return S2N_SUCCESS;
1692 : 196686 : }
1693 : :
1694 : : int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
1695 : 196689 : {
1696 [ + - ][ + + ]: 196689 : POSIX_ENSURE_REF(conn);
1697 [ + + ][ + - ]: 196688 : POSIX_ENSURE(!conn->negotiate_in_use, S2N_ERR_REENTRANCY);
1698 : 196687 : conn->negotiate_in_use = true;
1699 : :
1700 : 196687 : int result = s2n_negotiate_impl(conn, blocked);
1701 : :
1702 : : /* finish up sending and receiving */
1703 [ - + ]: 196687 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
1704 [ - + ]: 196687 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_out_buffer(conn));
1705 : :
1706 : 196687 : conn->negotiate_in_use = false;
1707 : 196687 : return result;
1708 : 196687 : }
|