Remove write_message from TLS 1.3 handshakes.

BUG=72

Change-Id: I4aad718762925191d85f0a468eeec4aa5d85d1e8
Reviewed-on: https://boringssl-review.googlesource.com/13225
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index 1f10038..f5bdf53 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -38,7 +38,6 @@
   state_process_client_hello = 0,
   state_select_parameters,
   state_send_hello_retry_request,
-  state_flush_hello_retry_request,
   state_process_second_client_hello,
   state_send_server_hello,
   state_send_encrypted_extensions,
@@ -47,13 +46,11 @@
   state_send_server_certificate_verify,
   state_complete_server_certificate_verify,
   state_send_server_finished,
-  state_flush,
   state_process_client_certificate,
   state_process_client_certificate_verify,
   state_process_channel_id,
   state_process_client_finished,
   state_send_new_session_ticket,
-  state_flush_new_session_tickets,
   state_done,
 };
 
@@ -354,11 +351,6 @@
     return ssl_hs_error;
   }
 
-  hs->tls13_state = state_flush_hello_retry_request;
-  return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL_HANDSHAKE *hs) {
   hs->tls13_state = state_process_second_client_hello;
   return ssl_hs_flush_and_read_message;
 }
@@ -422,7 +414,7 @@
   }
 
   hs->tls13_state = state_send_encrypted_extensions;
-  return ssl_hs_write_message;
+  return ssl_hs_ok;
 
 err:
   CBB_cleanup(&cbb);
@@ -449,7 +441,7 @@
   }
 
   hs->tls13_state = state_send_certificate_request;
-  return ssl_hs_write_message;
+  return ssl_hs_ok;
 }
 
 static enum ssl_hs_wait_t do_send_certificate_request(SSL_HANDSHAKE *hs) {
@@ -493,7 +485,7 @@
   }
 
   hs->tls13_state = state_send_server_certificate;
-  return ssl_hs_write_message;
+  return ssl_hs_ok;
 
 err:
   CBB_cleanup(&cbb);
@@ -517,7 +509,7 @@
   }
 
   hs->tls13_state = state_send_server_certificate_verify;
-  return ssl_hs_write_message;
+  return ssl_hs_ok;
 }
 
 static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
@@ -525,7 +517,7 @@
   switch (tls13_prepare_certificate_verify(hs, is_first_run)) {
     case ssl_private_key_success:
       hs->tls13_state = state_send_server_finished;
-      return ssl_hs_write_message;
+      return ssl_hs_ok;
 
     case ssl_private_key_retry:
       hs->tls13_state = state_complete_server_certificate_verify;
@@ -540,18 +532,10 @@
 }
 
 static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
-  if (!tls13_prepare_finished(hs)) {
-    return ssl_hs_error;
-  }
-
-  hs->tls13_state = state_flush;
-  return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_flush(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  /* Update the secret to the master secret and derive traffic keys. */
-  if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
+  if (!tls13_prepare_finished(hs) ||
+      /* Update the secret to the master secret and derive traffic keys. */
+      !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
       !tls13_derive_application_secrets(hs) ||
       !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
                              hs->hash_len)) {
@@ -644,11 +628,11 @@
   return ssl_hs_ok;
 }
 
-/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
- * client makes several connections before getting a renewal. */
-static const int kNumTickets = 2;
-
 static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
+  /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
+   * client makes several connections before getting a renewal. */
+  static const int kNumTickets = 2;
+
   SSL *const ssl = hs->ssl;
   /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
    * session ticket. */
@@ -658,63 +642,58 @@
   }
 
   SSL_SESSION *session = ssl->s3->new_session;
-  if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
-    goto err;
-  }
+  CBB cbb;
+  CBB_zero(&cbb);
 
-  CBB cbb, body, ticket, extensions;
-  if (!ssl->method->init_message(ssl, &cbb, &body,
-                                 SSL3_MT_NEW_SESSION_TICKET) ||
-      !CBB_add_u32(&body, session->timeout) ||
-      !CBB_add_u32(&body, session->ticket_age_add) ||
-      !CBB_add_u16_length_prefixed(&body, &ticket) ||
-      !ssl_encrypt_ticket(ssl, &ticket, session) ||
-      !CBB_add_u16_length_prefixed(&body, &extensions)) {
-    goto err;
-  }
+  for (int i = 0; i < kNumTickets; i++) {
+    if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
+      goto err;
+    }
 
-  if (ssl->ctx->enable_early_data) {
-    session->ticket_max_early_data = kMaxEarlyDataAccepted;
+    CBB body, ticket, extensions;
+    if (!ssl->method->init_message(ssl, &cbb, &body,
+                                   SSL3_MT_NEW_SESSION_TICKET) ||
+        !CBB_add_u32(&body, session->timeout) ||
+        !CBB_add_u32(&body, session->ticket_age_add) ||
+        !CBB_add_u16_length_prefixed(&body, &ticket) ||
+        !ssl_encrypt_ticket(ssl, &ticket, session) ||
+        !CBB_add_u16_length_prefixed(&body, &extensions)) {
+      goto err;
+    }
 
-    CBB early_data_info;
-    if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
-        !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
-        !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
-        !CBB_flush(&extensions)) {
+    if (ssl->ctx->enable_early_data) {
+      session->ticket_max_early_data = kMaxEarlyDataAccepted;
+
+      CBB early_data_info;
+      if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
+          !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
+          !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
+          !CBB_flush(&extensions)) {
+        goto err;
+      }
+    }
+
+    /* Add a fake extension. See draft-davidben-tls-grease-01. */
+    if (!CBB_add_u16(&extensions,
+                     ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
+        !CBB_add_u16(&extensions, 0 /* empty */)) {
+      goto err;
+    }
+
+    if (!ssl_add_message_cbb(ssl, &cbb)) {
       goto err;
     }
   }
 
-  /* Add a fake extension. See draft-davidben-tls-grease-01. */
-  if (!CBB_add_u16(&extensions,
-                   ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
-      !CBB_add_u16(&extensions, 0 /* empty */)) {
-    goto err;
-  }
-
-  if (!ssl_add_message_cbb(ssl, &cbb)) {
-    goto err;
-  }
-
   hs->session_tickets_sent++;
-  if (hs->session_tickets_sent >= kNumTickets) {
-    hs->tls13_state = state_flush_new_session_tickets;
-  } else {
-    hs->tls13_state = state_send_new_session_ticket;
-  }
-
-  return ssl_hs_write_message;
+  hs->tls13_state = state_done;
+  return ssl_hs_flush;
 
 err:
   CBB_cleanup(&cbb);
   return ssl_hs_error;
 }
 
-static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL_HANDSHAKE *hs) {
-  hs->tls13_state = state_done;
-  return ssl_hs_flush;
-}
-
 enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
   while (hs->tls13_state != state_done) {
     enum ssl_hs_wait_t ret = ssl_hs_error;
@@ -729,9 +708,6 @@
       case state_send_hello_retry_request:
         ret = do_send_hello_retry_request(hs);
         break;
-      case state_flush_hello_retry_request:
-        ret = do_flush_hello_retry_request(hs);
-        break;
       case state_process_second_client_hello:
         ret = do_process_second_client_hello(hs);
         break;
@@ -756,9 +732,6 @@
       case state_send_server_finished:
         ret = do_send_server_finished(hs);
         break;
-      case state_flush:
-        ret = do_flush(hs);
-        break;
       case state_process_client_certificate:
         ret = do_process_client_certificate(hs);
         break;
@@ -774,9 +747,6 @@
       case state_send_new_session_ticket:
         ret = do_send_new_session_ticket(hs);
         break;
-      case state_flush_new_session_tickets:
-        ret = do_flush_new_session_tickets(hs);
-        break;
       case state_done:
         ret = ssl_hs_ok;
         break;