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