external/boringssl: Sync to 3120950b1e27635ee9b9d167052ce11ce9c96fd4.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/5e578c9dba73460c3eb17f771c77fc8e36f7812e..3120950b1e27635ee9b9d167052ce11ce9c96fd4

Test: BoringSSL CTS Presubmits.
Change-Id: I54d7540777ffdf1e72c4ff67f3138097cbdbeafb
diff --git a/src/ssl/handshake_server.c b/src/ssl/handshake_server.c
index 4eaf3cb..d591c80 100644
--- a/src/ssl/handshake_server.c
+++ b/src/ssl/handshake_server.c
@@ -175,31 +175,17 @@
 static int ssl3_select_parameters(SSL_HANDSHAKE *hs);
 static int ssl3_send_server_hello(SSL_HANDSHAKE *hs);
 static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs);
-static int ssl3_send_certificate_status(SSL_HANDSHAKE *hs);
 static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs);
-static int ssl3_send_certificate_request(SSL_HANDSHAKE *hs);
 static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs);
 static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs);
 static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs);
 static int ssl3_get_cert_verify(SSL_HANDSHAKE *hs);
 static int ssl3_get_next_proto(SSL_HANDSHAKE *hs);
 static int ssl3_get_channel_id(SSL_HANDSHAKE *hs);
-static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs);
-
-static struct CRYPTO_STATIC_MUTEX g_v2clienthello_lock =
-    CRYPTO_STATIC_MUTEX_INIT;
-static uint64_t g_v2clienthello_count = 0;
-
-uint64_t SSL_get_v2clienthello_count(void) {
-  CRYPTO_STATIC_MUTEX_lock_read(&g_v2clienthello_lock);
-  uint64_t ret = g_v2clienthello_count;
-  CRYPTO_STATIC_MUTEX_unlock_read(&g_v2clienthello_lock);
-  return ret;
-}
+static int ssl3_send_server_finished(SSL_HANDSHAKE *hs);
 
 int ssl3_accept(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  uint32_t alg_a;
   int ret = -1;
 
   assert(ssl->handshake_func == ssl3_accept);
@@ -255,55 +241,28 @@
           goto end;
         }
         if (ssl->session != NULL) {
-          hs->state = SSL3_ST_SW_SESSION_TICKET_A;
+          hs->state = SSL3_ST_SW_FINISHED_A;
         } else {
           hs->state = SSL3_ST_SW_CERT_A;
         }
         break;
 
       case SSL3_ST_SW_CERT_A:
-        if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
-          ret = ssl3_send_server_certificate(hs);
-          if (ret <= 0) {
-            goto end;
-          }
-        }
-        hs->state = SSL3_ST_SW_CERT_STATUS_A;
-        break;
-
-      case SSL3_ST_SW_CERT_STATUS_A:
-        if (hs->certificate_status_expected) {
-          ret = ssl3_send_certificate_status(hs);
-          if (ret <= 0) {
-            goto end;
-          }
+        ret = ssl3_send_server_certificate(hs);
+        if (ret <= 0) {
+          goto end;
         }
         hs->state = SSL3_ST_SW_KEY_EXCH_A;
         break;
 
       case SSL3_ST_SW_KEY_EXCH_A:
-      case SSL3_ST_SW_KEY_EXCH_B:
-        alg_a = hs->new_cipher->algorithm_auth;
-
-        /* PSK ciphers send ServerKeyExchange if there is an identity hint. */
-        if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) ||
-            ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
+        if (hs->server_params_len > 0) {
           ret = ssl3_send_server_key_exchange(hs);
           if (ret <= 0) {
             goto end;
           }
         }
 
-        hs->state = SSL3_ST_SW_CERT_REQ_A;
-        break;
-
-      case SSL3_ST_SW_CERT_REQ_A:
-        if (hs->cert_request) {
-          ret = ssl3_send_certificate_request(hs);
-          if (ret <= 0) {
-            goto end;
-          }
-        }
         hs->state = SSL3_ST_SW_SRVR_DONE_A;
         break;
 
@@ -388,7 +347,7 @@
         if (ssl->session != NULL) {
           hs->state = SSL_ST_OK;
         } else {
-          hs->state = SSL3_ST_SW_SESSION_TICKET_A;
+          hs->state = SSL3_ST_SW_FINISHED_A;
         }
 
         /* If this is a full handshake with ChannelID then record the handshake
@@ -402,28 +361,8 @@
         }
         break;
 
-      case SSL3_ST_SW_SESSION_TICKET_A:
-        if (hs->ticket_expected) {
-          ret = ssl3_send_new_session_ticket(hs);
-          if (ret <= 0) {
-            goto end;
-          }
-        }
-        hs->state = SSL3_ST_SW_CHANGE;
-        break;
-
-      case SSL3_ST_SW_CHANGE:
-        if (!ssl->method->add_change_cipher_spec(ssl) ||
-            !tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
-          ret = -1;
-          goto end;
-        }
-
-        hs->state = SSL3_ST_SW_FINISHED_A;
-        break;
-
       case SSL3_ST_SW_FINISHED_A:
-        ret = ssl3_send_finished(hs);
+        ret = ssl3_send_server_finished(hs);
         if (ret <= 0) {
           goto end;
         }
@@ -485,12 +424,6 @@
           hs->new_session = NULL;
         }
 
-        if (hs->v2_clienthello) {
-          CRYPTO_STATIC_MUTEX_lock_write(&g_v2clienthello_lock);
-          g_v2clienthello_count++;
-          CRYPTO_STATIC_MUTEX_unlock_write(&g_v2clienthello_lock);
-        }
-
         ssl->s3->initial_handshake_complete = 1;
         ssl_update_cache(hs, SSL_SESS_CACHE_SERVER);
 
@@ -538,12 +471,6 @@
                              const SSL_CLIENT_HELLO *client_hello) {
   SSL *const ssl = hs->ssl;
   assert(!ssl->s3->have_version);
-  uint16_t min_version, max_version;
-  if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
-    *out_alert = SSL_AD_PROTOCOL_VERSION;
-    return 0;
-  }
-
   uint16_t version = 0;
   /* Check supported_versions extension if it is present. */
   CBS supported_versions;
@@ -572,8 +499,8 @@
       if (!ssl->method->version_from_wire(&ext_version, ext_version)) {
         continue;
       }
-      if (min_version <= ext_version &&
-          ext_version <= max_version &&
+      if (hs->min_version <= ext_version &&
+          ext_version <= hs->max_version &&
           (!found_version || version < ext_version)) {
         version = ext_version;
         found_version = 1;
@@ -609,11 +536,11 @@
     }
 
     /* Apply our minimum and maximum version. */
-    if (version > max_version) {
-      version = max_version;
+    if (version > hs->max_version) {
+      version = hs->max_version;
     }
 
-    if (version < min_version) {
+    if (version < hs->min_version) {
       goto unsupported_protocol;
     }
   }
@@ -621,7 +548,7 @@
   /* Handle FALLBACK_SCSV. */
   if (ssl_client_cipher_list_contains_cipher(client_hello,
                                              SSL3_CK_FALLBACK_SCSV & 0xffff) &&
-      version < max_version) {
+      version < hs->max_version) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
     *out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK;
     return 0;
@@ -821,6 +748,11 @@
     }
   }
 
+  /* Freeze the version range after the early callback. */
+  if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) {
+    return -1;
+  }
+
   uint8_t alert = SSL_AD_DECODE_ERROR;
   if (!negotiate_version(hs, &alert, &client_hello)) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
@@ -903,7 +835,6 @@
 
 static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  uint8_t al = SSL_AD_INTERNAL_ERROR;
   int ret = -1;
   SSL_SESSION *session = NULL;
 
@@ -933,9 +864,9 @@
     if (session->extended_master_secret && !hs->extended_master_secret) {
       /* A ClientHello without EMS that attempts to resume a session with EMS
        * is fatal to the connection. */
-      al = SSL_AD_HANDSHAKE_FAILURE;
       OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+      goto err;
     }
 
     if (!ssl_session_is_resumable(hs, session) ||
@@ -969,9 +900,9 @@
   if (ssl->ctx->dos_protection_cb != NULL &&
       ssl->ctx->dos_protection_cb(&client_hello) == 0) {
     /* Connection rejected for DOS reasons. */
-    al = SSL_AD_INTERNAL_ERROR;
     OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
-    goto f_err;
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+    goto err;
   }
 
   if (ssl->session == NULL) {
@@ -982,8 +913,8 @@
       OPENSSL_free(hs->new_session->tlsext_hostname);
       hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
       if (hs->new_session->tlsext_hostname == NULL) {
-        al = SSL_AD_INTERNAL_ERROR;
-        goto f_err;
+        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        goto err;
       }
     }
 
@@ -1008,8 +939,10 @@
 
   /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
    * deferred. Complete it now. */
-  if (!ssl_negotiate_alpn(hs, &al, &client_hello)) {
-    goto f_err;
+  uint8_t alert = SSL_AD_DECODE_ERROR;
+  if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+    goto err;
   }
 
   /* Now that all parameters are known, initialize the handshake hash and hash
@@ -1017,7 +950,8 @@
   if (!SSL_TRANSCRIPT_init_hash(&hs->transcript, ssl3_protocol_version(ssl),
                                 hs->new_cipher->algorithm_prf) ||
       !ssl_hash_current_message(hs)) {
-    goto f_err;
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+    goto err;
   }
 
   /* Release the handshake buffer if client authentication isn't required. */
@@ -1027,11 +961,6 @@
 
   ret = 1;
 
-  if (0) {
-  f_err:
-    ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
-  }
-
 err:
   SSL_SESSION_free(session);
   return ret;
@@ -1094,48 +1023,48 @@
 
 static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  if (!ssl_has_certificate(ssl)) {
-    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
-    return -1;
-  }
-
-  if (!ssl3_output_cert_chain(ssl)) {
-    return -1;
-  }
-  return 1;
-}
-
-static int ssl3_send_certificate_status(SSL_HANDSHAKE *hs) {
-  SSL *const ssl = hs->ssl;
-  CBB cbb, body, ocsp_response;
-  if (!ssl->method->init_message(ssl, &cbb, &body,
-                                 SSL3_MT_CERTIFICATE_STATUS) ||
-      !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) ||
-      !CBB_add_u24_length_prefixed(&body, &ocsp_response) ||
-      !CBB_add_bytes(&ocsp_response,
-                     CRYPTO_BUFFER_data(ssl->cert->ocsp_response),
-                     CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
-      !ssl_add_message_cbb(ssl, &cbb)) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-    CBB_cleanup(&cbb);
-    return -1;
-  }
-
-  return 1;
-}
-
-static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
-  SSL *const ssl = hs->ssl;
-  CBB cbb, child;
+  int ret = -1;
+  CBB cbb;
   CBB_zero(&cbb);
 
-  /* Put together the parameters. */
-  if (hs->state == SSL3_ST_SW_KEY_EXCH_A) {
-    uint32_t alg_k = hs->new_cipher->algorithm_mkey;
-    uint32_t alg_a = hs->new_cipher->algorithm_auth;
+  if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
+    if (!ssl_has_certificate(ssl)) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
+      goto err;
+    }
 
-    /* Pre-allocate enough room to comfortably fit an ECDHE public key. */
-    if (!CBB_init(&cbb, 128)) {
+    if (!ssl3_output_cert_chain(ssl)) {
+      goto err;
+    }
+
+    if (hs->certificate_status_expected) {
+      CBB body, ocsp_response;
+      if (!ssl->method->init_message(ssl, &cbb, &body,
+                                     SSL3_MT_CERTIFICATE_STATUS) ||
+          !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) ||
+          !CBB_add_u24_length_prefixed(&body, &ocsp_response) ||
+          !CBB_add_bytes(&ocsp_response,
+                         CRYPTO_BUFFER_data(ssl->cert->ocsp_response),
+                         CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
+          !ssl_add_message_cbb(ssl, &cbb)) {
+        OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+        goto err;
+      }
+    }
+  }
+
+  /* Assemble ServerKeyExchange parameters if needed. */
+  uint32_t alg_k = hs->new_cipher->algorithm_mkey;
+  uint32_t alg_a = hs->new_cipher->algorithm_auth;
+  if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) ||
+      ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
+
+    /* Pre-allocate enough room to comfortably fit an ECDHE public key. Prepend
+     * the client and server randoms for the signing transcript. */
+    CBB child;
+    if (!CBB_init(&cbb, SSL3_RANDOM_SIZE * 2 + 128) ||
+        !CBB_add_bytes(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
+        !CBB_add_bytes(&cbb, ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
       goto err;
     }
 
@@ -1177,11 +1106,22 @@
     }
   }
 
-  /* Assemble the message. */
-  CBB body;
+  ret = 1;
+
+err:
+  CBB_cleanup(&cbb);
+  return ret;
+}
+
+static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
+  SSL *const ssl = hs->ssl;
+  CBB cbb, body, child;
   if (!ssl->method->init_message(ssl, &cbb, &body,
                                  SSL3_MT_SERVER_KEY_EXCHANGE) ||
-      !CBB_add_bytes(&body, hs->server_params, hs->server_params_len)) {
+      /* |hs->server_params| contains a prefix for signing. */
+      hs->server_params_len < 2 * SSL3_RANDOM_SIZE ||
+      !CBB_add_bytes(&body, hs->server_params + 2 * SSL3_RANDOM_SIZE,
+                     hs->server_params_len - 2 * SSL3_RANDOM_SIZE)) {
     goto err;
   }
 
@@ -1214,36 +1154,9 @@
     }
 
     size_t sig_len;
-    enum ssl_private_key_result_t sign_result;
-    if (hs->state == SSL3_ST_SW_KEY_EXCH_A) {
-      CBB transcript;
-      uint8_t *transcript_data;
-      size_t transcript_len;
-      if (!CBB_init(&transcript,
-                    2 * SSL3_RANDOM_SIZE + hs->server_params_len) ||
-          !CBB_add_bytes(&transcript, ssl->s3->client_random,
-                         SSL3_RANDOM_SIZE) ||
-          !CBB_add_bytes(&transcript, ssl->s3->server_random,
-                         SSL3_RANDOM_SIZE) ||
-          !CBB_add_bytes(&transcript, hs->server_params,
-                         hs->server_params_len) ||
-          !CBB_finish(&transcript, &transcript_data, &transcript_len)) {
-        CBB_cleanup(&transcript);
-        OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
-        goto err;
-      }
-
-      sign_result = ssl_private_key_sign(ssl, ptr, &sig_len, max_sig_len,
-                                         signature_algorithm, transcript_data,
-                                         transcript_len);
-      OPENSSL_free(transcript_data);
-    } else {
-      assert(hs->state == SSL3_ST_SW_KEY_EXCH_B);
-      sign_result = ssl_private_key_complete(ssl, ptr, &sig_len, max_sig_len);
-    }
-
-    switch (sign_result) {
+    switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len,
+                                 signature_algorithm, hs->server_params,
+                                 hs->server_params_len)) {
       case ssl_private_key_success:
         if (!CBB_did_write(&child, sig_len)) {
           goto err;
@@ -1253,7 +1166,6 @@
         goto err;
       case ssl_private_key_retry:
         ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
-        hs->state = SSL3_ST_SW_KEY_EXCH_B;
         goto err;
     }
   }
@@ -1273,26 +1185,28 @@
   return -1;
 }
 
-static int ssl3_send_certificate_request(SSL_HANDSHAKE *hs) {
+static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  CBB cbb, body, cert_types, sigalgs_cbb;
-  if (!ssl->method->init_message(ssl, &cbb, &body,
-                                 SSL3_MT_CERTIFICATE_REQUEST) ||
-      !CBB_add_u8_length_prefixed(&body, &cert_types) ||
-      !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
-      (ssl->version >= TLS1_VERSION &&
-       !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN))) {
-    goto err;
-  }
+  CBB cbb, body;
 
-  if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
-    if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
-        !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) {
+  if (hs->cert_request) {
+    CBB cert_types, sigalgs_cbb;
+    if (!ssl->method->init_message(ssl, &cbb, &body,
+                                   SSL3_MT_CERTIFICATE_REQUEST) ||
+        !CBB_add_u8_length_prefixed(&body, &cert_types) ||
+        !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
+        (ssl3_protocol_version(ssl) >= TLS1_VERSION &&
+         !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN)) ||
+        (ssl3_protocol_version(ssl) >= TLS1_2_VERSION &&
+         (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
+          !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb))) ||
+        !ssl_add_client_CA_list(ssl, &body) ||
+        !ssl_add_message_cbb(ssl, &cbb)) {
       goto err;
     }
   }
 
-  if (!ssl_add_client_CA_list(ssl, &body) ||
+  if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
       !ssl_add_message_cbb(ssl, &cbb)) {
     goto err;
   }
@@ -1305,19 +1219,6 @@
   return -1;
 }
 
-static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
-  SSL *const ssl = hs->ssl;
-  CBB cbb, body;
-  if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
-      !ssl_add_message_cbb(ssl, &cbb)) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-    CBB_cleanup(&cbb);
-    return -1;
-  }
-
-  return 1;
-}
-
 static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
   assert(hs->cert_request);
@@ -1417,34 +1318,27 @@
 
 static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  int al;
   CBS client_key_exchange;
-  uint32_t alg_k;
-  uint32_t alg_a;
   uint8_t *premaster_secret = NULL;
   size_t premaster_secret_len = 0;
   uint8_t *decrypt_buf = NULL;
 
-  unsigned psk_len = 0;
-  uint8_t psk[PSK_MAX_PSK_LEN];
-
   if (hs->state == SSL3_ST_SR_KEY_EXCH_A) {
     int ret = ssl->method->ssl_get_message(ssl);
     if (ret <= 0) {
       return ret;
     }
+  }
 
-    if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE) ||
-        !ssl_hash_current_message(hs)) {
-      return -1;
-    }
+  if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE)) {
+    return -1;
   }
 
   CBS_init(&client_key_exchange, ssl->init_msg, ssl->init_num);
-  alg_k = hs->new_cipher->algorithm_mkey;
-  alg_a = hs->new_cipher->algorithm_auth;
+  uint32_t alg_k = hs->new_cipher->algorithm_mkey;
+  uint32_t alg_a = hs->new_cipher->algorithm_auth;
 
-  /* If using a PSK key exchange, prepare the pre-shared key. */
+  /* If using a PSK key exchange, parse the PSK identity. */
   if (alg_a & SSL_aPSK) {
     CBS psk_identity;
 
@@ -1453,47 +1347,40 @@
     if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) ||
         ((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
-      al = SSL_AD_DECODE_ERROR;
-      goto f_err;
-    }
-
-    if (ssl->psk_server_callback == NULL) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
-      al = SSL_AD_INTERNAL_ERROR;
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      goto err;
     }
 
     if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN ||
         CBS_contains_zero_byte(&psk_identity)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
-      al = SSL_AD_ILLEGAL_PARAMETER;
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+      goto err;
     }
 
     if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) {
-      al = SSL_AD_INTERNAL_ERROR;
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      goto f_err;
-    }
-
-    /* Look up the key for the identity. */
-    psk_len = ssl->psk_server_callback(ssl, hs->new_session->psk_identity, psk,
-                                       sizeof(psk));
-    if (psk_len > PSK_MAX_PSK_LEN) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-      al = SSL_AD_INTERNAL_ERROR;
-      goto f_err;
-    } else if (psk_len == 0) {
-      /* PSK related to the given identity not found */
-      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
-      al = SSL_AD_UNKNOWN_PSK_IDENTITY;
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+      goto err;
     }
   }
 
   /* Depending on the key exchange method, compute |premaster_secret| and
    * |premaster_secret_len|. */
   if (alg_k & SSL_kRSA) {
+    CBS encrypted_premaster_secret;
+    if (ssl->version > SSL3_VERSION) {
+      if (!CBS_get_u16_length_prefixed(&client_key_exchange,
+                                       &encrypted_premaster_secret) ||
+          CBS_len(&client_key_exchange) != 0) {
+        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+        goto err;
+      }
+    } else {
+      encrypted_premaster_secret = client_key_exchange;
+    }
+
     /* Allocate a buffer large enough for an RSA decryption. */
     const size_t rsa_size = EVP_PKEY_size(hs->local_pubkey);
     decrypt_buf = OPENSSL_malloc(rsa_size);
@@ -1502,43 +1389,12 @@
       goto err;
     }
 
-    enum ssl_private_key_result_t decrypt_result;
+    /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
+     * timing-sensitive code below. */
     size_t decrypt_len;
-    if (hs->state == SSL3_ST_SR_KEY_EXCH_A) {
-      if (!ssl_has_private_key(ssl) ||
-          EVP_PKEY_id(hs->local_pubkey) != EVP_PKEY_RSA) {
-        al = SSL_AD_HANDSHAKE_FAILURE;
-        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
-        goto f_err;
-      }
-      CBS encrypted_premaster_secret;
-      if (ssl->version > SSL3_VERSION) {
-        if (!CBS_get_u16_length_prefixed(&client_key_exchange,
-                                         &encrypted_premaster_secret) ||
-            CBS_len(&client_key_exchange) != 0) {
-          al = SSL_AD_DECODE_ERROR;
-          OPENSSL_PUT_ERROR(SSL,
-                            SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
-          goto f_err;
-        }
-      } else {
-        encrypted_premaster_secret = client_key_exchange;
-      }
-
-      /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
-       * timing-sensitive code below. */
-      decrypt_result = ssl_private_key_decrypt(
-          ssl, decrypt_buf, &decrypt_len, rsa_size,
-          CBS_data(&encrypted_premaster_secret),
-          CBS_len(&encrypted_premaster_secret));
-    } else {
-      assert(hs->state == SSL3_ST_SR_KEY_EXCH_B);
-      /* Complete async decrypt. */
-      decrypt_result =
-          ssl_private_key_complete(ssl, decrypt_buf, &decrypt_len, rsa_size);
-    }
-
-    switch (decrypt_result) {
+    switch (ssl_private_key_decrypt(hs, decrypt_buf, &decrypt_len, rsa_size,
+                                    CBS_data(&encrypted_premaster_secret),
+                                    CBS_len(&encrypted_premaster_secret))) {
       case ssl_private_key_success:
         break;
       case ssl_private_key_failure:
@@ -1550,9 +1406,9 @@
     }
 
     if (decrypt_len != rsa_size) {
-      al = SSL_AD_DECRYPT_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+      goto err;
     }
 
     /* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
@@ -1570,9 +1426,9 @@
     /* The smallest padded premaster is 11 bytes of overhead. Small keys are
      * publicly invalid. */
     if (decrypt_len < 11 + premaster_secret_len) {
-      al = SSL_AD_DECRYPT_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+      goto err;
     }
 
     /* Check the padding. See RFC 3447, section 7.2.2. */
@@ -1605,9 +1461,9 @@
     CBS peer_key;
     if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) ||
         CBS_len(&client_key_exchange) != 0) {
-      al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      goto err;
     }
 
     /* Compute the premaster. */
@@ -1615,35 +1471,57 @@
     if (!SSL_ECDH_CTX_finish(&hs->ecdh_ctx, &premaster_secret,
                              &premaster_secret_len, &alert, CBS_data(&peer_key),
                              CBS_len(&peer_key))) {
-      al = alert;
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+      goto err;
     }
 
     /* The key exchange state may now be discarded. */
     SSL_ECDH_CTX_cleanup(&hs->ecdh_ctx);
-  } else if (alg_k & SSL_kPSK) {
-    /* For plain PSK, other_secret is a block of 0s with the same length as the
-     * pre-shared key. */
-    premaster_secret_len = psk_len;
-    premaster_secret = OPENSSL_malloc(premaster_secret_len);
-    if (premaster_secret == NULL) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      goto err;
-    }
-    OPENSSL_memset(premaster_secret, 0, premaster_secret_len);
-  } else {
-    al = SSL_AD_HANDSHAKE_FAILURE;
+  } else if (!(alg_k & SSL_kPSK)) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE);
-    goto f_err;
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+    goto err;
   }
 
   /* For a PSK cipher suite, the actual pre-master secret is combined with the
    * pre-shared key. */
   if (alg_a & SSL_aPSK) {
+    if (ssl->psk_server_callback == NULL) {
+      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+      goto err;
+    }
+
+    /* Look up the key for the identity. */
+    uint8_t psk[PSK_MAX_PSK_LEN];
+    unsigned psk_len = ssl->psk_server_callback(
+        ssl, hs->new_session->psk_identity, psk, sizeof(psk));
+    if (psk_len > PSK_MAX_PSK_LEN) {
+      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+      goto err;
+    } else if (psk_len == 0) {
+      /* PSK related to the given identity not found */
+      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY);
+      goto err;
+    }
+
+    if (alg_k & SSL_kPSK) {
+      /* In plain PSK, other_secret is a block of 0s with the same length as the
+       * pre-shared key. */
+      premaster_secret_len = psk_len;
+      premaster_secret = OPENSSL_malloc(premaster_secret_len);
+      if (premaster_secret == NULL) {
+        OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+        goto err;
+      }
+      OPENSSL_memset(premaster_secret, 0, premaster_secret_len);
+    }
+
     CBB new_premaster, child;
     uint8_t *new_data;
     size_t new_len;
-
     CBB_zero(&new_premaster);
     if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len) ||
         !CBB_add_u16_length_prefixed(&new_premaster, &child) ||
@@ -1662,6 +1540,10 @@
     premaster_secret_len = new_len;
   }
 
+  if (!ssl_hash_current_message(hs)) {
+    goto err;
+  }
+
   /* Compute the master secret */
   hs->new_session->master_key_length = tls1_generate_master_secret(
       hs, hs->new_session->master_key, premaster_secret, premaster_secret_len);
@@ -1674,8 +1556,6 @@
   OPENSSL_free(premaster_secret);
   return 1;
 
-f_err:
-  ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
 err:
   if (premaster_secret != NULL) {
     OPENSSL_cleanse(premaster_secret, premaster_secret_len);
@@ -1688,7 +1568,6 @@
 
 static int ssl3_get_cert_verify(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  int al;
   CBS certificate_verify, signature;
 
   /* Only RSA and ECDSA client certificates are supported, so a
@@ -1714,27 +1593,29 @@
   uint16_t signature_algorithm = 0;
   if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
     if (!CBS_get_u16(&certificate_verify, &signature_algorithm)) {
-      al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
-      goto f_err;
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      return -1;
     }
-    if (!tls12_check_peer_sigalg(ssl, &al, signature_algorithm)) {
-      goto f_err;
+    uint8_t alert = SSL_AD_DECODE_ERROR;
+    if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
+      ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+      return -1;
     }
     hs->new_session->peer_signature_algorithm = signature_algorithm;
   } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
                                                   hs->peer_pubkey)) {
-    al = SSL_AD_UNSUPPORTED_CERTIFICATE;
     OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
-    goto f_err;
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
+    return -1;
   }
 
   /* Parse and verify the signature. */
   if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) ||
       CBS_len(&certificate_verify) != 0) {
-    al = SSL_AD_DECODE_ERROR;
     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
-    goto f_err;
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+    return -1;
   }
 
   int sig_ok;
@@ -1746,7 +1627,7 @@
     if (!SSL_TRANSCRIPT_ssl3_cert_verify_hash(&hs->transcript, digest,
                                               &digest_len, hs->new_session,
                                               signature_algorithm)) {
-      goto err;
+      return -1;
     }
 
     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(hs->peer_pubkey, NULL);
@@ -1767,24 +1648,19 @@
   ERR_clear_error();
 #endif
   if (!sig_ok) {
-    al = SSL_AD_DECRYPT_ERROR;
     OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
-    goto f_err;
+    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+    return -1;
   }
 
   /* The handshake buffer is no longer necessary, and we may hash the current
    * message.*/
   SSL_TRANSCRIPT_free_buffer(&hs->transcript);
   if (!ssl_hash_current_message(hs)) {
-    goto err;
+    return -1;
   }
 
   return 1;
-
-f_err:
-  ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
-err:
-  return 0;
 }
 
 /* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
@@ -1835,40 +1711,46 @@
   return 1;
 }
 
-static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs) {
+static int ssl3_send_server_finished(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
-  const SSL_SESSION *session;
-  SSL_SESSION *session_copy = NULL;
-  if (ssl->session == NULL) {
-    /* Fix the timeout to measure from the ticket issuance time. */
-    ssl_session_rebase_time(ssl, hs->new_session);
-    session = hs->new_session;
-  } else {
-    /* We are renewing an existing session. Duplicate the session to adjust the
-     * timeout. */
-    session_copy = SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH);
-    if (session_copy == NULL) {
-      return -1;
+
+  if (hs->ticket_expected) {
+    const SSL_SESSION *session;
+    SSL_SESSION *session_copy = NULL;
+    if (ssl->session == NULL) {
+      /* Fix the timeout to measure from the ticket issuance time. */
+      ssl_session_rebase_time(ssl, hs->new_session);
+      session = hs->new_session;
+    } else {
+      /* We are renewing an existing session. Duplicate the session to adjust
+       * the timeout. */
+      session_copy = SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH);
+      if (session_copy == NULL) {
+        return -1;
+      }
+
+      ssl_session_rebase_time(ssl, session_copy);
+      session = session_copy;
     }
 
-    ssl_session_rebase_time(ssl, session_copy);
-    session = session_copy;
+    CBB cbb, body, ticket;
+    int ok = ssl->method->init_message(ssl, &cbb, &body,
+                                       SSL3_MT_NEW_SESSION_TICKET) &&
+             CBB_add_u32(&body, session->timeout) &&
+             CBB_add_u16_length_prefixed(&body, &ticket) &&
+             ssl_encrypt_ticket(ssl, &ticket, session) &&
+             ssl_add_message_cbb(ssl, &cbb);
+    SSL_SESSION_free(session_copy);
+    CBB_cleanup(&cbb);
+    if (!ok) {
+      return -1;
+    }
   }
 
-  CBB cbb, body, ticket;
-  int ok =
-      ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_NEW_SESSION_TICKET) &&
-      CBB_add_u32(&body, session->timeout) &&
-      CBB_add_u16_length_prefixed(&body, &ticket) &&
-      ssl_encrypt_ticket(ssl, &ticket, session) &&
-      ssl_add_message_cbb(ssl, &cbb);
-
-  SSL_SESSION_free(session_copy);
-  CBB_cleanup(&cbb);
-
-  if (!ok) {
+  if (!ssl->method->add_change_cipher_spec(ssl) ||
+      !tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
     return -1;
   }
 
-  return 1;
+  return ssl3_send_finished(hs);
 }