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 : 3192058 : #define IS_TLS13_HANDSHAKE(conn) ((conn)->handshake.state_machine == S2N_STATE_MACHINE_TLS13)
831 : :
832 : 1000253 : #define ACTIVE_STATE_MACHINE(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_state_machine : state_machine)
833 : 2140562 : #define ACTIVE_HANDSHAKES(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_handshakes : handshakes)
834 : :
835 : 2140562 : #define ACTIVE_MESSAGE(conn) ACTIVE_HANDSHAKES(conn)[(conn)->handshake.handshake_type][(conn)->handshake.message_number]
836 : :
837 : 1000253 : #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 : 180109 : #define EXPECTED_RECORD_TYPE(conn) ACTIVE_STATE(conn).record_type
844 : 68997 : #define EXPECTED_MESSAGE_TYPE(conn) ACTIVE_STATE(conn).message_type
845 : :
846 : 360666 : #define CONNECTION_WRITER(conn) (conn->mode == S2N_CLIENT ? 'C' : 'S')
847 : 258551 : #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 : 812977 : {
852 [ + + ]: 812977 : return ACTIVE_MESSAGE(conn);
853 : 812977 : }
854 : :
855 : : static int s2n_advance_message(struct s2n_connection *conn)
856 : 102115 : {
857 : : /* Get the mode: 'C'lient or 'S'erver */
858 : 102115 : #ifndef _WIN32
859 [ + + ][ + + ]: 102115 : char previous_writer = ACTIVE_STATE(conn).writer;
860 : 102115 : #endif
861 [ + + ]: 102115 : char this_mode = CONNECTION_WRITER(conn);
862 : :
863 : : /* Actually advance the message number */
864 : 102115 : conn->handshake.message_number++;
865 : :
866 : : /* When reading and using TLS1.3, skip optional change_cipher_spec states. */
867 [ + + ][ + + ]: 102115 : if (ACTIVE_STATE(conn).writer != this_mode && EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && IS_TLS13_HANDSHAKE(conn)) {
[ + + ][ + + ]
[ + + ][ + + ]
[ + + ]
868 : 8535 : conn->handshake.message_number++;
869 : 8535 : }
870 : :
871 : 102115 : #ifndef _WIN32
872 : : /* Set TCP_QUICKACK to avoid artificial delay during the handshake */
873 [ - + ]: 102115 : 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 [ + + ][ - + ]: 102115 : if (!conn->corked_io || s2n_socket_was_corked(conn)) {
879 : 101775 : return S2N_SUCCESS;
880 : 101775 : }
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 : 4728 : {
909 [ + + ]: 4728 : if (conn->mode == S2N_SERVER) {
910 : 2413 : struct s2n_blob session_id = { 0 };
911 [ - + ]: 2413 : POSIX_GUARD(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
912 : :
913 : : /* Generate a new session id */
914 [ - + ]: 2413 : POSIX_GUARD_RESULT(s2n_get_public_random_data(&session_id));
915 : 2413 : conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
916 : 2413 : }
917 : :
918 : 4728 : return S2N_SUCCESS;
919 : 4728 : }
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 : 1970 : {
924 [ - + ][ # # ]: 1970 : POSIX_ENSURE_REF(conn);
925 : :
926 [ + - ][ + + ]: 1970 : POSIX_ENSURE(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
927 [ - + ]: 1969 : 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 [ + + ]: 1969 : 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 : 1969 : return S2N_SUCCESS;
944 : 1969 : }
945 : :
946 : : bool s2n_is_hello_retry_message(struct s2n_connection *conn)
947 : 45589 : {
948 [ + - ][ + - ]: 45589 : return (conn != NULL && s2n_result_is_ok(s2n_handshake_validate(&(conn->handshake))) && ACTIVE_MESSAGE(conn) == HELLO_RETRY_MSG);
[ + + ][ + + ]
949 : 45589 : }
950 : :
951 : : bool s2n_is_hello_retry_handshake(struct s2n_connection *conn)
952 : 93263 : {
953 : 93263 : return IS_HELLO_RETRY_HANDSHAKE(conn);
954 : 93263 : }
955 : :
956 : : static S2N_RESULT s2n_conn_set_tls13_handshake_type(struct s2n_connection *conn)
957 : 10581 : {
958 [ # # ][ - + ]: 10581 : 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 : 10581 : conn->handshake.handshake_type &= (HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS);
966 : :
967 : : /* A handshake type has been negotiated */
968 [ - + ]: 10581 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, NEGOTIATED));
969 : :
970 [ + + ]: 10581 : if (conn->psk_params.chosen_psk == NULL) {
971 [ - + ]: 8929 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
972 : 8929 : }
973 : :
974 [ + + ]: 10581 : if (conn->early_data_state == S2N_EARLY_DATA_ACCEPTED) {
975 : 46 : conn->handshake.handshake_type |= WITH_EARLY_DATA;
976 : 46 : }
977 : :
978 : 10581 : s2n_cert_auth_type client_cert_auth_type = 0;
979 [ - + ]: 10581 : RESULT_GUARD_POSIX(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
980 : :
981 [ + + ][ + + ]: 10581 : if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED
982 [ + + ]: 10581 : && 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 [ - + ]: 28 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
985 [ + + ][ + + ]: 10553 : } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE
986 [ + + ]: 10553 : && 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 [ - + ]: 83 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
989 : 83 : }
990 : :
991 [ + + ]: 10581 : if (s2n_is_middlebox_compat_enabled(conn)) {
992 [ - + ]: 10564 : RESULT_GUARD(s2n_handshake_type_set_tls13_flag(conn, MIDDLEBOX_COMPAT));
993 : 10564 : }
994 : :
995 : 10581 : return S2N_RESULT_OK;
996 : 10581 : }
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 : 15507 : {
1024 [ # # ][ - + ]: 15507 : POSIX_ENSURE_REF(conn);
1025 [ # # ][ - + ]: 15507 : POSIX_ENSURE_REF(conn->secure);
1026 : :
1027 [ - + ]: 15507 : POSIX_GUARD_RESULT(s2n_conn_choose_state_machine(conn, conn->actual_protocol_version));
1028 : :
1029 [ + + ]: 15507 : if (IS_TLS13_HANDSHAKE(conn)) {
1030 [ - + ]: 10723 : POSIX_GUARD_RESULT(s2n_conn_set_tls13_handshake_type(conn));
1031 : 10723 : return S2N_SUCCESS;
1032 : 10723 : }
1033 : :
1034 [ - + ]: 4784 : POSIX_GUARD_RESULT(s2n_handshake_type_reset(conn));
1035 : :
1036 : : /* A handshake type has been negotiated */
1037 [ - + ]: 4784 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, NEGOTIATED));
1038 : :
1039 : 4784 : s2n_cert_auth_type client_cert_auth_type = 0;
1040 [ - + ]: 4784 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1041 : :
1042 [ + + ][ + + ]: 4784 : 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 [ + + ][ + + ]: 4723 : } 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 [ + + ]: 4784 : if (conn->npn_negotiated) {
1051 [ - + ]: 4 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_NPN));
1052 : 4 : }
1053 : :
1054 [ + + ]: 4784 : if (conn->config->use_tickets) {
1055 [ + + ]: 126 : 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 [ + + ]: 97 : if (conn->session_ticket_status == S2N_NEW_TICKET) {
1076 [ - + ]: 39 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
1077 : 39 : }
1078 : 97 : }
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 [ + - ][ + + ]: 4755 : 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 : 4750 : skip_cache_lookup:
1091 [ + + ][ + + ]: 4750 : 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 [ - + ]: 4728 : POSIX_GUARD(s2n_generate_new_client_session_id(conn));
1097 : :
1098 : : /* If we get this far, it's a full handshake */
1099 [ - + ]: 4728 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
1100 : :
1101 : 4728 : bool is_ephemeral = false;
1102 [ - + ]: 4728 : POSIX_GUARD_RESULT(s2n_kex_is_ephemeral(conn->secure->cipher_suite->key_exchange_alg, &is_ephemeral));
1103 [ + + ]: 4728 : if (is_ephemeral) {
1104 [ - + ]: 1734 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, TLS12_PERFECT_FORWARD_SECRECY));
1105 : 1734 : }
1106 : :
1107 [ + + ][ + + ]: 4728 : 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 : 4728 : return S2N_SUCCESS;
1112 : 4728 : }
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 = 0;
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 : 33092 : {
1127 [ # # ][ - + ]: 33092 : RESULT_ENSURE_REF(conn);
1128 : :
1129 : : /* This should never be called before we know what version we're on */
1130 [ # # ][ - + ]: 33092 : RESULT_ENSURE_NE(protocol_version, S2N_UNKNOWN_PROTOCOL_VERSION);
1131 : :
1132 [ + + ]: 33092 : if (protocol_version == S2N_TLS13) {
1133 : : /* State machine should not change once set */
1134 [ - + ][ # # ]: 26472 : RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS12);
1135 : 26472 : conn->handshake.state_machine = S2N_STATE_MACHINE_TLS13;
1136 : 26472 : } else {
1137 : : /* State machine should not change once set */
1138 [ # # ][ - + ]: 6620 : RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS13);
1139 : 6620 : conn->handshake.state_machine = S2N_STATE_MACHINE_TLS12;
1140 : 6620 : }
1141 : :
1142 : 33092 : return S2N_RESULT_OK;
1143 : 33092 : }
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 : 120075 : {
1207 [ - + ][ # # ]: 120075 : RESULT_ENSURE_REF(conn);
1208 : 120075 : struct s2n_stuffer *in = &conn->handshake.io;
1209 : :
1210 : 120075 : uint32_t size = s2n_stuffer_data_available(in);
1211 [ + + ]: 120075 : if (size == 0) {
1212 : 51784 : return S2N_RESULT_OK;
1213 : 51784 : }
1214 : :
1215 [ + + ]: 68291 : 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 : 68241 : struct iovec iov = { 0 };
1222 : 68241 : iov.iov_len = size;
1223 : 68241 : iov.iov_base = s2n_stuffer_raw_read(in, size);
1224 [ - + ][ # # ]: 68241 : RESULT_ENSURE_REF(iov.iov_base);
1225 [ - + ]: 68241 : RESULT_GUARD_POSIX(s2n_stuffer_rewind_read(in, size));
1226 : :
1227 : 68241 : uint32_t total_bytes_written = 0;
1228 [ + + ]: 127354 : while (total_bytes_written < size) {
1229 : 69866 : int bytes_written = s2n_record_writev(conn, content_type, &iov, 1,
1230 : 69866 : total_bytes_written, size - total_bytes_written);
1231 [ - + ]: 69866 : RESULT_GUARD_POSIX(bytes_written);
1232 : 69866 : total_bytes_written += bytes_written;
1233 [ - + ]: 69866 : RESULT_GUARD_POSIX(s2n_stuffer_skip_read(in, bytes_written));
1234 [ + + ]: 69866 : RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
1235 : 69866 : }
1236 : 57488 : return S2N_RESULT_OK;
1237 : 68241 : }
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 : 66589 : {
1246 [ + + ][ + + ]: 66589 : uint8_t record_type = EXPECTED_RECORD_TYPE(conn);
1247 : 66589 : 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 [ + + ]: 66589 : if (s2n_stuffer_is_wiped(&conn->handshake.io)) {
1254 [ + + ]: 56809 : if (record_type == TLS_HANDSHAKE) {
1255 [ - + ][ + + ]: 45418 : POSIX_GUARD(s2n_handshake_write_header(&conn->handshake.io, ACTIVE_STATE(conn).message_type));
[ + + ]
1256 : 45418 : }
1257 [ + + ][ + + ]: 56809 : POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn));
[ + + ]
1258 [ - + ][ + + ]: 56699 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1259 : 56699 : conn, message_names[ACTIVE_MESSAGE(conn)], (uint8_t) conn->mode));
1260 [ + + ]: 56699 : if (record_type == TLS_HANDSHAKE) {
1261 [ - + ]: 45308 : POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
1262 : 45308 : }
1263 : 56699 : }
1264 : :
1265 [ + + ]: 66479 : POSIX_GUARD_RESULT(s2n_handshake_message_send(conn, record_type, &blocked));
1266 [ - + ]: 56761 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(conn, "RECORD_WRITE", (uint8_t) conn->mode));
1267 [ + + ]: 56761 : if (record_type == TLS_HANDSHAKE) {
1268 [ - + ]: 45370 : POSIX_GUARD_RESULT(s2n_handshake_transcript_update(conn));
1269 : 45370 : }
1270 : :
1271 : : /* We're done sending the last record, reset everything */
1272 [ - + ]: 56761 : POSIX_GUARD(s2n_stuffer_wipe(&conn->out));
1273 [ - + ]: 56761 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1274 : :
1275 : : /* Update the secrets, if necessary */
1276 [ - + ]: 56761 : POSIX_GUARD_RESULT(s2n_tls13_secrets_update(conn));
1277 [ - + ]: 56761 : POSIX_GUARD_RESULT(s2n_tls13_key_schedule_update(conn));
1278 : :
1279 : : /* Advance the state machine */
1280 [ - + ]: 56761 : POSIX_GUARD(s2n_advance_message(conn));
1281 : :
1282 : 56761 : return S2N_SUCCESS;
1283 : 56761 : }
1284 : :
1285 : : /*
1286 : : * Returns:
1287 : : * 1 - more data is needed to complete the handshake message.
1288 : : * 0 - we read the whole handshake message.
1289 : : * -1 - error processing the handshake message.
1290 : : */
1291 : : static int s2n_read_full_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
1292 : 51934 : {
1293 : 51934 : uint32_t current_handshake_data = s2n_stuffer_data_available(&conn->handshake.io);
1294 [ + + ]: 51934 : if (current_handshake_data < TLS_HANDSHAKE_HEADER_LENGTH) {
1295 : : /* The message may be so badly fragmented that we don't even read the full header, take
1296 : : * what we can and then continue to the next record read iteration.
1297 : : */
1298 [ + + ]: 41963 : if (s2n_stuffer_data_available(&conn->in) < (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)) {
1299 [ - + ]: 116 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1300 : 116 : return 1;
1301 : 116 : }
1302 : :
1303 : : /* Get the remainder of the header */
1304 [ - + ]: 41847 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)));
1305 : 41847 : }
1306 : :
1307 : 51818 : uint32_t handshake_message_length = 0;
1308 [ - + ]: 51818 : POSIX_GUARD_RESULT(s2n_handshake_parse_header(&conn->handshake.io, message_type, &handshake_message_length));
1309 : :
1310 [ + + ][ + - ]: 51818 : S2N_ERROR_IF(handshake_message_length > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
1311 : :
1312 : 51817 : uint32_t bytes_to_take = handshake_message_length - s2n_stuffer_data_available(&conn->handshake.io);
1313 [ + + ]: 51817 : bytes_to_take = S2N_MIN(bytes_to_take, s2n_stuffer_data_available(&conn->in));
1314 : :
1315 : : /* If the record is handshake data, add it to the handshake buffer */
1316 [ - + ]: 51817 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, bytes_to_take));
1317 : :
1318 : : /* If we have the whole handshake message, then success */
1319 [ + + ]: 51817 : if (s2n_stuffer_data_available(&conn->handshake.io) == handshake_message_length) {
1320 : 41888 : return 0;
1321 : 41888 : }
1322 : :
1323 : : /* We don't have the whole message, so we'll need to go again */
1324 [ - + ]: 9929 : POSIX_GUARD(s2n_stuffer_reread(&conn->handshake.io));
1325 : :
1326 : 9929 : return 1;
1327 : 9929 : }
1328 : :
1329 : : static int s2n_handshake_handle_sslv2(struct s2n_connection *conn)
1330 : 3 : {
1331 [ - + ][ - + ]: 3 : S2N_ERROR_IF(ACTIVE_MESSAGE(conn) != CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
[ # # ]
1332 : :
1333 : : /* Add the message to our handshake hashes */
1334 : 3 : struct s2n_blob hashed = { 0 };
1335 [ - + ]: 3 : POSIX_GUARD(s2n_blob_init(&hashed, conn->header_in.blob.data + 2, 3));
1336 [ - + ]: 3 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
1337 : :
1338 : 3 : hashed.data = conn->in.blob.data;
1339 : 3 : hashed.size = s2n_stuffer_data_available(&conn->in);
1340 [ - + ]: 3 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
1341 : :
1342 : : /* Handle an SSLv2 client hello */
1343 [ - + ]: 3 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1344 : 3 : conn->client_hello.sslv2 = true;
1345 : : /* Execute the state machine handler */
1346 [ - + ][ - + ]: 3 : int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
1347 [ - + ]: 3 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1348 : :
1349 : : /* We're done with the record, wipe it */
1350 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1351 : :
1352 [ - + ][ + - ]: 3 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
1353 : :
1354 : : /* Advance the state machine */
1355 [ - + ]: 3 : POSIX_GUARD(s2n_advance_message(conn));
1356 : :
1357 : 3 : return S2N_SUCCESS;
1358 : 3 : }
1359 : :
1360 : : static int s2n_try_delete_session_cache(struct s2n_connection *conn)
1361 : 2521 : {
1362 [ - + ][ # # ]: 2521 : POSIX_ENSURE_REF(conn);
1363 : :
1364 [ + + ]: 2521 : if (s2n_allowed_to_cache_connection(conn) > 0) {
1365 : 1 : conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
1366 : 1 : }
1367 : :
1368 : 2521 : return S2N_SUCCESS;
1369 : 2521 : }
1370 : :
1371 : : static S2N_RESULT s2n_finish_read(struct s2n_connection *conn)
1372 : 41749 : {
1373 [ - + ][ # # ]: 41749 : RESULT_ENSURE_REF(conn);
1374 : :
1375 [ - + ]: 41749 : RESULT_GUARD(s2n_handshake_transcript_update(conn));
1376 [ - + ]: 41749 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->handshake.io));
1377 [ - + ]: 41749 : RESULT_GUARD(s2n_tls13_secrets_update(conn));
1378 [ - + ]: 41749 : RESULT_GUARD(s2n_tls13_key_schedule_update(conn));
1379 [ - + ]: 41749 : RESULT_GUARD_POSIX(s2n_advance_message(conn));
1380 : 41749 : return S2N_RESULT_OK;
1381 : 41749 : }
1382 : :
1383 : : static S2N_RESULT s2n_handshake_app_data_recv(struct s2n_connection *conn)
1384 : 89 : {
1385 [ + + ]: 89 : if (conn->early_data_expected) {
1386 [ - + ]: 63 : RESULT_GUARD(s2n_early_data_validate_recv(conn));
1387 [ + - ]: 63 : RESULT_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
1388 : 63 : }
1389 : :
1390 [ + + ]: 26 : if (conn->handshake.renegotiation) {
1391 [ - + ]: 25 : RESULT_GUARD(s2n_renegotiate_validate(conn));
1392 : : /* During renegotiation, Application Data may only be received until
1393 : : * the server acknowledges the new handshake with a ServerHello.
1394 : : */
1395 [ + - ][ + + ]: 25 : RESULT_ENSURE(ACTIVE_MESSAGE(conn) == SERVER_HELLO, S2N_ERR_BAD_MESSAGE);
[ - + ]
1396 [ + - ]: 20 : RESULT_BAIL(S2N_ERR_APP_DATA_BLOCKED);
1397 : 20 : }
1398 : :
1399 [ + - ]: 1 : RESULT_BAIL(S2N_ERR_BAD_MESSAGE);
1400 : 1 : }
1401 : :
1402 : : static int s2n_handshake_message_process(struct s2n_connection *conn, uint8_t record_type)
1403 : 52001 : {
1404 [ - + ][ # # ]: 52001 : POSIX_ENSURE_REF(conn);
1405 : :
1406 : 52001 : uint8_t message_type = 0;
1407 [ + + ]: 93684 : while (s2n_stuffer_data_available(&conn->in)) {
1408 : : /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */
1409 [ + + ][ + + ]: 51934 : S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
[ - + ][ # # ]
1410 : 51934 : int r = 0;
1411 [ + + ]: 51934 : POSIX_GUARD((r = s2n_read_full_handshake_message(conn, &message_type)));
1412 : :
1413 : : /* Do we need more data? This happens for message fragmentation */
1414 [ + + ]: 51933 : if (r == 1) {
1415 : : /* Break out of this inner loop, but since we're not changing the state, the
1416 : : * outer loop in s2n_handshake_io() will read another record.
1417 : : */
1418 [ - + ]: 10045 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1419 : 10045 : return S2N_SUCCESS;
1420 : 10045 : }
1421 : :
1422 [ + + ]: 41888 : if (conn->mode == S2N_CLIENT) {
1423 : 27128 : s2n_cert_auth_type client_cert_auth_type = { 0 };
1424 [ - + ]: 27128 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1425 : : /* If client auth is optional, we initially assume it will not be requested.
1426 : : * If we received a request, switch to a client auth handshake.
1427 : : */
1428 [ + + ][ + + ]: 27128 : if (client_cert_auth_type != S2N_CERT_AUTH_REQUIRED && message_type == TLS_CERT_REQ) {
1429 [ + - ][ + + ]: 101 : POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_UNEXPECTED_CERT_REQUEST);
1430 [ - + ][ # # ]: 93 : POSIX_ENSURE(IS_FULL_HANDSHAKE(conn), S2N_ERR_HANDSHAKE_STATE);
1431 [ - + ]: 93 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
1432 : 93 : }
1433 : :
1434 : : /* According to rfc6066 section 8, the server may choose not to send a "CertificateStatus"
1435 : : * message even if it has sent a "status_request" extension in the ServerHello message.
1436 : : */
1437 [ + + ][ + + ]: 27120 : if (EXPECTED_MESSAGE_TYPE(conn) == TLS_SERVER_CERT_STATUS
[ + + ]
1438 [ - + ]: 27120 : && message_type != TLS_SERVER_CERT_STATUS) {
1439 [ # # ]: 0 : POSIX_GUARD_RESULT(s2n_handshake_type_unset_tls12_flag(conn, OCSP_STATUS));
1440 : 0 : }
1441 : 27120 : }
1442 : :
1443 : : /*
1444 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4
1445 : : *# The one message that is not bound by these ordering rules
1446 : : *# is the HelloRequest message, which can be sent at any time, but which
1447 : : *# SHOULD be ignored by the client if it arrives in the middle of a handshake.
1448 : : */
1449 [ + + ]: 41880 : if (message_type == TLS_HELLO_REQUEST) {
1450 [ + + ]: 3 : POSIX_GUARD_RESULT(s2n_client_hello_request_validate(conn));
1451 [ - + ]: 2 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1452 : 2 : continue;
1453 : 2 : }
1454 : :
1455 : : /* Check for missing Certificate Requests to surface a more specific error */
1456 [ + + ][ + + ]: 41877 : if (EXPECTED_MESSAGE_TYPE(conn) == TLS_CERT_REQ) {
[ + + ]
1457 [ - + ][ # # ]: 172 : POSIX_ENSURE(message_type == TLS_CERT_REQ,
1458 : 172 : S2N_ERR_MISSING_CERT_REQUEST);
1459 : 172 : }
1460 : :
1461 [ - + ][ # # ]: 41877 : POSIX_ENSURE(record_type == EXPECTED_RECORD_TYPE(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
1462 [ + + ][ + - ]: 41877 : POSIX_ENSURE(message_type == EXPECTED_MESSAGE_TYPE(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
1463 [ - + ][ # # ]: 41874 : POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
[ + + ]
1464 : :
1465 : : /* Call the relevant handler */
1466 [ + + ][ + + ]: 41874 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn)));
[ + + ][ + - ]
1467 [ - + ][ + + ]: 41681 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1468 : 41681 : conn, message_names[ACTIVE_MESSAGE(conn)], (uint8_t) conn->mode));
1469 : :
1470 : : /* Advance the state machine */
1471 [ - + ]: 41681 : POSIX_GUARD_RESULT(s2n_finish_read(conn));
1472 : 41681 : }
1473 : :
1474 : : /* We're done with the record, wipe it */
1475 [ - + ]: 41750 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1476 : :
1477 : 41750 : return S2N_SUCCESS;
1478 : 41750 : }
1479 : :
1480 : : /* Reading is a little more complicated than writing as the TLS RFCs allow content
1481 : : * types to be interleaved at the record layer. We may get an alert message
1482 : : * during the handshake phase, or messages of types that we don't support (e.g.
1483 : : * HEARTBEAT messages), or during renegotiations we may even get application
1484 : : * data messages that need to be handled by the application.
1485 : : */
1486 : : static int s2n_handshake_read_io(struct s2n_connection *conn)
1487 : 186727 : {
1488 : 186727 : uint8_t record_type = 0;
1489 : 186727 : int isSSLv2 = 0;
1490 : :
1491 : : /* Fill conn->in stuffer necessary for the handshake.
1492 : : * If using TCP, read a record. If using QUIC, read a message. */
1493 [ + + ]: 186727 : if (s2n_connection_is_quic_enabled(conn)) {
1494 : 62 : record_type = TLS_HANDSHAKE;
1495 : 62 : uint8_t message_type = 0;
1496 [ + + ]: 62 : POSIX_GUARD_RESULT(s2n_quic_read_handshake_message(conn, &message_type));
1497 : 186665 : } else {
1498 : 186665 : int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
1499 : :
1500 : : /**
1501 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
1502 : : *# If the client attempts a 0-RTT handshake but the server
1503 : : *# rejects it, the server will generally not have the 0-RTT record
1504 : : *# protection keys and must instead use trial decryption (either with
1505 : : *# the 1-RTT handshake keys or by looking for a cleartext ClientHello in
1506 : : *# the case of a HelloRetryRequest) to find the first non-0-RTT message.
1507 : : *#
1508 : : *# If the server chooses to accept the "early_data" extension, then it
1509 : : *# MUST comply with the same error-handling requirements specified for
1510 : : *# all records when processing early data records. Specifically, if the
1511 : : *# server fails to decrypt a 0-RTT record following an accepted
1512 : : *# "early_data" extension, it MUST terminate the connection with a
1513 : : *# "bad_record_mac" alert as per Section 5.2.
1514 : : */
1515 [ + + ][ + + ]: 186665 : if ((r < S2N_SUCCESS) && (s2n_errno == S2N_ERR_EARLY_DATA_TRIAL_DECRYPT)) {
1516 [ - + ]: 505 : POSIX_GUARD(s2n_stuffer_reread(&conn->in));
1517 [ + + ]: 505 : POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, s2n_stuffer_data_available(&conn->in)));
1518 [ - + ]: 504 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1519 : 504 : return S2N_SUCCESS;
1520 : 504 : }
1521 [ + + ]: 186160 : POSIX_GUARD(r);
1522 : 186160 : }
1523 : :
1524 [ - + ]: 64875 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(conn, "RECORD_READ", (uint8_t) conn->mode));
1525 : :
1526 [ + + ]: 64875 : if (isSSLv2) {
1527 [ - + ][ # # ]: 3 : S2N_ERROR_IF(record_type != SSLv2_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
1528 [ - + ]: 3 : POSIX_GUARD(s2n_handshake_handle_sslv2(conn));
1529 : 3 : return S2N_SUCCESS;
1530 : 3 : }
1531 : :
1532 : : /* Now we have a record, but it could be a partial fragment of a message, or it might
1533 : : * contain several messages.
1534 : : */
1535 : :
1536 : 64872 : switch (record_type) {
1537 [ + + ]: 89 : case TLS_APPLICATION_DATA:
1538 [ + - ]: 89 : POSIX_GUARD_RESULT(s2n_handshake_app_data_recv(conn));
1539 : 0 : return S2N_SUCCESS;
1540 [ + + ]: 11338 : case TLS_CHANGE_CIPHER_SPEC:
1541 : : /* TLS1.3 can receive unexpected CCS messages at any point in the handshake
1542 : : * due to a peer operating in middlebox compatibility mode.
1543 : : * However, when operating in QUIC mode, S2N should not accept ANY CCS messages,
1544 : : * including these unexpected ones.*/
1545 [ + + ][ - + ]: 11338 : if (!IS_TLS13_HANDSHAKE(conn) || s2n_connection_is_quic_enabled(conn)) {
1546 [ - + ][ # # ]: 3602 : POSIX_ENSURE(EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC, S2N_ERR_BAD_MESSAGE);
[ - + ][ - + ]
1547 [ # # ][ - + ]: 3602 : POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
[ - + ][ - + ]
[ + + ]
1548 : 3602 : }
1549 : :
1550 [ - + ][ # # ]: 11338 : S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) != 1, S2N_ERR_BAD_MESSAGE);
1551 : :
1552 [ - + ]: 11338 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1553 [ - + ][ + + ]: 11338 : POSIX_GUARD(CCS_STATE(conn).handler[conn->mode](conn));
[ + + ][ + + ]
1554 [ - + ]: 11338 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1555 : :
1556 : : /* We're done with the record, wipe it */
1557 [ - + ]: 11338 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1558 : :
1559 : : /* Advance the state machine if this was an expected message */
1560 [ + + ][ + + ]: 11338 : if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) {
[ - + ][ - + ]
[ + + ][ + + ]
[ + - ]
1561 [ - + ]: 3602 : POSIX_GUARD(s2n_advance_message(conn));
1562 : 3602 : }
1563 : :
1564 : 11338 : return S2N_SUCCESS;
1565 [ + + ]: 1511 : case TLS_ALERT:
1566 [ + + ]: 1511 : POSIX_GUARD(s2n_process_alert_fragment(conn));
1567 [ - + ]: 4 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1568 : 4 : return S2N_SUCCESS;
1569 [ + + ]: 51933 : case TLS_HANDSHAKE:
1570 : : /* Record is a handshake message */
1571 [ - + ][ # # ]: 51933 : S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
1572 [ + + ]: 51933 : POSIX_GUARD(s2n_handshake_message_process(conn, record_type));
1573 : 51727 : return S2N_SUCCESS;
1574 [ + + ]: 1 : default:
1575 : : /*
1576 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5
1577 : : *# Implementations MUST NOT send record types not defined in this
1578 : : *# document unless negotiated by some extension. If a TLS
1579 : : *# implementation receives an unexpected record type, it MUST terminate
1580 : : *# the connection with an "unexpected_message" alert.
1581 : : */
1582 [ + - ]: 1 : POSIX_BAIL(S2N_ERR_BAD_MESSAGE);
1583 : 64872 : }
1584 : :
1585 : 0 : return S2N_SUCCESS;
1586 : 64872 : }
1587 : :
1588 : : static int s2n_handle_retry_state(struct s2n_connection *conn)
1589 : 249 : {
1590 : : /* If we were blocked reading or writing a record, then the handler is waiting on
1591 : : * external data. The handler will know how to continue, so we should call the
1592 : : * handler right away. We aren't going to read more handshake data yet or proceed
1593 : : * to the next handler because the current message has not finished processing. */
1594 : 249 : s2n_errno = S2N_ERR_OK;
1595 [ + + ][ + + ]: 249 : const int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
1596 : :
1597 [ + + ][ + + ]: 249 : if (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno)) {
1598 : : /* If the handler is still waiting for data, return control to the caller. */
1599 : 109 : S2N_ERROR_PRESERVE_ERRNO();
1600 : 109 : }
1601 : :
1602 : : /* Resume the handshake */
1603 : 140 : conn->handshake.paused = false;
1604 : :
1605 [ + + ][ + + ]: 140 : if (CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1606 [ - + ]: 67 : POSIX_GUARD(r);
1607 : :
1608 : : /* If we're the writer and handler just finished, update the record header if
1609 : : * needed and let the s2n_handshake_write_io write the data to the socket */
1610 [ + - ][ + + ]: 67 : if (EXPECTED_RECORD_TYPE(conn) == TLS_HANDSHAKE) {
[ + + ]
1611 [ - + ]: 67 : POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
1612 : 67 : }
1613 : 73 : } else {
1614 [ + + ][ + - ]: 73 : if (r < S2N_SUCCESS && conn->session_id_len) {
1615 : 5 : s2n_try_delete_session_cache(conn);
1616 : 5 : }
1617 [ + + ][ + - ]: 73 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
1618 : :
1619 : : /* The read handler processed the message successfully, we are done with this
1620 : : * message. Advance the state machine. */
1621 [ - + ]: 68 : POSIX_GUARD_RESULT(s2n_finish_read(conn));
1622 : :
1623 : : /* We may need to handle remaining handshake messages in the record */
1624 [ - + ]: 68 : POSIX_GUARD(s2n_handshake_message_process(conn, TLS_HANDSHAKE));
1625 : 68 : }
1626 : :
1627 : 135 : return S2N_SUCCESS;
1628 : 140 : }
1629 : :
1630 : : static S2N_RESULT s2n_set_blocked_error_from_errno(struct s2n_connection *conn, s2n_blocked_status *blocked)
1631 : 133081 : {
1632 [ - + ][ # # ]: 133081 : RESULT_ENSURE_REF(conn);
1633 [ # # ][ - + ]: 133081 : RESULT_ENSURE_REF(blocked);
1634 : :
1635 [ + + ]: 133081 : if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
1636 : 253 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1637 : 253 : conn->handshake.paused = true;
1638 [ + + ]: 132828 : } else if (s2n_errno == S2N_ERR_EARLY_DATA_BLOCKED) {
1639 : 103 : *blocked = S2N_BLOCKED_ON_EARLY_DATA;
1640 : 103 : }
1641 : :
1642 : 133081 : return S2N_RESULT_OK;
1643 : 133081 : }
1644 : :
1645 : : bool s2n_handshake_is_complete(struct s2n_connection *conn)
1646 : 320442 : {
1647 : : /* A deserialized connection implies that the handshake is complete because
1648 : : * connections cannot be serialized before completing the handshake. */
1649 [ + + ][ + + ]: 320442 : return conn && (ACTIVE_STATE(conn).writer == 'B' || conn->deserialized_conn);
[ + + ][ + + ]
[ + + ]
1650 : 320442 : }
1651 : :
1652 : : bool s2n_connection_handshake_complete(struct s2n_connection *conn)
1653 : 17 : {
1654 : 17 : return s2n_handshake_is_complete(conn);
1655 : 17 : }
1656 : :
1657 : : int s2n_negotiate_impl(struct s2n_connection *conn, s2n_blocked_status *blocked)
1658 : 170757 : {
1659 [ # # ][ - + ]: 170757 : POSIX_ENSURE_REF(conn);
1660 [ + + ][ + - ]: 170757 : POSIX_ENSURE_REF(blocked);
1661 : :
1662 [ + + ][ + + ]: 292515 : while (!s2n_handshake_is_complete(conn) && ACTIVE_MESSAGE(conn) != conn->handshake.end_of_messages) {
[ + + ]
1663 : 276043 : errno = 0;
1664 : 276043 : s2n_errno = S2N_ERR_OK;
1665 : :
1666 : : /* Flush any pending I/O or alert messages */
1667 [ + + ]: 276043 : POSIX_GUARD(s2n_flush(conn, blocked));
1668 : :
1669 [ + - ][ + + ]: 256588 : POSIX_ENSURE(s2n_connection_check_io_status(conn, S2N_IO_FULL_DUPLEX), S2N_ERR_CLOSED);
1670 : :
1671 : : /* If the handshake was paused, retry the current message */
1672 [ + + ]: 255084 : if (conn->handshake.paused) {
1673 : 275 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1674 : 275 : const int retry_result = s2n_handle_retry_state(conn);
1675 [ + + ]: 275 : if (retry_result != S2N_SUCCESS) {
1676 [ - + ]: 137 : POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
1677 : 137 : S2N_ERROR_PRESERVE_ERRNO();
1678 : 137 : }
1679 : :
1680 : 138 : continue;
1681 : 275 : }
1682 : :
1683 [ + + ][ + + ]: 254809 : if (CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1684 : 67267 : *blocked = S2N_BLOCKED_ON_WRITE;
1685 : 67267 : const int write_result = s2n_handshake_write_io(conn);
1686 : :
1687 [ + + ]: 67267 : if (write_result < S2N_SUCCESS) {
1688 [ + + ]: 9835 : if (!S2N_ERROR_IS_BLOCKING(s2n_errno)) {
1689 : : /* Non-retryable write error. The peer might have sent an alert. Try and read it. */
1690 : 11 : const int write_errno = errno;
1691 : 11 : const int write_s2n_errno = s2n_errno;
1692 : 11 : struct s2n_debug_info write_s2n_debug_info = _s2n_debug_info;
1693 : :
1694 [ + - ][ + + ]: 11 : if (s2n_handshake_read_io(conn) < 0 && s2n_errno == S2N_ERR_ALERT) {
1695 : : /* s2n_handshake_read_io has set s2n_errno */
1696 : 1 : S2N_ERROR_PRESERVE_ERRNO();
1697 : 10 : } else {
1698 : : /* Let the write error take precedence if we didn't read an alert. */
1699 : 10 : errno = write_errno;
1700 : 10 : s2n_errno = write_s2n_errno;
1701 : 10 : _s2n_debug_info = write_s2n_debug_info;
1702 : 10 : S2N_ERROR_PRESERVE_ERRNO();
1703 : 10 : }
1704 : 11 : }
1705 : :
1706 [ - + ]: 9824 : POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
1707 : :
1708 : 9824 : S2N_ERROR_PRESERVE_ERRNO();
1709 : 9824 : }
1710 : 187542 : } else {
1711 : 187542 : *blocked = S2N_BLOCKED_ON_READ;
1712 : 187542 : const int read_result = s2n_handshake_read_io(conn);
1713 : :
1714 [ + + ]: 187542 : if (read_result < S2N_SUCCESS) {
1715 : : /* One blocking condition is waiting on the session resumption cache. */
1716 : : /* So we don't want to delete anything if we are blocked. */
1717 [ + + ][ + + ]: 123353 : if (!S2N_ERROR_IS_BLOCKING(s2n_errno) && conn->session_id_len) {
1718 : 2538 : s2n_try_delete_session_cache(conn);
1719 : 2538 : }
1720 : :
1721 [ - + ]: 123353 : POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
1722 : :
1723 : 123353 : S2N_ERROR_PRESERVE_ERRNO();
1724 : 123353 : }
1725 : 187542 : }
1726 : 254809 : }
1727 : :
1728 [ + + ][ + + ]: 16472 : if (ACTIVE_STATE(conn).writer == 'B') {
[ + + ]
1729 : : /* Clean up handshake secrets */
1730 [ - + ]: 11134 : POSIX_GUARD_RESULT(s2n_tls13_secrets_clean(conn));
1731 : :
1732 : : /* Send any pending post-handshake messages */
1733 [ - + ]: 11134 : POSIX_GUARD(s2n_post_handshake_send(conn, blocked));
1734 : :
1735 : : /* If the handshake has just ended, free up memory */
1736 [ - + ]: 11134 : POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
1737 : 11134 : }
1738 : :
1739 : 16472 : *blocked = S2N_NOT_BLOCKED;
1740 : :
1741 : 16472 : return S2N_SUCCESS;
1742 : 16472 : }
1743 : :
1744 : : int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
1745 : 170759 : {
1746 [ + - ][ + + ]: 170759 : POSIX_ENSURE_REF(conn);
1747 [ + - ][ + + ]: 170758 : POSIX_ENSURE(!conn->negotiate_in_use, S2N_ERR_REENTRANCY);
1748 : 170757 : conn->negotiate_in_use = true;
1749 : :
1750 : : /* We use the default monotonic clock so that we can avoid referencing any
1751 : : * item on the config until after the client hello callback is invoked. */
1752 : 170757 : uint64_t negotiate_start = 0;
1753 [ - + ]: 170757 : POSIX_GUARD(s2n_default_monotonic_clock(NULL, &negotiate_start));
1754 [ + + ]: 170757 : if (conn->handshake_event.handshake_start_ns == 0) {
1755 : 14329 : conn->handshake_event.handshake_start_ns = negotiate_start;
1756 [ - + ]: 14329 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1757 : 14329 : conn, "NEGOTIATE_START", (uint8_t) conn->mode));
1758 : 14329 : }
1759 : :
1760 : 170757 : int result = s2n_negotiate_impl(conn, blocked);
1761 : :
1762 : : /* finish up sending and receiving */
1763 [ - + ]: 170757 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
1764 [ - + ]: 170757 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_out_buffer(conn));
1765 : :
1766 : 170757 : uint64_t negotiate_end = 0;
1767 [ - + ]: 170757 : POSIX_GUARD(s2n_default_monotonic_clock(NULL, &negotiate_end));
1768 : 170757 : conn->handshake_event.handshake_time_ns += negotiate_end - negotiate_start;
1769 : :
1770 [ + + ]: 170757 : if (result == S2N_SUCCESS) {
1771 : 16472 : conn->handshake_event.handshake_end_ns = negotiate_end;
1772 [ - + ]: 16472 : POSIX_GUARD_RESULT(s2n_event_handshake_populate(conn, &conn->handshake_event));
1773 [ - + ]: 16472 : POSIX_GUARD_RESULT(s2n_event_handshake_send(conn, &conn->handshake_event));
1774 [ - + ]: 16472 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1775 : 16472 : conn, "NEGOTIATE_END", (uint8_t) conn->mode));
1776 [ + + ][ + + ]: 154285 : } else if (s2n_error_get_type(s2n_errno) != S2N_ERR_T_BLOCKED && conn->config) {
1777 : : /* S2N_ERR_T_BLOCKED is the only retryable error type -- it indicates
1778 : : * the handshake is still in progress but IO would block. All other
1779 : : * error types are terminal failures, so we emit the failure event. */
1780 : 4090 : conn->handshake_event.handshake_end_ns = negotiate_end;
1781 : 4090 : conn->handshake_event.error_code = s2n_errno;
1782 : : /* Save and restore error state because populate calls functions
1783 : : * that may overwrite them (e.g. s2n_connection_get_key_exchange_group). */
1784 : 4090 : int saved_errno = s2n_errno;
1785 : 4090 : struct s2n_debug_info saved_debug_info = _s2n_debug_info;
1786 [ - + ]: 4090 : POSIX_GUARD_RESULT(s2n_event_handshake_populate(conn, &conn->handshake_event));
1787 [ - + ]: 4090 : POSIX_GUARD_RESULT(s2n_event_handshake_send(conn, &conn->handshake_event));
1788 : 4090 : s2n_errno = saved_errno;
1789 : 4090 : _s2n_debug_info = saved_debug_info;
1790 : 4090 : }
1791 : :
1792 : 170757 : conn->negotiate_in_use = false;
1793 : 170757 : return result;
1794 : 170757 : }
|