blob: a3517ba47a10bc25ea14389b7b16891a247469f0 [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
20#include <openssl/bytestring.h>
21#include <openssl/digest.h>
22#include <openssl/err.h>
23#include <openssl/mem.h>
24#include <openssl/rand.h>
25#include <openssl/stack.h>
26
27#include "internal.h"
28
29
30enum server_hs_state_t {
31 state_process_client_hello = 0,
Steven Valdez5440fe02016-07-18 12:40:30 -040032 state_send_hello_retry_request,
33 state_flush_hello_retry_request,
34 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040035 state_send_server_hello,
36 state_send_encrypted_extensions,
37 state_send_certificate_request,
38 state_send_server_certificate,
39 state_send_server_certificate_verify,
40 state_complete_server_certificate_verify,
41 state_send_server_finished,
42 state_flush,
Steven Valdez143e8b32016-07-11 13:19:03 -040043 state_process_client_certificate,
44 state_process_client_certificate_verify,
45 state_process_client_finished,
46 state_done,
47};
48
Steven Valdez5440fe02016-07-18 12:40:30 -040049static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
50
51static int resolve_psk_secret(SSL *ssl) {
52 SSL_HANDSHAKE *hs = ssl->s3->hs;
53
54 if (ssl->s3->tmp.new_cipher->algorithm_auth != SSL_aPSK) {
55 return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
56 }
57
58 /* TODO(davidben): Support PSK. */
59 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
60 return 0;
61}
62
63static int resolve_ecdhe_secret(SSL *ssl, int *out_need_retry,
64 struct ssl_early_callback_ctx *early_ctx) {
65 *out_need_retry = 0;
66 SSL_HANDSHAKE *hs = ssl->s3->hs;
67
68 if (ssl->s3->tmp.new_cipher->algorithm_mkey != SSL_kECDHE) {
69 return tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len);
70 }
71
72 const uint8_t *key_share_buf = NULL;
73 size_t key_share_len = 0;
74 CBS key_share;
75 if (!SSL_early_callback_ctx_extension_get(early_ctx, TLSEXT_TYPE_key_share,
76 &key_share_buf, &key_share_len)) {
77 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
78 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
79 return ssl_hs_error;
80 }
81
82 CBS_init(&key_share, key_share_buf, key_share_len);
83 int found_key_share;
84 uint8_t *dhe_secret;
85 size_t dhe_secret_len;
86 uint8_t alert;
87 if (!ext_key_share_parse_clienthello(ssl, &found_key_share, &dhe_secret,
88 &dhe_secret_len, &alert, &key_share)) {
89 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
90 return 0;
91 }
92
93 if (!found_key_share) {
94 *out_need_retry = 1;
95 return 0;
96 }
97
98 int ok = tls13_advance_key_schedule(ssl, dhe_secret, dhe_secret_len);
99 OPENSSL_free(dhe_secret);
100 return ok;
101}
102
Steven Valdez143e8b32016-07-11 13:19:03 -0400103static enum ssl_hs_wait_t do_process_client_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
104 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
105 return ssl_hs_error;
106 }
107
108 struct ssl_early_callback_ctx early_ctx;
David Benjamind7573dc2016-07-20 19:05:22 +0200109 if (!ssl_early_callback_init(ssl, &early_ctx, ssl->init_msg,
110 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400111 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
112 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
113 return ssl_hs_error;
114 }
115
David Benjamind7573dc2016-07-20 19:05:22 +0200116 CBS cbs, client_random, session_id, cipher_suites, compression_methods;
117 uint16_t client_wire_version;
Steven Valdez143e8b32016-07-11 13:19:03 -0400118 CBS_init(&cbs, ssl->init_msg, ssl->init_num);
119 if (!CBS_get_u16(&cbs, &client_wire_version) ||
120 !CBS_get_bytes(&cbs, &client_random, SSL3_RANDOM_SIZE) ||
121 !CBS_get_u8_length_prefixed(&cbs, &session_id) ||
122 CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
123 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
124 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
125 return ssl_hs_error;
126 }
127
128 uint16_t min_version, max_version;
129 if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
130 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
131 return ssl_hs_error;
132 }
133
134 assert(ssl->s3->have_version);
135
136 /* Load the client random. */
137 memcpy(ssl->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);
138
139 ssl->hit = 0;
140 if (!ssl_get_new_session(ssl, 1 /* server */)) {
141 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
142 return ssl_hs_error;
143 }
144
145 if (ssl->ctx->dos_protection_cb != NULL &&
146 ssl->ctx->dos_protection_cb(&early_ctx) == 0) {
147 /* Connection rejected for DOS reasons. */
148 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
149 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ACCESS_DENIED);
150 return ssl_hs_error;
151 }
152
153 if (!CBS_get_u16_length_prefixed(&cbs, &cipher_suites) ||
154 CBS_len(&cipher_suites) == 0 ||
155 CBS_len(&cipher_suites) % 2 != 0 ||
156 !CBS_get_u8_length_prefixed(&cbs, &compression_methods) ||
157 CBS_len(&compression_methods) == 0) {
158 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
159 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
160 return ssl_hs_error;
161 }
162
163 /* TLS 1.3 requires the peer only advertise the null compression. */
164 if (CBS_len(&compression_methods) != 1 ||
165 CBS_data(&compression_methods)[0] != 0) {
166 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
167 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
168 return ssl_hs_error;
169 }
170
171 /* TLS extensions. */
172 if (!ssl_parse_clienthello_tlsext(ssl, &cbs)) {
173 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
174 return ssl_hs_error;
175 }
176
177 /* There should be nothing left over in the message. */
178 if (CBS_len(&cbs) != 0) {
179 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
180 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
181 return ssl_hs_error;
182 }
183
184 /* Let cert callback update server certificates if required.
185 *
186 * TODO(davidben): Can this get run earlier? */
187 if (ssl->cert->cert_cb != NULL) {
188 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
189 if (rv == 0) {
190 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
191 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
192 return ssl_hs_error;
193 }
194 if (rv < 0) {
195 hs->state = state_process_client_hello;
196 return ssl_hs_x509_lookup;
197 }
198 }
199
200 STACK_OF(SSL_CIPHER) *ciphers =
201 ssl_bytes_to_cipher_list(ssl, &cipher_suites, max_version);
202 if (ciphers == NULL) {
203 return ssl_hs_error;
204 }
205
206 const SSL_CIPHER *cipher =
207 ssl3_choose_cipher(ssl, ciphers, ssl_get_cipher_preferences(ssl));
208 sk_SSL_CIPHER_free(ciphers);
209 if (cipher == NULL) {
210 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
211 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
212 return ssl_hs_error;
213 }
214
215 ssl->session->cipher = cipher;
216 ssl->s3->tmp.new_cipher = cipher;
217
David Benjamin613fe3b2016-07-22 17:39:29 +0200218 ssl->method->received_flight(ssl);
219
Steven Valdez143e8b32016-07-11 13:19:03 -0400220 /* The PRF hash is now known. Set up the key schedule and hash the
221 * ClientHello. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400222 size_t hash_len =
223 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
224 if (!tls13_init_key_schedule(ssl, kZeroes, hash_len)) {
225 return ssl_hs_error;
226 }
227
228 /* Resolve PSK and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400229 if (!resolve_psk_secret(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400230 return ssl_hs_error;
231 }
232
233 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400234 int need_retry;
235 if (!resolve_ecdhe_secret(ssl, &need_retry, &early_ctx)) {
236 if (need_retry) {
237 hs->state = state_send_hello_retry_request;
238 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400239 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400240 return ssl_hs_error;
241 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400242
Steven Valdez5440fe02016-07-18 12:40:30 -0400243 hs->state = state_send_server_hello;
244 return ssl_hs_ok;
245}
Steven Valdez143e8b32016-07-11 13:19:03 -0400246
Steven Valdez5440fe02016-07-18 12:40:30 -0400247static enum ssl_hs_wait_t do_send_hello_retry_request(SSL *ssl,
248 SSL_HANDSHAKE *hs) {
249 CBB cbb, body, extensions;
250 uint16_t group_id;
251 if (!ssl->method->init_message(ssl, &cbb, &body,
252 SSL3_MT_HELLO_RETRY_REQUEST) ||
253 !CBB_add_u16(&body, ssl->version) ||
254 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
255 !tls1_get_shared_group(ssl, &group_id) ||
256 !CBB_add_u16(&body, group_id) ||
257 !CBB_add_u16_length_prefixed(&body, &extensions) ||
258 !ssl->method->finish_message(ssl, &cbb)) {
259 CBB_cleanup(&cbb);
260 return ssl_hs_error;
261 }
262
263 hs->state = state_flush_hello_retry_request;
264 return ssl_hs_write_message;
265}
266
267static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL *ssl,
268 SSL_HANDSHAKE *hs) {
269 hs->state = state_process_second_client_hello;
270 return ssl_hs_flush_and_read_message;
271}
272
273static enum ssl_hs_wait_t do_process_second_client_hello(SSL *ssl,
274 SSL_HANDSHAKE *hs) {
275 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
276 return ssl_hs_error;
277 }
278
279 struct ssl_early_callback_ctx early_ctx;
David Benjamind7573dc2016-07-20 19:05:22 +0200280 if (!ssl_early_callback_init(ssl, &early_ctx, ssl->init_msg,
281 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400282 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
283 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
284 return ssl_hs_error;
285 }
286
287 int need_retry;
288 if (!resolve_ecdhe_secret(ssl, &need_retry, &early_ctx)) {
289 if (need_retry) {
290 /* Only send one HelloRetryRequest. */
291 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
292 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400293 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400294 return ssl_hs_error;
295 }
296
297 if (!ssl->method->hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400298 return ssl_hs_error;
299 }
300
David Benjamin613fe3b2016-07-22 17:39:29 +0200301 ssl->method->received_flight(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400302 hs->state = state_send_server_hello;
303 return ssl_hs_ok;
304}
305
306static enum ssl_hs_wait_t do_send_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
307 CBB cbb, body, extensions;
308 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
309 !CBB_add_u16(&body, ssl->version) ||
310 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
311 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
312 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
313 !CBB_add_u16_length_prefixed(&body, &extensions) ||
314 !ext_key_share_add_serverhello(ssl, &extensions) ||
315 !ssl->method->finish_message(ssl, &cbb)) {
316 CBB_cleanup(&cbb);
317 return ssl_hs_error;
318 }
319
320 hs->state = state_send_encrypted_extensions;
321 return ssl_hs_write_message;
322}
323
324static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL *ssl,
325 SSL_HANDSHAKE *hs) {
326 if (!tls13_set_handshake_traffic(ssl)) {
327 return ssl_hs_error;
328 }
329
330 CBB cbb, body;
331 if (!ssl->method->init_message(ssl, &cbb, &body,
332 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
333 !ssl_add_serverhello_tlsext(ssl, &body) ||
334 !ssl->method->finish_message(ssl, &cbb)) {
335 CBB_cleanup(&cbb);
336 return ssl_hs_error;
337 }
338
339 hs->state = state_send_certificate_request;
340 return ssl_hs_write_message;
341}
342
343static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl,
344 SSL_HANDSHAKE *hs) {
345 /* Determine whether to request a client certificate. */
346 ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
347 /* CertificateRequest may only be sent in certificate-based ciphers. */
348 if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
349 ssl->s3->tmp.cert_request = 0;
350 }
351
352 if (!ssl->s3->tmp.cert_request) {
353 /* Skip this state. */
354 hs->state = state_send_server_certificate;
355 return ssl_hs_ok;
356 }
357
358 CBB cbb, body, sigalgs_cbb;
359 if (!ssl->method->init_message(ssl, &cbb, &body,
360 SSL3_MT_CERTIFICATE_REQUEST) ||
361 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
362 goto err;
363 }
364
365 const uint16_t *sigalgs;
366 size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
367 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
368 goto err;
369 }
370
371 for (size_t i = 0; i < sigalgs_len; i++) {
372 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
373 goto err;
374 }
375 }
376
377 if (!ssl_add_client_CA_list(ssl, &body) ||
378 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
379 !ssl->method->finish_message(ssl, &cbb)) {
380 goto err;
381 }
382
383 hs->state = state_send_server_certificate;
384 return ssl_hs_write_message;
385
386err:
387 CBB_cleanup(&cbb);
388 return ssl_hs_error;
389}
390
391static enum ssl_hs_wait_t do_send_server_certificate(SSL *ssl,
392 SSL_HANDSHAKE *hs) {
393 if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
394 hs->state = state_send_server_finished;
395 return ssl_hs_ok;
396 }
397
398 if (!ssl_has_certificate(ssl)) {
399 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
400 return ssl_hs_error;
401 }
402
403 if (!tls13_prepare_certificate(ssl)) {
404 return ssl_hs_error;
405 }
406
407 hs->state = state_send_server_certificate_verify;
408 return ssl_hs_write_message;
409}
410
411static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL *ssl,
412 SSL_HANDSHAKE *hs,
413 int is_first_run) {
414 switch (tls13_prepare_certificate_verify(ssl, is_first_run)) {
415 case ssl_private_key_success:
416 hs->state = state_send_server_finished;
417 return ssl_hs_write_message;
418
419 case ssl_private_key_retry:
420 hs->state = state_complete_server_certificate_verify;
421 return ssl_hs_private_key_operation;
422
423 case ssl_private_key_failure:
424 return ssl_hs_error;
425 }
426
427 assert(0);
428 return ssl_hs_error;
429}
430
431static enum ssl_hs_wait_t do_send_server_finished(SSL *ssl, SSL_HANDSHAKE *hs) {
432 if (!tls13_prepare_finished(ssl)) {
433 return ssl_hs_error;
434 }
435
436 hs->state = state_flush;
437 return ssl_hs_write_message;
438}
439
440static enum ssl_hs_wait_t do_flush(SSL *ssl, SSL_HANDSHAKE *hs) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400441 /* Update the secret to the master secret and derive traffic keys. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400442 if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
443 !tls13_derive_traffic_secret_0(ssl) ||
444 !tls13_set_traffic_key(ssl, type_data, evp_aead_seal,
445 hs->traffic_secret_0, hs->hash_len)) {
446 return ssl_hs_error;
447 }
448
449 hs->state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200450 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400451}
452
453static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl,
454 SSL_HANDSHAKE *hs) {
455 if (!ssl->s3->tmp.cert_request) {
456 /* Skip this state. */
457 hs->state = state_process_client_certificate_verify;
458 return ssl_hs_ok;
459 }
460
461 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
462 !tls13_process_certificate(ssl) ||
463 !ssl->method->hash_current_message(ssl)) {
464 return ssl_hs_error;
465 }
466
467 hs->state = state_process_client_certificate_verify;
468 return ssl_hs_read_message;
469}
470
471static enum ssl_hs_wait_t do_process_client_certificate_verify(
472 SSL *ssl, SSL_HANDSHAKE *hs) {
473 if (ssl->session->peer == NULL) {
474 /* Skip this state. */
475 hs->state = state_process_client_finished;
476 return ssl_hs_ok;
477 }
478
479 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
480 !tls13_process_certificate_verify(ssl) ||
481 !ssl->method->hash_current_message(ssl)) {
482 return 0;
483 }
484
485 hs->state = state_process_client_finished;
486 return ssl_hs_read_message;
487}
488
489static enum ssl_hs_wait_t do_process_client_finished(SSL *ssl,
490 SSL_HANDSHAKE *hs) {
491 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
492 !tls13_process_finished(ssl) ||
493 !ssl->method->hash_current_message(ssl) ||
494 /* evp_aead_seal keys have already been switched. */
495 !tls13_set_traffic_key(ssl, type_data, evp_aead_open,
496 hs->traffic_secret_0, hs->hash_len) ||
497 !tls13_finalize_keys(ssl)) {
498 return ssl_hs_error;
499 }
500
David Benjamin613fe3b2016-07-22 17:39:29 +0200501 ssl->method->received_flight(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400502 hs->state = state_done;
503 return ssl_hs_ok;
504}
505
506enum ssl_hs_wait_t tls13_server_handshake(SSL *ssl) {
507 SSL_HANDSHAKE *hs = ssl->s3->hs;
508
509 while (hs->state != state_done) {
510 enum ssl_hs_wait_t ret = ssl_hs_error;
511 enum server_hs_state_t state = hs->state;
512 switch (state) {
513 case state_process_client_hello:
514 ret = do_process_client_hello(ssl, hs);
515 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400516 case state_send_hello_retry_request:
517 ret = do_send_hello_retry_request(ssl, hs);
518 break;
519 case state_flush_hello_retry_request:
520 ret = do_flush_hello_retry_request(ssl, hs);
521 break;
522 case state_process_second_client_hello:
523 ret = do_process_second_client_hello(ssl, hs);
524 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400525 case state_send_server_hello:
526 ret = do_send_server_hello(ssl, hs);
527 break;
528 case state_send_encrypted_extensions:
529 ret = do_send_encrypted_extensions(ssl, hs);
530 break;
531 case state_send_certificate_request:
532 ret = do_send_certificate_request(ssl, hs);
533 break;
534 case state_send_server_certificate:
535 ret = do_send_server_certificate(ssl, hs);
536 break;
537 case state_send_server_certificate_verify:
538 ret = do_send_server_certificate_verify(ssl, hs, 1 /* first run */);
539 break;
540 case state_complete_server_certificate_verify:
541 ret = do_send_server_certificate_verify(ssl, hs, 0 /* complete */);
542 break;
543 case state_send_server_finished:
544 ret = do_send_server_finished(ssl, hs);
545 break;
546 case state_flush:
547 ret = do_flush(ssl, hs);
548 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400549 case state_process_client_certificate:
550 ret = do_process_client_certificate(ssl, hs);
551 break;
552 case state_process_client_certificate_verify:
553 ret = do_process_client_certificate_verify(ssl, hs);
554 break;
555 case state_process_client_finished:
556 ret = do_process_client_finished(ssl, hs);
557 break;
558 case state_done:
559 ret = ssl_hs_ok;
560 break;
561 }
562
563 if (ret != ssl_hs_ok) {
564 return ret;
565 }
566 }
567
568 return ssl_hs_ok;
569}