blob: cdf78e6668fdc2b8159d1f788f344bd1a284dc10 [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
32enum server_hs_state_t {
33 state_process_client_hello = 0,
David Benjamin25fe85b2016-08-09 20:00:32 -040034 state_select_parameters,
Steven Valdez5440fe02016-07-18 12:40:30 -040035 state_send_hello_retry_request,
36 state_flush_hello_retry_request,
37 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040038 state_send_server_hello,
39 state_send_encrypted_extensions,
40 state_send_certificate_request,
41 state_send_server_certificate,
42 state_send_server_certificate_verify,
43 state_complete_server_certificate_verify,
44 state_send_server_finished,
45 state_flush,
Steven Valdez143e8b32016-07-11 13:19:03 -040046 state_process_client_certificate,
47 state_process_client_certificate_verify,
Nick Harper60a85cb2016-09-23 16:25:11 -070048 state_process_channel_id,
Steven Valdez143e8b32016-07-11 13:19:03 -040049 state_process_client_finished,
Steven Valdez1e6f11a2016-07-27 11:10:52 -040050 state_send_new_session_ticket,
David Benjamin0a011fc2016-11-03 17:19:16 -040051 state_flush_new_session_tickets,
Steven Valdez143e8b32016-07-11 13:19:03 -040052 state_done,
53};
54
Steven Valdez5440fe02016-07-18 12:40:30 -040055static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
56
David Benjamin6e4fc332016-11-17 16:43:08 +090057static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, int *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050058 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090059 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -040060 *out_need_retry = 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040061
Steven Valdez803c77a2016-09-06 14:13:43 -040062 /* We only support connections that include an ECDHE key exchange. */
Steven Valdez5440fe02016-07-18 12:40:30 -040063 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050064 if (!ssl_client_hello_get_extension(client_hello, &key_share,
65 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040066 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
67 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090068 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040069 }
70
Steven Valdez5440fe02016-07-18 12:40:30 -040071 int found_key_share;
72 uint8_t *dhe_secret;
73 size_t dhe_secret_len;
David Benjamin7e1f9842016-09-20 19:24:40 -040074 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090075 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
Steven Valdez7259f2f2016-08-02 16:55:05 -040076 &dhe_secret_len, &alert,
77 &key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040078 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
79 return 0;
80 }
81
82 if (!found_key_share) {
83 *out_need_retry = 1;
84 return 0;
85 }
86
David Benjamin6e4fc332016-11-17 16:43:08 +090087 int ok = tls13_advance_key_schedule(hs, dhe_secret, dhe_secret_len);
Steven Valdez5440fe02016-07-18 12:40:30 -040088 OPENSSL_free(dhe_secret);
89 return ok;
90}
91
David Benjaminc3c88822016-11-14 10:32:04 +090092static enum ssl_hs_wait_t do_process_client_hello(SSL_HANDSHAKE *hs) {
93 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -040094 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
95 return ssl_hs_error;
96 }
97
David Benjamin731058e2016-12-03 23:15:13 -050098 SSL_CLIENT_HELLO client_hello;
99 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
100 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400101 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
102 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
103 return ssl_hs_error;
104 }
105
Steven Valdez143e8b32016-07-11 13:19:03 -0400106 assert(ssl->s3->have_version);
107
108 /* Load the client random. */
David Benjamine14ff062016-08-09 16:21:24 -0400109 if (client_hello.random_len != SSL3_RANDOM_SIZE) {
110 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6929f272016-11-16 19:10:08 +0900111 return ssl_hs_error;
David Benjamine14ff062016-08-09 16:21:24 -0400112 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500113 OPENSSL_memcpy(ssl->s3->client_random, client_hello.random,
114 client_hello.random_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400115
David Benjamin4eb95cc2016-11-16 17:08:23 +0900116 /* TLS 1.3 requires the peer only advertise the null compression. */
117 if (client_hello.compression_methods_len != 1 ||
118 client_hello.compression_methods[0] != 0) {
119 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
120 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
David Benjamin6929f272016-11-16 19:10:08 +0900121 return ssl_hs_error;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400122 }
123
David Benjamin4eb95cc2016-11-16 17:08:23 +0900124 /* TLS extensions. */
David Benjamin8c880a22016-12-03 02:20:34 -0500125 if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900126 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
127 return ssl_hs_error;
128 }
Steven Valdeza833c352016-11-01 13:39:36 -0400129
David Benjamin6f600d62016-12-21 16:06:54 -0500130 /* The short record header extension is incompatible with early data. */
131 if (ssl->s3->skip_early_data && ssl->s3->short_header) {
132 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
133 return ssl_hs_error;
134 }
135
David Benjamin3977f302016-12-11 13:30:41 -0500136 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900137 return ssl_hs_ok;
138}
139
140static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -0500141 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +0900142 if (client_hello->cipher_suites_len % 2 != 0) {
143 return NULL;
144 }
145
146 CBS cipher_suites;
147 CBS_init(&cipher_suites, client_hello->cipher_suites,
148 client_hello->cipher_suites_len);
149
150 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900151 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900152
153 const SSL_CIPHER *best = NULL;
154 while (CBS_len(&cipher_suites) > 0) {
155 uint16_t cipher_suite;
156 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
157 return NULL;
158 }
159
David Benjaminf01f42a2016-11-16 19:05:33 +0900160 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900161 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900162 if (candidate == NULL ||
163 SSL_CIPHER_get_min_version(candidate) > version ||
164 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900165 continue;
166 }
167
168 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
169 * ChaCha20 if we do not have AES hardware. */
170 if (aes_is_fine) {
171 return candidate;
172 }
173
174 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
175 return candidate;
176 }
177
178 if (best == NULL) {
179 best = candidate;
180 }
181 }
182
183 return best;
184}
185
David Benjaminc3c88822016-11-14 10:32:04 +0900186static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
187 SSL *const ssl = hs->ssl;
David Benjamin34202b92016-11-16 19:07:53 +0900188 /* Call |cert_cb| to update server certificates if required. */
189 if (ssl->cert->cert_cb != NULL) {
190 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
191 if (rv == 0) {
192 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
193 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
194 return ssl_hs_error;
195 }
196 if (rv < 0) {
David Benjamin3977f302016-12-11 13:30:41 -0500197 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900198 return ssl_hs_x509_lookup;
199 }
200 }
201
David Benjamin650aa1c2016-12-20 18:55:16 -0500202 if (!ssl_auto_chain_if_needed(ssl)) {
203 return ssl_hs_error;
204 }
205
David Benjamin731058e2016-12-03 23:15:13 -0500206 SSL_CLIENT_HELLO client_hello;
207 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
208 ssl->init_num)) {
David Benjamin34202b92016-11-16 19:07:53 +0900209 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
210 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
211 return ssl_hs_error;
212 }
213
David Benjaminf01f42a2016-11-16 19:05:33 +0900214 /* Negotiate the cipher suite. */
215 ssl->s3->tmp.new_cipher = choose_tls13_cipher(ssl, &client_hello);
216 if (ssl->s3->tmp.new_cipher == NULL) {
217 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
218 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
219 return ssl_hs_error;
220 }
221
222 /* Decode the ticket if we agree on a PSK key exchange mode. */
David Benjamin4eb95cc2016-11-16 17:08:23 +0900223 uint8_t alert = SSL_AD_DECODE_ERROR;
224 SSL_SESSION *session = NULL;
225 CBS pre_shared_key, binders;
226 if (hs->accept_psk_mode &&
David Benjamin731058e2016-12-03 23:15:13 -0500227 ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
228 TLSEXT_TYPE_pre_shared_key)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900229 /* Verify that the pre_shared_key extension is the last extension in
230 * ClientHello. */
231 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
232 client_hello.extensions + client_hello.extensions_len) {
233 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
234 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
235 return ssl_hs_error;
236 }
237
David Benjamin8baf9632016-11-17 17:11:16 +0900238 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &session, &binders,
David Benjamin4eb95cc2016-11-16 17:08:23 +0900239 &alert, &pre_shared_key)) {
240 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
241 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400242 }
243 }
244
Steven Valdez4aa154e2016-07-29 14:32:55 -0400245 if (session != NULL &&
David Benjamin75f99142016-11-12 12:36:06 +0900246 !ssl_session_is_resumable(ssl, session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400247 SSL_SESSION_free(session);
248 session = NULL;
249 }
250
David Benjaminf01f42a2016-11-16 19:05:33 +0900251 /* Set up the new session, either using the original one as a template or
252 * creating a fresh one. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400253 if (session == NULL) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900254 if (!ssl_get_new_session(hs, 1 /* server */)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400255 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
256 return ssl_hs_error;
257 }
David Benjaminf01f42a2016-11-16 19:05:33 +0900258
259 ssl->s3->new_session->cipher = ssl->s3->tmp.new_cipher;
260
261 /* On new sessions, stash the SNI value in the session. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900262 if (hs->hostname != NULL) {
263 ssl->s3->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
David Benjaminf01f42a2016-11-16 19:05:33 +0900264 if (ssl->s3->new_session->tlsext_hostname == NULL) {
265 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
266 return ssl_hs_error;
267 }
268 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400269 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400270 /* Check the PSK binder. */
271 if (!tls13_verify_psk_binder(ssl, session, &binders)) {
272 SSL_SESSION_free(session);
273 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
274 return ssl_hs_error;
275 }
276
Steven Valdez4aa154e2016-07-29 14:32:55 -0400277 /* Only authentication information carries over in TLS 1.3. */
278 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
279 if (ssl->s3->new_session == NULL) {
280 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
281 return ssl_hs_error;
282 }
283 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400284 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400285 }
286
287 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400288 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400289 /* Connection rejected for DOS reasons. */
290 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400291 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400292 return ssl_hs_error;
293 }
294
David Benjaminf01f42a2016-11-16 19:05:33 +0900295 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
296 * deferred. Complete it now. */
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900297 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamin9ef31f02016-10-31 18:01:13 -0400298 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
299 return ssl_hs_error;
300 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400301
David Benjamin8f820b42016-11-30 11:24:40 -0500302 /* The PRF hash is now known. Set up the key schedule. */
Steven Valdez803c77a2016-09-06 14:13:43 -0400303 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400304 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
David Benjamin6e4fc332016-11-17 16:43:08 +0900305 if (!tls13_init_key_schedule(hs)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500306 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400307 }
308
David Benjamin8f820b42016-11-30 11:24:40 -0500309 /* Incorporate the PSK into the running secret. */
310 if (ssl->s3->session_reused) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900311 if (!tls13_advance_key_schedule(hs, ssl->s3->new_session->master_key,
David Benjamin8f820b42016-11-30 11:24:40 -0500312 ssl->s3->new_session->master_key_length)) {
313 return ssl_hs_error;
314 }
David Benjamin6e4fc332016-11-17 16:43:08 +0900315 } else if (!tls13_advance_key_schedule(hs, kZeroes, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400316 return ssl_hs_error;
317 }
318
David Benjaminf01f42a2016-11-16 19:05:33 +0900319 ssl->method->received_flight(ssl);
320
Steven Valdez143e8b32016-07-11 13:19:03 -0400321 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400322 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900323 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400324 if (need_retry) {
David Benjamin3977f302016-12-11 13:30:41 -0500325 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400326 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400327 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400328 return ssl_hs_error;
329 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400330
David Benjamin3977f302016-12-11 13:30:41 -0500331 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400332 return ssl_hs_ok;
333}
Steven Valdez143e8b32016-07-11 13:19:03 -0400334
David Benjaminc3c88822016-11-14 10:32:04 +0900335static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
336 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400337 CBB cbb, body, extensions;
338 uint16_t group_id;
339 if (!ssl->method->init_message(ssl, &cbb, &body,
340 SSL3_MT_HELLO_RETRY_REQUEST) ||
341 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900342 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400343 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400344 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
345 !CBB_add_u16(&extensions, 2 /* length */) ||
346 !CBB_add_u16(&extensions, group_id) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500347 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400348 CBB_cleanup(&cbb);
349 return ssl_hs_error;
350 }
351
David Benjamin3977f302016-12-11 13:30:41 -0500352 hs->tls13_state = state_flush_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400353 return ssl_hs_write_message;
354}
355
David Benjaminc3c88822016-11-14 10:32:04 +0900356static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500357 hs->tls13_state = state_process_second_client_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400358 return ssl_hs_flush_and_read_message;
359}
360
David Benjaminc3c88822016-11-14 10:32:04 +0900361static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
362 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400363 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
364 return ssl_hs_error;
365 }
366
David Benjamin731058e2016-12-03 23:15:13 -0500367 SSL_CLIENT_HELLO client_hello;
368 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
369 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400370 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
371 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
372 return ssl_hs_error;
373 }
374
375 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900376 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400377 if (need_retry) {
378 /* Only send one HelloRetryRequest. */
379 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
380 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400381 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400382 return ssl_hs_error;
383 }
384
David Benjaminced94792016-11-14 17:12:11 +0900385 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400386 return ssl_hs_error;
387 }
388
David Benjamin613fe3b2016-07-22 17:39:29 +0200389 ssl->method->received_flight(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500390 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400391 return ssl_hs_ok;
392}
393
David Benjaminc3c88822016-11-14 10:32:04 +0900394static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
395 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400396 CBB cbb, body, extensions;
397 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
398 !CBB_add_u16(&body, ssl->version) ||
399 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
400 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
401 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
402 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900403 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
David Benjamin6f600d62016-12-21 16:06:54 -0500404 !ssl_ext_key_share_add_serverhello(hs, &extensions)) {
405 goto err;
406 }
407
408 if (ssl->s3->short_header) {
409 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_short_header) ||
410 !CBB_add_u16(&extensions, 0 /* empty extension */)) {
411 goto err;
412 }
413 }
414
415 if (!ssl_complete_message(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400416 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400417 }
418
David Benjamin3977f302016-12-11 13:30:41 -0500419 hs->tls13_state = state_send_encrypted_extensions;
Steven Valdez143e8b32016-07-11 13:19:03 -0400420 return ssl_hs_write_message;
Steven Valdez803c77a2016-09-06 14:13:43 -0400421
422err:
423 CBB_cleanup(&cbb);
424 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400425}
426
David Benjaminc3c88822016-11-14 10:32:04 +0900427static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL_HANDSHAKE *hs) {
428 SSL *const ssl = hs->ssl;
Steven Valdez4cb84942016-12-16 11:29:28 -0500429 if (!tls13_derive_handshake_secrets(hs) ||
430 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
431 hs->hash_len) ||
432 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
433 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400434 return ssl_hs_error;
435 }
436
437 CBB cbb, body;
438 if (!ssl->method->init_message(ssl, &cbb, &body,
439 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500440 !ssl_add_serverhello_tlsext(hs, &body) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500441 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400442 CBB_cleanup(&cbb);
443 return ssl_hs_error;
444 }
445
David Benjamin3977f302016-12-11 13:30:41 -0500446 hs->tls13_state = state_send_certificate_request;
Steven Valdez143e8b32016-07-11 13:19:03 -0400447 return ssl_hs_write_message;
448}
449
David Benjaminc3c88822016-11-14 10:32:04 +0900450static enum ssl_hs_wait_t do_send_certificate_request(SSL_HANDSHAKE *hs) {
451 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400452 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900453 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400454 /* CertificateRequest may only be sent in non-resumption handshakes. */
455 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900456 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400457 }
458
David Benjaminc3c88822016-11-14 10:32:04 +0900459 if (!hs->cert_request) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400460 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500461 hs->tls13_state = state_send_server_certificate;
Steven Valdez143e8b32016-07-11 13:19:03 -0400462 return ssl_hs_ok;
463 }
464
465 CBB cbb, body, sigalgs_cbb;
466 if (!ssl->method->init_message(ssl, &cbb, &body,
467 SSL3_MT_CERTIFICATE_REQUEST) ||
468 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
469 goto err;
470 }
471
472 const uint16_t *sigalgs;
David Benjamin3ef76972016-10-17 17:59:54 -0400473 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400474 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
475 goto err;
476 }
477
David Benjamin0fc37ef2016-08-17 15:29:46 -0400478 for (size_t i = 0; i < num_sigalgs; i++) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400479 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
480 goto err;
481 }
482 }
483
484 if (!ssl_add_client_CA_list(ssl, &body) ||
485 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500486 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400487 goto err;
488 }
489
David Benjamin3977f302016-12-11 13:30:41 -0500490 hs->tls13_state = state_send_server_certificate;
Steven Valdez143e8b32016-07-11 13:19:03 -0400491 return ssl_hs_write_message;
492
493err:
494 CBB_cleanup(&cbb);
495 return ssl_hs_error;
496}
497
David Benjaminc3c88822016-11-14 10:32:04 +0900498static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
499 SSL *const ssl = hs->ssl;
Steven Valdez803c77a2016-09-06 14:13:43 -0400500 if (ssl->s3->session_reused) {
David Benjamin3977f302016-12-11 13:30:41 -0500501 hs->tls13_state = state_send_server_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400502 return ssl_hs_ok;
503 }
504
505 if (!ssl_has_certificate(ssl)) {
506 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
507 return ssl_hs_error;
508 }
509
David Benjamin6e4fc332016-11-17 16:43:08 +0900510 if (!tls13_prepare_certificate(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400511 return ssl_hs_error;
512 }
513
David Benjamin3977f302016-12-11 13:30:41 -0500514 hs->tls13_state = state_send_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400515 return ssl_hs_write_message;
516}
517
David Benjaminc3c88822016-11-14 10:32:04 +0900518static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400519 int is_first_run) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900520 switch (tls13_prepare_certificate_verify(hs, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400521 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500522 hs->tls13_state = state_send_server_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400523 return ssl_hs_write_message;
524
525 case ssl_private_key_retry:
David Benjamin3977f302016-12-11 13:30:41 -0500526 hs->tls13_state = state_complete_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400527 return ssl_hs_private_key_operation;
528
529 case ssl_private_key_failure:
530 return ssl_hs_error;
531 }
532
533 assert(0);
534 return ssl_hs_error;
535}
536
David Benjaminc3c88822016-11-14 10:32:04 +0900537static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900538 if (!tls13_prepare_finished(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400539 return ssl_hs_error;
540 }
541
David Benjamin3977f302016-12-11 13:30:41 -0500542 hs->tls13_state = state_flush;
Steven Valdez143e8b32016-07-11 13:19:03 -0400543 return ssl_hs_write_message;
544}
545
David Benjaminc3c88822016-11-14 10:32:04 +0900546static enum ssl_hs_wait_t do_flush(SSL_HANDSHAKE *hs) {
547 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400548 /* Update the secret to the master secret and derive traffic keys. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900549 if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
550 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400551 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
552 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400553 return ssl_hs_error;
554 }
555
David Benjamin3977f302016-12-11 13:30:41 -0500556 hs->tls13_state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200557 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400558}
559
David Benjaminc3c88822016-11-14 10:32:04 +0900560static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
561 SSL *const ssl = hs->ssl;
562 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700563 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400564 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700565 ssl->s3->new_session->verify_result = X509_V_OK;
566
Steven Valdez143e8b32016-07-11 13:19:03 -0400567 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500568 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400569 return ssl_hs_ok;
570 }
571
David Benjamin4087df92016-08-01 20:16:31 -0400572 const int allow_anonymous =
573 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
574
Steven Valdez143e8b32016-07-11 13:19:03 -0400575 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
Adam Langley0c294252016-12-12 11:46:09 -0800576 !tls13_process_certificate(hs, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900577 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400578 return ssl_hs_error;
579 }
580
David Benjamin3977f302016-12-11 13:30:41 -0500581 hs->tls13_state = state_process_client_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400582 return ssl_hs_read_message;
583}
584
585static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900586 SSL_HANDSHAKE *hs) {
587 SSL *const ssl = hs->ssl;
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800588 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400589 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500590 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400591 return ssl_hs_ok;
592 }
593
594 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
Adam Langley0c294252016-12-12 11:46:09 -0800595 !tls13_process_certificate_verify(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900596 !ssl_hash_current_message(ssl)) {
David Benjamin6929f272016-11-16 19:10:08 +0900597 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400598 }
599
David Benjamin3977f302016-12-11 13:30:41 -0500600 hs->tls13_state = state_process_channel_id;
Nick Harper60a85cb2016-09-23 16:25:11 -0700601 return ssl_hs_read_message;
602}
603
David Benjaminc3c88822016-11-14 10:32:04 +0900604static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
605 SSL *const ssl = hs->ssl;
Nick Harper60a85cb2016-09-23 16:25:11 -0700606 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin3977f302016-12-11 13:30:41 -0500607 hs->tls13_state = state_process_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700608 return ssl_hs_ok;
609 }
610
611 if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
612 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900613 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700614 return ssl_hs_error;
615 }
616
David Benjamin3977f302016-12-11 13:30:41 -0500617 hs->tls13_state = state_process_client_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400618 return ssl_hs_read_message;
619}
620
David Benjaminc3c88822016-11-14 10:32:04 +0900621static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
622 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400623 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900624 !tls13_process_finished(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900625 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400626 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400627 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
628 hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900629 !tls13_derive_resumption_secret(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400630 return ssl_hs_error;
631 }
632
David Benjamin613fe3b2016-07-22 17:39:29 +0200633 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400634
635 /* Refresh the session timestamp so that it is measured from ticket
636 * issuance. */
637 ssl_session_refresh_time(ssl, ssl->s3->new_session);
David Benjamin3977f302016-12-11 13:30:41 -0500638 hs->tls13_state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400639 return ssl_hs_ok;
640}
641
David Benjamin0a011fc2016-11-03 17:19:16 -0400642/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
643 * client makes several connections before getting a renewal. */
644static const int kNumTickets = 2;
645
David Benjaminc3c88822016-11-14 10:32:04 +0900646static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
647 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400648 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
649 * session ticket. */
650 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500651 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400652 return ssl_hs_ok;
653 }
654
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400655 SSL_SESSION *session = ssl->s3->new_session;
Steven Valdeza833c352016-11-01 13:39:36 -0400656 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
657 goto err;
658 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400659
Steven Valdez5b986082016-09-01 12:29:49 -0400660 /* TODO(svaldez): Add support for sending 0RTT through TicketEarlyDataInfo
661 * extension. */
662
Steven Valdeza833c352016-11-01 13:39:36 -0400663 CBB cbb, body, ticket, extensions;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400664 if (!ssl->method->init_message(ssl, &cbb, &body,
665 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin123db572016-11-03 16:59:25 -0400666 !CBB_add_u32(&body, session->timeout) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400667 !CBB_add_u32(&body, session->ticket_age_add) ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400668 !CBB_add_u16_length_prefixed(&body, &ticket) ||
669 !ssl_encrypt_ticket(ssl, &ticket, session) ||
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400670 !CBB_add_u16_length_prefixed(&body, &extensions)) {
671 goto err;
672 }
673
674 /* Add a fake extension. See draft-davidben-tls-grease-01. */
David Benjamin079b3942016-10-20 13:19:20 -0400675 if (!CBB_add_u16(&extensions,
676 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
677 !CBB_add_u16(&extensions, 0 /* empty */)) {
678 goto err;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400679 }
680
Steven Valdez5eead162016-11-11 22:23:25 -0500681 if (!ssl_complete_message(ssl, &cbb)) {
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400682 goto err;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400683 }
684
685 hs->session_tickets_sent++;
David Benjamin0a011fc2016-11-03 17:19:16 -0400686 if (hs->session_tickets_sent >= kNumTickets) {
David Benjamin3977f302016-12-11 13:30:41 -0500687 hs->tls13_state = state_flush_new_session_tickets;
David Benjamin0a011fc2016-11-03 17:19:16 -0400688 } else {
David Benjamin3977f302016-12-11 13:30:41 -0500689 hs->tls13_state = state_send_new_session_ticket;
David Benjamin0a011fc2016-11-03 17:19:16 -0400690 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400691
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400692 return ssl_hs_write_message;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400693
694err:
695 CBB_cleanup(&cbb);
696 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400697}
698
David Benjaminc3c88822016-11-14 10:32:04 +0900699static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500700 hs->tls13_state = state_done;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400701 return ssl_hs_flush;
702}
703
David Benjaminc3c88822016-11-14 10:32:04 +0900704enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500705 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400706 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamin3977f302016-12-11 13:30:41 -0500707 enum server_hs_state_t state = hs->tls13_state;
Steven Valdez143e8b32016-07-11 13:19:03 -0400708 switch (state) {
709 case state_process_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900710 ret = do_process_client_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400711 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400712 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900713 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400714 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400715 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900716 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400717 break;
718 case state_flush_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900719 ret = do_flush_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400720 break;
721 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900722 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400723 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400724 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900725 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400726 break;
727 case state_send_encrypted_extensions:
David Benjaminc3c88822016-11-14 10:32:04 +0900728 ret = do_send_encrypted_extensions(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400729 break;
730 case state_send_certificate_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900731 ret = do_send_certificate_request(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400732 break;
733 case state_send_server_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900734 ret = do_send_server_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400735 break;
736 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900737 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400738 break;
739 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900740 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400741 break;
742 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900743 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400744 break;
745 case state_flush:
David Benjaminc3c88822016-11-14 10:32:04 +0900746 ret = do_flush(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400747 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400748 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900749 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400750 break;
751 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900752 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400753 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700754 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900755 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700756 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400757 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900758 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400759 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400760 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900761 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400762 break;
David Benjamin0a011fc2016-11-03 17:19:16 -0400763 case state_flush_new_session_tickets:
David Benjaminc3c88822016-11-14 10:32:04 +0900764 ret = do_flush_new_session_tickets(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400765 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400766 case state_done:
767 ret = ssl_hs_ok;
768 break;
769 }
770
771 if (ret != ssl_hs_ok) {
772 return ret;
773 }
774 }
775
776 return ssl_hs_ok;
777}