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