external/boringssl: Sync to 8625ec4b436ccb4098ed4aac10891eff8372be41.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/c596415ec62b501523d80f9afa26b135406da6bf..8625ec4b436ccb4098ed4aac10891eff8372be41

Test: cts -m CtsLibcoreTestCases
Change-Id: I47a45e6b6f46b19fcbcb6c917895867d56dcd2ca
diff --git a/src/ssl/handshake_server.cc b/src/ssl/handshake_server.cc
index 6404cc9..0159c9e 100644
--- a/src/ssl/handshake_server.cc
+++ b/src/ssl/handshake_server.cc
@@ -172,8 +172,8 @@
 
 namespace bssl {
 
-int ssl_client_cipher_list_contains_cipher(const SSL_CLIENT_HELLO *client_hello,
-                                           uint16_t id) {
+bool ssl_client_cipher_list_contains_cipher(
+    const SSL_CLIENT_HELLO *client_hello, uint16_t id) {
   CBS cipher_suites;
   CBS_init(&cipher_suites, client_hello->cipher_suites,
            client_hello->cipher_suites_len);
@@ -181,19 +181,19 @@
   while (CBS_len(&cipher_suites) > 0) {
     uint16_t got_id;
     if (!CBS_get_u16(&cipher_suites, &got_id)) {
-      return 0;
+      return false;
     }
 
     if (got_id == id) {
-      return 1;
+      return true;
     }
   }
 
-  return 0;
+  return false;
 }
 
-static int negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
-                             const SSL_CLIENT_HELLO *client_hello) {
+static bool negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+                              const SSL_CLIENT_HELLO *client_hello) {
   SSL *const ssl = hs->ssl;
   assert(!ssl->s3->have_version);
   CBS supported_versions, versions;
@@ -204,7 +204,7 @@
         CBS_len(&versions) == 0) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
       *out_alert = SSL_AD_DECODE_ERROR;
-      return 0;
+      return false;
     }
   } else {
     // Convert the ClientHello version to an equivalent supported_versions
@@ -213,7 +213,6 @@
         0x03, 0x03,  // TLS 1.2
         0x03, 0x02,  // TLS 1.1
         0x03, 0x01,  // TLS 1
-        0x03, 0x00,  // SSL 3
     };
 
     static const uint8_t kDTLSVersions[] = {
@@ -232,12 +231,10 @@
                versions_len);
     } else {
       if (client_hello->version >= TLS1_2_VERSION) {
-        versions_len = 8;
-      } else if (client_hello->version >= TLS1_1_VERSION) {
         versions_len = 6;
-      } else if (client_hello->version >= TLS1_VERSION) {
+      } else if (client_hello->version >= TLS1_1_VERSION) {
         versions_len = 4;
-      } else if (client_hello->version >= SSL3_VERSION) {
+      } else if (client_hello->version >= TLS1_VERSION) {
         versions_len = 2;
       }
       CBS_init(&versions, kTLSVersions + sizeof(kTLSVersions) - versions_len,
@@ -246,7 +243,7 @@
   }
 
   if (!ssl_negotiate_version(hs, out_alert, &ssl->version, &versions)) {
-    return 0;
+    return false;
   }
 
   // At this point, the connection's version is known and |ssl->version| is
@@ -260,10 +257,10 @@
       ssl_protocol_version(ssl) < hs->max_version) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
     *out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK;
-    return 0;
+    return false;
   }
 
-  return 1;
+  return true;
 }
 
 static UniquePtr<STACK_OF(SSL_CIPHER)> ssl_parse_client_cipher_list(
@@ -303,11 +300,10 @@
 static void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs,
                                               uint32_t *out_mask_k,
                                               uint32_t *out_mask_a) {
-  SSL *const ssl = hs->ssl;
   uint32_t mask_k = 0;
   uint32_t mask_a = 0;
 
-  if (ssl_has_certificate(ssl)) {
+  if (ssl_has_certificate(hs->config)) {
     mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey.get());
     if (EVP_PKEY_id(hs->local_pubkey.get()) == EVP_PKEY_RSA) {
       mask_k |= SSL_kRSA;
@@ -321,7 +317,7 @@
   }
 
   // PSK requires a server callback.
-  if (ssl->psk_server_callback != NULL) {
+  if (hs->config->psk_server_callback != NULL) {
     mask_k |= SSL_kPSK;
     mask_a |= SSL_aPSK;
   }
@@ -417,7 +413,7 @@
     return ssl_hs_error;
   }
 
-  if (ssl->handoff) {
+  if (hs->config->handoff) {
     return ssl_hs_handoff;
   }
 
@@ -446,7 +442,7 @@
   }
 
   // Freeze the version range after the early callback.
-  if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) {
+  if (!ssl_get_version_range(hs, &hs->min_version, &hs->max_version)) {
     return ssl_hs_error;
   }
 
@@ -494,8 +490,8 @@
   }
 
   // Call |cert_cb| to update server certificates if required.
-  if (ssl->cert->cert_cb != NULL) {
-    int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
+  if (hs->config->cert->cert_cb != NULL) {
+    int rv = hs->config->cert->cert_cb(ssl, hs->config->cert->cert_cb_arg);
     if (rv == 0) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
@@ -510,6 +506,22 @@
     return ssl_hs_error;
   }
 
+  if (hs->ocsp_stapling_requested &&
+      ssl->ctx->legacy_ocsp_callback != nullptr) {
+    switch (ssl->ctx->legacy_ocsp_callback(
+        ssl, ssl->ctx->legacy_ocsp_callback_arg)) {
+      case SSL_TLSEXT_ERR_OK:
+        break;
+      case SSL_TLSEXT_ERR_NOACK:
+        hs->ocsp_stapling_requested = false;
+        break;
+      default:
+        OPENSSL_PUT_ERROR(SSL, SSL_R_OCSP_CB_ERROR);
+        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        return ssl_hs_error;
+    }
+  }
+
   if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
     // Jump to the TLS 1.3 state machine.
     hs->state = state12_tls13;
@@ -523,8 +535,10 @@
 
   // Negotiate the cipher suite. This must be done after |cert_cb| so the
   // certificate is finalized.
-  hs->new_cipher =
-      ssl3_choose_cipher(hs, &client_hello, ssl_get_cipher_preferences(ssl));
+  SSLCipherPreferenceList *prefs = hs->config->cipher_list
+                                       ? hs->config->cipher_list.get()
+                                       : ssl->ctx->cipher_list.get();
+  hs->new_cipher = ssl3_choose_cipher(hs, &client_hello, prefs);
   if (hs->new_cipher == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
@@ -562,7 +576,7 @@
   UniquePtr<SSL_SESSION> session;
   bool tickets_supported = false, renew_ticket = false;
   enum ssl_hs_wait_t wait = ssl_get_prev_session(
-      ssl, &session, &tickets_supported, &renew_ticket, &client_hello);
+      hs, &session, &tickets_supported, &renew_ticket, &client_hello);
   if (wait != ssl_hs_ok) {
     return wait;
   }
@@ -587,7 +601,7 @@
   if (session) {
     // Use the old session.
     hs->ticket_expected = renew_ticket;
-    ssl->session = session.release();
+    ssl->session = std::move(session);
     ssl->s3->session_reused = true;
   } else {
     hs->ticket_expected = tickets_supported;
@@ -614,10 +628,10 @@
     hs->new_session->cipher = hs->new_cipher;
 
     // Determine whether to request a client certificate.
-    hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
+    hs->cert_request = !!(hs->config->verify_mode & SSL_VERIFY_PEER);
     // Only request a certificate if Channel ID isn't negotiated.
-    if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
-        ssl->s3->tlsext_channel_id_valid) {
+    if ((hs->config->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
+        ssl->s3->channel_id_valid) {
       hs->cert_request = false;
     }
     // CertificateRequest may only be sent in certificate-based ciphers.
@@ -650,7 +664,7 @@
 
   // Handback includes the whole handshake transcript, so we cannot free the
   // transcript buffer in the handback case.
-  if (!hs->cert_request && !hs->ssl->handback) {
+  if (!hs->cert_request && !hs->handback) {
     hs->transcript.FreeBuffer();
   }
 
@@ -665,9 +679,9 @@
 
   // We only accept ChannelIDs on connections with ECDHE in order to avoid a
   // known attack while we fix ChannelID itself.
-  if (ssl->s3->tlsext_channel_id_valid &&
+  if (ssl->s3->channel_id_valid &&
       (hs->new_cipher->algorithm_mkey & SSL_kECDHE) == 0) {
-    ssl->s3->tlsext_channel_id_valid = false;
+    ssl->s3->channel_id_valid = false;
   }
 
   // If this is a resumption and the original handshake didn't support
@@ -675,7 +689,7 @@
   // session and so cannot resume with ChannelIDs.
   if (ssl->session != NULL &&
       ssl->session->original_handshake_hash_len == 0) {
-    ssl->s3->tlsext_channel_id_valid = false;
+    ssl->s3->channel_id_valid = false;
   }
 
   struct OPENSSL_timeval now;
@@ -700,8 +714,8 @@
   }
 
   const SSL_SESSION *session = hs->new_session.get();
-  if (ssl->session != NULL) {
-    session = ssl->session;
+  if (ssl->session != nullptr) {
+    session = ssl->session.get();
   }
 
   ScopedCBB cbb;
@@ -733,12 +747,12 @@
   ScopedCBB cbb;
 
   if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
-    if (!ssl_has_certificate(ssl)) {
+    if (!ssl_has_certificate(hs->config)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
       return ssl_hs_error;
     }
 
-    if (!ssl_output_cert_chain(ssl)) {
+    if (!ssl_output_cert_chain(hs)) {
       return ssl_hs_error;
     }
 
@@ -748,9 +762,10 @@
                                      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.get()),
-                         CRYPTO_BUFFER_len(ssl->cert->ocsp_response.get())) ||
+          !CBB_add_bytes(
+              &ocsp_response,
+              CRYPTO_BUFFER_data(hs->config->cert->ocsp_response.get()),
+              CRYPTO_BUFFER_len(hs->config->cert->ocsp_response.get())) ||
           !ssl_add_message_cbb(ssl, cbb.get())) {
         OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
         return ssl_hs_error;
@@ -762,8 +777,7 @@
   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)) {
-
+      ((alg_a & SSL_aPSK) && hs->config->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;
@@ -775,10 +789,12 @@
 
     // PSK ciphers begin with an identity hint.
     if (alg_a & SSL_aPSK) {
-      size_t len =
-          (ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint);
+      size_t len = hs->config->psk_identity_hint == nullptr
+                       ? 0
+                       : strlen(hs->config->psk_identity_hint.get());
       if (!CBB_add_u16_length_prefixed(cbb.get(), &child) ||
-          !CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint,
+          !CBB_add_bytes(&child,
+                         (const uint8_t *)hs->config->psk_identity_hint.get(),
                          len)) {
         return ssl_hs_error;
       }
@@ -837,7 +853,7 @@
 
   // Add a signature.
   if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
-    if (!ssl_has_private_key(ssl)) {
+    if (!ssl_has_private_key(hs->config)) {
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
       return ssl_hs_error;
     }
@@ -845,6 +861,7 @@
     // Determine the signature algorithm.
     uint16_t signature_algorithm;
     if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
+      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
       return ssl_hs_error;
     }
     if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) {
@@ -900,15 +917,14 @@
                                    SSL3_MT_CERTIFICATE_REQUEST) ||
         !CBB_add_u8_length_prefixed(&body, &cert_types) ||
         !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
-        (ssl_protocol_version(ssl) >= TLS1_VERSION &&
-         !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN)) ||
+        !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN) ||
         // TLS 1.2 has no way to specify different signature algorithms for
         // certificates and the online signature, so emit the more restrictive
         // certificate list.
         (ssl_protocol_version(ssl) >= TLS1_2_VERSION &&
          (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
           !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb, true /* certs */))) ||
-        !ssl_add_client_CA_list(ssl, &body) ||
+        !ssl_add_client_CA_list(hs, &body) ||
         !ssl_add_message_cbb(ssl, cbb.get())) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
       return ssl_hs_error;
@@ -929,8 +945,8 @@
 static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
 
-  if (ssl->handback && hs->new_cipher->algorithm_mkey == SSL_kECDHE) {
-     return ssl_hs_handback;
+  if (hs->handback && hs->new_cipher->algorithm_mkey == SSL_kECDHE) {
+    return ssl_hs_handback;
   }
   if (!hs->cert_request) {
     hs->state = state12_verify_client_certificate;
@@ -942,26 +958,7 @@
     return ssl_hs_read_message;
   }
 
-  if (msg.type != SSL3_MT_CERTIFICATE) {
-    if (ssl->version == SSL3_VERSION &&
-        msg.type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
-      // In SSL 3.0, the Certificate message is omitted to signal no
-      // certificate.
-      if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
-        OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
-        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-        return ssl_hs_error;
-      }
-
-      // OpenSSL returns X509_V_OK when no certificates are received. This is
-      // classed by them as a bug, but it's assumed by at least NGINX.
-      hs->new_session->verify_result = X509_V_OK;
-      hs->state = state12_verify_client_certificate;
-      return ssl_hs_ok;
-    }
-
-    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
-    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+  if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE)) {
     return ssl_hs_error;
   }
 
@@ -971,17 +968,14 @@
 
   CBS certificate_msg = msg.body;
   uint8_t alert = SSL_AD_DECODE_ERROR;
-  UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain;
-  if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey,
-                            ssl->retain_only_sha256_of_client_certs
+  if (!ssl_parse_cert_chain(&alert, &hs->new_session->certs, &hs->peer_pubkey,
+                            hs->config->retain_only_sha256_of_client_certs
                                 ? hs->new_session->peer_sha256
-                                : NULL,
+                                : nullptr,
                             &certificate_msg, ssl->ctx->pool)) {
     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
     return ssl_hs_error;
   }
-  sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
-  hs->new_session->certs = chain.release();
 
   if (CBS_len(&certificate_msg) != 0 ||
       !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
@@ -990,19 +984,11 @@
     return ssl_hs_error;
   }
 
-  if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
+  if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
     // No client certificate so the handshake buffer may be discarded.
     hs->transcript.FreeBuffer();
 
-    // In SSL 3.0, sending no certificate is signaled by omitting the
-    // Certificate message.
-    if (ssl->version == SSL3_VERSION) {
-      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
-      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-      return ssl_hs_error;
-    }
-
-    if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
+    if (hs->config->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
       // Fail for TLS only if we required a certificate
       OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
@@ -1012,7 +998,7 @@
     // OpenSSL returns X509_V_OK when no certificates are received. This is
     // classed by them as a bug, but it's assumed by at least NGINX.
     hs->new_session->verify_result = X509_V_OK;
-  } else if (ssl->retain_only_sha256_of_client_certs) {
+  } else if (hs->config->retain_only_sha256_of_client_certs) {
     // The hash will have been filled in.
     hs->new_session->peer_sha256_valid = 1;
   }
@@ -1023,7 +1009,7 @@
 }
 
 static enum ssl_hs_wait_t do_verify_client_certificate(SSL_HANDSHAKE *hs) {
-  if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) > 0) {
+  if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) > 0) {
     switch (ssl_verify_peer_cert(hs)) {
       case ssl_verify_ok:
         break;
@@ -1072,28 +1058,25 @@
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
       return ssl_hs_error;
     }
-
-    if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) {
+    char *raw = nullptr;
+    if (!CBS_strdup(&psk_identity, &raw)) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
       return ssl_hs_error;
     }
+    hs->new_session->psk_identity.reset(raw);
   }
 
   // Depending on the key exchange method, compute |premaster_secret|.
   Array<uint8_t> premaster_secret;
   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);
-        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
-        return ssl_hs_error;
-      }
-    } else {
-      encrypted_premaster_secret = client_key_exchange;
+    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);
+      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+      return ssl_hs_error;
     }
 
     // Allocate a buffer large enough for an RSA decryption.
@@ -1187,7 +1170,7 @@
   // 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) {
+    if (hs->config->psk_server_callback == NULL) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
       return ssl_hs_error;
@@ -1195,8 +1178,8 @@
 
     // 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));
+    unsigned psk_len = hs->config->psk_server_callback(
+        ssl, hs->new_session->psk_identity.get(), psk, sizeof(psk));
     if (psk_len > PSK_MAX_PSK_LEN) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
@@ -1300,29 +1283,9 @@
     return ssl_hs_error;
   }
 
-  bool sig_ok;
-  // The SSL3 construction for CertificateVerify does not decompose into a
-  // single final digest and signature, and must be special-cased.
-  if (ssl_protocol_version(ssl) == SSL3_VERSION) {
-    uint8_t digest[EVP_MAX_MD_SIZE];
-    size_t digest_len;
-    if (!hs->transcript.GetSSL3CertVerifyHash(
-            digest, &digest_len, hs->new_session.get(), signature_algorithm)) {
-      return ssl_hs_error;
-    }
-
-    UniquePtr<EVP_PKEY_CTX> pctx(
-        EVP_PKEY_CTX_new(hs->peer_pubkey.get(), nullptr));
-    sig_ok = pctx &&
-             EVP_PKEY_verify_init(pctx.get()) &&
-             EVP_PKEY_verify(pctx.get(), CBS_data(&signature),
-                             CBS_len(&signature), digest, digest_len);
-  } else {
-    sig_ok =
-        ssl_public_key_verify(ssl, signature, signature_algorithm,
-                              hs->peer_pubkey.get(), hs->transcript.buffer());
-  }
-
+  bool sig_ok =
+      ssl_public_key_verify(ssl, signature, signature_algorithm,
+                            hs->peer_pubkey.get(), hs->transcript.buffer());
 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
   sig_ok = true;
   ERR_clear_error();
@@ -1346,6 +1309,9 @@
 }
 
 static enum ssl_hs_wait_t do_read_change_cipher_spec(SSL_HANDSHAKE *hs) {
+  if (hs->handback && hs->ssl->session != NULL) {
+    return ssl_hs_handback;
+  }
   hs->state = state12_process_change_cipher_spec;
   return ssl_hs_read_change_cipher_spec;
 }
@@ -1398,7 +1364,7 @@
 static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
 
-  if (!ssl->s3->tlsext_channel_id_valid) {
+  if (!ssl->s3->channel_id_valid) {
     hs->state = state12_read_client_finished;
     return ssl_hs_ok;
   }
@@ -1435,7 +1401,7 @@
   // If this is a full handshake with ChannelID then record the handshake
   // hashes in |hs->new_session| in case we need them to verify a
   // ChannelID signature on a resumption of this session in the future.
-  if (ssl->session == NULL && ssl->s3->tlsext_channel_id_valid &&
+  if (ssl->session == NULL && ssl->s3->channel_id_valid &&
       !tls1_record_handshake_hashes_for_channel_id(hs)) {
     return ssl_hs_error;
   }
@@ -1456,7 +1422,8 @@
     } 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);
+      session_copy =
+          SSL_SESSION_dup(ssl->session.get(), SSL_SESSION_INCLUDE_NONAUTH);
       if (!session_copy) {
         return ssl_hs_error;
       }
@@ -1471,7 +1438,7 @@
                                    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_encrypt_ticket(hs, &ticket, session) ||
         !ssl_add_message_cbb(ssl, cbb.get())) {
       return ssl_hs_error;
     }
@@ -1494,25 +1461,24 @@
 static enum ssl_hs_wait_t do_finish_server_handshake(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
 
-  if (ssl->handback) {
+  if (hs->handback) {
     return ssl_hs_handback;
   }
 
   ssl->method->on_handshake_complete(ssl);
 
   // If we aren't retaining peer certificates then we can discard it now.
-  if (hs->new_session != NULL && ssl->retain_only_sha256_of_client_certs) {
-    sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
-    hs->new_session->certs = NULL;
+  if (hs->new_session != NULL &&
+      hs->config->retain_only_sha256_of_client_certs) {
+    hs->new_session->certs.reset();
     ssl->ctx->x509_method->session_clear(hs->new_session.get());
   }
 
   if (ssl->session != NULL) {
-    SSL_SESSION_up_ref(ssl->session);
-    ssl->s3->established_session.reset(ssl->session);
+    ssl->s3->established_session = UpRef(ssl->session);
   } else {
     ssl->s3->established_session = std::move(hs->new_session);
-    ssl->s3->established_session->not_resumable = 0;
+    ssl->s3->established_session->not_resumable = false;
   }
 
   hs->handshake_finalized = true;