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 : 3429614 : #define IS_TLS13_HANDSHAKE(conn) ((conn)->handshake.state_machine == S2N_STATE_MACHINE_TLS13)
831 : :
832 : 1049020 : #define ACTIVE_STATE_MACHINE(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_state_machine : state_machine)
833 : 2329255 : #define ACTIVE_HANDSHAKES(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_handshakes : handshakes)
834 : :
835 : 2329255 : #define ACTIVE_MESSAGE(conn) ACTIVE_HANDSHAKES(conn)[(conn)->handshake.handshake_type][(conn)->handshake.message_number]
836 : :
837 : 1049020 : #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 : 180461 : #define EXPECTED_RECORD_TYPE(conn) ACTIVE_STATE(conn).record_type
844 : 69153 : #define EXPECTED_MESSAGE_TYPE(conn) ACTIVE_STATE(conn).message_type
845 : :
846 : 375001 : #define CONNECTION_WRITER(conn) (conn->mode == S2N_CLIENT ? 'C' : 'S')
847 : 272677 : #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 : 938698 : {
852 [ + + ]: 938698 : return ACTIVE_MESSAGE(conn);
853 : 938698 : }
854 : :
855 : : static int s2n_advance_message(struct s2n_connection *conn)
856 : 102324 : {
857 : : /* Get the mode: 'C'lient or 'S'erver */
858 : 102324 : #ifndef _WIN32
859 [ + + ][ + + ]: 102324 : char previous_writer = ACTIVE_STATE(conn).writer;
860 : 102324 : #endif
861 [ + + ]: 102324 : char this_mode = CONNECTION_WRITER(conn);
862 : :
863 : : /* Actually advance the message number */
864 : 102324 : conn->handshake.message_number++;
865 : :
866 : : /* When reading and using TLS1.3, skip optional change_cipher_spec states. */
867 [ + + ][ + + ]: 102324 : if (ACTIVE_STATE(conn).writer != this_mode && EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && IS_TLS13_HANDSHAKE(conn)) {
[ + + ][ + + ]
[ + + ][ + + ]
[ + + ]
868 : 8559 : conn->handshake.message_number++;
869 : 8559 : }
870 : :
871 : 102324 : #ifndef _WIN32
872 : : /* Set TCP_QUICKACK to avoid artificial delay during the handshake */
873 [ - + ]: 102324 : 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 [ + + ][ - + ]: 102324 : if (!conn->corked_io || s2n_socket_was_corked(conn)) {
879 : 101984 : return S2N_SUCCESS;
880 : 101984 : }
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 : 1969 : {
924 [ # # ][ - + ]: 1969 : POSIX_ENSURE_REF(conn);
925 : :
926 [ + - ][ + + ]: 1969 : POSIX_ENSURE(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
927 [ - + ]: 1968 : 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 [ + + ]: 1968 : 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 : 1968 : return S2N_SUCCESS;
944 : 1968 : }
945 : :
946 : : bool s2n_is_hello_retry_message(struct s2n_connection *conn)
947 : 45661 : {
948 [ + - ][ + - ]: 45661 : return (conn != NULL && s2n_result_is_ok(s2n_handshake_validate(&(conn->handshake))) && ACTIVE_MESSAGE(conn) == HELLO_RETRY_MSG);
[ + + ][ + + ]
949 : 45661 : }
950 : :
951 : : bool s2n_is_hello_retry_handshake(struct s2n_connection *conn)
952 : 93420 : {
953 : 93420 : return IS_HELLO_RETRY_HANDSHAKE(conn);
954 : 93420 : }
955 : :
956 : : static S2N_RESULT s2n_conn_set_tls13_handshake_type(struct s2n_connection *conn)
957 : 10605 : {
958 [ # # ][ - + ]: 10605 : 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 : 10605 : conn->handshake.handshake_type &= (HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS);
966 : :
967 : : /* A handshake type has been negotiated */
968 [ - + ]: 10605 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, NEGOTIATED));
969 : :
970 [ + + ]: 10605 : if (conn->psk_params.chosen_psk == NULL) {
971 [ - + ]: 8953 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
972 : 8953 : }
973 : :
974 [ + + ]: 10605 : if (conn->early_data_state == S2N_EARLY_DATA_ACCEPTED) {
975 : 46 : conn->handshake.handshake_type |= WITH_EARLY_DATA;
976 : 46 : }
977 : :
978 : 10605 : s2n_cert_auth_type client_cert_auth_type = 0;
979 [ - + ]: 10605 : RESULT_GUARD_POSIX(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
980 : :
981 [ + + ][ + + ]: 10605 : if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED
982 [ + + ]: 10605 : && 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 [ - + ]: 29 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
985 [ + + ][ + + ]: 10576 : } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE
986 [ + + ]: 10576 : && 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 [ - + ]: 86 : RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
989 : 86 : }
990 : :
991 [ + + ]: 10605 : if (s2n_is_middlebox_compat_enabled(conn)) {
992 [ - + ]: 10588 : RESULT_GUARD(s2n_handshake_type_set_tls13_flag(conn, MIDDLEBOX_COMPAT));
993 : 10588 : }
994 : :
995 : 10605 : return S2N_RESULT_OK;
996 : 10605 : }
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 : 15531 : {
1024 [ # # ][ - + ]: 15531 : POSIX_ENSURE_REF(conn);
1025 [ # # ][ - + ]: 15531 : POSIX_ENSURE_REF(conn->secure);
1026 : :
1027 [ - + ]: 15531 : POSIX_GUARD_RESULT(s2n_conn_choose_state_machine(conn, conn->actual_protocol_version));
1028 : :
1029 [ + + ]: 15531 : if (IS_TLS13_HANDSHAKE(conn)) {
1030 [ - + ]: 10747 : POSIX_GUARD_RESULT(s2n_conn_set_tls13_handshake_type(conn));
1031 : 10747 : return S2N_SUCCESS;
1032 : 10747 : }
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 : : /* Ensure that we have not been able to resume without setting the master secret */
1061 : 23 : uint8_t zero_block[S2N_TLS_SECRET_LEN] = { 0 };
1062 [ - + ][ # # ]: 23 : POSIX_ENSURE(!s2n_constant_time_equals(conn->secrets.version.tls12.master_secret,
1063 : 23 : zero_block, S2N_TLS_SECRET_LEN),
1064 : 23 : S2N_ERR_KEY_CHECK);
1065 : 23 : return S2N_SUCCESS;
1066 : 23 : }
1067 : :
1068 [ + + ]: 6 : POSIX_GUARD_RESULT(s2n_validate_ems_status(conn));
1069 : :
1070 : : /* Set up the handshake to send a session ticket since a valid ticket was not provided */
1071 [ + + ]: 5 : if (s2n_result_is_ok(s2n_config_is_encrypt_key_available(conn->config))) {
1072 : 3 : conn->session_ticket_status = S2N_NEW_TICKET;
1073 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
1074 : 3 : }
1075 : :
1076 : : /* If a session ticket is presented by the client, then skip lookup in Session ID server cache */
1077 : 5 : goto skip_cache_lookup;
1078 : 5 : }
1079 : :
1080 [ + + ]: 97 : if (conn->session_ticket_status == S2N_NEW_TICKET) {
1081 [ - + ]: 39 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
1082 : 39 : }
1083 : 97 : }
1084 : :
1085 : : /* If a TLS session is resumed, the Server should respond in its ServerHello with the same SessionId the
1086 : : * Client sent in the ClientHello. */
1087 [ + - ][ + + ]: 4755 : if (conn->actual_protocol_version <= S2N_TLS12 && conn->mode == S2N_SERVER && s2n_allowed_to_cache_connection(conn)) {
[ + + ]
1088 : 16 : int r = s2n_resume_from_cache(conn);
1089 [ + + ][ + - ]: 16 : if (r == S2N_SUCCESS || (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno))) {
[ + + ]
1090 : 9 : return r;
1091 : 9 : }
1092 [ + + ]: 7 : POSIX_GUARD_RESULT(s2n_validate_ems_status(conn));
1093 : 7 : }
1094 : :
1095 : 4750 : skip_cache_lookup:
1096 [ + + ][ + + ]: 4750 : if (conn->mode == S2N_CLIENT && conn->client_session_resumed == 1) {
1097 : 22 : return S2N_SUCCESS;
1098 : 22 : }
1099 : :
1100 : : /* If we're doing full handshake, generate a new session id. */
1101 [ - + ]: 4728 : POSIX_GUARD(s2n_generate_new_client_session_id(conn));
1102 : :
1103 : : /* If we get this far, it's a full handshake */
1104 [ - + ]: 4728 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
1105 : :
1106 : 4728 : bool is_ephemeral = false;
1107 [ - + ]: 4728 : POSIX_GUARD_RESULT(s2n_kex_is_ephemeral(conn->secure->cipher_suite->key_exchange_alg, &is_ephemeral));
1108 [ + + ]: 4728 : if (is_ephemeral) {
1109 [ - + ]: 1734 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, TLS12_PERFECT_FORWARD_SECRECY));
1110 : 1734 : }
1111 : :
1112 [ + + ][ + + ]: 4728 : if (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn)) {
[ + - ][ + + ]
[ + + ][ + + ]
1113 [ - + ]: 5 : POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, OCSP_STATUS));
1114 : 5 : }
1115 : :
1116 : 4728 : return S2N_SUCCESS;
1117 : 4728 : }
1118 : :
1119 : : int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn)
1120 : 69 : {
1121 : 69 : s2n_cert_auth_type client_cert_auth_type = 0;
1122 [ - + ]: 69 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1123 [ + + ][ + - ]: 69 : POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_MISSING_CLIENT_CERT);
1124 : :
1125 [ - + ]: 60 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, NO_CLIENT_CERT));
1126 : :
1127 : 60 : return S2N_SUCCESS;
1128 : 60 : }
1129 : :
1130 : : S2N_RESULT s2n_conn_choose_state_machine(struct s2n_connection *conn, uint8_t protocol_version)
1131 : 33139 : {
1132 [ # # ][ - + ]: 33139 : RESULT_ENSURE_REF(conn);
1133 : :
1134 : : /* This should never be called before we know what version we're on */
1135 [ # # ][ - + ]: 33139 : RESULT_ENSURE_NE(protocol_version, S2N_UNKNOWN_PROTOCOL_VERSION);
1136 : :
1137 [ + + ]: 33139 : if (protocol_version == S2N_TLS13) {
1138 : : /* State machine should not change once set */
1139 [ # # ][ - + ]: 26519 : RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS12);
1140 : 26519 : conn->handshake.state_machine = S2N_STATE_MACHINE_TLS13;
1141 : 26519 : } else {
1142 : : /* State machine should not change once set */
1143 [ # # ][ - + ]: 6620 : RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS13);
1144 : 6620 : conn->handshake.state_machine = S2N_STATE_MACHINE_TLS12;
1145 : 6620 : }
1146 : :
1147 : 33139 : return S2N_RESULT_OK;
1148 : 33139 : }
1149 : :
1150 : : const char *s2n_connection_get_last_message_name(struct s2n_connection *conn)
1151 : 362 : {
1152 [ # # ][ - + ]: 362 : PTR_ENSURE_REF(conn);
1153 [ - + ]: 362 : PTR_GUARD_RESULT(s2n_handshake_validate(&(conn->handshake)));
1154 [ + + ]: 362 : return message_names[ACTIVE_MESSAGE(conn)];
1155 : 362 : }
1156 : :
1157 : : const char *s2n_connection_get_handshake_type_name(struct s2n_connection *conn)
1158 : 3863 : {
1159 [ - + ][ # # ]: 3863 : PTR_ENSURE_REF(conn);
1160 [ - + ][ + - ]: 3863 : PTR_PRECONDITION(s2n_handshake_validate(&(conn->handshake)));
1161 : :
1162 : 3863 : uint32_t handshake_type = conn->handshake.handshake_type;
1163 : :
1164 [ + + ]: 3863 : if (handshake_type == INITIAL) {
1165 : 88 : return "INITIAL";
1166 : 88 : }
1167 : :
1168 : 3775 : const char **handshake_labels = tls13_handshake_type_names;
1169 : 3775 : size_t handshake_labels_len = s2n_array_len(tls13_handshake_type_names);
1170 : 3775 : char(*names)[MAX_HANDSHAKE_TYPE_LEN] = handshake_type_str_tls13;
1171 [ + + ]: 3775 : if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
1172 : 2811 : handshake_labels = tls12_handshake_type_names;
1173 : 2811 : handshake_labels_len = s2n_array_len(tls12_handshake_type_names);
1174 : 2811 : names = handshake_type_str_tls12ish;
1175 : 2811 : }
1176 : :
1177 : : /* Not all handshake strings will be created already. If the handshake string
1178 : : * is not null, we can just return the handshake. Otherwise we have to compute
1179 : : * it down below. */
1180 [ + + ]: 3775 : if (names[handshake_type][0] != '\0') {
1181 : 3690 : return names[handshake_type];
1182 : 3690 : }
1183 : :
1184 : : /* Compute the cached string by concatenating each applicable handshake_type.
1185 : : *
1186 : : * Unit tests enforce that the elements of the cache are always
1187 : : * long enough to contain the longest possible valid handshake_type, but
1188 : : * for safety we still handle the case where we need to truncate.
1189 : : */
1190 : 85 : char *p = names[handshake_type];
1191 : 85 : size_t remaining = MAX_HANDSHAKE_TYPE_LEN;
1192 [ + + ]: 765 : for (size_t i = 0; i < handshake_labels_len; i++) {
1193 : 680 : bool label_applies = handshake_type & (1 << i);
1194 [ + + ]: 680 : if (label_applies) {
1195 [ - + ]: 372 : size_t bytes_to_copy = S2N_MIN(remaining, strlen(handshake_labels[i]));
1196 [ # # ][ - + ]: 372 : PTR_CHECKED_MEMCPY(p, handshake_labels[i], bytes_to_copy);
[ + - ]
1197 : 372 : p[bytes_to_copy] = '\0';
1198 : 372 : p += bytes_to_copy;
1199 : 372 : remaining -= bytes_to_copy;
1200 : 372 : }
1201 : 680 : }
1202 : :
1203 [ + - ][ + - ]: 85 : if (p != names[handshake_type] && '|' == *(p - 1)) {
1204 : 85 : *(p - 1) = '\0';
1205 : 85 : }
1206 : :
1207 : 85 : return names[handshake_type];
1208 : 85 : }
1209 : :
1210 : : S2N_RESULT s2n_handshake_message_send(struct s2n_connection *conn, uint8_t content_type, s2n_blocked_status *blocked)
1211 : 120150 : {
1212 [ - + ][ # # ]: 120150 : RESULT_ENSURE_REF(conn);
1213 : 120150 : struct s2n_stuffer *in = &conn->handshake.io;
1214 : :
1215 : 120150 : uint32_t size = s2n_stuffer_data_available(in);
1216 [ + + ]: 120150 : if (size == 0) {
1217 : 51738 : return S2N_RESULT_OK;
1218 : 51738 : }
1219 : :
1220 [ + + ]: 68412 : if (s2n_connection_is_quic_enabled(conn)) {
1221 [ - + ]: 50 : RESULT_GUARD(s2n_quic_write_handshake_message(conn));
1222 [ + + ]: 50 : RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
1223 : 49 : return S2N_RESULT_OK;
1224 : 50 : }
1225 : :
1226 : 68362 : struct iovec iov = { 0 };
1227 : 68362 : iov.iov_len = size;
1228 : 68362 : iov.iov_base = s2n_stuffer_raw_read(in, size);
1229 [ - + ][ # # ]: 68362 : RESULT_ENSURE_REF(iov.iov_base);
1230 [ - + ]: 68362 : RESULT_GUARD_POSIX(s2n_stuffer_rewind_read(in, size));
1231 : :
1232 : 68362 : uint32_t total_bytes_written = 0;
1233 [ + + ]: 127594 : while (total_bytes_written < size) {
1234 : 69987 : int bytes_written = s2n_record_writev(conn, content_type, &iov, 1,
1235 : 69987 : total_bytes_written, size - total_bytes_written);
1236 [ - + ]: 69987 : RESULT_GUARD_POSIX(bytes_written);
1237 : 69987 : total_bytes_written += bytes_written;
1238 [ - + ]: 69987 : RESULT_GUARD_POSIX(s2n_stuffer_skip_read(in, bytes_written));
1239 [ + + ]: 69987 : RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
1240 : 69987 : }
1241 : 57607 : return S2N_RESULT_OK;
1242 : 68362 : }
1243 : :
1244 : : /* Writing is relatively straight forward, simply write each message out as a record,
1245 : : * we may fragment a message across multiple records, but we never coalesce multiple
1246 : : * messages into single records.
1247 : : * Precondition: secure outbound I/O has already been flushed
1248 : : */
1249 : : static int s2n_handshake_write_io(struct s2n_connection *conn)
1250 : 66708 : {
1251 [ + + ][ + + ]: 66708 : uint8_t record_type = EXPECTED_RECORD_TYPE(conn);
1252 : 66708 : s2n_blocked_status blocked = S2N_NOT_BLOCKED;
1253 : :
1254 : : /* Populate handshake.io with header/payload for the current state, once.
1255 : : * Check wiped instead of s2n_stuffer_data_available to differentiate between the initial call
1256 : : * to s2n_handshake_write_io and a repeated call after an EWOULDBLOCK.
1257 : : */
1258 [ + + ]: 66708 : if (s2n_stuffer_is_wiped(&conn->handshake.io)) {
1259 [ + + ]: 56926 : if (record_type == TLS_HANDSHAKE) {
1260 [ - + ][ + + ]: 45511 : POSIX_GUARD(s2n_handshake_write_header(&conn->handshake.io, ACTIVE_STATE(conn).message_type));
[ + + ]
1261 : 45511 : }
1262 [ + + ][ + + ]: 56926 : POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn));
[ + + ]
1263 [ - + ][ + + ]: 56816 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1264 : 56816 : conn, message_names[ACTIVE_MESSAGE(conn)], (uint8_t) conn->mode));
1265 [ + + ]: 56816 : if (record_type == TLS_HANDSHAKE) {
1266 [ - + ]: 45401 : POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
1267 : 45401 : }
1268 : 56816 : }
1269 : :
1270 [ + + ]: 66598 : POSIX_GUARD_RESULT(s2n_handshake_message_send(conn, record_type, &blocked));
1271 [ - + ]: 56878 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(conn, "RECORD_WRITE", (uint8_t) conn->mode));
1272 [ + + ]: 56878 : if (record_type == TLS_HANDSHAKE) {
1273 [ - + ]: 45463 : POSIX_GUARD_RESULT(s2n_handshake_transcript_update(conn));
1274 : 45463 : }
1275 : :
1276 : : /* We're done sending the last record, reset everything */
1277 [ - + ]: 56878 : POSIX_GUARD(s2n_stuffer_wipe(&conn->out));
1278 [ - + ]: 56878 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1279 : :
1280 : : /* Update the secrets, if necessary */
1281 [ - + ]: 56878 : POSIX_GUARD_RESULT(s2n_tls13_secrets_update(conn));
1282 [ - + ]: 56878 : POSIX_GUARD_RESULT(s2n_tls13_key_schedule_update(conn));
1283 : :
1284 : : /* Advance the state machine */
1285 [ - + ]: 56878 : POSIX_GUARD(s2n_advance_message(conn));
1286 : :
1287 : 56878 : return S2N_SUCCESS;
1288 : 56878 : }
1289 : :
1290 : : /*
1291 : : * Returns:
1292 : : * 1 - more data is needed to complete the handshake message.
1293 : : * 0 - we read the whole handshake message.
1294 : : * -1 - error processing the handshake message.
1295 : : */
1296 : : static int s2n_read_full_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
1297 : 52029 : {
1298 : 52029 : uint32_t current_handshake_data = s2n_stuffer_data_available(&conn->handshake.io);
1299 [ + + ]: 52029 : if (current_handshake_data < TLS_HANDSHAKE_HEADER_LENGTH) {
1300 : : /* The message may be so badly fragmented that we don't even read the full header, take
1301 : : * what we can and then continue to the next record read iteration.
1302 : : */
1303 [ + + ]: 42056 : if (s2n_stuffer_data_available(&conn->in) < (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)) {
1304 [ - + ]: 116 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1305 : 116 : return 1;
1306 : 116 : }
1307 : :
1308 : : /* Get the remainder of the header */
1309 [ - + ]: 41940 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)));
1310 : 41940 : }
1311 : :
1312 : 51913 : uint32_t handshake_message_length = 0;
1313 [ - + ]: 51913 : POSIX_GUARD_RESULT(s2n_handshake_parse_header(&conn->handshake.io, message_type, &handshake_message_length));
1314 : :
1315 [ + + ][ + - ]: 51913 : S2N_ERROR_IF(handshake_message_length > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
1316 : :
1317 : 51912 : uint32_t bytes_to_take = handshake_message_length - s2n_stuffer_data_available(&conn->handshake.io);
1318 [ + + ]: 51912 : bytes_to_take = S2N_MIN(bytes_to_take, s2n_stuffer_data_available(&conn->in));
1319 : :
1320 : : /* If the record is handshake data, add it to the handshake buffer */
1321 [ - + ]: 51912 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, bytes_to_take));
1322 : :
1323 : : /* If we have the whole handshake message, then success */
1324 [ + + ]: 51912 : if (s2n_stuffer_data_available(&conn->handshake.io) == handshake_message_length) {
1325 : 41981 : return 0;
1326 : 41981 : }
1327 : :
1328 : : /* We don't have the whole message, so we'll need to go again */
1329 [ - + ]: 9931 : POSIX_GUARD(s2n_stuffer_reread(&conn->handshake.io));
1330 : :
1331 : 9931 : return 1;
1332 : 9931 : }
1333 : :
1334 : : static int s2n_handshake_handle_sslv2(struct s2n_connection *conn)
1335 : 3 : {
1336 [ - + ][ - + ]: 3 : S2N_ERROR_IF(ACTIVE_MESSAGE(conn) != CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
[ # # ]
1337 : :
1338 : : /* Add the message to our handshake hashes */
1339 : 3 : struct s2n_blob hashed = { 0 };
1340 [ - + ]: 3 : POSIX_GUARD(s2n_blob_init(&hashed, conn->header_in.blob.data + 2, 3));
1341 [ - + ]: 3 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
1342 : :
1343 : 3 : hashed.data = conn->in.blob.data;
1344 : 3 : hashed.size = s2n_stuffer_data_available(&conn->in);
1345 [ - + ]: 3 : POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
1346 : :
1347 : : /* Handle an SSLv2 client hello */
1348 [ - + ]: 3 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1349 : 3 : conn->client_hello.sslv2 = true;
1350 : : /* Execute the state machine handler */
1351 [ - + ][ - + ]: 3 : int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
1352 [ - + ]: 3 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1353 : :
1354 : : /* We're done with the record, wipe it */
1355 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1356 : :
1357 [ - + ][ + - ]: 3 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
1358 : :
1359 : : /* Advance the state machine */
1360 [ - + ]: 3 : POSIX_GUARD(s2n_advance_message(conn));
1361 : :
1362 : 3 : return S2N_SUCCESS;
1363 : 3 : }
1364 : :
1365 : : static int s2n_try_delete_session_cache(struct s2n_connection *conn)
1366 : 2522 : {
1367 [ # # ][ - + ]: 2522 : POSIX_ENSURE_REF(conn);
1368 : :
1369 [ + + ]: 2522 : if (s2n_allowed_to_cache_connection(conn) > 0) {
1370 : 1 : conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
1371 : 1 : }
1372 : :
1373 : 2522 : return S2N_SUCCESS;
1374 : 2522 : }
1375 : :
1376 : : static S2N_RESULT s2n_finish_read(struct s2n_connection *conn)
1377 : 41841 : {
1378 [ - + ][ # # ]: 41841 : RESULT_ENSURE_REF(conn);
1379 : :
1380 [ - + ]: 41841 : RESULT_GUARD(s2n_handshake_transcript_update(conn));
1381 [ - + ]: 41841 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->handshake.io));
1382 [ - + ]: 41841 : RESULT_GUARD(s2n_tls13_secrets_update(conn));
1383 [ - + ]: 41841 : RESULT_GUARD(s2n_tls13_key_schedule_update(conn));
1384 [ - + ]: 41841 : RESULT_GUARD_POSIX(s2n_advance_message(conn));
1385 : 41841 : return S2N_RESULT_OK;
1386 : 41841 : }
1387 : :
1388 : : static S2N_RESULT s2n_handshake_app_data_recv(struct s2n_connection *conn)
1389 : 89 : {
1390 [ + + ]: 89 : if (conn->early_data_expected) {
1391 [ - + ]: 63 : RESULT_GUARD(s2n_early_data_validate_recv(conn));
1392 [ + - ]: 63 : RESULT_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
1393 : 63 : }
1394 : :
1395 [ + + ]: 26 : if (conn->handshake.renegotiation) {
1396 [ - + ]: 25 : RESULT_GUARD(s2n_renegotiate_validate(conn));
1397 : : /* During renegotiation, Application Data may only be received until
1398 : : * the server acknowledges the new handshake with a ServerHello.
1399 : : */
1400 [ + - ][ + + ]: 25 : RESULT_ENSURE(ACTIVE_MESSAGE(conn) == SERVER_HELLO, S2N_ERR_BAD_MESSAGE);
[ - + ]
1401 [ + - ]: 20 : RESULT_BAIL(S2N_ERR_APP_DATA_BLOCKED);
1402 : 20 : }
1403 : :
1404 [ + - ]: 1 : RESULT_BAIL(S2N_ERR_BAD_MESSAGE);
1405 : 1 : }
1406 : :
1407 : : static int s2n_handshake_message_process(struct s2n_connection *conn, uint8_t record_type)
1408 : 52096 : {
1409 [ - + ][ # # ]: 52096 : POSIX_ENSURE_REF(conn);
1410 : :
1411 : 52096 : uint8_t message_type = 0;
1412 [ + + ]: 93871 : while (s2n_stuffer_data_available(&conn->in)) {
1413 : : /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */
1414 [ + + ][ - + ]: 52029 : S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
[ + + ][ # # ]
1415 : 52029 : int r = 0;
1416 [ + + ]: 52029 : POSIX_GUARD((r = s2n_read_full_handshake_message(conn, &message_type)));
1417 : :
1418 : : /* Do we need more data? This happens for message fragmentation */
1419 [ + + ]: 52028 : if (r == 1) {
1420 : : /* Break out of this inner loop, but since we're not changing the state, the
1421 : : * outer loop in s2n_handshake_io() will read another record.
1422 : : */
1423 [ - + ]: 10047 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1424 : 10047 : return S2N_SUCCESS;
1425 : 10047 : }
1426 : :
1427 [ + + ]: 41981 : if (conn->mode == S2N_CLIENT) {
1428 : 27191 : s2n_cert_auth_type client_cert_auth_type = { 0 };
1429 [ - + ]: 27191 : POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
1430 : : /* If client auth is optional, we initially assume it will not be requested.
1431 : : * If we received a request, switch to a client auth handshake.
1432 : : */
1433 [ + + ][ + + ]: 27191 : if (client_cert_auth_type != S2N_CERT_AUTH_REQUIRED && message_type == TLS_CERT_REQ) {
1434 [ + - ][ + + ]: 103 : POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_UNEXPECTED_CERT_REQUEST);
1435 [ - + ][ # # ]: 95 : POSIX_ENSURE(IS_FULL_HANDSHAKE(conn), S2N_ERR_HANDSHAKE_STATE);
1436 [ - + ]: 95 : POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
1437 : 95 : }
1438 : :
1439 : : /* According to rfc6066 section 8, the server may choose not to send a "CertificateStatus"
1440 : : * message even if it has sent a "status_request" extension in the ServerHello message.
1441 : : */
1442 [ + + ][ + + ]: 27183 : if (EXPECTED_MESSAGE_TYPE(conn) == TLS_SERVER_CERT_STATUS
[ + + ]
1443 [ - + ]: 27183 : && message_type != TLS_SERVER_CERT_STATUS) {
1444 [ # # ]: 0 : POSIX_GUARD_RESULT(s2n_handshake_type_unset_tls12_flag(conn, OCSP_STATUS));
1445 : 0 : }
1446 : 27183 : }
1447 : :
1448 : : /*
1449 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4
1450 : : *# The one message that is not bound by these ordering rules
1451 : : *# is the HelloRequest message, which can be sent at any time, but which
1452 : : *# SHOULD be ignored by the client if it arrives in the middle of a handshake.
1453 : : */
1454 [ + + ]: 41973 : if (message_type == TLS_HELLO_REQUEST) {
1455 [ + + ]: 3 : POSIX_GUARD_RESULT(s2n_client_hello_request_validate(conn));
1456 [ - + ]: 2 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1457 : 2 : continue;
1458 : 2 : }
1459 : :
1460 : : /* Check for missing Certificate Requests to surface a more specific error */
1461 [ + + ][ + + ]: 41970 : if (EXPECTED_MESSAGE_TYPE(conn) == TLS_CERT_REQ) {
[ + + ]
1462 [ - + ][ # # ]: 175 : POSIX_ENSURE(message_type == TLS_CERT_REQ,
1463 : 175 : S2N_ERR_MISSING_CERT_REQUEST);
1464 : 175 : }
1465 : :
1466 [ - + ][ # # ]: 41970 : POSIX_ENSURE(record_type == EXPECTED_RECORD_TYPE(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
1467 [ + + ][ + - ]: 41970 : POSIX_ENSURE(message_type == EXPECTED_MESSAGE_TYPE(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
1468 [ - + ][ # # ]: 41967 : POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
[ + + ][ + + ]
[ + + ]
1469 : :
1470 : : /* Call the relevant handler */
1471 [ + + ][ + + ]: 41967 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn)));
[ + + ][ + - ]
1472 [ - + ][ + + ]: 41773 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1473 : 41773 : conn, message_names[ACTIVE_MESSAGE(conn)], (uint8_t) conn->mode));
1474 : :
1475 : : /* Advance the state machine */
1476 [ - + ]: 41773 : POSIX_GUARD_RESULT(s2n_finish_read(conn));
1477 : 41773 : }
1478 : :
1479 : : /* We're done with the record, wipe it */
1480 [ - + ]: 41842 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1481 : :
1482 : 41842 : return S2N_SUCCESS;
1483 : 41842 : }
1484 : :
1485 : : /* Reading is a little more complicated than writing as the TLS RFCs allow content
1486 : : * types to be interleaved at the record layer. We may get an alert message
1487 : : * during the handshake phase, or messages of types that we don't support (e.g.
1488 : : * HEARTBEAT messages), or during renegotiations we may even get application
1489 : : * data messages that need to be handled by the application.
1490 : : */
1491 : : static int s2n_handshake_read_io(struct s2n_connection *conn)
1492 : 200734 : {
1493 : 200734 : uint8_t record_type = 0;
1494 : 200734 : int isSSLv2 = 0;
1495 : :
1496 : : /* Fill conn->in stuffer necessary for the handshake.
1497 : : * If using TCP, read a record. If using QUIC, read a message. */
1498 [ + + ]: 200734 : if (s2n_connection_is_quic_enabled(conn)) {
1499 : 62 : record_type = TLS_HANDSHAKE;
1500 : 62 : uint8_t message_type = 0;
1501 [ + + ]: 62 : POSIX_GUARD_RESULT(s2n_quic_read_handshake_message(conn, &message_type));
1502 : 200672 : } else {
1503 : 200672 : int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
1504 : :
1505 : : /**
1506 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
1507 : : *# If the client attempts a 0-RTT handshake but the server
1508 : : *# rejects it, the server will generally not have the 0-RTT record
1509 : : *# protection keys and must instead use trial decryption (either with
1510 : : *# the 1-RTT handshake keys or by looking for a cleartext ClientHello in
1511 : : *# the case of a HelloRetryRequest) to find the first non-0-RTT message.
1512 : : *#
1513 : : *# If the server chooses to accept the "early_data" extension, then it
1514 : : *# MUST comply with the same error-handling requirements specified for
1515 : : *# all records when processing early data records. Specifically, if the
1516 : : *# server fails to decrypt a 0-RTT record following an accepted
1517 : : *# "early_data" extension, it MUST terminate the connection with a
1518 : : *# "bad_record_mac" alert as per Section 5.2.
1519 : : */
1520 [ + + ][ + + ]: 200672 : if ((r < S2N_SUCCESS) && (s2n_errno == S2N_ERR_EARLY_DATA_TRIAL_DECRYPT)) {
1521 [ - + ]: 505 : POSIX_GUARD(s2n_stuffer_reread(&conn->in));
1522 [ + + ]: 505 : POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, s2n_stuffer_data_available(&conn->in)));
1523 [ - + ]: 504 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1524 : 504 : return S2N_SUCCESS;
1525 : 504 : }
1526 [ + + ]: 200167 : POSIX_GUARD(r);
1527 : 200167 : }
1528 : :
1529 [ - + ]: 64994 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(conn, "RECORD_READ", (uint8_t) conn->mode));
1530 : :
1531 [ + + ]: 64994 : if (isSSLv2) {
1532 [ - + ][ # # ]: 3 : S2N_ERROR_IF(record_type != SSLv2_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
1533 [ - + ]: 3 : POSIX_GUARD(s2n_handshake_handle_sslv2(conn));
1534 : 3 : return S2N_SUCCESS;
1535 : 3 : }
1536 : :
1537 : : /* Now we have a record, but it could be a partial fragment of a message, or it might
1538 : : * contain several messages.
1539 : : */
1540 : :
1541 : 64991 : switch (record_type) {
1542 [ + + ]: 89 : case TLS_APPLICATION_DATA:
1543 [ + - ]: 89 : POSIX_GUARD_RESULT(s2n_handshake_app_data_recv(conn));
1544 : 0 : return S2N_SUCCESS;
1545 [ + + ]: 11362 : case TLS_CHANGE_CIPHER_SPEC:
1546 : : /* TLS1.3 can receive unexpected CCS messages at any point in the handshake
1547 : : * due to a peer operating in middlebox compatibility mode.
1548 : : * However, when operating in QUIC mode, S2N should not accept ANY CCS messages,
1549 : : * including these unexpected ones.*/
1550 [ + + ][ - + ]: 11362 : if (!IS_TLS13_HANDSHAKE(conn) || s2n_connection_is_quic_enabled(conn)) {
1551 [ - + ][ # # ]: 3602 : POSIX_ENSURE(EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC, S2N_ERR_BAD_MESSAGE);
[ - + ][ - + ]
1552 [ # # ][ - + ]: 3602 : POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
[ - + ][ - + ]
[ + + ]
1553 : 3602 : }
1554 : :
1555 [ - + ][ # # ]: 11362 : S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) != 1, S2N_ERR_BAD_MESSAGE);
1556 : :
1557 [ - + ]: 11362 : POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
1558 [ - + ][ + + ]: 11362 : POSIX_GUARD(CCS_STATE(conn).handler[conn->mode](conn));
[ + + ][ + + ]
1559 [ - + ]: 11362 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
1560 : :
1561 : : /* We're done with the record, wipe it */
1562 [ - + ]: 11362 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1563 : :
1564 : : /* Advance the state machine if this was an expected message */
1565 [ + + ][ + + ]: 11362 : if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) {
[ - + ][ - + ]
[ + + ][ + + ]
[ + - ]
1566 [ - + ]: 3602 : POSIX_GUARD(s2n_advance_message(conn));
1567 : 3602 : }
1568 : :
1569 : 11362 : return S2N_SUCCESS;
1570 [ + + ]: 1511 : case TLS_ALERT:
1571 [ + + ]: 1511 : POSIX_GUARD(s2n_process_alert_fragment(conn));
1572 [ - + ]: 4 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
1573 : 4 : return S2N_SUCCESS;
1574 [ + + ]: 52028 : case TLS_HANDSHAKE:
1575 : : /* Record is a handshake message */
1576 [ - + ][ # # ]: 52028 : S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
1577 [ + + ]: 52028 : POSIX_GUARD(s2n_handshake_message_process(conn, record_type));
1578 : 51821 : return S2N_SUCCESS;
1579 [ + + ]: 1 : default:
1580 : : /*
1581 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5
1582 : : *# Implementations MUST NOT send record types not defined in this
1583 : : *# document unless negotiated by some extension. If a TLS
1584 : : *# implementation receives an unexpected record type, it MUST terminate
1585 : : *# the connection with an "unexpected_message" alert.
1586 : : */
1587 [ + - ]: 1 : POSIX_BAIL(S2N_ERR_BAD_MESSAGE);
1588 : 64991 : }
1589 : :
1590 : 0 : return S2N_SUCCESS;
1591 : 64991 : }
1592 : :
1593 : : static int s2n_handle_retry_state(struct s2n_connection *conn)
1594 : 249 : {
1595 : : /* If we were blocked reading or writing a record, then the handler is waiting on
1596 : : * external data. The handler will know how to continue, so we should call the
1597 : : * handler right away. We aren't going to read more handshake data yet or proceed
1598 : : * to the next handler because the current message has not finished processing. */
1599 : 249 : s2n_errno = S2N_ERR_OK;
1600 [ + + ][ + + ]: 249 : const int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
1601 : :
1602 [ + + ][ + + ]: 249 : if (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno)) {
1603 : : /* If the handler is still waiting for data, return control to the caller. */
1604 : 109 : S2N_ERROR_PRESERVE_ERRNO();
1605 : 109 : }
1606 : :
1607 : : /* Resume the handshake */
1608 : 140 : conn->handshake.paused = false;
1609 : :
1610 [ + + ][ + + ]: 140 : if (CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1611 [ - + ]: 67 : POSIX_GUARD(r);
1612 : :
1613 : : /* If we're the writer and handler just finished, update the record header if
1614 : : * needed and let the s2n_handshake_write_io write the data to the socket */
1615 [ + - ][ + + ]: 67 : if (EXPECTED_RECORD_TYPE(conn) == TLS_HANDSHAKE) {
[ + + ]
1616 [ - + ]: 67 : POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
1617 : 67 : }
1618 : 73 : } else {
1619 [ + + ][ + - ]: 73 : if (r < S2N_SUCCESS && conn->session_id_len) {
1620 : 5 : s2n_try_delete_session_cache(conn);
1621 : 5 : }
1622 [ + + ][ + - ]: 73 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
1623 : :
1624 : : /* The read handler processed the message successfully, we are done with this
1625 : : * message. Advance the state machine. */
1626 [ - + ]: 68 : POSIX_GUARD_RESULT(s2n_finish_read(conn));
1627 : :
1628 : : /* We may need to handle remaining handshake messages in the record */
1629 [ - + ]: 68 : POSIX_GUARD(s2n_handshake_message_process(conn, TLS_HANDSHAKE));
1630 : 68 : }
1631 : :
1632 : 135 : return S2N_SUCCESS;
1633 : 140 : }
1634 : :
1635 : : static S2N_RESULT s2n_set_blocked_error_from_errno(struct s2n_connection *conn, s2n_blocked_status *blocked)
1636 : 146972 : {
1637 [ - + ][ # # ]: 146972 : RESULT_ENSURE_REF(conn);
1638 [ - + ][ # # ]: 146972 : RESULT_ENSURE_REF(blocked);
1639 : :
1640 [ + + ]: 146972 : if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
1641 : 253 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1642 : 253 : conn->handshake.paused = true;
1643 [ + + ]: 146719 : } else if (s2n_errno == S2N_ERR_EARLY_DATA_BLOCKED) {
1644 : 103 : *blocked = S2N_BLOCKED_ON_EARLY_DATA;
1645 : 103 : }
1646 : :
1647 : 146972 : return S2N_RESULT_OK;
1648 : 146972 : }
1649 : :
1650 : : bool s2n_handshake_is_complete(struct s2n_connection *conn)
1651 : 354236 : {
1652 : : /* A deserialized connection implies that the handshake is complete because
1653 : : * connections cannot be serialized before completing the handshake. */
1654 [ + + ][ + + ]: 354236 : return conn && (ACTIVE_STATE(conn).writer == 'B' || conn->deserialized_conn);
[ + + ][ + + ]
[ + + ]
1655 : 354236 : }
1656 : :
1657 : : bool s2n_connection_handshake_complete(struct s2n_connection *conn)
1658 : 17 : {
1659 : 17 : return s2n_handshake_is_complete(conn);
1660 : 17 : }
1661 : :
1662 : : int s2n_negotiate_impl(struct s2n_connection *conn, s2n_blocked_status *blocked)
1663 : 184678 : {
1664 [ # # ][ - + ]: 184678 : POSIX_ENSURE_REF(conn);
1665 [ + + ][ + - ]: 184678 : POSIX_ENSURE_REF(blocked);
1666 : :
1667 [ + + ][ + + ]: 306671 : while (!s2n_handshake_is_complete(conn) && ACTIVE_MESSAGE(conn) != conn->handshake.end_of_messages) {
[ + + ]
1668 : 290173 : errno = 0;
1669 : 290173 : s2n_errno = S2N_ERR_OK;
1670 : :
1671 : : /* Flush any pending I/O or alert messages */
1672 [ + + ]: 290173 : POSIX_GUARD(s2n_flush(conn, blocked));
1673 : :
1674 [ + - ][ + + ]: 270714 : POSIX_ENSURE(s2n_connection_check_io_status(conn, S2N_IO_FULL_DUPLEX), S2N_ERR_CLOSED);
1675 : :
1676 : : /* If the handshake was paused, retry the current message */
1677 [ + + ]: 269210 : if (conn->handshake.paused) {
1678 : 275 : *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
1679 : 275 : const int retry_result = s2n_handle_retry_state(conn);
1680 [ + + ]: 275 : if (retry_result != S2N_SUCCESS) {
1681 [ - + ]: 137 : POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
1682 : 137 : S2N_ERROR_PRESERVE_ERRNO();
1683 : 137 : }
1684 : :
1685 : 138 : continue;
1686 : 275 : }
1687 : :
1688 [ + + ][ + + ]: 268935 : if (CONNECTION_IS_WRITER(conn)) {
[ + + ][ + + ]
1689 : 67386 : *blocked = S2N_BLOCKED_ON_WRITE;
1690 : 67386 : const int write_result = s2n_handshake_write_io(conn);
1691 : :
1692 [ + + ]: 67386 : if (write_result < S2N_SUCCESS) {
1693 [ + + ]: 9837 : if (!S2N_ERROR_IS_BLOCKING(s2n_errno)) {
1694 : : /* Non-retryable write error. The peer might have sent an alert. Try and read it. */
1695 : 11 : const int write_errno = errno;
1696 : 11 : const int write_s2n_errno = s2n_errno;
1697 : 11 : struct s2n_debug_info write_s2n_debug_info = _s2n_debug_info;
1698 : :
1699 [ + - ][ + + ]: 11 : if (s2n_handshake_read_io(conn) < 0 && s2n_errno == S2N_ERR_ALERT) {
1700 : : /* s2n_handshake_read_io has set s2n_errno */
1701 : 1 : S2N_ERROR_PRESERVE_ERRNO();
1702 : 10 : } else {
1703 : : /* Let the write error take precedence if we didn't read an alert. */
1704 : 10 : errno = write_errno;
1705 : 10 : s2n_errno = write_s2n_errno;
1706 : 10 : _s2n_debug_info = write_s2n_debug_info;
1707 : 10 : S2N_ERROR_PRESERVE_ERRNO();
1708 : 10 : }
1709 : 11 : }
1710 : :
1711 [ - + ]: 9826 : POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
1712 : :
1713 : 9826 : S2N_ERROR_PRESERVE_ERRNO();
1714 : 9826 : }
1715 : 201549 : } else {
1716 : 201549 : *blocked = S2N_BLOCKED_ON_READ;
1717 : 201549 : const int read_result = s2n_handshake_read_io(conn);
1718 : :
1719 [ + + ]: 201549 : if (read_result < S2N_SUCCESS) {
1720 : : /* One blocking condition is waiting on the session resumption cache. */
1721 : : /* So we don't want to delete anything if we are blocked. */
1722 [ + + ][ + + ]: 137242 : if (!S2N_ERROR_IS_BLOCKING(s2n_errno) && conn->session_id_len) {
1723 : 2539 : s2n_try_delete_session_cache(conn);
1724 : 2539 : }
1725 : :
1726 [ - + ]: 137242 : POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
1727 : :
1728 : 137242 : S2N_ERROR_PRESERVE_ERRNO();
1729 : 137242 : }
1730 : 201549 : }
1731 : 268935 : }
1732 : :
1733 [ + + ][ + + ]: 16498 : if (ACTIVE_STATE(conn).writer == 'B') {
[ + + ]
1734 : : /* Clean up handshake secrets */
1735 [ - + ]: 11157 : POSIX_GUARD_RESULT(s2n_tls13_secrets_clean(conn));
1736 : :
1737 : : /* Send any pending post-handshake messages */
1738 [ - + ]: 11157 : POSIX_GUARD(s2n_post_handshake_send(conn, blocked));
1739 : :
1740 : : /* If the handshake has just ended, free up memory */
1741 [ - + ]: 11157 : POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
1742 : 11157 : }
1743 : :
1744 : 16498 : *blocked = S2N_NOT_BLOCKED;
1745 : :
1746 : 16498 : return S2N_SUCCESS;
1747 : 16498 : }
1748 : :
1749 : : int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
1750 : 184680 : {
1751 [ + - ][ + + ]: 184680 : POSIX_ENSURE_REF(conn);
1752 [ + - ][ + + ]: 184679 : POSIX_ENSURE(!conn->negotiate_in_use, S2N_ERR_REENTRANCY);
1753 : 184678 : conn->negotiate_in_use = true;
1754 : :
1755 : : /* We use the default monotonic clock so that we can avoid referencing any
1756 : : * item on the config until after the client hello callback is invoked. */
1757 : 184678 : uint64_t negotiate_start = 0;
1758 [ - + ]: 184678 : POSIX_GUARD(s2n_default_monotonic_clock(NULL, &negotiate_start));
1759 [ + + ]: 184678 : if (conn->handshake_event.handshake_start_ns == 0) {
1760 : 14353 : conn->handshake_event.handshake_start_ns = negotiate_start;
1761 [ - + ]: 14353 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1762 : 14353 : conn, "NEGOTIATE_START", (uint8_t) conn->mode));
1763 : 14353 : }
1764 : :
1765 : 184678 : int result = s2n_negotiate_impl(conn, blocked);
1766 : :
1767 : : /* finish up sending and receiving */
1768 [ - + ]: 184678 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
1769 [ - + ]: 184678 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_out_buffer(conn));
1770 : :
1771 : 184678 : uint64_t negotiate_end = 0;
1772 [ - + ]: 184678 : POSIX_GUARD(s2n_default_monotonic_clock(NULL, &negotiate_end));
1773 : 184678 : conn->handshake_event.handshake_time_ns += negotiate_end - negotiate_start;
1774 : :
1775 [ + + ]: 184678 : if (result == S2N_SUCCESS) {
1776 : 16498 : conn->handshake_event.handshake_end_ns = negotiate_end;
1777 [ - + ]: 16498 : POSIX_GUARD_RESULT(s2n_event_handshake_populate(conn, &conn->handshake_event));
1778 [ - + ]: 16498 : POSIX_GUARD_RESULT(s2n_event_handshake_send(conn, &conn->handshake_event));
1779 [ - + ]: 16498 : POSIX_GUARD_RESULT(s2n_event_checkpoint_send(
1780 : 16498 : conn, "NEGOTIATE_END", (uint8_t) conn->mode));
1781 [ + + ][ + + ]: 168180 : } else if (s2n_error_get_type(s2n_errno) != S2N_ERR_T_BLOCKED && conn->config) {
1782 : : /* S2N_ERR_T_BLOCKED is the only retryable error type -- it indicates
1783 : : * the handshake is still in progress but IO would block. All other
1784 : : * error types are terminal failures, so we emit the failure event. */
1785 : 4091 : conn->handshake_event.handshake_end_ns = negotiate_end;
1786 : 4091 : conn->handshake_event.error_code = s2n_errno;
1787 : : /* Save and restore error state because populate calls functions
1788 : : * that may overwrite them (e.g. s2n_connection_get_key_exchange_group). */
1789 : 4091 : int saved_errno = s2n_errno;
1790 : 4091 : struct s2n_debug_info saved_debug_info = _s2n_debug_info;
1791 [ - + ]: 4091 : POSIX_GUARD_RESULT(s2n_event_handshake_populate(conn, &conn->handshake_event));
1792 [ - + ]: 4091 : POSIX_GUARD_RESULT(s2n_event_handshake_send(conn, &conn->handshake_event));
1793 : 4091 : s2n_errno = saved_errno;
1794 : 4091 : _s2n_debug_info = saved_debug_info;
1795 : 4091 : }
1796 : :
1797 : 184678 : conn->negotiate_in_use = false;
1798 : 184678 : return result;
1799 : 184678 : }
|