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