blob: f5bdf535e66961745af5fe950e52188e7259f03a [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,
Steven Valdez5440fe02016-07-18 12:40:30 -040041 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040042 state_send_server_hello,
43 state_send_encrypted_extensions,
44 state_send_certificate_request,
45 state_send_server_certificate,
46 state_send_server_certificate_verify,
47 state_complete_server_certificate_verify,
48 state_send_server_finished,
Steven Valdez143e8b32016-07-11 13:19:03 -040049 state_process_client_certificate,
50 state_process_client_certificate_verify,
Nick Harper60a85cb2016-09-23 16:25:11 -070051 state_process_channel_id,
Steven Valdez143e8b32016-07-11 13:19:03 -040052 state_process_client_finished,
Steven Valdez1e6f11a2016-07-27 11:10:52 -040053 state_send_new_session_ticket,
Steven Valdez143e8b32016-07-11 13:19:03 -040054 state_done,
55};
56
Steven Valdez5440fe02016-07-18 12:40:30 -040057static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
58
David Benjamin6e4fc332016-11-17 16:43:08 +090059static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, int *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050060 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090061 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -040062 *out_need_retry = 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040063
Steven Valdez803c77a2016-09-06 14:13:43 -040064 /* We only support connections that include an ECDHE key exchange. */
Steven Valdez5440fe02016-07-18 12:40:30 -040065 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050066 if (!ssl_client_hello_get_extension(client_hello, &key_share,
67 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040068 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
69 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090070 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040071 }
72
Steven Valdez5440fe02016-07-18 12:40:30 -040073 int found_key_share;
74 uint8_t *dhe_secret;
75 size_t dhe_secret_len;
David Benjamin7e1f9842016-09-20 19:24:40 -040076 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090077 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
Steven Valdez7259f2f2016-08-02 16:55:05 -040078 &dhe_secret_len, &alert,
79 &key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040080 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
81 return 0;
82 }
83
84 if (!found_key_share) {
85 *out_need_retry = 1;
86 return 0;
87 }
88
David Benjamin6e4fc332016-11-17 16:43:08 +090089 int ok = tls13_advance_key_schedule(hs, dhe_secret, dhe_secret_len);
Steven Valdez5440fe02016-07-18 12:40:30 -040090 OPENSSL_free(dhe_secret);
91 return ok;
92}
93
David Benjaminc3c88822016-11-14 10:32:04 +090094static enum ssl_hs_wait_t do_process_client_hello(SSL_HANDSHAKE *hs) {
95 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -040096 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
97 return ssl_hs_error;
98 }
99
David Benjamin731058e2016-12-03 23:15:13 -0500100 SSL_CLIENT_HELLO client_hello;
101 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
102 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400103 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
104 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
105 return ssl_hs_error;
106 }
107
Steven Valdez143e8b32016-07-11 13:19:03 -0400108 assert(ssl->s3->have_version);
109
110 /* Load the client random. */
David Benjamine14ff062016-08-09 16:21:24 -0400111 if (client_hello.random_len != SSL3_RANDOM_SIZE) {
112 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6929f272016-11-16 19:10:08 +0900113 return ssl_hs_error;
David Benjamine14ff062016-08-09 16:21:24 -0400114 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500115 OPENSSL_memcpy(ssl->s3->client_random, client_hello.random,
116 client_hello.random_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400117
David Benjamin4eb95cc2016-11-16 17:08:23 +0900118 /* TLS 1.3 requires the peer only advertise the null compression. */
119 if (client_hello.compression_methods_len != 1 ||
120 client_hello.compression_methods[0] != 0) {
121 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
122 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
David Benjamin6929f272016-11-16 19:10:08 +0900123 return ssl_hs_error;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400124 }
125
David Benjamin4eb95cc2016-11-16 17:08:23 +0900126 /* TLS extensions. */
David Benjamin8c880a22016-12-03 02:20:34 -0500127 if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900128 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
129 return ssl_hs_error;
130 }
Steven Valdeza833c352016-11-01 13:39:36 -0400131
David Benjamin6f600d62016-12-21 16:06:54 -0500132 /* The short record header extension is incompatible with early data. */
133 if (ssl->s3->skip_early_data && ssl->s3->short_header) {
134 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
135 return ssl_hs_error;
136 }
137
David Benjamin3977f302016-12-11 13:30:41 -0500138 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900139 return ssl_hs_ok;
140}
141
142static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -0500143 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +0900144 if (client_hello->cipher_suites_len % 2 != 0) {
145 return NULL;
146 }
147
148 CBS cipher_suites;
149 CBS_init(&cipher_suites, client_hello->cipher_suites,
150 client_hello->cipher_suites_len);
151
152 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900153 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900154
155 const SSL_CIPHER *best = NULL;
156 while (CBS_len(&cipher_suites) > 0) {
157 uint16_t cipher_suite;
158 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
159 return NULL;
160 }
161
David Benjaminf01f42a2016-11-16 19:05:33 +0900162 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900163 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900164 if (candidate == NULL ||
165 SSL_CIPHER_get_min_version(candidate) > version ||
166 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900167 continue;
168 }
169
170 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
171 * ChaCha20 if we do not have AES hardware. */
172 if (aes_is_fine) {
173 return candidate;
174 }
175
176 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
177 return candidate;
178 }
179
180 if (best == NULL) {
181 best = candidate;
182 }
183 }
184
185 return best;
186}
187
David Benjaminc3c88822016-11-14 10:32:04 +0900188static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
189 SSL *const ssl = hs->ssl;
David Benjamin34202b92016-11-16 19:07:53 +0900190 /* Call |cert_cb| to update server certificates if required. */
191 if (ssl->cert->cert_cb != NULL) {
192 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
193 if (rv == 0) {
194 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
195 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
196 return ssl_hs_error;
197 }
198 if (rv < 0) {
David Benjamin3977f302016-12-11 13:30:41 -0500199 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900200 return ssl_hs_x509_lookup;
201 }
202 }
203
David Benjamin650aa1c2016-12-20 18:55:16 -0500204 if (!ssl_auto_chain_if_needed(ssl)) {
205 return ssl_hs_error;
206 }
207
David Benjamin731058e2016-12-03 23:15:13 -0500208 SSL_CLIENT_HELLO client_hello;
209 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
210 ssl->init_num)) {
David Benjamin34202b92016-11-16 19:07:53 +0900211 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
212 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
213 return ssl_hs_error;
214 }
215
David Benjaminf01f42a2016-11-16 19:05:33 +0900216 /* Negotiate the cipher suite. */
217 ssl->s3->tmp.new_cipher = choose_tls13_cipher(ssl, &client_hello);
218 if (ssl->s3->tmp.new_cipher == NULL) {
219 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
220 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
221 return ssl_hs_error;
222 }
223
224 /* Decode the ticket if we agree on a PSK key exchange mode. */
David Benjamin4eb95cc2016-11-16 17:08:23 +0900225 uint8_t alert = SSL_AD_DECODE_ERROR;
226 SSL_SESSION *session = NULL;
227 CBS pre_shared_key, binders;
228 if (hs->accept_psk_mode &&
David Benjamin731058e2016-12-03 23:15:13 -0500229 ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
230 TLSEXT_TYPE_pre_shared_key)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900231 /* Verify that the pre_shared_key extension is the last extension in
232 * ClientHello. */
233 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
234 client_hello.extensions + client_hello.extensions_len) {
235 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
236 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
237 return ssl_hs_error;
238 }
239
David Benjamin8baf9632016-11-17 17:11:16 +0900240 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &session, &binders,
David Benjamin4eb95cc2016-11-16 17:08:23 +0900241 &alert, &pre_shared_key)) {
242 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
243 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400244 }
245 }
246
Steven Valdez4aa154e2016-07-29 14:32:55 -0400247 if (session != NULL &&
David Benjamin75f99142016-11-12 12:36:06 +0900248 !ssl_session_is_resumable(ssl, session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400249 SSL_SESSION_free(session);
250 session = NULL;
251 }
252
David Benjaminf01f42a2016-11-16 19:05:33 +0900253 /* Set up the new session, either using the original one as a template or
254 * creating a fresh one. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400255 if (session == NULL) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900256 if (!ssl_get_new_session(hs, 1 /* server */)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400257 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
258 return ssl_hs_error;
259 }
David Benjaminf01f42a2016-11-16 19:05:33 +0900260
261 ssl->s3->new_session->cipher = ssl->s3->tmp.new_cipher;
262
263 /* On new sessions, stash the SNI value in the session. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900264 if (hs->hostname != NULL) {
265 ssl->s3->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
David Benjaminf01f42a2016-11-16 19:05:33 +0900266 if (ssl->s3->new_session->tlsext_hostname == NULL) {
267 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
268 return ssl_hs_error;
269 }
270 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400271 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400272 /* Check the PSK binder. */
273 if (!tls13_verify_psk_binder(ssl, session, &binders)) {
274 SSL_SESSION_free(session);
275 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
276 return ssl_hs_error;
277 }
278
Steven Valdez4aa154e2016-07-29 14:32:55 -0400279 /* Only authentication information carries over in TLS 1.3. */
280 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
281 if (ssl->s3->new_session == NULL) {
282 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
283 return ssl_hs_error;
284 }
285 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400286 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400287 }
288
289 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400290 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400291 /* Connection rejected for DOS reasons. */
292 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400293 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400294 return ssl_hs_error;
295 }
296
David Benjaminf01f42a2016-11-16 19:05:33 +0900297 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
298 * deferred. Complete it now. */
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900299 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamin9ef31f02016-10-31 18:01:13 -0400300 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
301 return ssl_hs_error;
302 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400303
David Benjamin8f820b42016-11-30 11:24:40 -0500304 /* The PRF hash is now known. Set up the key schedule. */
Steven Valdez803c77a2016-09-06 14:13:43 -0400305 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400306 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
David Benjamin6e4fc332016-11-17 16:43:08 +0900307 if (!tls13_init_key_schedule(hs)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500308 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400309 }
310
David Benjamin8f820b42016-11-30 11:24:40 -0500311 /* Incorporate the PSK into the running secret. */
312 if (ssl->s3->session_reused) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900313 if (!tls13_advance_key_schedule(hs, ssl->s3->new_session->master_key,
David Benjamin8f820b42016-11-30 11:24:40 -0500314 ssl->s3->new_session->master_key_length)) {
315 return ssl_hs_error;
316 }
David Benjamin6e4fc332016-11-17 16:43:08 +0900317 } else if (!tls13_advance_key_schedule(hs, kZeroes, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400318 return ssl_hs_error;
319 }
320
David Benjaminf01f42a2016-11-16 19:05:33 +0900321 ssl->method->received_flight(ssl);
322
Steven Valdez143e8b32016-07-11 13:19:03 -0400323 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400324 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900325 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400326 if (need_retry) {
David Benjamin3977f302016-12-11 13:30:41 -0500327 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400328 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400329 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400330 return ssl_hs_error;
331 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400332
David Benjamin3977f302016-12-11 13:30:41 -0500333 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400334 return ssl_hs_ok;
335}
Steven Valdez143e8b32016-07-11 13:19:03 -0400336
David Benjaminc3c88822016-11-14 10:32:04 +0900337static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
338 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400339 CBB cbb, body, extensions;
340 uint16_t group_id;
341 if (!ssl->method->init_message(ssl, &cbb, &body,
342 SSL3_MT_HELLO_RETRY_REQUEST) ||
343 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900344 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400345 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400346 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
347 !CBB_add_u16(&extensions, 2 /* length */) ||
348 !CBB_add_u16(&extensions, group_id) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500349 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400350 CBB_cleanup(&cbb);
351 return ssl_hs_error;
352 }
353
David Benjamin3977f302016-12-11 13:30:41 -0500354 hs->tls13_state = state_process_second_client_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400355 return ssl_hs_flush_and_read_message;
356}
357
David Benjaminc3c88822016-11-14 10:32:04 +0900358static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
359 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400360 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
361 return ssl_hs_error;
362 }
363
David Benjamin731058e2016-12-03 23:15:13 -0500364 SSL_CLIENT_HELLO client_hello;
365 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
366 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400367 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
368 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
369 return ssl_hs_error;
370 }
371
372 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900373 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400374 if (need_retry) {
375 /* Only send one HelloRetryRequest. */
376 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
377 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400378 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400379 return ssl_hs_error;
380 }
381
David Benjaminced94792016-11-14 17:12:11 +0900382 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400383 return ssl_hs_error;
384 }
385
David Benjamin613fe3b2016-07-22 17:39:29 +0200386 ssl->method->received_flight(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500387 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400388 return ssl_hs_ok;
389}
390
David Benjaminc3c88822016-11-14 10:32:04 +0900391static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
392 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400393 CBB cbb, body, extensions;
394 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
395 !CBB_add_u16(&body, ssl->version) ||
396 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
397 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
398 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
399 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900400 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
David Benjamin6f600d62016-12-21 16:06:54 -0500401 !ssl_ext_key_share_add_serverhello(hs, &extensions)) {
402 goto err;
403 }
404
405 if (ssl->s3->short_header) {
406 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_short_header) ||
407 !CBB_add_u16(&extensions, 0 /* empty extension */)) {
408 goto err;
409 }
410 }
411
David Benjamindaf207a2017-01-03 18:37:41 -0500412 if (!ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400413 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400414 }
415
David Benjamin3977f302016-12-11 13:30:41 -0500416 hs->tls13_state = state_send_encrypted_extensions;
David Benjamin25ac2512017-01-12 19:31:28 -0500417 return ssl_hs_ok;
Steven Valdez803c77a2016-09-06 14:13:43 -0400418
419err:
420 CBB_cleanup(&cbb);
421 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400422}
423
David Benjaminc3c88822016-11-14 10:32:04 +0900424static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL_HANDSHAKE *hs) {
425 SSL *const ssl = hs->ssl;
Steven Valdez4cb84942016-12-16 11:29:28 -0500426 if (!tls13_derive_handshake_secrets(hs) ||
427 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
428 hs->hash_len) ||
429 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
430 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400431 return ssl_hs_error;
432 }
433
434 CBB cbb, body;
435 if (!ssl->method->init_message(ssl, &cbb, &body,
436 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500437 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500438 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400439 CBB_cleanup(&cbb);
440 return ssl_hs_error;
441 }
442
David Benjamin3977f302016-12-11 13:30:41 -0500443 hs->tls13_state = state_send_certificate_request;
David Benjamin25ac2512017-01-12 19:31:28 -0500444 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400445}
446
David Benjaminc3c88822016-11-14 10:32:04 +0900447static enum ssl_hs_wait_t do_send_certificate_request(SSL_HANDSHAKE *hs) {
448 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400449 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900450 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400451 /* CertificateRequest may only be sent in non-resumption handshakes. */
452 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900453 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400454 }
455
David Benjaminc3c88822016-11-14 10:32:04 +0900456 if (!hs->cert_request) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400457 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500458 hs->tls13_state = state_send_server_certificate;
Steven Valdez143e8b32016-07-11 13:19:03 -0400459 return ssl_hs_ok;
460 }
461
462 CBB cbb, body, sigalgs_cbb;
463 if (!ssl->method->init_message(ssl, &cbb, &body,
464 SSL3_MT_CERTIFICATE_REQUEST) ||
465 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
466 goto err;
467 }
468
469 const uint16_t *sigalgs;
David Benjamin3ef76972016-10-17 17:59:54 -0400470 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400471 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
472 goto err;
473 }
474
David Benjamin0fc37ef2016-08-17 15:29:46 -0400475 for (size_t i = 0; i < num_sigalgs; i++) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400476 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
477 goto err;
478 }
479 }
480
481 if (!ssl_add_client_CA_list(ssl, &body) ||
482 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500483 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400484 goto err;
485 }
486
David Benjamin3977f302016-12-11 13:30:41 -0500487 hs->tls13_state = state_send_server_certificate;
David Benjamin25ac2512017-01-12 19:31:28 -0500488 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400489
490err:
491 CBB_cleanup(&cbb);
492 return ssl_hs_error;
493}
494
David Benjaminc3c88822016-11-14 10:32:04 +0900495static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
496 SSL *const ssl = hs->ssl;
Steven Valdez803c77a2016-09-06 14:13:43 -0400497 if (ssl->s3->session_reused) {
David Benjamin3977f302016-12-11 13:30:41 -0500498 hs->tls13_state = state_send_server_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400499 return ssl_hs_ok;
500 }
501
502 if (!ssl_has_certificate(ssl)) {
503 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
504 return ssl_hs_error;
505 }
506
David Benjamin6e4fc332016-11-17 16:43:08 +0900507 if (!tls13_prepare_certificate(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400508 return ssl_hs_error;
509 }
510
David Benjamin3977f302016-12-11 13:30:41 -0500511 hs->tls13_state = state_send_server_certificate_verify;
David Benjamin25ac2512017-01-12 19:31:28 -0500512 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400513}
514
David Benjaminc3c88822016-11-14 10:32:04 +0900515static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400516 int is_first_run) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900517 switch (tls13_prepare_certificate_verify(hs, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400518 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500519 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500520 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400521
522 case ssl_private_key_retry:
David Benjamin3977f302016-12-11 13:30:41 -0500523 hs->tls13_state = state_complete_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400524 return ssl_hs_private_key_operation;
525
526 case ssl_private_key_failure:
527 return ssl_hs_error;
528 }
529
530 assert(0);
531 return ssl_hs_error;
532}
533
David Benjaminc3c88822016-11-14 10:32:04 +0900534static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900535 SSL *const ssl = hs->ssl;
David Benjamin25ac2512017-01-12 19:31:28 -0500536 if (!tls13_prepare_finished(hs) ||
537 /* Update the secret to the master secret and derive traffic keys. */
538 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900539 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400540 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
541 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400542 return ssl_hs_error;
543 }
544
David Benjamin3977f302016-12-11 13:30:41 -0500545 hs->tls13_state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200546 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400547}
548
David Benjaminc3c88822016-11-14 10:32:04 +0900549static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
550 SSL *const ssl = hs->ssl;
551 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700552 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400553 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700554 ssl->s3->new_session->verify_result = X509_V_OK;
555
Steven Valdez143e8b32016-07-11 13:19:03 -0400556 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500557 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400558 return ssl_hs_ok;
559 }
560
David Benjamin4087df92016-08-01 20:16:31 -0400561 const int allow_anonymous =
562 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
563
Steven Valdez143e8b32016-07-11 13:19:03 -0400564 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
Adam Langley0c294252016-12-12 11:46:09 -0800565 !tls13_process_certificate(hs, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900566 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400567 return ssl_hs_error;
568 }
569
David Benjamin3977f302016-12-11 13:30:41 -0500570 hs->tls13_state = state_process_client_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400571 return ssl_hs_read_message;
572}
573
574static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900575 SSL_HANDSHAKE *hs) {
576 SSL *const ssl = hs->ssl;
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800577 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400578 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500579 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400580 return ssl_hs_ok;
581 }
582
583 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
Adam Langley0c294252016-12-12 11:46:09 -0800584 !tls13_process_certificate_verify(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900585 !ssl_hash_current_message(ssl)) {
David Benjamin6929f272016-11-16 19:10:08 +0900586 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400587 }
588
David Benjamin3977f302016-12-11 13:30:41 -0500589 hs->tls13_state = state_process_channel_id;
Nick Harper60a85cb2016-09-23 16:25:11 -0700590 return ssl_hs_read_message;
591}
592
David Benjaminc3c88822016-11-14 10:32:04 +0900593static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
594 SSL *const ssl = hs->ssl;
Nick Harper60a85cb2016-09-23 16:25:11 -0700595 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin3977f302016-12-11 13:30:41 -0500596 hs->tls13_state = state_process_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700597 return ssl_hs_ok;
598 }
599
600 if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
601 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900602 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700603 return ssl_hs_error;
604 }
605
David Benjamin3977f302016-12-11 13:30:41 -0500606 hs->tls13_state = state_process_client_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400607 return ssl_hs_read_message;
608}
609
David Benjaminc3c88822016-11-14 10:32:04 +0900610static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
611 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400612 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900613 !tls13_process_finished(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900614 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400615 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400616 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
617 hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900618 !tls13_derive_resumption_secret(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400619 return ssl_hs_error;
620 }
621
David Benjamin613fe3b2016-07-22 17:39:29 +0200622 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400623
624 /* Refresh the session timestamp so that it is measured from ticket
625 * issuance. */
626 ssl_session_refresh_time(ssl, ssl->s3->new_session);
David Benjamin3977f302016-12-11 13:30:41 -0500627 hs->tls13_state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400628 return ssl_hs_ok;
629}
630
David Benjaminc3c88822016-11-14 10:32:04 +0900631static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjamin25ac2512017-01-12 19:31:28 -0500632 /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
633 * client makes several connections before getting a renewal. */
634 static const int kNumTickets = 2;
635
David Benjaminc3c88822016-11-14 10:32:04 +0900636 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400637 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
638 * session ticket. */
639 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500640 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400641 return ssl_hs_ok;
642 }
643
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400644 SSL_SESSION *session = ssl->s3->new_session;
David Benjamin25ac2512017-01-12 19:31:28 -0500645 CBB cbb;
646 CBB_zero(&cbb);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400647
David Benjamin25ac2512017-01-12 19:31:28 -0500648 for (int i = 0; i < kNumTickets; i++) {
649 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
650 goto err;
651 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400652
David Benjamin25ac2512017-01-12 19:31:28 -0500653 CBB body, ticket, extensions;
654 if (!ssl->method->init_message(ssl, &cbb, &body,
655 SSL3_MT_NEW_SESSION_TICKET) ||
656 !CBB_add_u32(&body, session->timeout) ||
657 !CBB_add_u32(&body, session->ticket_age_add) ||
658 !CBB_add_u16_length_prefixed(&body, &ticket) ||
659 !ssl_encrypt_ticket(ssl, &ticket, session) ||
660 !CBB_add_u16_length_prefixed(&body, &extensions)) {
661 goto err;
662 }
Steven Valdez08b65f42016-12-07 15:29:45 -0500663
David Benjamin25ac2512017-01-12 19:31:28 -0500664 if (ssl->ctx->enable_early_data) {
665 session->ticket_max_early_data = kMaxEarlyDataAccepted;
666
667 CBB early_data_info;
668 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
669 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
670 !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
671 !CBB_flush(&extensions)) {
672 goto err;
673 }
674 }
675
676 /* Add a fake extension. See draft-davidben-tls-grease-01. */
677 if (!CBB_add_u16(&extensions,
678 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
679 !CBB_add_u16(&extensions, 0 /* empty */)) {
680 goto err;
681 }
682
683 if (!ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez08b65f42016-12-07 15:29:45 -0500684 goto err;
685 }
686 }
687
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400688 hs->session_tickets_sent++;
David Benjamin25ac2512017-01-12 19:31:28 -0500689 hs->tls13_state = state_done;
690 return ssl_hs_flush;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400691
692err:
693 CBB_cleanup(&cbb);
694 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400695}
696
David Benjaminc3c88822016-11-14 10:32:04 +0900697enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500698 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400699 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamin3977f302016-12-11 13:30:41 -0500700 enum server_hs_state_t state = hs->tls13_state;
Steven Valdez143e8b32016-07-11 13:19:03 -0400701 switch (state) {
702 case state_process_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900703 ret = do_process_client_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400704 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400705 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900706 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400707 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400708 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900709 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400710 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400711 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900712 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400713 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400714 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900715 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400716 break;
717 case state_send_encrypted_extensions:
David Benjaminc3c88822016-11-14 10:32:04 +0900718 ret = do_send_encrypted_extensions(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400719 break;
720 case state_send_certificate_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900721 ret = do_send_certificate_request(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400722 break;
723 case state_send_server_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900724 ret = do_send_server_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400725 break;
726 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900727 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400728 break;
729 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900730 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400731 break;
732 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900733 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400734 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400735 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900736 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400737 break;
738 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900739 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400740 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700741 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900742 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700743 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400744 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900745 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400746 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400747 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900748 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400749 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400750 case state_done:
751 ret = ssl_hs_ok;
752 break;
753 }
754
755 if (ret != ssl_hs_ok) {
756 return ret;
757 }
758 }
759
760 return ssl_hs_ok;
761}