blob: 52b267232921de84d5cf1f370137c3d7a913c45a [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,
Steven Valdez143e8b32016-07-11 13:19:03 -040043 state_send_server_certificate_verify,
44 state_complete_server_certificate_verify,
45 state_send_server_finished,
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,
Steven Valdez143e8b32016-07-11 13:19:03 -040051 state_done,
52};
53
Steven Valdez5440fe02016-07-18 12:40:30 -040054static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
55
David Benjamin6e4fc332016-11-17 16:43:08 +090056static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, int *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050057 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090058 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -040059 *out_need_retry = 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040060
Steven Valdez803c77a2016-09-06 14:13:43 -040061 /* We only support connections that include an ECDHE key exchange. */
Steven Valdez5440fe02016-07-18 12:40:30 -040062 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050063 if (!ssl_client_hello_get_extension(client_hello, &key_share,
64 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040065 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
66 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090067 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040068 }
69
Steven Valdez5440fe02016-07-18 12:40:30 -040070 int found_key_share;
71 uint8_t *dhe_secret;
72 size_t dhe_secret_len;
David Benjamin7e1f9842016-09-20 19:24:40 -040073 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090074 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
Steven Valdez7259f2f2016-08-02 16:55:05 -040075 &dhe_secret_len, &alert,
76 &key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040077 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
78 return 0;
79 }
80
81 if (!found_key_share) {
82 *out_need_retry = 1;
83 return 0;
84 }
85
David Benjamin6e4fc332016-11-17 16:43:08 +090086 int ok = tls13_advance_key_schedule(hs, dhe_secret, dhe_secret_len);
Steven Valdez5440fe02016-07-18 12:40:30 -040087 OPENSSL_free(dhe_secret);
88 return ok;
89}
90
David Benjaminc3c88822016-11-14 10:32:04 +090091static enum ssl_hs_wait_t do_process_client_hello(SSL_HANDSHAKE *hs) {
92 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -050093 if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez143e8b32016-07-11 13:19:03 -040094 return ssl_hs_error;
95 }
96
David Benjamin731058e2016-12-03 23:15:13 -050097 SSL_CLIENT_HELLO client_hello;
98 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
99 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400100 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
101 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
102 return ssl_hs_error;
103 }
104
Steven Valdez143e8b32016-07-11 13:19:03 -0400105 assert(ssl->s3->have_version);
106
107 /* Load the client random. */
David Benjamine14ff062016-08-09 16:21:24 -0400108 if (client_hello.random_len != SSL3_RANDOM_SIZE) {
109 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6929f272016-11-16 19:10:08 +0900110 return ssl_hs_error;
David Benjamine14ff062016-08-09 16:21:24 -0400111 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500112 OPENSSL_memcpy(ssl->s3->client_random, client_hello.random,
113 client_hello.random_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400114
David Benjamin4eb95cc2016-11-16 17:08:23 +0900115 /* TLS 1.3 requires the peer only advertise the null compression. */
116 if (client_hello.compression_methods_len != 1 ||
117 client_hello.compression_methods[0] != 0) {
118 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
119 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
David Benjamin6929f272016-11-16 19:10:08 +0900120 return ssl_hs_error;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400121 }
122
David Benjamin4eb95cc2016-11-16 17:08:23 +0900123 /* TLS extensions. */
David Benjamin8c880a22016-12-03 02:20:34 -0500124 if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900125 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
126 return ssl_hs_error;
127 }
Steven Valdeza833c352016-11-01 13:39:36 -0400128
David Benjamin6f600d62016-12-21 16:06:54 -0500129 /* The short record header extension is incompatible with early data. */
130 if (ssl->s3->skip_early_data && ssl->s3->short_header) {
131 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
132 return ssl_hs_error;
133 }
134
David Benjamin3977f302016-12-11 13:30:41 -0500135 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900136 return ssl_hs_ok;
137}
138
139static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -0500140 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +0900141 if (client_hello->cipher_suites_len % 2 != 0) {
142 return NULL;
143 }
144
145 CBS cipher_suites;
146 CBS_init(&cipher_suites, client_hello->cipher_suites,
147 client_hello->cipher_suites_len);
148
149 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900150 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900151
152 const SSL_CIPHER *best = NULL;
153 while (CBS_len(&cipher_suites) > 0) {
154 uint16_t cipher_suite;
155 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
156 return NULL;
157 }
158
David Benjaminf01f42a2016-11-16 19:05:33 +0900159 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900160 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900161 if (candidate == NULL ||
162 SSL_CIPHER_get_min_version(candidate) > version ||
163 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900164 continue;
165 }
166
167 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
168 * ChaCha20 if we do not have AES hardware. */
169 if (aes_is_fine) {
170 return candidate;
171 }
172
173 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
174 return candidate;
175 }
176
177 if (best == NULL) {
178 best = candidate;
179 }
180 }
181
182 return best;
183}
184
David Benjaminc3c88822016-11-14 10:32:04 +0900185static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
186 SSL *const ssl = hs->ssl;
David Benjamin34202b92016-11-16 19:07:53 +0900187 /* Call |cert_cb| to update server certificates if required. */
188 if (ssl->cert->cert_cb != NULL) {
189 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
190 if (rv == 0) {
191 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
192 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
193 return ssl_hs_error;
194 }
195 if (rv < 0) {
David Benjamin3977f302016-12-11 13:30:41 -0500196 hs->tls13_state = state_select_parameters;
David Benjamin34202b92016-11-16 19:07:53 +0900197 return ssl_hs_x509_lookup;
198 }
199 }
200
David Benjamin650aa1c2016-12-20 18:55:16 -0500201 if (!ssl_auto_chain_if_needed(ssl)) {
202 return ssl_hs_error;
203 }
204
David Benjamin731058e2016-12-03 23:15:13 -0500205 SSL_CLIENT_HELLO client_hello;
206 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
207 ssl->init_num)) {
David Benjamin34202b92016-11-16 19:07:53 +0900208 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
209 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
210 return ssl_hs_error;
211 }
212
David Benjaminf01f42a2016-11-16 19:05:33 +0900213 /* Negotiate the cipher suite. */
214 ssl->s3->tmp.new_cipher = choose_tls13_cipher(ssl, &client_hello);
215 if (ssl->s3->tmp.new_cipher == NULL) {
216 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
217 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
218 return ssl_hs_error;
219 }
220
221 /* Decode the ticket if we agree on a PSK key exchange mode. */
David Benjamin4eb95cc2016-11-16 17:08:23 +0900222 uint8_t alert = SSL_AD_DECODE_ERROR;
223 SSL_SESSION *session = NULL;
224 CBS pre_shared_key, binders;
225 if (hs->accept_psk_mode &&
David Benjamin731058e2016-12-03 23:15:13 -0500226 ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
227 TLSEXT_TYPE_pre_shared_key)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900228 /* Verify that the pre_shared_key extension is the last extension in
229 * ClientHello. */
230 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
231 client_hello.extensions + client_hello.extensions_len) {
232 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
233 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
234 return ssl_hs_error;
235 }
236
David Benjamin8baf9632016-11-17 17:11:16 +0900237 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &session, &binders,
David Benjamin4eb95cc2016-11-16 17:08:23 +0900238 &alert, &pre_shared_key)) {
239 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
240 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400241 }
242 }
243
Steven Valdez4aa154e2016-07-29 14:32:55 -0400244 if (session != NULL &&
David Benjamin75f99142016-11-12 12:36:06 +0900245 !ssl_session_is_resumable(ssl, session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400246 SSL_SESSION_free(session);
247 session = NULL;
248 }
249
David Benjaminf01f42a2016-11-16 19:05:33 +0900250 /* Set up the new session, either using the original one as a template or
251 * creating a fresh one. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400252 if (session == NULL) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900253 if (!ssl_get_new_session(hs, 1 /* server */)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400254 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
255 return ssl_hs_error;
256 }
David Benjaminf01f42a2016-11-16 19:05:33 +0900257
258 ssl->s3->new_session->cipher = ssl->s3->tmp.new_cipher;
259
260 /* On new sessions, stash the SNI value in the session. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900261 if (hs->hostname != NULL) {
262 ssl->s3->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
David Benjaminf01f42a2016-11-16 19:05:33 +0900263 if (ssl->s3->new_session->tlsext_hostname == NULL) {
264 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
265 return ssl_hs_error;
266 }
267 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400268 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400269 /* Check the PSK binder. */
270 if (!tls13_verify_psk_binder(ssl, session, &binders)) {
271 SSL_SESSION_free(session);
272 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
273 return ssl_hs_error;
274 }
275
Steven Valdez4aa154e2016-07-29 14:32:55 -0400276 /* Only authentication information carries over in TLS 1.3. */
277 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
278 if (ssl->s3->new_session == NULL) {
279 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
280 return ssl_hs_error;
281 }
282 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400283 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400284 }
285
286 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400287 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400288 /* Connection rejected for DOS reasons. */
289 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400290 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400291 return ssl_hs_error;
292 }
293
David Benjaminf01f42a2016-11-16 19:05:33 +0900294 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
295 * deferred. Complete it now. */
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900296 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamin9ef31f02016-10-31 18:01:13 -0400297 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
298 return ssl_hs_error;
299 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400300
David Benjamin8f820b42016-11-30 11:24:40 -0500301 /* The PRF hash is now known. Set up the key schedule. */
Steven Valdez803c77a2016-09-06 14:13:43 -0400302 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400303 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
David Benjamin6e4fc332016-11-17 16:43:08 +0900304 if (!tls13_init_key_schedule(hs)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500305 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400306 }
307
David Benjamin8f820b42016-11-30 11:24:40 -0500308 /* Incorporate the PSK into the running secret. */
309 if (ssl->s3->session_reused) {
David Benjamin6e4fc332016-11-17 16:43:08 +0900310 if (!tls13_advance_key_schedule(hs, ssl->s3->new_session->master_key,
David Benjamin8f820b42016-11-30 11:24:40 -0500311 ssl->s3->new_session->master_key_length)) {
312 return ssl_hs_error;
313 }
David Benjamin6e4fc332016-11-17 16:43:08 +0900314 } else if (!tls13_advance_key_schedule(hs, kZeroes, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400315 return ssl_hs_error;
316 }
317
David Benjaminf01f42a2016-11-16 19:05:33 +0900318 ssl->method->received_flight(ssl);
319
Steven Valdez143e8b32016-07-11 13:19:03 -0400320 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400321 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900322 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400323 if (need_retry) {
David Benjamin3977f302016-12-11 13:30:41 -0500324 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400325 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400326 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400327 return ssl_hs_error;
328 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400329
David Benjamin3977f302016-12-11 13:30:41 -0500330 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400331 return ssl_hs_ok;
332}
Steven Valdez143e8b32016-07-11 13:19:03 -0400333
David Benjaminc3c88822016-11-14 10:32:04 +0900334static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
335 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400336 CBB cbb, body, extensions;
337 uint16_t group_id;
338 if (!ssl->method->init_message(ssl, &cbb, &body,
339 SSL3_MT_HELLO_RETRY_REQUEST) ||
340 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900341 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400342 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400343 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
344 !CBB_add_u16(&extensions, 2 /* length */) ||
345 !CBB_add_u16(&extensions, group_id) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500346 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400347 CBB_cleanup(&cbb);
348 return ssl_hs_error;
349 }
350
David Benjamin3977f302016-12-11 13:30:41 -0500351 hs->tls13_state = state_process_second_client_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400352 return ssl_hs_flush_and_read_message;
353}
354
David Benjaminc3c88822016-11-14 10:32:04 +0900355static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
356 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -0500357 if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400358 return ssl_hs_error;
359 }
360
David Benjamin731058e2016-12-03 23:15:13 -0500361 SSL_CLIENT_HELLO client_hello;
362 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
363 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400364 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
365 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
366 return ssl_hs_error;
367 }
368
369 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900370 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400371 if (need_retry) {
372 /* Only send one HelloRetryRequest. */
373 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
374 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400375 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400376 return ssl_hs_error;
377 }
378
David Benjaminced94792016-11-14 17:12:11 +0900379 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400380 return ssl_hs_error;
381 }
382
David Benjamin613fe3b2016-07-22 17:39:29 +0200383 ssl->method->received_flight(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500384 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400385 return ssl_hs_ok;
386}
387
David Benjaminc3c88822016-11-14 10:32:04 +0900388static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
389 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500390
391 /* Send a ServerHello. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400392 CBB cbb, body, extensions;
393 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
394 !CBB_add_u16(&body, ssl->version) ||
395 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
396 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
397 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
398 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900399 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
David Benjamin6f600d62016-12-21 16:06:54 -0500400 !ssl_ext_key_share_add_serverhello(hs, &extensions)) {
401 goto err;
402 }
403
404 if (ssl->s3->short_header) {
405 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_short_header) ||
406 !CBB_add_u16(&extensions, 0 /* empty extension */)) {
407 goto err;
408 }
409 }
410
David Benjamindaf207a2017-01-03 18:37:41 -0500411 if (!ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400412 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400413 }
414
David Benjamin81b7bc32017-01-12 19:44:57 -0500415 /* Derive and enable the handshake traffic secrets. */
Steven Valdez4cb84942016-12-16 11:29:28 -0500416 if (!tls13_derive_handshake_secrets(hs) ||
417 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
418 hs->hash_len) ||
419 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
420 hs->hash_len)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500421 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400422 }
423
David Benjamin81b7bc32017-01-12 19:44:57 -0500424 /* Send EncryptedExtensions. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400425 if (!ssl->method->init_message(ssl, &cbb, &body,
426 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500427 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500428 !ssl_add_message_cbb(ssl, &cbb)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500429 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400430 }
431
Steven Valdez143e8b32016-07-11 13:19:03 -0400432 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900433 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400434 /* CertificateRequest may only be sent in non-resumption handshakes. */
435 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900436 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400437 }
438
David Benjamin81b7bc32017-01-12 19:44:57 -0500439 /* Send a CertificateRequest, if necessary. */
440 if (hs->cert_request) {
441 CBB sigalgs_cbb;
442 if (!ssl->method->init_message(ssl, &cbb, &body,
443 SSL3_MT_CERTIFICATE_REQUEST) ||
444 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
445 goto err;
446 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400447
David Benjamin81b7bc32017-01-12 19:44:57 -0500448 const uint16_t *sigalgs;
449 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
450 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
451 goto err;
452 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400453
David Benjamin81b7bc32017-01-12 19:44:57 -0500454 for (size_t i = 0; i < num_sigalgs; i++) {
455 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
456 goto err;
457 }
458 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400459
David Benjamin81b7bc32017-01-12 19:44:57 -0500460 if (!ssl_add_client_CA_list(ssl, &body) ||
461 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
462 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400463 goto err;
464 }
465 }
466
David Benjamin81b7bc32017-01-12 19:44:57 -0500467 /* Send the server Certificate message, if necessary. */
468 if (!ssl->s3->session_reused) {
469 if (!ssl_has_certificate(ssl)) {
470 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
471 goto err;
472 }
473
David Benjamin0f24bed2017-01-12 19:46:50 -0500474 if (!tls13_add_certificate(hs)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500475 goto err;
476 }
477
478 hs->tls13_state = state_send_server_certificate_verify;
479 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400480 }
481
David Benjamin81b7bc32017-01-12 19:44:57 -0500482 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500483 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400484
485err:
486 CBB_cleanup(&cbb);
487 return ssl_hs_error;
488}
489
David Benjaminc3c88822016-11-14 10:32:04 +0900490static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400491 int is_first_run) {
David Benjamin0f24bed2017-01-12 19:46:50 -0500492 switch (tls13_add_certificate_verify(hs, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400493 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500494 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500495 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400496
497 case ssl_private_key_retry:
David Benjamin3977f302016-12-11 13:30:41 -0500498 hs->tls13_state = state_complete_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400499 return ssl_hs_private_key_operation;
500
501 case ssl_private_key_failure:
502 return ssl_hs_error;
503 }
504
505 assert(0);
506 return ssl_hs_error;
507}
508
David Benjaminc3c88822016-11-14 10:32:04 +0900509static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900510 SSL *const ssl = hs->ssl;
David Benjamin0f24bed2017-01-12 19:46:50 -0500511 if (!tls13_add_finished(hs) ||
David Benjamin25ac2512017-01-12 19:31:28 -0500512 /* Update the secret to the master secret and derive traffic keys. */
513 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900514 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400515 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
516 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400517 return ssl_hs_error;
518 }
519
David Benjamin3977f302016-12-11 13:30:41 -0500520 hs->tls13_state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200521 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400522}
523
David Benjaminc3c88822016-11-14 10:32:04 +0900524static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
525 SSL *const ssl = hs->ssl;
526 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700527 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400528 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700529 ssl->s3->new_session->verify_result = X509_V_OK;
530
Steven Valdez143e8b32016-07-11 13:19:03 -0400531 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500532 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400533 return ssl_hs_ok;
534 }
535
David Benjamin4087df92016-08-01 20:16:31 -0400536 const int allow_anonymous =
537 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
538
David Benjamin276b7e82017-01-21 14:13:39 -0500539 if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
Adam Langley0c294252016-12-12 11:46:09 -0800540 !tls13_process_certificate(hs, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900541 !ssl_hash_current_message(ssl)) {
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_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400546 return ssl_hs_read_message;
547}
548
549static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900550 SSL_HANDSHAKE *hs) {
551 SSL *const ssl = hs->ssl;
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800552 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400553 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500554 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400555 return ssl_hs_ok;
556 }
557
David Benjamin276b7e82017-01-21 14:13:39 -0500558 if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
Adam Langley0c294252016-12-12 11:46:09 -0800559 !tls13_process_certificate_verify(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900560 !ssl_hash_current_message(ssl)) {
David Benjamin6929f272016-11-16 19:10:08 +0900561 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400562 }
563
David Benjamin3977f302016-12-11 13:30:41 -0500564 hs->tls13_state = state_process_channel_id;
Nick Harper60a85cb2016-09-23 16:25:11 -0700565 return ssl_hs_read_message;
566}
567
David Benjaminc3c88822016-11-14 10:32:04 +0900568static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
569 SSL *const ssl = hs->ssl;
Nick Harper60a85cb2016-09-23 16:25:11 -0700570 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin3977f302016-12-11 13:30:41 -0500571 hs->tls13_state = state_process_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700572 return ssl_hs_ok;
573 }
574
David Benjamin276b7e82017-01-21 14:13:39 -0500575 if (!ssl_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
Nick Harper60a85cb2016-09-23 16:25:11 -0700576 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900577 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700578 return ssl_hs_error;
579 }
580
David Benjamin3977f302016-12-11 13:30:41 -0500581 hs->tls13_state = state_process_client_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400582 return ssl_hs_read_message;
583}
584
David Benjaminc3c88822016-11-14 10:32:04 +0900585static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
586 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -0500587 if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900588 !tls13_process_finished(hs) ||
David Benjaminced94792016-11-14 17:12:11 +0900589 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400590 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400591 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
592 hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900593 !tls13_derive_resumption_secret(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400594 return ssl_hs_error;
595 }
596
David Benjamin613fe3b2016-07-22 17:39:29 +0200597 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400598
599 /* Refresh the session timestamp so that it is measured from ticket
600 * issuance. */
601 ssl_session_refresh_time(ssl, ssl->s3->new_session);
David Benjamin3977f302016-12-11 13:30:41 -0500602 hs->tls13_state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400603 return ssl_hs_ok;
604}
605
David Benjaminc3c88822016-11-14 10:32:04 +0900606static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjamin25ac2512017-01-12 19:31:28 -0500607 /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
608 * client makes several connections before getting a renewal. */
609 static const int kNumTickets = 2;
610
David Benjaminc3c88822016-11-14 10:32:04 +0900611 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400612 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
613 * session ticket. */
614 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500615 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400616 return ssl_hs_ok;
617 }
618
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400619 SSL_SESSION *session = ssl->s3->new_session;
David Benjamin25ac2512017-01-12 19:31:28 -0500620 CBB cbb;
621 CBB_zero(&cbb);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400622
David Benjamin25ac2512017-01-12 19:31:28 -0500623 for (int i = 0; i < kNumTickets; i++) {
624 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
625 goto err;
626 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400627
David Benjamin25ac2512017-01-12 19:31:28 -0500628 CBB body, ticket, extensions;
629 if (!ssl->method->init_message(ssl, &cbb, &body,
630 SSL3_MT_NEW_SESSION_TICKET) ||
631 !CBB_add_u32(&body, session->timeout) ||
632 !CBB_add_u32(&body, session->ticket_age_add) ||
633 !CBB_add_u16_length_prefixed(&body, &ticket) ||
634 !ssl_encrypt_ticket(ssl, &ticket, session) ||
635 !CBB_add_u16_length_prefixed(&body, &extensions)) {
636 goto err;
637 }
Steven Valdez08b65f42016-12-07 15:29:45 -0500638
David Benjamin25ac2512017-01-12 19:31:28 -0500639 if (ssl->ctx->enable_early_data) {
640 session->ticket_max_early_data = kMaxEarlyDataAccepted;
641
642 CBB early_data_info;
643 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
644 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
645 !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
646 !CBB_flush(&extensions)) {
647 goto err;
648 }
649 }
650
651 /* Add a fake extension. See draft-davidben-tls-grease-01. */
652 if (!CBB_add_u16(&extensions,
653 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
654 !CBB_add_u16(&extensions, 0 /* empty */)) {
655 goto err;
656 }
657
658 if (!ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez08b65f42016-12-07 15:29:45 -0500659 goto err;
660 }
661 }
662
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400663 hs->session_tickets_sent++;
David Benjamin25ac2512017-01-12 19:31:28 -0500664 hs->tls13_state = state_done;
665 return ssl_hs_flush;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400666
667err:
668 CBB_cleanup(&cbb);
669 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400670}
671
David Benjaminc3c88822016-11-14 10:32:04 +0900672enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500673 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400674 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamin3977f302016-12-11 13:30:41 -0500675 enum server_hs_state_t state = hs->tls13_state;
Steven Valdez143e8b32016-07-11 13:19:03 -0400676 switch (state) {
677 case state_process_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900678 ret = do_process_client_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400679 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400680 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900681 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400682 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400683 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900684 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400685 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400686 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900687 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400688 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400689 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900690 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400691 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400692 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900693 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400694 break;
695 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900696 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400697 break;
698 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900699 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400700 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400701 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900702 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400703 break;
704 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900705 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400706 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700707 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900708 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700709 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400710 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900711 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400712 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400713 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900714 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400715 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400716 case state_done:
717 ret = ssl_hs_ok;
718 break;
719 }
720
721 if (ret != ssl_hs_ok) {
722 return ret;
723 }
724 }
725
726 return ssl_hs_ok;
727}