blob: 750e47fa4019eaf07419dd808f12e38ccb20479d [file] [log] [blame]
Steven Valdez143e8b32016-07-11 13:19:03 -04001/* Copyright (c) 2016, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <openssl/ssl.h>
16
17#include <assert.h>
18#include <string.h>
19
David Benjaminabbbee12016-10-31 19:20:42 -040020#include <openssl/aead.h>
Steven Valdez143e8b32016-07-11 13:19:03 -040021#include <openssl/bytestring.h>
22#include <openssl/digest.h>
23#include <openssl/err.h>
24#include <openssl/mem.h>
25#include <openssl/rand.h>
26#include <openssl/stack.h>
27
David Benjamin17cf2cb2016-12-13 01:07:13 -050028#include "../crypto/internal.h"
Steven Valdez143e8b32016-07-11 13:19:03 -040029#include "internal.h"
30
31
Steven Valdez08b65f42016-12-07 15:29:45 -050032/* kMaxEarlyDataAccepted is the advertised number of plaintext bytes of early
33 * data that will be accepted. This value should be slightly below
34 * kMaxEarlyDataSkipped in tls_record.c, which is measured in ciphertext. */
35static const size_t kMaxEarlyDataAccepted = 14336;
36
Steven Valdez143e8b32016-07-11 13:19:03 -040037enum server_hs_state_t {
38 state_process_client_hello = 0,
David Benjamin25fe85b2016-08-09 20:00:32 -040039 state_select_parameters,
Steven Valdez5440fe02016-07-18 12:40:30 -040040 state_send_hello_retry_request,
41 state_flush_hello_retry_request,
42 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040043 state_send_server_hello,
44 state_send_encrypted_extensions,
45 state_send_certificate_request,
46 state_send_server_certificate,
47 state_send_server_certificate_verify,
48 state_complete_server_certificate_verify,
49 state_send_server_finished,
50 state_flush,
Steven Valdez143e8b32016-07-11 13:19:03 -040051 state_process_client_certificate,
52 state_process_client_certificate_verify,
Nick Harper60a85cb2016-09-23 16:25:11 -070053 state_process_channel_id,
Steven Valdez143e8b32016-07-11 13:19:03 -040054 state_process_client_finished,
Steven Valdez1e6f11a2016-07-27 11:10:52 -040055 state_send_new_session_ticket,
David Benjamin0a011fc2016-11-03 17:19:16 -040056 state_flush_new_session_tickets,
Steven Valdez143e8b32016-07-11 13:19:03 -040057 state_done,
58};
59
Steven Valdez5440fe02016-07-18 12:40:30 -040060static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
61
David Benjamin6e4fc332016-11-17 16:43:08 +090062static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, int *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050063 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090064 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -040065 *out_need_retry = 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040066
Steven Valdez803c77a2016-09-06 14:13:43 -040067 /* We only support connections that include an ECDHE key exchange. */
Steven Valdez5440fe02016-07-18 12:40:30 -040068 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050069 if (!ssl_client_hello_get_extension(client_hello, &key_share,
70 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040071 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
72 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090073 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040074 }
75
Steven Valdez5440fe02016-07-18 12:40:30 -040076 int found_key_share;
77 uint8_t *dhe_secret;
78 size_t dhe_secret_len;
David Benjamin7e1f9842016-09-20 19:24:40 -040079 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090080 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
Steven Valdez7259f2f2016-08-02 16:55:05 -040081 &dhe_secret_len, &alert,
82 &key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040083 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
84 return 0;
85 }
86
87 if (!found_key_share) {
88 *out_need_retry = 1;
89 return 0;
90 }
91
David Benjamin6e4fc332016-11-17 16:43:08 +090092 int ok = tls13_advance_key_schedule(hs, dhe_secret, dhe_secret_len);
Steven Valdez5440fe02016-07-18 12:40:30 -040093 OPENSSL_free(dhe_secret);
94 return ok;
95}
96
David Benjaminc3c88822016-11-14 10:32:04 +090097static enum ssl_hs_wait_t do_process_client_hello(SSL_HANDSHAKE *hs) {
98 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -040099 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
100 return ssl_hs_error;
101 }
102
David Benjamin731058e2016-12-03 23:15:13 -0500103 SSL_CLIENT_HELLO client_hello;
104 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
105 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400106 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
107 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
108 return ssl_hs_error;
109 }
110
Steven Valdez143e8b32016-07-11 13:19:03 -0400111 assert(ssl->s3->have_version);
112
113 /* Load the client random. */
David Benjamine14ff062016-08-09 16:21:24 -0400114 if (client_hello.random_len != SSL3_RANDOM_SIZE) {
115 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6929f272016-11-16 19:10:08 +0900116 return ssl_hs_error;
David Benjamine14ff062016-08-09 16:21:24 -0400117 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500118 OPENSSL_memcpy(ssl->s3->client_random, client_hello.random,
119 client_hello.random_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400120
David Benjamin4eb95cc2016-11-16 17:08:23 +0900121 /* TLS 1.3 requires the peer only advertise the null compression. */
122 if (client_hello.compression_methods_len != 1 ||
123 client_hello.compression_methods[0] != 0) {
124 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
125 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
David Benjamin6929f272016-11-16 19:10:08 +0900126 return ssl_hs_error;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400127 }
128
David Benjamin4eb95cc2016-11-16 17:08:23 +0900129 /* TLS extensions. */
David Benjamin8c880a22016-12-03 02:20:34 -0500130 if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900131 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
132 return ssl_hs_error;
133 }
Steven Valdeza833c352016-11-01 13:39:36 -0400134
David Benjamin6f600d62016-12-21 16:06:54 -0500135 /* The short record header extension is incompatible with early data. */
136 if (ssl->s3->skip_early_data && ssl->s3->short_header) {
137 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
138 return ssl_hs_error;
139 }
140
David Benjamin3977f302016-12-11 13:30:41 -0500141 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900142 return ssl_hs_ok;
143}
144
145static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -0500146 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +0900147 if (client_hello->cipher_suites_len % 2 != 0) {
148 return NULL;
149 }
150
151 CBS cipher_suites;
152 CBS_init(&cipher_suites, client_hello->cipher_suites,
153 client_hello->cipher_suites_len);
154
155 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900156 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900157
158 const SSL_CIPHER *best = NULL;
159 while (CBS_len(&cipher_suites) > 0) {
160 uint16_t cipher_suite;
161 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
162 return NULL;
163 }
164
David Benjaminf01f42a2016-11-16 19:05:33 +0900165 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900166 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900167 if (candidate == NULL ||
168 SSL_CIPHER_get_min_version(candidate) > version ||
169 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900170 continue;
171 }
172
173 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
174 * ChaCha20 if we do not have AES hardware. */
175 if (aes_is_fine) {
176 return candidate;
177 }
178
179 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
180 return candidate;
181 }
182
183 if (best == NULL) {
184 best = candidate;
185 }
186 }
187
188 return best;
189}
190
David Benjaminc3c88822016-11-14 10:32:04 +0900191static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
192 SSL *const ssl = hs->ssl;
David Benjamin34202b92016-11-16 19:07:53 +0900193 /* Call |cert_cb| to update server certificates if required. */
194 if (ssl->cert->cert_cb != NULL) {
195 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
196 if (rv == 0) {
197 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
198 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
199 return ssl_hs_error;
200 }
201 if (rv < 0) {
David Benjamin3977f302016-12-11 13:30:41 -0500202 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900203 return ssl_hs_x509_lookup;
204 }
205 }
206
David Benjamin650aa1c2016-12-20 18:55:16 -0500207 if (!ssl_auto_chain_if_needed(ssl)) {
208 return ssl_hs_error;
209 }
210
David Benjamin731058e2016-12-03 23:15:13 -0500211 SSL_CLIENT_HELLO client_hello;
212 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
213 ssl->init_num)) {
David Benjamin34202b92016-11-16 19:07:53 +0900214 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
215 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
216 return ssl_hs_error;
217 }
218
David Benjaminf01f42a2016-11-16 19:05:33 +0900219 /* Negotiate the cipher suite. */
220 ssl->s3->tmp.new_cipher = choose_tls13_cipher(ssl, &client_hello);
221 if (ssl->s3->tmp.new_cipher == NULL) {
222 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
223 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
224 return ssl_hs_error;
225 }
226
227 /* Decode the ticket if we agree on a PSK key exchange mode. */
David Benjamin4eb95cc2016-11-16 17:08:23 +0900228 uint8_t alert = SSL_AD_DECODE_ERROR;
229 SSL_SESSION *session = NULL;
230 CBS pre_shared_key, binders;
231 if (hs->accept_psk_mode &&
David Benjamin731058e2016-12-03 23:15:13 -0500232 ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
233 TLSEXT_TYPE_pre_shared_key)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900234 /* Verify that the pre_shared_key extension is the last extension in
235 * ClientHello. */
236 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
237 client_hello.extensions + client_hello.extensions_len) {
238 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
239 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
240 return ssl_hs_error;
241 }
242
David Benjamin8baf9632016-11-17 17:11:16 +0900243 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &session, &binders,
David Benjamin4eb95cc2016-11-16 17:08:23 +0900244 &alert, &pre_shared_key)) {
245 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
246 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400247 }
248 }
249
Steven Valdez4aa154e2016-07-29 14:32:55 -0400250 if (session != NULL &&
David Benjamin75f99142016-11-12 12:36:06 +0900251 !ssl_session_is_resumable(ssl, session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400252 SSL_SESSION_free(session);
253 session = NULL;
254 }
255
David Benjaminf01f42a2016-11-16 19:05:33 +0900256 /* Set up the new session, either using the original one as a template or
257 * creating a fresh one. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400258 if (session == NULL) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900259 if (!ssl_get_new_session(hs, 1 /* server */)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400260 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
261 return ssl_hs_error;
262 }
David Benjaminf01f42a2016-11-16 19:05:33 +0900263
264 ssl->s3->new_session->cipher = ssl->s3->tmp.new_cipher;
265
266 /* On new sessions, stash the SNI value in the session. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900267 if (hs->hostname != NULL) {
268 ssl->s3->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
David Benjaminf01f42a2016-11-16 19:05:33 +0900269 if (ssl->s3->new_session->tlsext_hostname == NULL) {
270 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
271 return ssl_hs_error;
272 }
273 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400274 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400275 /* Check the PSK binder. */
276 if (!tls13_verify_psk_binder(ssl, session, &binders)) {
277 SSL_SESSION_free(session);
278 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
279 return ssl_hs_error;
280 }
281
Steven Valdez4aa154e2016-07-29 14:32:55 -0400282 /* Only authentication information carries over in TLS 1.3. */
283 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
284 if (ssl->s3->new_session == NULL) {
285 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
286 return ssl_hs_error;
287 }
288 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400289 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400290 }
291
292 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400293 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400294 /* Connection rejected for DOS reasons. */
295 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400296 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400297 return ssl_hs_error;
298 }
299
David Benjaminf01f42a2016-11-16 19:05:33 +0900300 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
301 * deferred. Complete it now. */
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900302 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamin9ef31f02016-10-31 18:01:13 -0400303 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
304 return ssl_hs_error;
305 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400306
David Benjamin8f820b42016-11-30 11:24:40 -0500307 /* The PRF hash is now known. Set up the key schedule. */
Steven Valdez803c77a2016-09-06 14:13:43 -0400308 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400309 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
David Benjamin6e4fc332016-11-17 16:43:08 +0900310 if (!tls13_init_key_schedule(hs)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500311 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400312 }
313
David Benjamin8f820b42016-11-30 11:24:40 -0500314 /* Incorporate the PSK into the running secret. */
315 if (ssl->s3->session_reused) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900316 if (!tls13_advance_key_schedule(hs, ssl->s3->new_session->master_key,
David Benjamin8f820b42016-11-30 11:24:40 -0500317 ssl->s3->new_session->master_key_length)) {
318 return ssl_hs_error;
319 }
David Benjamin6e4fc332016-11-17 16:43:08 +0900320 } else if (!tls13_advance_key_schedule(hs, kZeroes, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400321 return ssl_hs_error;
322 }
323
David Benjaminf01f42a2016-11-16 19:05:33 +0900324 ssl->method->received_flight(ssl);
325
Steven Valdez143e8b32016-07-11 13:19:03 -0400326 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400327 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900328 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400329 if (need_retry) {
David Benjamin3977f302016-12-11 13:30:41 -0500330 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400331 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400332 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400333 return ssl_hs_error;
334 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400335
David Benjamin3977f302016-12-11 13:30:41 -0500336 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400337 return ssl_hs_ok;
338}
Steven Valdez143e8b32016-07-11 13:19:03 -0400339
David Benjaminc3c88822016-11-14 10:32:04 +0900340static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
341 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400342 CBB cbb, body, extensions;
343 uint16_t group_id;
344 if (!ssl->method->init_message(ssl, &cbb, &body,
345 SSL3_MT_HELLO_RETRY_REQUEST) ||
346 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900347 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400348 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400349 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
350 !CBB_add_u16(&extensions, 2 /* length */) ||
351 !CBB_add_u16(&extensions, group_id) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500352 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400353 CBB_cleanup(&cbb);
354 return ssl_hs_error;
355 }
356
David Benjamin3977f302016-12-11 13:30:41 -0500357 hs->tls13_state = state_flush_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400358 return ssl_hs_write_message;
359}
360
David Benjaminc3c88822016-11-14 10:32:04 +0900361static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500362 hs->tls13_state = state_process_second_client_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400363 return ssl_hs_flush_and_read_message;
364}
365
David Benjaminc3c88822016-11-14 10:32:04 +0900366static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
367 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400368 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
369 return ssl_hs_error;
370 }
371
David Benjamin731058e2016-12-03 23:15:13 -0500372 SSL_CLIENT_HELLO client_hello;
373 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
374 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400375 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
376 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
377 return ssl_hs_error;
378 }
379
380 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900381 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400382 if (need_retry) {
383 /* Only send one HelloRetryRequest. */
384 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
385 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400386 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400387 return ssl_hs_error;
388 }
389
David Benjaminced94792016-11-14 17:12:11 +0900390 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400391 return ssl_hs_error;
392 }
393
David Benjamin613fe3b2016-07-22 17:39:29 +0200394 ssl->method->received_flight(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500395 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400396 return ssl_hs_ok;
397}
398
David Benjaminc3c88822016-11-14 10:32:04 +0900399static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
400 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400401 CBB cbb, body, extensions;
402 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
403 !CBB_add_u16(&body, ssl->version) ||
404 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
405 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
406 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
407 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900408 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
David Benjamin6f600d62016-12-21 16:06:54 -0500409 !ssl_ext_key_share_add_serverhello(hs, &extensions)) {
410 goto err;
411 }
412
413 if (ssl->s3->short_header) {
414 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_short_header) ||
415 !CBB_add_u16(&extensions, 0 /* empty extension */)) {
416 goto err;
417 }
418 }
419
420 if (!ssl_complete_message(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400421 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400422 }
423
David Benjamin3977f302016-12-11 13:30:41 -0500424 hs->tls13_state = state_send_encrypted_extensions;
Steven Valdez143e8b32016-07-11 13:19:03 -0400425 return ssl_hs_write_message;
Steven Valdez803c77a2016-09-06 14:13:43 -0400426
427err:
428 CBB_cleanup(&cbb);
429 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400430}
431
David Benjaminc3c88822016-11-14 10:32:04 +0900432static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL_HANDSHAKE *hs) {
433 SSL *const ssl = hs->ssl;
Steven Valdez4cb84942016-12-16 11:29:28 -0500434 if (!tls13_derive_handshake_secrets(hs) ||
435 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
436 hs->hash_len) ||
437 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
438 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400439 return ssl_hs_error;
440 }
441
442 CBB cbb, body;
443 if (!ssl->method->init_message(ssl, &cbb, &body,
444 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500445 !ssl_add_serverhello_tlsext(hs, &body) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500446 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400447 CBB_cleanup(&cbb);
448 return ssl_hs_error;
449 }
450
David Benjamin3977f302016-12-11 13:30:41 -0500451 hs->tls13_state = state_send_certificate_request;
Steven Valdez143e8b32016-07-11 13:19:03 -0400452 return ssl_hs_write_message;
453}
454
David Benjaminc3c88822016-11-14 10:32:04 +0900455static enum ssl_hs_wait_t do_send_certificate_request(SSL_HANDSHAKE *hs) {
456 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400457 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900458 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400459 /* CertificateRequest may only be sent in non-resumption handshakes. */
460 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900461 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400462 }
463
David Benjaminc3c88822016-11-14 10:32:04 +0900464 if (!hs->cert_request) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400465 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500466 hs->tls13_state = state_send_server_certificate;
Steven Valdez143e8b32016-07-11 13:19:03 -0400467 return ssl_hs_ok;
468 }
469
470 CBB cbb, body, sigalgs_cbb;
471 if (!ssl->method->init_message(ssl, &cbb, &body,
472 SSL3_MT_CERTIFICATE_REQUEST) ||
473 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
474 goto err;
475 }
476
477 const uint16_t *sigalgs;
David Benjamin3ef76972016-10-17 17:59:54 -0400478 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400479 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
480 goto err;
481 }
482
David Benjamin0fc37ef2016-08-17 15:29:46 -0400483 for (size_t i = 0; i < num_sigalgs; i++) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400484 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
485 goto err;
486 }
487 }
488
489 if (!ssl_add_client_CA_list(ssl, &body) ||
490 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500491 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400492 goto err;
493 }
494
David Benjamin3977f302016-12-11 13:30:41 -0500495 hs->tls13_state = state_send_server_certificate;
Steven Valdez143e8b32016-07-11 13:19:03 -0400496 return ssl_hs_write_message;
497
498err:
499 CBB_cleanup(&cbb);
500 return ssl_hs_error;
501}
502
David Benjaminc3c88822016-11-14 10:32:04 +0900503static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
504 SSL *const ssl = hs->ssl;
Steven Valdez803c77a2016-09-06 14:13:43 -0400505 if (ssl->s3->session_reused) {
David Benjamin3977f302016-12-11 13:30:41 -0500506 hs->tls13_state = state_send_server_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400507 return ssl_hs_ok;
508 }
509
510 if (!ssl_has_certificate(ssl)) {
511 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
512 return ssl_hs_error;
513 }
514
David Benjamin6e4fc332016-11-17 16:43:08 +0900515 if (!tls13_prepare_certificate(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400516 return ssl_hs_error;
517 }
518
David Benjamin3977f302016-12-11 13:30:41 -0500519 hs->tls13_state = state_send_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400520 return ssl_hs_write_message;
521}
522
David Benjaminc3c88822016-11-14 10:32:04 +0900523static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400524 int is_first_run) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900525 switch (tls13_prepare_certificate_verify(hs, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400526 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500527 hs->tls13_state = state_send_server_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400528 return ssl_hs_write_message;
529
530 case ssl_private_key_retry:
David Benjamin3977f302016-12-11 13:30:41 -0500531 hs->tls13_state = state_complete_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400532 return ssl_hs_private_key_operation;
533
534 case ssl_private_key_failure:
535 return ssl_hs_error;
536 }
537
538 assert(0);
539 return ssl_hs_error;
540}
541
David Benjaminc3c88822016-11-14 10:32:04 +0900542static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900543 if (!tls13_prepare_finished(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400544 return ssl_hs_error;
545 }
546
David Benjamin3977f302016-12-11 13:30:41 -0500547 hs->tls13_state = state_flush;
Steven Valdez143e8b32016-07-11 13:19:03 -0400548 return ssl_hs_write_message;
549}
550
David Benjaminc3c88822016-11-14 10:32:04 +0900551static enum ssl_hs_wait_t do_flush(SSL_HANDSHAKE *hs) {
552 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400553 /* Update the secret to the master secret and derive traffic keys. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900554 if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
555 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400556 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
557 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400558 return ssl_hs_error;
559 }
560
David Benjamin3977f302016-12-11 13:30:41 -0500561 hs->tls13_state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200562 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400563}
564
David Benjaminc3c88822016-11-14 10:32:04 +0900565static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
566 SSL *const ssl = hs->ssl;
567 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700568 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400569 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700570 ssl->s3->new_session->verify_result = X509_V_OK;
571
Steven Valdez143e8b32016-07-11 13:19:03 -0400572 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500573 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400574 return ssl_hs_ok;
575 }
576
David Benjamin4087df92016-08-01 20:16:31 -0400577 const int allow_anonymous =
578 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
579
Steven Valdez143e8b32016-07-11 13:19:03 -0400580 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
Adam Langley0c294252016-12-12 11:46:09 -0800581 !tls13_process_certificate(hs, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900582 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400583 return ssl_hs_error;
584 }
585
David Benjamin3977f302016-12-11 13:30:41 -0500586 hs->tls13_state = state_process_client_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400587 return ssl_hs_read_message;
588}
589
590static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900591 SSL_HANDSHAKE *hs) {
592 SSL *const ssl = hs->ssl;
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800593 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400594 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500595 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400596 return ssl_hs_ok;
597 }
598
599 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
Adam Langley0c294252016-12-12 11:46:09 -0800600 !tls13_process_certificate_verify(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900601 !ssl_hash_current_message(ssl)) {
David Benjamin6929f272016-11-16 19:10:08 +0900602 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400603 }
604
David Benjamin3977f302016-12-11 13:30:41 -0500605 hs->tls13_state = state_process_channel_id;
Nick Harper60a85cb2016-09-23 16:25:11 -0700606 return ssl_hs_read_message;
607}
608
David Benjaminc3c88822016-11-14 10:32:04 +0900609static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
610 SSL *const ssl = hs->ssl;
Nick Harper60a85cb2016-09-23 16:25:11 -0700611 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin3977f302016-12-11 13:30:41 -0500612 hs->tls13_state = state_process_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700613 return ssl_hs_ok;
614 }
615
616 if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
617 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900618 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700619 return ssl_hs_error;
620 }
621
David Benjamin3977f302016-12-11 13:30:41 -0500622 hs->tls13_state = state_process_client_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400623 return ssl_hs_read_message;
624}
625
David Benjaminc3c88822016-11-14 10:32:04 +0900626static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
627 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400628 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900629 !tls13_process_finished(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900630 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400631 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400632 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
633 hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900634 !tls13_derive_resumption_secret(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400635 return ssl_hs_error;
636 }
637
David Benjamin613fe3b2016-07-22 17:39:29 +0200638 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400639
640 /* Refresh the session timestamp so that it is measured from ticket
641 * issuance. */
642 ssl_session_refresh_time(ssl, ssl->s3->new_session);
David Benjamin3977f302016-12-11 13:30:41 -0500643 hs->tls13_state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400644 return ssl_hs_ok;
645}
646
David Benjamin0a011fc2016-11-03 17:19:16 -0400647/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
648 * client makes several connections before getting a renewal. */
649static const int kNumTickets = 2;
650
David Benjaminc3c88822016-11-14 10:32:04 +0900651static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
652 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400653 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
654 * session ticket. */
655 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500656 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400657 return ssl_hs_ok;
658 }
659
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400660 SSL_SESSION *session = ssl->s3->new_session;
Steven Valdeza833c352016-11-01 13:39:36 -0400661 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
662 goto err;
663 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400664
Steven Valdeza833c352016-11-01 13:39:36 -0400665 CBB cbb, body, ticket, extensions;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400666 if (!ssl->method->init_message(ssl, &cbb, &body,
667 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin123db572016-11-03 16:59:25 -0400668 !CBB_add_u32(&body, session->timeout) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400669 !CBB_add_u32(&body, session->ticket_age_add) ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400670 !CBB_add_u16_length_prefixed(&body, &ticket) ||
671 !ssl_encrypt_ticket(ssl, &ticket, session) ||
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400672 !CBB_add_u16_length_prefixed(&body, &extensions)) {
673 goto err;
674 }
675
Steven Valdez08b65f42016-12-07 15:29:45 -0500676 if (ssl->ctx->enable_early_data) {
677 session->ticket_max_early_data = kMaxEarlyDataAccepted;
678
679 CBB early_data_info;
680 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
681 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
682 !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
683 !CBB_flush(&extensions)) {
684 goto err;
685 }
686 }
687
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400688 /* Add a fake extension. See draft-davidben-tls-grease-01. */
David Benjamin079b3942016-10-20 13:19:20 -0400689 if (!CBB_add_u16(&extensions,
690 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
691 !CBB_add_u16(&extensions, 0 /* empty */)) {
692 goto err;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400693 }
694
Steven Valdez5eead162016-11-11 22:23:25 -0500695 if (!ssl_complete_message(ssl, &cbb)) {
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400696 goto err;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400697 }
698
699 hs->session_tickets_sent++;
David Benjamin0a011fc2016-11-03 17:19:16 -0400700 if (hs->session_tickets_sent >= kNumTickets) {
David Benjamin3977f302016-12-11 13:30:41 -0500701 hs->tls13_state = state_flush_new_session_tickets;
David Benjamin0a011fc2016-11-03 17:19:16 -0400702 } else {
David Benjamin3977f302016-12-11 13:30:41 -0500703 hs->tls13_state = state_send_new_session_ticket;
David Benjamin0a011fc2016-11-03 17:19:16 -0400704 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400705
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400706 return ssl_hs_write_message;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400707
708err:
709 CBB_cleanup(&cbb);
710 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400711}
712
David Benjaminc3c88822016-11-14 10:32:04 +0900713static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500714 hs->tls13_state = state_done;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400715 return ssl_hs_flush;
716}
717
David Benjaminc3c88822016-11-14 10:32:04 +0900718enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500719 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400720 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamin3977f302016-12-11 13:30:41 -0500721 enum server_hs_state_t state = hs->tls13_state;
Steven Valdez143e8b32016-07-11 13:19:03 -0400722 switch (state) {
723 case state_process_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900724 ret = do_process_client_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400725 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400726 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900727 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400728 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400729 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900730 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400731 break;
732 case state_flush_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900733 ret = do_flush_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400734 break;
735 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900736 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400737 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400738 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900739 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400740 break;
741 case state_send_encrypted_extensions:
David Benjaminc3c88822016-11-14 10:32:04 +0900742 ret = do_send_encrypted_extensions(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400743 break;
744 case state_send_certificate_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900745 ret = do_send_certificate_request(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400746 break;
747 case state_send_server_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900748 ret = do_send_server_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400749 break;
750 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900751 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400752 break;
753 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900754 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400755 break;
756 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900757 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400758 break;
759 case state_flush:
David Benjaminc3c88822016-11-14 10:32:04 +0900760 ret = do_flush(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400761 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400762 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900763 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400764 break;
765 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900766 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400767 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700768 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900769 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700770 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400771 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900772 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400773 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400774 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900775 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400776 break;
David Benjamin0a011fc2016-11-03 17:19:16 -0400777 case state_flush_new_session_tickets:
David Benjaminc3c88822016-11-14 10:32:04 +0900778 ret = do_flush_new_session_tickets(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400779 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400780 case state_done:
781 ret = ssl_hs_ok;
782 break;
783 }
784
785 if (ret != ssl_hs_ok) {
786 return ret;
787 }
788 }
789
790 return ssl_hs_ok;
791}