diff --git a/ssl/test/CMakeLists.txt b/ssl/test/CMakeLists.txt
index 5a73319..2fdee73 100644
--- a/ssl/test/CMakeLists.txt
+++ b/ssl/test/CMakeLists.txt
@@ -8,6 +8,7 @@
   packeted_bio.cc
   settings_writer.cc
   test_config.cc
+  test_state.cc
 
   $<TARGET_OBJECTS:test_support>
 )
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 27a0783..f73fc69 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -67,10 +67,9 @@
 #include "packeted_bio.h"
 #include "settings_writer.h"
 #include "test_config.h"
+#include "test_state.h"
 
 
-static CRYPTO_BUFFER_POOL *g_pool = nullptr;
-
 #if !defined(OPENSSL_WINDOWS)
 static int closesocket(int sock) {
   return close(sock);
@@ -90,79 +89,6 @@
   return 1;
 }
 
-struct TestState {
-  // async_bio is async BIO which pauses reads and writes.
-  BIO *async_bio = nullptr;
-  // packeted_bio is the packeted BIO which simulates read timeouts.
-  BIO *packeted_bio = nullptr;
-  bssl::UniquePtr<EVP_PKEY> channel_id;
-  bool cert_ready = false;
-  bssl::UniquePtr<SSL_SESSION> session;
-  bssl::UniquePtr<SSL_SESSION> pending_session;
-  bool early_callback_called = false;
-  bool handshake_done = false;
-  // private_key is the underlying private key used when testing custom keys.
-  bssl::UniquePtr<EVP_PKEY> private_key;
-  std::vector<uint8_t> private_key_result;
-  // private_key_retries is the number of times an asynchronous private key
-  // operation has been retried.
-  unsigned private_key_retries = 0;
-  bool got_new_session = false;
-  bssl::UniquePtr<SSL_SESSION> new_session;
-  bool ticket_decrypt_done = false;
-  bool alpn_select_done = false;
-  bool is_resume = false;
-  bool early_callback_ready = false;
-  bool custom_verify_ready = false;
-  std::string msg_callback_text;
-  bool msg_callback_ok = true;
-  // cert_verified is true if certificate verification has been driven to
-  // completion. This tests that the callback is not called again after this.
-  bool cert_verified = false;
-};
-
-static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
-                            int index, long argl, void *argp) {
-  delete ((TestState *)ptr);
-}
-
-static int g_config_index = 0;
-static int g_state_index = 0;
-
-static bool SetTestConfig(SSL *ssl, const TestConfig *config) {
-  return SSL_set_ex_data(ssl, g_config_index, (void *)config) == 1;
-}
-
-static const TestConfig *GetTestConfig(const SSL *ssl) {
-  return (const TestConfig *)SSL_get_ex_data(ssl, g_config_index);
-}
-
-static bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state) {
-  // |SSL_set_ex_data| takes ownership of |state| only on success.
-  if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) {
-    state.release();
-    return true;
-  }
-  return false;
-}
-
-static TestState *GetTestState(const SSL *ssl) {
-  return (TestState *)SSL_get_ex_data(ssl, g_state_index);
-}
-
-static bool MoveExData(SSL *dest, SSL *src) {
-  TestState *state = GetTestState(src);
-  const TestConfig *config = GetTestConfig(src);
-  if (!SSL_set_ex_data(src, g_state_index, nullptr) ||
-      !SSL_set_ex_data(dest, g_state_index, state) ||
-      !SSL_set_ex_data(src, g_config_index, nullptr) ||
-      !SSL_set_ex_data(dest, g_config_index, (void *) config)) {
-    return false;
-  }
-
-  return true;
-}
-
 // MoveBIOs moves the |BIO|s of |src| to |dst|.  It is used for handoff.
 static void MoveBIOs(SSL *dest, SSL *src) {
   BIO *rbio = SSL_get_rbio(src);
@@ -177,262 +103,6 @@
   SSL_set0_wbio(src, nullptr);
 }
 
-static bool LoadCertificate(bssl::UniquePtr<X509> *out_x509,
-                            bssl::UniquePtr<STACK_OF(X509)> *out_chain,
-                            const std::string &file) {
-  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
-  if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
-    return false;
-  }
-
-  out_x509->reset(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
-  if (!*out_x509) {
-    return false;
-  }
-
-  out_chain->reset(sk_X509_new_null());
-  if (!*out_chain) {
-    return false;
-  }
-
-  // Keep reading the certificate chain.
-  for (;;) {
-    bssl::UniquePtr<X509> cert(
-        PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
-    if (!cert) {
-      break;
-    }
-
-    if (!bssl::PushToStack(out_chain->get(), std::move(cert))) {
-      return false;
-    }
-  }
-
-  uint32_t err = ERR_peek_last_error();
-  if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
-      ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
-    return false;
-}
-
-  ERR_clear_error();
-  return true;
-}
-
-static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
-  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
-  if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
-    return nullptr;
-  }
-  return bssl::UniquePtr<EVP_PKEY>(
-      PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
-}
-
-static bool FromHexDigit(uint8_t *out, char c) {
-  if ('0' <= c && c <= '9') {
-    *out = c - '0';
-    return true;
-  }
-  if ('a' <= c && c <= 'f') {
-    *out = c - 'a' + 10;
-    return true;
-  }
-  if ('A' <= c && c <= 'F') {
-    *out = c - 'A' + 10;
-    return true;
-  }
-  return false;
-}
-
-static bool HexDecode(std::string *out, const std::string &in) {
-  if ((in.size() & 1) != 0) {
-    return false;
-  }
-
-  std::unique_ptr<uint8_t[]> buf(new uint8_t[in.size() / 2]);
-  for (size_t i = 0; i < in.size() / 2; i++) {
-    uint8_t high, low;
-    if (!FromHexDigit(&high, in[i*2]) ||
-        !FromHexDigit(&low, in[i*2+1])) {
-      return false;
-    }
-    buf[i] = (high << 4) | low;
-  }
-
-  out->assign(reinterpret_cast<const char *>(buf.get()), in.size() / 2);
-  return true;
-}
-
-static std::vector<std::string> SplitParts(const std::string &in,
-                                           const char delim) {
-  std::vector<std::string> ret;
-  size_t start = 0;
-
-  for (size_t i = 0; i < in.size(); i++) {
-    if (in[i] == delim) {
-      ret.push_back(in.substr(start, i - start));
-      start = i + 1;
-    }
-  }
-
-  ret.push_back(in.substr(start, std::string::npos));
-  return ret;
-}
-
-static std::vector<std::string> DecodeHexStrings(
-    const std::string &hex_strings) {
-  std::vector<std::string> ret;
-  const std::vector<std::string> parts = SplitParts(hex_strings, ',');
-
-  for (const auto &part : parts) {
-    std::string binary;
-    if (!HexDecode(&binary, part)) {
-      fprintf(stderr, "Bad hex string: %s\n", part.c_str());
-      return ret;
-    }
-
-    ret.push_back(binary);
-  }
-
-  return ret;
-}
-
-static bssl::UniquePtr<STACK_OF(X509_NAME)> DecodeHexX509Names(
-    const std::string &hex_names) {
-  const std::vector<std::string> der_names = DecodeHexStrings(hex_names);
-  bssl::UniquePtr<STACK_OF(X509_NAME)> ret(sk_X509_NAME_new_null());
-  if (!ret) {
-    return nullptr;
-  }
-
-  for (const auto &der_name : der_names) {
-    const uint8_t *const data =
-        reinterpret_cast<const uint8_t *>(der_name.data());
-    const uint8_t *derp = data;
-    bssl::UniquePtr<X509_NAME> name(
-        d2i_X509_NAME(nullptr, &derp, der_name.size()));
-    if (!name || derp != data + der_name.size()) {
-      fprintf(stderr, "Failed to parse X509_NAME.\n");
-      return nullptr;
-    }
-
-    if (!bssl::PushToStack(ret.get(), std::move(name))) {
-      return nullptr;
-    }
-  }
-
-  return ret;
-}
-
-static ssl_private_key_result_t AsyncPrivateKeySign(
-    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
-    uint16_t signature_algorithm, const uint8_t *in, size_t in_len) {
-  TestState *test_state = GetTestState(ssl);
-  if (!test_state->private_key_result.empty()) {
-    fprintf(stderr, "AsyncPrivateKeySign called with operation pending.\n");
-    abort();
-  }
-
-  if (EVP_PKEY_id(test_state->private_key.get()) !=
-      SSL_get_signature_algorithm_key_type(signature_algorithm)) {
-    fprintf(stderr, "Key type does not match signature algorithm.\n");
-    abort();
-  }
-
-  // Determine the hash.
-  const EVP_MD *md = SSL_get_signature_algorithm_digest(signature_algorithm);
-  bssl::ScopedEVP_MD_CTX ctx;
-  EVP_PKEY_CTX *pctx;
-  if (!EVP_DigestSignInit(ctx.get(), &pctx, md, nullptr,
-                          test_state->private_key.get())) {
-    return ssl_private_key_failure;
-  }
-
-  // Configure additional signature parameters.
-  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
-    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
-        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) {
-      return ssl_private_key_failure;
-    }
-  }
-
-  // Write the signature into |test_state|.
-  size_t len = 0;
-  if (!EVP_DigestSign(ctx.get(), nullptr, &len, in, in_len)) {
-    return ssl_private_key_failure;
-  }
-  test_state->private_key_result.resize(len);
-  if (!EVP_DigestSign(ctx.get(), test_state->private_key_result.data(), &len,
-                      in, in_len)) {
-    return ssl_private_key_failure;
-  }
-  test_state->private_key_result.resize(len);
-
-  // The signature will be released asynchronously in |AsyncPrivateKeyComplete|.
-  return ssl_private_key_retry;
-}
-
-static ssl_private_key_result_t AsyncPrivateKeyDecrypt(
-    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
-    const uint8_t *in, size_t in_len) {
-  TestState *test_state = GetTestState(ssl);
-  if (!test_state->private_key_result.empty()) {
-    fprintf(stderr,
-            "AsyncPrivateKeyDecrypt called with operation pending.\n");
-    abort();
-  }
-
-  RSA *rsa = EVP_PKEY_get0_RSA(test_state->private_key.get());
-  if (rsa == NULL) {
-    fprintf(stderr,
-            "AsyncPrivateKeyDecrypt called with incorrect key type.\n");
-    abort();
-  }
-  test_state->private_key_result.resize(RSA_size(rsa));
-  if (!RSA_decrypt(rsa, out_len, test_state->private_key_result.data(),
-                   RSA_size(rsa), in, in_len, RSA_NO_PADDING)) {
-    return ssl_private_key_failure;
-  }
-
-  test_state->private_key_result.resize(*out_len);
-
-  // The decryption will be released asynchronously in |AsyncPrivateComplete|.
-  return ssl_private_key_retry;
-}
-
-static ssl_private_key_result_t AsyncPrivateKeyComplete(
-    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
-  TestState *test_state = GetTestState(ssl);
-  if (test_state->private_key_result.empty()) {
-    fprintf(stderr,
-            "AsyncPrivateKeyComplete called without operation pending.\n");
-    abort();
-  }
-
-  if (test_state->private_key_retries < 2) {
-    // Only return the decryption on the second attempt, to test both incomplete
-    // |decrypt| and |decrypt_complete|.
-    return ssl_private_key_retry;
-  }
-
-  if (max_out < test_state->private_key_result.size()) {
-    fprintf(stderr, "Output buffer too small.\n");
-    return ssl_private_key_failure;
-  }
-  OPENSSL_memcpy(out, test_state->private_key_result.data(),
-                 test_state->private_key_result.size());
-  *out_len = test_state->private_key_result.size();
-
-  test_state->private_key_result.clear();
-  test_state->private_key_retries = 0;
-  return ssl_private_key_success;
-}
-
-static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
-    AsyncPrivateKeySign,
-    AsyncPrivateKeyDecrypt,
-    AsyncPrivateKeyComplete,
-};
-
 template<typename T>
 struct Free {
   void operator()(T *buf) {
@@ -440,651 +110,6 @@
   }
 };
 
-static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
-                           bssl::UniquePtr<STACK_OF(X509)> *out_chain,
-                           bssl::UniquePtr<EVP_PKEY> *out_pkey) {
-  const TestConfig *config = GetTestConfig(ssl);
-
-  if (!config->signing_prefs.empty()) {
-    std::vector<uint16_t> u16s(config->signing_prefs.begin(),
-                               config->signing_prefs.end());
-    if (!SSL_set_signing_algorithm_prefs(ssl, u16s.data(), u16s.size())) {
-      return false;
-    }
-  }
-
-  if (!config->key_file.empty()) {
-    *out_pkey = LoadPrivateKey(config->key_file.c_str());
-    if (!*out_pkey) {
-      return false;
-    }
-  }
-  if (!config->cert_file.empty() &&
-      !LoadCertificate(out_x509, out_chain, config->cert_file.c_str())) {
-    return false;
-  }
-  if (!config->ocsp_response.empty() &&
-      !config->set_ocsp_in_callback &&
-      !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
-                             config->ocsp_response.size())) {
-    return false;
-  }
-  return true;
-}
-
-static bool InstallCertificate(SSL *ssl) {
-  bssl::UniquePtr<X509> x509;
-  bssl::UniquePtr<STACK_OF(X509)> chain;
-  bssl::UniquePtr<EVP_PKEY> pkey;
-  if (!GetCertificate(ssl, &x509, &chain, &pkey)) {
-    return false;
-  }
-
-  if (pkey) {
-    TestState *test_state = GetTestState(ssl);
-    const TestConfig *config = GetTestConfig(ssl);
-    if (config->async) {
-      test_state->private_key = std::move(pkey);
-      SSL_set_private_key_method(ssl, &g_async_private_key_method);
-    } else if (!SSL_use_PrivateKey(ssl, pkey.get())) {
-      return false;
-    }
-  }
-
-  if (x509 && !SSL_use_certificate(ssl, x509.get())) {
-    return false;
-  }
-
-  if (sk_X509_num(chain.get()) > 0 &&
-      !SSL_set1_chain(ssl, chain.get())) {
-    return false;
-  }
-
-  return true;
-}
-
-static enum ssl_select_cert_result_t SelectCertificateCallback(
-    const SSL_CLIENT_HELLO *client_hello) {
-  const TestConfig *config = GetTestConfig(client_hello->ssl);
-  GetTestState(client_hello->ssl)->early_callback_called = true;
-
-  if (!config->expected_server_name.empty()) {
-    const uint8_t *extension_data;
-    size_t extension_len;
-    CBS extension, server_name_list, host_name;
-    uint8_t name_type;
-
-    if (!SSL_early_callback_ctx_extension_get(
-            client_hello, TLSEXT_TYPE_server_name, &extension_data,
-            &extension_len)) {
-      fprintf(stderr, "Could not find server_name extension.\n");
-      return ssl_select_cert_error;
-    }
-
-    CBS_init(&extension, extension_data, extension_len);
-    if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
-        CBS_len(&extension) != 0 ||
-        !CBS_get_u8(&server_name_list, &name_type) ||
-        name_type != TLSEXT_NAMETYPE_host_name ||
-        !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
-        CBS_len(&server_name_list) != 0) {
-      fprintf(stderr, "Could not decode server_name extension.\n");
-      return ssl_select_cert_error;
-    }
-
-    if (!CBS_mem_equal(&host_name,
-                       (const uint8_t*)config->expected_server_name.data(),
-                       config->expected_server_name.size())) {
-      fprintf(stderr, "Server name mismatch.\n");
-    }
-  }
-
-  if (config->fail_early_callback) {
-    return ssl_select_cert_error;
-  }
-
-  // Install the certificate in the early callback.
-  if (config->use_early_callback) {
-    bool early_callback_ready =
-        GetTestState(client_hello->ssl)->early_callback_ready;
-    if (config->async && !early_callback_ready) {
-      // Install the certificate asynchronously.
-      return ssl_select_cert_retry;
-    }
-    if (!InstallCertificate(client_hello->ssl)) {
-      return ssl_select_cert_error;
-    }
-  }
-  return ssl_select_cert_success;
-}
-
-static bool CheckCertificateRequest(SSL *ssl) {
-  const TestConfig *config = GetTestConfig(ssl);
-
-  if (!config->expected_certificate_types.empty()) {
-    const uint8_t *certificate_types;
-    size_t certificate_types_len =
-        SSL_get0_certificate_types(ssl, &certificate_types);
-    if (certificate_types_len != config->expected_certificate_types.size() ||
-        OPENSSL_memcmp(certificate_types,
-                       config->expected_certificate_types.data(),
-                       certificate_types_len) != 0) {
-      fprintf(stderr, "certificate types mismatch\n");
-      return false;
-    }
-  }
-
-  if (!config->expected_client_ca_list.empty()) {
-    bssl::UniquePtr<STACK_OF(X509_NAME)> expected =
-        DecodeHexX509Names(config->expected_client_ca_list);
-    const size_t num_expected = sk_X509_NAME_num(expected.get());
-
-    const STACK_OF(X509_NAME) *received = SSL_get_client_CA_list(ssl);
-    const size_t num_received = sk_X509_NAME_num(received);
-
-    if (num_received != num_expected) {
-      fprintf(stderr, "expected %u names in CertificateRequest but got %u\n",
-              static_cast<unsigned>(num_expected),
-              static_cast<unsigned>(num_received));
-      return false;
-    }
-
-    for (size_t i = 0; i < num_received; i++) {
-      if (X509_NAME_cmp(sk_X509_NAME_value(received, i),
-                        sk_X509_NAME_value(expected.get(), i)) != 0) {
-        fprintf(stderr, "names in CertificateRequest differ at index #%d\n",
-                static_cast<unsigned>(i));
-        return false;
-      }
-    }
-
-    const STACK_OF(CRYPTO_BUFFER) *buffers = SSL_get0_server_requested_CAs(ssl);
-    if (sk_CRYPTO_BUFFER_num(buffers) != num_received) {
-      fprintf(stderr,
-              "Mismatch between SSL_get_server_requested_CAs and "
-              "SSL_get_client_CA_list.\n");
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static int ClientCertCallback(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
-  if (!CheckCertificateRequest(ssl)) {
-    return -1;
-  }
-
-  if (GetTestConfig(ssl)->async && !GetTestState(ssl)->cert_ready) {
-    return -1;
-  }
-
-  bssl::UniquePtr<X509> x509;
-  bssl::UniquePtr<STACK_OF(X509)> chain;
-  bssl::UniquePtr<EVP_PKEY> pkey;
-  if (!GetCertificate(ssl, &x509, &chain, &pkey)) {
-    return -1;
-  }
-
-  // Return zero for no certificate.
-  if (!x509) {
-    return 0;
-  }
-
-  // Chains and asynchronous private keys are not supported with client_cert_cb.
-  *out_x509 = x509.release();
-  *out_pkey = pkey.release();
-  return 1;
-}
-
-static int CertCallback(SSL *ssl, void *arg) {
-  const TestConfig *config = GetTestConfig(ssl);
-
-  // Check the CertificateRequest metadata is as expected.
-  if (!SSL_is_server(ssl) && !CheckCertificateRequest(ssl)) {
-    return -1;
-  }
-
-  if (config->fail_cert_callback) {
-    return 0;
-  }
-
-  // The certificate will be installed via other means.
-  if (!config->async || config->use_early_callback) {
-    return 1;
-  }
-
-  if (!GetTestState(ssl)->cert_ready) {
-    return -1;
-  }
-  if (!InstallCertificate(ssl)) {
-    return 0;
-  }
-  return 1;
-}
-
-static bool CheckVerifyCallback(SSL *ssl) {
-  const TestConfig *config = GetTestConfig(ssl);
-  if (!config->expected_ocsp_response.empty()) {
-    const uint8_t *data;
-    size_t len;
-    SSL_get0_ocsp_response(ssl, &data, &len);
-    if (len == 0) {
-      fprintf(stderr, "OCSP response not available in verify callback\n");
-      return false;
-    }
-  }
-
-  if (GetTestState(ssl)->cert_verified) {
-    fprintf(stderr, "Certificate verified twice.\n");
-    return false;
-  }
-
-  return true;
-}
-
-static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) {
-  SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(store_ctx,
-      SSL_get_ex_data_X509_STORE_CTX_idx());
-  const TestConfig *config = GetTestConfig(ssl);
-  if (!CheckVerifyCallback(ssl)) {
-    return 0;
-  }
-
-  GetTestState(ssl)->cert_verified = true;
-  if (config->verify_fail) {
-    store_ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
-    return 0;
-  }
-
-  return 1;
-}
-
-static ssl_verify_result_t CustomVerifyCallback(SSL *ssl, uint8_t *out_alert) {
-  const TestConfig *config = GetTestConfig(ssl);
-  if (!CheckVerifyCallback(ssl)) {
-    return ssl_verify_invalid;
-  }
-
-  if (config->async && !GetTestState(ssl)->custom_verify_ready) {
-    return ssl_verify_retry;
-  }
-
-  GetTestState(ssl)->cert_verified = true;
-  if (config->verify_fail) {
-    return ssl_verify_invalid;
-  }
-
-  return ssl_verify_ok;
-}
-
-static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out,
-                                        unsigned int *out_len, void *arg) {
-  const TestConfig *config = GetTestConfig(ssl);
-  if (config->advertise_npn.empty()) {
-    return SSL_TLSEXT_ERR_NOACK;
-  }
-
-  *out = (const uint8_t*)config->advertise_npn.data();
-  *out_len = config->advertise_npn.size();
-  return SSL_TLSEXT_ERR_OK;
-}
-
-static int NextProtoSelectCallback(SSL* ssl, uint8_t** out, uint8_t* outlen,
-                                   const uint8_t* in, unsigned inlen, void* arg) {
-  const TestConfig *config = GetTestConfig(ssl);
-  if (config->select_next_proto.empty()) {
-    return SSL_TLSEXT_ERR_NOACK;
-  }
-
-  *out = (uint8_t*)config->select_next_proto.data();
-  *outlen = config->select_next_proto.size();
-  return SSL_TLSEXT_ERR_OK;
-}
-
-static int AlpnSelectCallback(SSL* ssl, const uint8_t** out, uint8_t* outlen,
-                              const uint8_t* in, unsigned inlen, void* arg) {
-  if (GetTestState(ssl)->alpn_select_done) {
-    fprintf(stderr, "AlpnSelectCallback called after completion.\n");
-    exit(1);
-  }
-
-  GetTestState(ssl)->alpn_select_done = true;
-
-  const TestConfig *config = GetTestConfig(ssl);
-  if (config->decline_alpn) {
-    return SSL_TLSEXT_ERR_NOACK;
-  }
-
-  if (!config->expected_advertised_alpn.empty() &&
-      (config->expected_advertised_alpn.size() != inlen ||
-       OPENSSL_memcmp(config->expected_advertised_alpn.data(), in, inlen) !=
-           0)) {
-    fprintf(stderr, "bad ALPN select callback inputs\n");
-    exit(1);
-  }
-
-  assert(config->select_alpn.empty() || !config->select_empty_alpn);
-  *out = (const uint8_t*)config->select_alpn.data();
-  *outlen = config->select_alpn.size();
-  return SSL_TLSEXT_ERR_OK;
-}
-
-static unsigned PskClientCallback(SSL *ssl, const char *hint,
-                                  char *out_identity,
-                                  unsigned max_identity_len,
-                                  uint8_t *out_psk, unsigned max_psk_len) {
-  const TestConfig *config = GetTestConfig(ssl);
-
-  if (config->psk_identity.empty()) {
-    if (hint != nullptr) {
-      fprintf(stderr, "Server PSK hint was non-null.\n");
-      return 0;
-    }
-  } else if (hint == nullptr ||
-             strcmp(hint, config->psk_identity.c_str()) != 0) {
-    fprintf(stderr, "Server PSK hint did not match.\n");
-    return 0;
-  }
-
-  // Account for the trailing '\0' for the identity.
-  if (config->psk_identity.size() >= max_identity_len ||
-      config->psk.size() > max_psk_len) {
-    fprintf(stderr, "PSK buffers too small\n");
-    return 0;
-  }
-
-  BUF_strlcpy(out_identity, config->psk_identity.c_str(),
-              max_identity_len);
-  OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size());
-  return config->psk.size();
-}
-
-static unsigned PskServerCallback(SSL *ssl, const char *identity,
-                                  uint8_t *out_psk, unsigned max_psk_len) {
-  const TestConfig *config = GetTestConfig(ssl);
-
-  if (strcmp(identity, config->psk_identity.c_str()) != 0) {
-    fprintf(stderr, "Client PSK identity did not match.\n");
-    return 0;
-  }
-
-  if (config->psk.size() > max_psk_len) {
-    fprintf(stderr, "PSK buffers too small\n");
-    return 0;
-  }
-
-  OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size());
-  return config->psk.size();
-}
-
-static timeval g_clock;
-
-static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
-  *out_clock = g_clock;
-}
-
-static void ChannelIdCallback(SSL *ssl, EVP_PKEY **out_pkey) {
-  *out_pkey = GetTestState(ssl)->channel_id.release();
-}
-
-static SSL_SESSION *GetSessionCallback(SSL *ssl, const uint8_t *data, int len,
-                                       int *copy) {
-  TestState *async_state = GetTestState(ssl);
-  if (async_state->session) {
-    *copy = 0;
-    return async_state->session.release();
-  } else if (async_state->pending_session) {
-    return SSL_magic_pending_session_ptr();
-  } else {
-    return NULL;
-  }
-}
-
-static int DDoSCallback(const SSL_CLIENT_HELLO *client_hello) {
-  const TestConfig *config = GetTestConfig(client_hello->ssl);
-  return config->fail_ddos_callback ? 0 : 1;
-}
-
-static void InfoCallback(const SSL *ssl, int type, int val) {
-  if (type == SSL_CB_HANDSHAKE_DONE) {
-    if (GetTestConfig(ssl)->handshake_never_done) {
-      fprintf(stderr, "Handshake unexpectedly completed.\n");
-      // Abort before any expected error code is printed, to ensure the overall
-      // test fails.
-      abort();
-    }
-    // This callback is called when the handshake completes. |SSL_get_session|
-    // must continue to work and |SSL_in_init| must return false.
-    if (SSL_in_init(ssl) || SSL_get_session(ssl) == nullptr) {
-      fprintf(stderr, "Invalid state for SSL_CB_HANDSHAKE_DONE.\n");
-      abort();
-    }
-    GetTestState(ssl)->handshake_done = true;
-
-    // Callbacks may be called again on a new handshake.
-    GetTestState(ssl)->ticket_decrypt_done = false;
-    GetTestState(ssl)->alpn_select_done = false;
-  }
-}
-
-static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
-  // This callback is called as the handshake completes. |SSL_get_session|
-  // must continue to work and, historically, |SSL_in_init| returned false at
-  // this point.
-  if (SSL_in_init(ssl) || SSL_get_session(ssl) == nullptr) {
-    fprintf(stderr, "Invalid state for NewSessionCallback.\n");
-    abort();
-  }
-
-  GetTestState(ssl)->got_new_session = true;
-  GetTestState(ssl)->new_session.reset(session);
-  return 1;
-}
-
-static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
-                             EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
-                             int encrypt) {
-  if (!encrypt) {
-    if (GetTestState(ssl)->ticket_decrypt_done) {
-      fprintf(stderr, "TicketKeyCallback called after completion.\n");
-      return -1;
-    }
-
-    GetTestState(ssl)->ticket_decrypt_done = true;
-  }
-
-  // This is just test code, so use the all-zeros key.
-  static const uint8_t kZeros[16] = {0};
-
-  if (encrypt) {
-    OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
-    RAND_bytes(iv, 16);
-  } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
-    return 0;
-  }
-
-  if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
-      !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
-    return -1;
-  }
-
-  if (!encrypt) {
-    return GetTestConfig(ssl)->renew_ticket ? 2 : 1;
-  }
-  return 1;
-}
-
-// kCustomExtensionValue is the extension value that the custom extension
-// callbacks will add.
-static const uint16_t kCustomExtensionValue = 1234;
-static void *const kCustomExtensionAddArg =
-    reinterpret_cast<void *>(kCustomExtensionValue);
-static void *const kCustomExtensionParseArg =
-    reinterpret_cast<void *>(kCustomExtensionValue + 1);
-static const char kCustomExtensionContents[] = "custom extension";
-
-static int CustomExtensionAddCallback(SSL *ssl, unsigned extension_value,
-                                      const uint8_t **out, size_t *out_len,
-                                      int *out_alert_value, void *add_arg) {
-  if (extension_value != kCustomExtensionValue ||
-      add_arg != kCustomExtensionAddArg) {
-    abort();
-  }
-
-  if (GetTestConfig(ssl)->custom_extension_skip) {
-    return 0;
-  }
-  if (GetTestConfig(ssl)->custom_extension_fail_add) {
-    return -1;
-  }
-
-  *out = reinterpret_cast<const uint8_t*>(kCustomExtensionContents);
-  *out_len = sizeof(kCustomExtensionContents) - 1;
-
-  return 1;
-}
-
-static void CustomExtensionFreeCallback(SSL *ssl, unsigned extension_value,
-                                        const uint8_t *out, void *add_arg) {
-  if (extension_value != kCustomExtensionValue ||
-      add_arg != kCustomExtensionAddArg ||
-      out != reinterpret_cast<const uint8_t *>(kCustomExtensionContents)) {
-    abort();
-  }
-}
-
-static int CustomExtensionParseCallback(SSL *ssl, unsigned extension_value,
-                                        const uint8_t *contents,
-                                        size_t contents_len,
-                                        int *out_alert_value, void *parse_arg) {
-  if (extension_value != kCustomExtensionValue ||
-      parse_arg != kCustomExtensionParseArg) {
-    abort();
-  }
-
-  if (contents_len != sizeof(kCustomExtensionContents) - 1 ||
-      OPENSSL_memcmp(contents, kCustomExtensionContents, contents_len) != 0) {
-    *out_alert_value = SSL_AD_DECODE_ERROR;
-    return 0;
-  }
-
-  return 1;
-}
-
-static int ServerNameCallback(SSL *ssl, int *out_alert, void *arg) {
-  // SNI must be accessible from the SNI callback.
-  const TestConfig *config = GetTestConfig(ssl);
-  const char *server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
-  if (server_name == nullptr ||
-      std::string(server_name) != config->expected_server_name) {
-    fprintf(stderr, "servername mismatch (got %s; want %s)\n", server_name,
-            config->expected_server_name.c_str());
-    return SSL_TLSEXT_ERR_ALERT_FATAL;
-  }
-
-  return SSL_TLSEXT_ERR_OK;
-}
-
-static void MessageCallback(int is_write, int version, int content_type,
-                            const void *buf, size_t len, SSL *ssl, void *arg) {
-  const uint8_t *buf_u8 = reinterpret_cast<const uint8_t *>(buf);
-  const TestConfig *config = GetTestConfig(ssl);
-  TestState *state = GetTestState(ssl);
-  if (!state->msg_callback_ok) {
-    return;
-  }
-
-  if (content_type == SSL3_RT_HEADER) {
-    if (len !=
-        (config->is_dtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH)) {
-      fprintf(stderr, "Incorrect length for record header: %zu\n", len);
-      state->msg_callback_ok = false;
-    }
-    return;
-  }
-
-  state->msg_callback_text += is_write ? "write " : "read ";
-  switch (content_type) {
-    case 0:
-      if (version != SSL2_VERSION) {
-        fprintf(stderr, "Incorrect version for V2ClientHello: %x\n", version);
-        state->msg_callback_ok = false;
-        return;
-      }
-      state->msg_callback_text += "v2clienthello\n";
-      return;
-
-    case SSL3_RT_HANDSHAKE: {
-      CBS cbs;
-      CBS_init(&cbs, buf_u8, len);
-      uint8_t type;
-      uint32_t msg_len;
-      if (!CBS_get_u8(&cbs, &type) ||
-          // TODO(davidben): Reporting on entire messages would be more
-          // consistent than fragments.
-          (config->is_dtls &&
-           !CBS_skip(&cbs, 3 /* total */ + 2 /* seq */ + 3 /* frag_off */)) ||
-          !CBS_get_u24(&cbs, &msg_len) ||
-          !CBS_skip(&cbs, msg_len) ||
-          CBS_len(&cbs) != 0) {
-        fprintf(stderr, "Could not parse handshake message.\n");
-        state->msg_callback_ok = false;
-        return;
-      }
-      char text[16];
-      snprintf(text, sizeof(text), "hs %d\n", type);
-      state->msg_callback_text += text;
-      return;
-    }
-
-    case SSL3_RT_CHANGE_CIPHER_SPEC:
-      if (len != 1 || buf_u8[0] != 1) {
-        fprintf(stderr, "Invalid ChangeCipherSpec.\n");
-        state->msg_callback_ok = false;
-        return;
-      }
-      state->msg_callback_text += "ccs\n";
-      return;
-
-    case SSL3_RT_ALERT:
-      if (len != 2) {
-        fprintf(stderr, "Invalid alert.\n");
-        state->msg_callback_ok = false;
-        return;
-      }
-      char text[16];
-      snprintf(text, sizeof(text), "alert %d %d\n", buf_u8[0], buf_u8[1]);
-      state->msg_callback_text += text;
-      return;
-
-    default:
-      fprintf(stderr, "Invalid content_type: %d\n", content_type);
-      state->msg_callback_ok = false;
-  }
-}
-
-static int LegacyOCSPCallback(SSL *ssl, void *arg) {
-  const TestConfig *config = GetTestConfig(ssl);
-  if (!SSL_is_server(ssl)) {
-    return !config->fail_ocsp_callback;
-  }
-
-  if (!config->ocsp_response.empty() &&
-      config->set_ocsp_in_callback &&
-      !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
-                             config->ocsp_response.size())) {
-    return SSL_TLSEXT_ERR_ALERT_FATAL;
-  }
-  if (config->fail_ocsp_callback) {
-    return SSL_TLSEXT_ERR_ALERT_FATAL;
-  }
-  if (config->decline_ocsp_callback) {
-    return SSL_TLSEXT_ERR_NOACK;
-  }
-  return SSL_TLSEXT_ERR_OK;
-}
-
 // Connect returns a new socket connected to localhost on |port| or -1 on
 // error.
 static int Connect(uint16_t port) {
@@ -1162,231 +187,6 @@
   const int sock_;
 };
 
-static void ssl_ctx_add_session(SSL_SESSION *session, void *void_param) {
-  SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(void_param);
-  bssl::UniquePtr<SSL_SESSION> new_session = bssl::SSL_SESSION_dup(
-      session, SSL_SESSION_INCLUDE_NONAUTH | SSL_SESSION_INCLUDE_TICKET);
-  if (new_session != nullptr) {
-    SSL_CTX_add_session(ctx, new_session.get());
-  }
-}
-
-static bssl::UniquePtr<SSL_CTX> SetupCtx(SSL_CTX *old_ctx,
-                                         const TestConfig *config) {
-  bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(
-      config->is_dtls ? DTLS_method() : TLS_method()));
-  if (!ssl_ctx) {
-    return nullptr;
-  }
-
-  SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool);
-
-  // Enable TLS 1.3 for tests.
-  if (!config->is_dtls &&
-      !SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION)) {
-    return nullptr;
-  }
-
-  std::string cipher_list = "ALL";
-  if (!config->cipher.empty()) {
-    cipher_list = config->cipher;
-    SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
-  }
-  if (!SSL_CTX_set_strict_cipher_list(ssl_ctx.get(), cipher_list.c_str())) {
-    return nullptr;
-  }
-
-  if (config->async && config->is_server) {
-    // Disable the internal session cache. To test asynchronous session lookup,
-    // we use an external session cache.
-    SSL_CTX_set_session_cache_mode(
-        ssl_ctx.get(), SSL_SESS_CACHE_BOTH | SSL_SESS_CACHE_NO_INTERNAL);
-    SSL_CTX_sess_set_get_cb(ssl_ctx.get(), GetSessionCallback);
-  } else {
-    SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
-  }
-
-  SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
-
-  if (config->use_old_client_cert_callback) {
-    SSL_CTX_set_client_cert_cb(ssl_ctx.get(), ClientCertCallback);
-  }
-
-  SSL_CTX_set_next_protos_advertised_cb(
-      ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);
-  if (!config->select_next_proto.empty()) {
-    SSL_CTX_set_next_proto_select_cb(ssl_ctx.get(), NextProtoSelectCallback,
-                                     NULL);
-  }
-
-  if (!config->select_alpn.empty() || config->decline_alpn ||
-      config->select_empty_alpn) {
-    SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
-  }
-
-  SSL_CTX_set_channel_id_cb(ssl_ctx.get(), ChannelIdCallback);
-
-  SSL_CTX_set_current_time_cb(ssl_ctx.get(), CurrentTimeCallback);
-
-  SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
-  SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
-
-  if (config->use_ticket_callback) {
-    SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
-  }
-
-  if (config->enable_client_custom_extension &&
-      !SSL_CTX_add_client_custom_ext(
-          ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
-          CustomExtensionFreeCallback, kCustomExtensionAddArg,
-          CustomExtensionParseCallback, kCustomExtensionParseArg)) {
-    return nullptr;
-  }
-
-  if (config->enable_server_custom_extension &&
-      !SSL_CTX_add_server_custom_ext(
-          ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
-          CustomExtensionFreeCallback, kCustomExtensionAddArg,
-          CustomExtensionParseCallback, kCustomExtensionParseArg)) {
-    return nullptr;
-  }
-
-  if (!config->use_custom_verify_callback) {
-    SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), CertVerifyCallback, NULL);
-  }
-
-  if (!config->signed_cert_timestamps.empty() &&
-      !SSL_CTX_set_signed_cert_timestamp_list(
-          ssl_ctx.get(), (const uint8_t *)config->signed_cert_timestamps.data(),
-          config->signed_cert_timestamps.size())) {
-    return nullptr;
-  }
-
-  if (!config->use_client_ca_list.empty()) {
-    if (config->use_client_ca_list == "<NULL>") {
-      SSL_CTX_set_client_CA_list(ssl_ctx.get(), nullptr);
-    } else if (config->use_client_ca_list == "<EMPTY>") {
-      bssl::UniquePtr<STACK_OF(X509_NAME)> names;
-      SSL_CTX_set_client_CA_list(ssl_ctx.get(), names.release());
-    } else {
-      bssl::UniquePtr<STACK_OF(X509_NAME)> names =
-          DecodeHexX509Names(config->use_client_ca_list);
-      SSL_CTX_set_client_CA_list(ssl_ctx.get(), names.release());
-    }
-  }
-
-  if (config->enable_grease) {
-    SSL_CTX_set_grease_enabled(ssl_ctx.get(), 1);
-  }
-
-  if (!config->expected_server_name.empty()) {
-    SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), ServerNameCallback);
-  }
-
-  if (!config->ticket_key.empty() &&
-      !SSL_CTX_set_tlsext_ticket_keys(ssl_ctx.get(), config->ticket_key.data(),
-                                      config->ticket_key.size())) {
-    return nullptr;
-  }
-
-  if (config->enable_early_data) {
-    SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
-  }
-
-  SSL_CTX_set_tls13_variant(
-      ssl_ctx.get(), static_cast<enum tls13_variant_t>(config->tls13_variant));
-
-  if (config->allow_unknown_alpn_protos) {
-    SSL_CTX_set_allow_unknown_alpn_protos(ssl_ctx.get(), 1);
-  }
-
-  if (config->enable_ed25519) {
-    SSL_CTX_set_ed25519_enabled(ssl_ctx.get(), 1);
-  }
-  if (config->no_rsa_pss_rsae_certs) {
-    SSL_CTX_set_rsa_pss_rsae_certs_enabled(ssl_ctx.get(), 0);
-  }
-
-  if (!config->verify_prefs.empty()) {
-    std::vector<uint16_t> u16s(config->verify_prefs.begin(),
-                               config->verify_prefs.end());
-    if (!SSL_CTX_set_verify_algorithm_prefs(ssl_ctx.get(), u16s.data(),
-                                            u16s.size())) {
-      return nullptr;
-    }
-  }
-
-  SSL_CTX_set_msg_callback(ssl_ctx.get(), MessageCallback);
-
-  if (config->allow_false_start_without_alpn) {
-    SSL_CTX_set_false_start_allowed_without_alpn(ssl_ctx.get(), 1);
-  }
-
-  if (config->use_ocsp_callback) {
-    SSL_CTX_set_tlsext_status_cb(ssl_ctx.get(), LegacyOCSPCallback);
-  }
-
-  if (old_ctx) {
-    uint8_t keys[48];
-    if (!SSL_CTX_get_tlsext_ticket_keys(old_ctx, &keys, sizeof(keys)) ||
-        !SSL_CTX_set_tlsext_ticket_keys(ssl_ctx.get(), keys, sizeof(keys))) {
-      return nullptr;
-    }
-    lh_SSL_SESSION_doall_arg(old_ctx->sessions, ssl_ctx_add_session,
-                             ssl_ctx.get());
-  }
-
-  if (config->install_cert_compression_algs &&
-      (!SSL_CTX_add_cert_compression_alg(
-           ssl_ctx.get(), 0xff02,
-           [](SSL *ssl, CBB *out, bssl::Span<const uint8_t> in) -> bool {
-             if (!CBB_add_u8(out, 1) ||
-                 !CBB_add_u8(out, 2) ||
-                 !CBB_add_u8(out, 3) ||
-                 !CBB_add_u8(out, 4) ||
-                 !CBB_add_bytes(out, in.data(), in.size())) {
-               return false;
-             }
-             return true;
-           },
-           [](SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
-              size_t uncompressed_len, bssl::Span<const uint8_t> in) -> bool {
-             if (in.size() < 4 || in[0] != 1 || in[1] != 2 || in[2] != 3 ||
-                 in[3] != 4 || uncompressed_len != in.size() - 4) {
-               return false;
-             }
-             const bssl::Span<const uint8_t> uncompressed(in.subspan(4));
-             out->reset(CRYPTO_BUFFER_new(uncompressed.data(),
-                                          uncompressed.size(), nullptr));
-             return true;
-           }) ||
-       !SSL_CTX_add_cert_compression_alg(
-           ssl_ctx.get(), 0xff01,
-           [](SSL *ssl, CBB *out, bssl::Span<const uint8_t> in) -> bool {
-             if (in.size() < 2 || in[0] != 0 || in[1] != 0) {
-               return false;
-             }
-             return CBB_add_bytes(out, in.data() + 2, in.size() - 2);
-           },
-           [](SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
-              size_t uncompressed_len, bssl::Span<const uint8_t> in) -> bool {
-             if (uncompressed_len != 2 + in.size()) {
-               return false;
-             }
-             std::unique_ptr<uint8_t[]> buf(new uint8_t[2 + in.size()]);
-             buf[0] = 0;
-             buf[1] = 0;
-             OPENSSL_memcpy(&buf[2], in.data(), in.size());
-             out->reset(CRYPTO_BUFFER_new(buf.get(), 2 + in.size(), nullptr));
-             return true;
-           }))) {
-    fprintf(stderr, "SSL_CTX_add_cert_compression_alg failed.\n");
-    abort();
-  }
-
-  return ssl_ctx;
-}
-
 // RetryAsync is called after a failed operation on |ssl| with return code
 // |ret|. If the operation should be retried, it simulates one asynchronous
 // event and returns true. Otherwise it returns false.
@@ -1934,219 +734,6 @@
   return true;
 }
 
-static bssl::UniquePtr<SSL> NewSSL(SSL_CTX *ssl_ctx, const TestConfig *config,
-                                   SSL_SESSION *session, bool is_resume,
-                                   std::unique_ptr<TestState> test_state) {
-  bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx));
-  if (!ssl) {
-    return nullptr;
-  }
-
-  if (!SetTestConfig(ssl.get(), config)) {
-    return nullptr;
-  }
-  if (test_state != nullptr) {
-    if (!SetTestState(ssl.get(), std::move(test_state))) {
-      return nullptr;
-    }
-    GetTestState(ssl.get())->is_resume = is_resume;
-  }
-
-  if (config->fallback_scsv &&
-      !SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
-    return nullptr;
-  }
-  // Install the certificate synchronously if nothing else will handle it.
-  if (!config->use_early_callback &&
-      !config->use_old_client_cert_callback &&
-      !config->async &&
-      !InstallCertificate(ssl.get())) {
-    return nullptr;
-  }
-  if (!config->use_old_client_cert_callback) {
-    SSL_set_cert_cb(ssl.get(), CertCallback, nullptr);
-  }
-  int mode = SSL_VERIFY_NONE;
-  if (config->require_any_client_certificate) {
-    mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-  }
-  if (config->verify_peer) {
-    mode = SSL_VERIFY_PEER;
-  }
-  if (config->verify_peer_if_no_obc) {
-    // Set SSL_VERIFY_FAIL_IF_NO_PEER_CERT so testing whether client
-    // certificates were requested is easy.
-    mode = SSL_VERIFY_PEER | SSL_VERIFY_PEER_IF_NO_OBC |
-           SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-  }
-  if (config->use_custom_verify_callback) {
-    SSL_set_custom_verify(ssl.get(), mode, CustomVerifyCallback);
-  } else if (mode != SSL_VERIFY_NONE) {
-    SSL_set_verify(ssl.get(), mode, NULL);
-  }
-  if (config->false_start) {
-    SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_FALSE_START);
-  }
-  if (config->cbc_record_splitting) {
-    SSL_set_mode(ssl.get(), SSL_MODE_CBC_RECORD_SPLITTING);
-  }
-  if (config->partial_write) {
-    SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
-  }
-  if (config->no_tls13) {
-    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_3);
-  }
-  if (config->no_tls12) {
-    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_2);
-  }
-  if (config->no_tls11) {
-    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_1);
-  }
-  if (config->no_tls1) {
-    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1);
-  }
-  if (!config->expected_channel_id.empty() ||
-      config->enable_channel_id) {
-    SSL_set_tls_channel_id_enabled(ssl.get(), 1);
-  }
-  if (!config->send_channel_id.empty()) {
-    SSL_set_tls_channel_id_enabled(ssl.get(), 1);
-    if (!config->async) {
-      // The async case will be supplied by |ChannelIdCallback|.
-      bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(config->send_channel_id);
-      if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
-        return nullptr;
-      }
-    }
-  }
-  if (!config->send_token_binding_params.empty()) {
-    SSL_set_token_binding_params(ssl.get(),
-                                 reinterpret_cast<const uint8_t *>(
-                                     config->send_token_binding_params.data()),
-                                 config->send_token_binding_params.length());
-  }
-  if (!config->host_name.empty() &&
-      !SSL_set_tlsext_host_name(ssl.get(), config->host_name.c_str())) {
-    return nullptr;
-  }
-  if (!config->advertise_alpn.empty() &&
-      SSL_set_alpn_protos(ssl.get(),
-                          (const uint8_t *)config->advertise_alpn.data(),
-                          config->advertise_alpn.size()) != 0) {
-    return nullptr;
-  }
-  if (!config->psk.empty()) {
-    SSL_set_psk_client_callback(ssl.get(), PskClientCallback);
-    SSL_set_psk_server_callback(ssl.get(), PskServerCallback);
-  }
-  if (!config->psk_identity.empty() &&
-      !SSL_use_psk_identity_hint(ssl.get(), config->psk_identity.c_str())) {
-    return nullptr;
-  }
-  if (!config->srtp_profiles.empty() &&
-      !SSL_set_srtp_profiles(ssl.get(), config->srtp_profiles.c_str())) {
-    return nullptr;
-  }
-  if (config->enable_ocsp_stapling) {
-    SSL_enable_ocsp_stapling(ssl.get());
-  }
-  if (config->enable_signed_cert_timestamps) {
-    SSL_enable_signed_cert_timestamps(ssl.get());
-  }
-  if (config->min_version != 0 &&
-      !SSL_set_min_proto_version(ssl.get(), (uint16_t)config->min_version)) {
-    return nullptr;
-  }
-  if (config->max_version != 0 &&
-      !SSL_set_max_proto_version(ssl.get(), (uint16_t)config->max_version)) {
-    return nullptr;
-  }
-  if (config->mtu != 0) {
-    SSL_set_options(ssl.get(), SSL_OP_NO_QUERY_MTU);
-    SSL_set_mtu(ssl.get(), config->mtu);
-  }
-  if (config->install_ddos_callback) {
-    SSL_CTX_set_dos_protection_cb(ssl_ctx, DDoSCallback);
-  }
-  SSL_set_shed_handshake_config(ssl.get(), true);
-  if (config->renegotiate_once) {
-    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_once);
-  }
-  if (config->renegotiate_freely ||
-      config->forbid_renegotiation_after_handshake) {
-    // |forbid_renegotiation_after_handshake| will disable renegotiation later.
-    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
-  }
-  if (config->renegotiate_ignore) {
-    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_ignore);
-  }
-  if (!config->check_close_notify) {
-    SSL_set_quiet_shutdown(ssl.get(), 1);
-  }
-  if (config->p384_only) {
-    int nid = NID_secp384r1;
-    if (!SSL_set1_curves(ssl.get(), &nid, 1)) {
-      return nullptr;
-    }
-  }
-  if (config->enable_all_curves) {
-    static const int kAllCurves[] = {
-        NID_secp224r1, NID_X9_62_prime256v1, NID_secp384r1,
-        NID_secp521r1, NID_X25519,
-    };
-    if (!SSL_set1_curves(ssl.get(), kAllCurves,
-                         OPENSSL_ARRAY_SIZE(kAllCurves))) {
-      return nullptr;
-    }
-  }
-  if (config->initial_timeout_duration_ms > 0) {
-    DTLSv1_set_initial_timeout_duration(ssl.get(),
-                                        config->initial_timeout_duration_ms);
-  }
-  if (config->max_cert_list > 0) {
-    SSL_set_max_cert_list(ssl.get(), config->max_cert_list);
-  }
-  if (config->retain_only_sha256_client_cert) {
-    SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1);
-  }
-  if (config->max_send_fragment > 0) {
-    SSL_set_max_send_fragment(ssl.get(), config->max_send_fragment);
-  }
-  if (config->dummy_pq_padding_len > 0 &&
-      !SSL_set_dummy_pq_padding_size(ssl.get(), config->dummy_pq_padding_len)) {
-    return nullptr;
-  }
-  if (!config->quic_transport_params.empty()) {
-    if (!SSL_set_quic_transport_params(
-            ssl.get(),
-            reinterpret_cast<const uint8_t *>(
-                config->quic_transport_params.data()),
-            config->quic_transport_params.size())) {
-      return nullptr;
-    }
-  }
-
-  if (session != NULL) {
-    if (!config->is_server) {
-      if (SSL_set_session(ssl.get(), session) != 1) {
-        return nullptr;
-      }
-    } else if (config->async) {
-      // The internal session cache is disabled, so install the session
-      // manually.
-      SSL_SESSION_up_ref(session);
-      GetTestState(ssl.get())->pending_session.reset(session);
-    }
-  }
-
-  if (SSL_get_current_cipher(ssl.get()) != nullptr) {
-    fprintf(stderr, "non-null cipher before handshake\n");
-    return nullptr;
-  }
-
-  return ssl;
-}
-
 static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
                        bssl::UniquePtr<SSL> *ssl_uniqueptr,
                        const TestConfig *config, bool is_resume, bool is_retry,
@@ -2160,8 +747,8 @@
                          SSL_CTX *ssl_ctx, const TestConfig *config,
                          const TestConfig *retry_config, bool is_resume,
                          SSL_SESSION *session, SettingsWriter *writer) {
-  bssl::UniquePtr<SSL> ssl = NewSSL(ssl_ctx, config, session, is_resume,
-                                    std::unique_ptr<TestState>(new TestState));
+  bssl::UniquePtr<SSL> ssl = config->NewSSL(
+      ssl_ctx, session, is_resume, std::unique_ptr<TestState>(new TestState));
   if (!ssl) {
     return false;
   }
@@ -2183,7 +770,7 @@
     return false;
   }
   if (config->is_dtls) {
-    bssl::UniquePtr<BIO> packeted = PacketedBioCreate(&g_clock);
+    bssl::UniquePtr<BIO> packeted = PacketedBioCreate(GetClock());
     if (!packeted) {
       return false;
     }
@@ -2280,19 +867,20 @@
 
   if (!config->implicit_handshake) {
     if (config->handoff) {
-      bssl::UniquePtr<SSL_CTX> ctx_handoff = SetupCtx(ssl->ctx, config);
+      bssl::UniquePtr<SSL_CTX> ctx_handoff = config->SetupCtx(ssl->ctx);
       if (!ctx_handoff) {
         return false;
       }
       SSL_CTX_set_handoff_mode(ctx_handoff.get(), 1);
 
       bssl::UniquePtr<SSL> ssl_handoff =
-          NewSSL(ctx_handoff.get(), config, nullptr, false, nullptr);
+          config->NewSSL(ctx_handoff.get(), nullptr, false, nullptr);
       if (!ssl_handoff) {
         return false;
       }
       SSL_set_accept_state(ssl_handoff.get());
-      if (!MoveExData(ssl_handoff.get(), ssl)) {
+      if (!MoveTestConfig(ssl_handoff.get(), ssl) ||
+          !MoveTestState(ssl_handoff.get(), ssl)) {
         return false;
       }
       MoveBIOs(ssl_handoff.get(), ssl);
@@ -2322,7 +910,8 @@
       }
 
       MoveBIOs(ssl, ssl_handoff.get());
-      if (!MoveExData(ssl, ssl_handoff.get())) {
+      if (!MoveTestConfig(ssl, ssl_handoff.get()) ||
+          !MoveTestState(ssl, ssl_handoff.get())) {
         return false;
       }
 
@@ -2354,17 +943,18 @@
         return false;
       }
 
-      bssl::UniquePtr<SSL_CTX> ctx_handback = SetupCtx(ssl->ctx, config);
+      bssl::UniquePtr<SSL_CTX> ctx_handback = config->SetupCtx(ssl->ctx);
       if (!ctx_handback) {
         return false;
       }
       bssl::UniquePtr<SSL> ssl_handback =
-          NewSSL(ctx_handback.get(), config, nullptr, false, nullptr);
+          config->NewSSL(ctx_handback.get(), nullptr, false, nullptr);
       if (!ssl_handback) {
         return false;
       }
       MoveBIOs(ssl_handback.get(), ssl);
-      if (!MoveExData(ssl_handback.get(), ssl)) {
+      if (!MoveTestConfig(ssl_handback.get(), ssl) ||
+          !MoveTestState(ssl_handback.get(), ssl)) {
         return false;
       }
 
@@ -2391,8 +981,7 @@
       return false;
     }
 
-    lh_SSL_SESSION_doall_arg(ssl->ctx->sessions, ssl_ctx_add_session,
-                             session_ctx);
+    CopySessions(session_ctx, ssl->ctx);
 
     if (is_resume && !is_retry && !config->is_server &&
         config->expect_no_offer_early_data && SSL_in_early_data(ssl)) {
@@ -2702,11 +1291,6 @@
 #endif
 
   CRYPTO_library_init();
-  g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
-  g_state_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, TestStateExFree);
-  if (g_config_index < 0 || g_state_index < 0) {
-    return 1;
-  }
 
   TestConfig initial_config, resume_config, retry_config;
   if (!ParseConfig(argc - 1, argv + 1, &initial_config, &resume_config,
@@ -2714,20 +1298,13 @@
     return Usage(argv[0]);
   }
 
-  g_pool = CRYPTO_BUFFER_POOL_new();
-
-  // Some code treats the zero time special, so initialize the clock to a
-  // non-zero time.
-  g_clock.tv_sec = 1234;
-  g_clock.tv_usec = 1234;
-
   bssl::UniquePtr<SSL_CTX> ssl_ctx;
 
   bssl::UniquePtr<SSL_SESSION> session;
   for (int i = 0; i < initial_config.resume_count + 1; i++) {
     bool is_resume = i > 0;
     TestConfig *config = is_resume ? &resume_config : &initial_config;
-    ssl_ctx = SetupCtx(ssl_ctx.get(), config);
+    ssl_ctx = config->SetupCtx(ssl_ctx.get());
     if (!ssl_ctx) {
       ERR_print_errors_fp(stderr);
       return 1;
@@ -2757,7 +1334,7 @@
     }
 
     if (config->resumption_delay != 0) {
-      g_clock.tv_sec += config->resumption_delay;
+      AdvanceClock(config->resumption_delay);
     }
   }
 
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 0ae3a73..f7804d6 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -14,6 +14,7 @@
 
 #include "test_config.h"
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -21,6 +22,12 @@
 #include <memory>
 
 #include <openssl/base64.h>
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+
+#include "../../crypto/internal.h"
+#include "../internal.h"
+#include "test_state.h"
 
 namespace {
 
@@ -339,3 +346,1348 @@
 
   return true;
 }
+
+static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
+static int g_config_index = 0;
+static CRYPTO_BUFFER_POOL *g_pool = nullptr;
+
+static void init_once() {
+  g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+  if (g_config_index < 0) {
+    abort();
+  }
+  g_pool = CRYPTO_BUFFER_POOL_new();
+  if (!g_pool) {
+    abort();
+  }
+}
+
+bool SetTestConfig(SSL *ssl, const TestConfig *config) {
+  CRYPTO_once(&once, init_once);
+  return SSL_set_ex_data(ssl, g_config_index, (void *)config) == 1;
+}
+
+const TestConfig *GetTestConfig(const SSL *ssl) {
+  CRYPTO_once(&once, init_once);
+  return (const TestConfig *)SSL_get_ex_data(ssl, g_config_index);
+}
+
+bool MoveTestConfig(SSL *dest, SSL *src) {
+  const TestConfig *config = GetTestConfig(src);
+  if (!SSL_set_ex_data(src, g_config_index, nullptr) ||
+      !SSL_set_ex_data(dest, g_config_index, (void *)config)) {
+    return false;
+  }
+
+  return true;
+}
+
+static int LegacyOCSPCallback(SSL *ssl, void *arg) {
+  const TestConfig *config = GetTestConfig(ssl);
+  if (!SSL_is_server(ssl)) {
+    return !config->fail_ocsp_callback;
+  }
+
+  if (!config->ocsp_response.empty() && config->set_ocsp_in_callback &&
+      !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
+                             config->ocsp_response.size())) {
+    return SSL_TLSEXT_ERR_ALERT_FATAL;
+  }
+  if (config->fail_ocsp_callback) {
+    return SSL_TLSEXT_ERR_ALERT_FATAL;
+  }
+  if (config->decline_ocsp_callback) {
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+  return SSL_TLSEXT_ERR_OK;
+}
+
+// kCustomExtensionValue is the extension value that the custom extension
+// callbacks will add.
+static const uint16_t kCustomExtensionValue = 1234;
+static void *const kCustomExtensionAddArg =
+    reinterpret_cast<void *>(kCustomExtensionValue);
+static void *const kCustomExtensionParseArg =
+    reinterpret_cast<void *>(kCustomExtensionValue + 1);
+static const char kCustomExtensionContents[] = "custom extension";
+
+static int CustomExtensionAddCallback(SSL *ssl, unsigned extension_value,
+                                      const uint8_t **out, size_t *out_len,
+                                      int *out_alert_value, void *add_arg) {
+  if (extension_value != kCustomExtensionValue ||
+      add_arg != kCustomExtensionAddArg) {
+    abort();
+  }
+
+  if (GetTestConfig(ssl)->custom_extension_skip) {
+    return 0;
+  }
+  if (GetTestConfig(ssl)->custom_extension_fail_add) {
+    return -1;
+  }
+
+  *out = reinterpret_cast<const uint8_t *>(kCustomExtensionContents);
+  *out_len = sizeof(kCustomExtensionContents) - 1;
+
+  return 1;
+}
+
+static void CustomExtensionFreeCallback(SSL *ssl, unsigned extension_value,
+                                        const uint8_t *out, void *add_arg) {
+  if (extension_value != kCustomExtensionValue ||
+      add_arg != kCustomExtensionAddArg ||
+      out != reinterpret_cast<const uint8_t *>(kCustomExtensionContents)) {
+    abort();
+  }
+}
+
+static int CustomExtensionParseCallback(SSL *ssl, unsigned extension_value,
+                                        const uint8_t *contents,
+                                        size_t contents_len,
+                                        int *out_alert_value, void *parse_arg) {
+  if (extension_value != kCustomExtensionValue ||
+      parse_arg != kCustomExtensionParseArg) {
+    abort();
+  }
+
+  if (contents_len != sizeof(kCustomExtensionContents) - 1 ||
+      OPENSSL_memcmp(contents, kCustomExtensionContents, contents_len) != 0) {
+    *out_alert_value = SSL_AD_DECODE_ERROR;
+    return 0;
+  }
+
+  return 1;
+}
+
+static int ServerNameCallback(SSL *ssl, int *out_alert, void *arg) {
+  // SNI must be accessible from the SNI callback.
+  const TestConfig *config = GetTestConfig(ssl);
+  const char *server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  if (server_name == nullptr ||
+      std::string(server_name) != config->expected_server_name) {
+    fprintf(stderr, "servername mismatch (got %s; want %s)\n", server_name,
+            config->expected_server_name.c_str());
+    return SSL_TLSEXT_ERR_ALERT_FATAL;
+  }
+
+  return SSL_TLSEXT_ERR_OK;
+}
+
+static int NextProtoSelectCallback(SSL *ssl, uint8_t **out, uint8_t *outlen,
+                                   const uint8_t *in, unsigned inlen,
+                                   void *arg) {
+  const TestConfig *config = GetTestConfig(ssl);
+  if (config->select_next_proto.empty()) {
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  *out = (uint8_t *)config->select_next_proto.data();
+  *outlen = config->select_next_proto.size();
+  return SSL_TLSEXT_ERR_OK;
+}
+
+static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out,
+                                        unsigned int *out_len, void *arg) {
+  const TestConfig *config = GetTestConfig(ssl);
+  if (config->advertise_npn.empty()) {
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  *out = (const uint8_t *)config->advertise_npn.data();
+  *out_len = config->advertise_npn.size();
+  return SSL_TLSEXT_ERR_OK;
+}
+
+static void MessageCallback(int is_write, int version, int content_type,
+                            const void *buf, size_t len, SSL *ssl, void *arg) {
+  const uint8_t *buf_u8 = reinterpret_cast<const uint8_t *>(buf);
+  const TestConfig *config = GetTestConfig(ssl);
+  TestState *state = GetTestState(ssl);
+  if (!state->msg_callback_ok) {
+    return;
+  }
+
+  if (content_type == SSL3_RT_HEADER) {
+    if (len !=
+        (config->is_dtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH)) {
+      fprintf(stderr, "Incorrect length for record header: %zu\n", len);
+      state->msg_callback_ok = false;
+    }
+    return;
+  }
+
+  state->msg_callback_text += is_write ? "write " : "read ";
+  switch (content_type) {
+    case 0:
+      if (version != SSL2_VERSION) {
+        fprintf(stderr, "Incorrect version for V2ClientHello: %x\n", version);
+        state->msg_callback_ok = false;
+        return;
+      }
+      state->msg_callback_text += "v2clienthello\n";
+      return;
+
+    case SSL3_RT_HANDSHAKE: {
+      CBS cbs;
+      CBS_init(&cbs, buf_u8, len);
+      uint8_t type;
+      uint32_t msg_len;
+      if (!CBS_get_u8(&cbs, &type) ||
+          // TODO(davidben): Reporting on entire messages would be more
+          // consistent than fragments.
+          (config->is_dtls &&
+           !CBS_skip(&cbs, 3 /* total */ + 2 /* seq */ + 3 /* frag_off */)) ||
+          !CBS_get_u24(&cbs, &msg_len) || !CBS_skip(&cbs, msg_len) ||
+          CBS_len(&cbs) != 0) {
+        fprintf(stderr, "Could not parse handshake message.\n");
+        state->msg_callback_ok = false;
+        return;
+      }
+      char text[16];
+      snprintf(text, sizeof(text), "hs %d\n", type);
+      state->msg_callback_text += text;
+      return;
+    }
+
+    case SSL3_RT_CHANGE_CIPHER_SPEC:
+      if (len != 1 || buf_u8[0] != 1) {
+        fprintf(stderr, "Invalid ChangeCipherSpec.\n");
+        state->msg_callback_ok = false;
+        return;
+      }
+      state->msg_callback_text += "ccs\n";
+      return;
+
+    case SSL3_RT_ALERT:
+      if (len != 2) {
+        fprintf(stderr, "Invalid alert.\n");
+        state->msg_callback_ok = false;
+        return;
+      }
+      char text[16];
+      snprintf(text, sizeof(text), "alert %d %d\n", buf_u8[0], buf_u8[1]);
+      state->msg_callback_text += text;
+      return;
+
+    default:
+      fprintf(stderr, "Invalid content_type: %d\n", content_type);
+      state->msg_callback_ok = false;
+  }
+}
+
+static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
+                             EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
+                             int encrypt) {
+  if (!encrypt) {
+    if (GetTestState(ssl)->ticket_decrypt_done) {
+      fprintf(stderr, "TicketKeyCallback called after completion.\n");
+      return -1;
+    }
+
+    GetTestState(ssl)->ticket_decrypt_done = true;
+  }
+
+  // This is just test code, so use the all-zeros key.
+  static const uint8_t kZeros[16] = {0};
+
+  if (encrypt) {
+    OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
+    RAND_bytes(iv, 16);
+  } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
+    return 0;
+  }
+
+  if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
+      !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
+    return -1;
+  }
+
+  if (!encrypt) {
+    return GetTestConfig(ssl)->renew_ticket ? 2 : 1;
+  }
+  return 1;
+}
+
+static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
+  // This callback is called as the handshake completes. |SSL_get_session|
+  // must continue to work and, historically, |SSL_in_init| returned false at
+  // this point.
+  if (SSL_in_init(ssl) || SSL_get_session(ssl) == nullptr) {
+    fprintf(stderr, "Invalid state for NewSessionCallback.\n");
+    abort();
+  }
+
+  GetTestState(ssl)->got_new_session = true;
+  GetTestState(ssl)->new_session.reset(session);
+  return 1;
+}
+
+static void InfoCallback(const SSL *ssl, int type, int val) {
+  if (type == SSL_CB_HANDSHAKE_DONE) {
+    if (GetTestConfig(ssl)->handshake_never_done) {
+      fprintf(stderr, "Handshake unexpectedly completed.\n");
+      // Abort before any expected error code is printed, to ensure the overall
+      // test fails.
+      abort();
+    }
+    // This callback is called when the handshake completes. |SSL_get_session|
+    // must continue to work and |SSL_in_init| must return false.
+    if (SSL_in_init(ssl) || SSL_get_session(ssl) == nullptr) {
+      fprintf(stderr, "Invalid state for SSL_CB_HANDSHAKE_DONE.\n");
+      abort();
+    }
+    GetTestState(ssl)->handshake_done = true;
+
+    // Callbacks may be called again on a new handshake.
+    GetTestState(ssl)->ticket_decrypt_done = false;
+    GetTestState(ssl)->alpn_select_done = false;
+  }
+}
+
+static void ChannelIdCallback(SSL *ssl, EVP_PKEY **out_pkey) {
+  *out_pkey = GetTestState(ssl)->channel_id.release();
+}
+
+static SSL_SESSION *GetSessionCallback(SSL *ssl, const uint8_t *data, int len,
+                                       int *copy) {
+  TestState *async_state = GetTestState(ssl);
+  if (async_state->session) {
+    *copy = 0;
+    return async_state->session.release();
+  } else if (async_state->pending_session) {
+    return SSL_magic_pending_session_ptr();
+  } else {
+    return NULL;
+  }
+}
+
+static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
+  *out_clock = *GetClock();
+}
+
+static int AlpnSelectCallback(SSL *ssl, const uint8_t **out, uint8_t *outlen,
+                              const uint8_t *in, unsigned inlen, void *arg) {
+  if (GetTestState(ssl)->alpn_select_done) {
+    fprintf(stderr, "AlpnSelectCallback called after completion.\n");
+    exit(1);
+  }
+
+  GetTestState(ssl)->alpn_select_done = true;
+
+  const TestConfig *config = GetTestConfig(ssl);
+  if (config->decline_alpn) {
+    return SSL_TLSEXT_ERR_NOACK;
+  }
+
+  if (!config->expected_advertised_alpn.empty() &&
+      (config->expected_advertised_alpn.size() != inlen ||
+       OPENSSL_memcmp(config->expected_advertised_alpn.data(), in, inlen) !=
+           0)) {
+    fprintf(stderr, "bad ALPN select callback inputs\n");
+    exit(1);
+  }
+
+  assert(config->select_alpn.empty() || !config->select_empty_alpn);
+  *out = (const uint8_t *)config->select_alpn.data();
+  *outlen = config->select_alpn.size();
+  return SSL_TLSEXT_ERR_OK;
+}
+
+static bool CheckVerifyCallback(SSL *ssl) {
+  const TestConfig *config = GetTestConfig(ssl);
+  if (!config->expected_ocsp_response.empty()) {
+    const uint8_t *data;
+    size_t len;
+    SSL_get0_ocsp_response(ssl, &data, &len);
+    if (len == 0) {
+      fprintf(stderr, "OCSP response not available in verify callback\n");
+      return false;
+    }
+  }
+
+  if (GetTestState(ssl)->cert_verified) {
+    fprintf(stderr, "Certificate verified twice.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) {
+  SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(
+      store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+  const TestConfig *config = GetTestConfig(ssl);
+  if (!CheckVerifyCallback(ssl)) {
+    return 0;
+  }
+
+  GetTestState(ssl)->cert_verified = true;
+  if (config->verify_fail) {
+    store_ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+    return 0;
+  }
+
+  return 1;
+}
+
+bool LoadCertificate(bssl::UniquePtr<X509> *out_x509,
+                     bssl::UniquePtr<STACK_OF(X509)> *out_chain,
+                     const std::string &file) {
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
+  if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
+    return false;
+  }
+
+  out_x509->reset(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+  if (!*out_x509) {
+    return false;
+  }
+
+  out_chain->reset(sk_X509_new_null());
+  if (!*out_chain) {
+    return false;
+  }
+
+  // Keep reading the certificate chain.
+  for (;;) {
+    bssl::UniquePtr<X509> cert(
+        PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+    if (!cert) {
+      break;
+    }
+
+    if (!bssl::PushToStack(out_chain->get(), std::move(cert))) {
+      return false;
+    }
+  }
+
+  uint32_t err = ERR_peek_last_error();
+  if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
+      ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
+    return false;
+  }
+
+  ERR_clear_error();
+  return true;
+}
+
+bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file) {
+  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_file()));
+  if (!bio || !BIO_read_filename(bio.get(), file.c_str())) {
+    return nullptr;
+  }
+  return bssl::UniquePtr<EVP_PKEY>(
+      PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
+}
+
+static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
+                           bssl::UniquePtr<STACK_OF(X509)> *out_chain,
+                           bssl::UniquePtr<EVP_PKEY> *out_pkey) {
+  const TestConfig *config = GetTestConfig(ssl);
+
+  if (!config->signing_prefs.empty()) {
+    std::vector<uint16_t> u16s(config->signing_prefs.begin(),
+                               config->signing_prefs.end());
+    if (!SSL_set_signing_algorithm_prefs(ssl, u16s.data(), u16s.size())) {
+      return false;
+    }
+  }
+
+  if (!config->key_file.empty()) {
+    *out_pkey = LoadPrivateKey(config->key_file.c_str());
+    if (!*out_pkey) {
+      return false;
+    }
+  }
+  if (!config->cert_file.empty() &&
+      !LoadCertificate(out_x509, out_chain, config->cert_file.c_str())) {
+    return false;
+  }
+  if (!config->ocsp_response.empty() && !config->set_ocsp_in_callback &&
+      !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
+                             config->ocsp_response.size())) {
+    return false;
+  }
+  return true;
+}
+
+static bool FromHexDigit(uint8_t *out, char c) {
+  if ('0' <= c && c <= '9') {
+    *out = c - '0';
+    return true;
+  }
+  if ('a' <= c && c <= 'f') {
+    *out = c - 'a' + 10;
+    return true;
+  }
+  if ('A' <= c && c <= 'F') {
+    *out = c - 'A' + 10;
+    return true;
+  }
+  return false;
+}
+
+static bool HexDecode(std::string *out, const std::string &in) {
+  if ((in.size() & 1) != 0) {
+    return false;
+  }
+
+  std::unique_ptr<uint8_t[]> buf(new uint8_t[in.size() / 2]);
+  for (size_t i = 0; i < in.size() / 2; i++) {
+    uint8_t high, low;
+    if (!FromHexDigit(&high, in[i * 2]) || !FromHexDigit(&low, in[i * 2 + 1])) {
+      return false;
+    }
+    buf[i] = (high << 4) | low;
+  }
+
+  out->assign(reinterpret_cast<const char *>(buf.get()), in.size() / 2);
+  return true;
+}
+
+static std::vector<std::string> SplitParts(const std::string &in,
+                                           const char delim) {
+  std::vector<std::string> ret;
+  size_t start = 0;
+
+  for (size_t i = 0; i < in.size(); i++) {
+    if (in[i] == delim) {
+      ret.push_back(in.substr(start, i - start));
+      start = i + 1;
+    }
+  }
+
+  ret.push_back(in.substr(start, std::string::npos));
+  return ret;
+}
+
+static std::vector<std::string> DecodeHexStrings(
+    const std::string &hex_strings) {
+  std::vector<std::string> ret;
+  const std::vector<std::string> parts = SplitParts(hex_strings, ',');
+
+  for (const auto &part : parts) {
+    std::string binary;
+    if (!HexDecode(&binary, part)) {
+      fprintf(stderr, "Bad hex string: %s\n", part.c_str());
+      return ret;
+    }
+
+    ret.push_back(binary);
+  }
+
+  return ret;
+}
+
+static bssl::UniquePtr<STACK_OF(X509_NAME)> DecodeHexX509Names(
+    const std::string &hex_names) {
+  const std::vector<std::string> der_names = DecodeHexStrings(hex_names);
+  bssl::UniquePtr<STACK_OF(X509_NAME)> ret(sk_X509_NAME_new_null());
+  if (!ret) {
+    return nullptr;
+  }
+
+  for (const auto &der_name : der_names) {
+    const uint8_t *const data =
+        reinterpret_cast<const uint8_t *>(der_name.data());
+    const uint8_t *derp = data;
+    bssl::UniquePtr<X509_NAME> name(
+        d2i_X509_NAME(nullptr, &derp, der_name.size()));
+    if (!name || derp != data + der_name.size()) {
+      fprintf(stderr, "Failed to parse X509_NAME.\n");
+      return nullptr;
+    }
+
+    if (!bssl::PushToStack(ret.get(), std::move(name))) {
+      return nullptr;
+    }
+  }
+
+  return ret;
+}
+
+static bool CheckCertificateRequest(SSL *ssl) {
+  const TestConfig *config = GetTestConfig(ssl);
+
+  if (!config->expected_certificate_types.empty()) {
+    const uint8_t *certificate_types;
+    size_t certificate_types_len =
+        SSL_get0_certificate_types(ssl, &certificate_types);
+    if (certificate_types_len != config->expected_certificate_types.size() ||
+        OPENSSL_memcmp(certificate_types,
+                       config->expected_certificate_types.data(),
+                       certificate_types_len) != 0) {
+      fprintf(stderr, "certificate types mismatch\n");
+      return false;
+    }
+  }
+
+  if (!config->expected_client_ca_list.empty()) {
+    bssl::UniquePtr<STACK_OF(X509_NAME)> expected =
+        DecodeHexX509Names(config->expected_client_ca_list);
+    const size_t num_expected = sk_X509_NAME_num(expected.get());
+
+    const STACK_OF(X509_NAME) *received = SSL_get_client_CA_list(ssl);
+    const size_t num_received = sk_X509_NAME_num(received);
+
+    if (num_received != num_expected) {
+      fprintf(stderr, "expected %u names in CertificateRequest but got %u\n",
+              static_cast<unsigned>(num_expected),
+              static_cast<unsigned>(num_received));
+      return false;
+    }
+
+    for (size_t i = 0; i < num_received; i++) {
+      if (X509_NAME_cmp(sk_X509_NAME_value(received, i),
+                        sk_X509_NAME_value(expected.get(), i)) != 0) {
+        fprintf(stderr, "names in CertificateRequest differ at index #%d\n",
+                static_cast<unsigned>(i));
+        return false;
+      }
+    }
+
+    const STACK_OF(CRYPTO_BUFFER) *buffers = SSL_get0_server_requested_CAs(ssl);
+    if (sk_CRYPTO_BUFFER_num(buffers) != num_received) {
+      fprintf(stderr,
+              "Mismatch between SSL_get_server_requested_CAs and "
+              "SSL_get_client_CA_list.\n");
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static int ClientCertCallback(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
+  if (!CheckCertificateRequest(ssl)) {
+    return -1;
+  }
+
+  if (GetTestConfig(ssl)->async && !GetTestState(ssl)->cert_ready) {
+    return -1;
+  }
+
+  bssl::UniquePtr<X509> x509;
+  bssl::UniquePtr<STACK_OF(X509)> chain;
+  bssl::UniquePtr<EVP_PKEY> pkey;
+  if (!GetCertificate(ssl, &x509, &chain, &pkey)) {
+    return -1;
+  }
+
+  // Return zero for no certificate.
+  if (!x509) {
+    return 0;
+  }
+
+  // Chains and asynchronous private keys are not supported with client_cert_cb.
+  *out_x509 = x509.release();
+  *out_pkey = pkey.release();
+  return 1;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeySign(
+    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+    uint16_t signature_algorithm, const uint8_t *in, size_t in_len) {
+  TestState *test_state = GetTestState(ssl);
+  if (!test_state->private_key_result.empty()) {
+    fprintf(stderr, "AsyncPrivateKeySign called with operation pending.\n");
+    abort();
+  }
+
+  if (EVP_PKEY_id(test_state->private_key.get()) !=
+      SSL_get_signature_algorithm_key_type(signature_algorithm)) {
+    fprintf(stderr, "Key type does not match signature algorithm.\n");
+    abort();
+  }
+
+  // Determine the hash.
+  const EVP_MD *md = SSL_get_signature_algorithm_digest(signature_algorithm);
+  bssl::ScopedEVP_MD_CTX ctx;
+  EVP_PKEY_CTX *pctx;
+  if (!EVP_DigestSignInit(ctx.get(), &pctx, md, nullptr,
+                          test_state->private_key.get())) {
+    return ssl_private_key_failure;
+  }
+
+  // Configure additional signature parameters.
+  if (SSL_is_signature_algorithm_rsa_pss(signature_algorithm)) {
+    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) {
+      return ssl_private_key_failure;
+    }
+  }
+
+  // Write the signature into |test_state|.
+  size_t len = 0;
+  if (!EVP_DigestSign(ctx.get(), nullptr, &len, in, in_len)) {
+    return ssl_private_key_failure;
+  }
+  test_state->private_key_result.resize(len);
+  if (!EVP_DigestSign(ctx.get(), test_state->private_key_result.data(), &len,
+                      in, in_len)) {
+    return ssl_private_key_failure;
+  }
+  test_state->private_key_result.resize(len);
+
+  // The signature will be released asynchronously in |AsyncPrivateKeyComplete|.
+  return ssl_private_key_retry;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeyDecrypt(SSL *ssl, uint8_t *out,
+                                                       size_t *out_len,
+                                                       size_t max_out,
+                                                       const uint8_t *in,
+                                                       size_t in_len) {
+  TestState *test_state = GetTestState(ssl);
+  if (!test_state->private_key_result.empty()) {
+    fprintf(stderr, "AsyncPrivateKeyDecrypt called with operation pending.\n");
+    abort();
+  }
+
+  RSA *rsa = EVP_PKEY_get0_RSA(test_state->private_key.get());
+  if (rsa == NULL) {
+    fprintf(stderr, "AsyncPrivateKeyDecrypt called with incorrect key type.\n");
+    abort();
+  }
+  test_state->private_key_result.resize(RSA_size(rsa));
+  if (!RSA_decrypt(rsa, out_len, test_state->private_key_result.data(),
+                   RSA_size(rsa), in, in_len, RSA_NO_PADDING)) {
+    return ssl_private_key_failure;
+  }
+
+  test_state->private_key_result.resize(*out_len);
+
+  // The decryption will be released asynchronously in |AsyncPrivateComplete|.
+  return ssl_private_key_retry;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeyComplete(SSL *ssl, uint8_t *out,
+                                                        size_t *out_len,
+                                                        size_t max_out) {
+  TestState *test_state = GetTestState(ssl);
+  if (test_state->private_key_result.empty()) {
+    fprintf(stderr,
+            "AsyncPrivateKeyComplete called without operation pending.\n");
+    abort();
+  }
+
+  if (test_state->private_key_retries < 2) {
+    // Only return the decryption on the second attempt, to test both incomplete
+    // |decrypt| and |decrypt_complete|.
+    return ssl_private_key_retry;
+  }
+
+  if (max_out < test_state->private_key_result.size()) {
+    fprintf(stderr, "Output buffer too small.\n");
+    return ssl_private_key_failure;
+  }
+  OPENSSL_memcpy(out, test_state->private_key_result.data(),
+                 test_state->private_key_result.size());
+  *out_len = test_state->private_key_result.size();
+
+  test_state->private_key_result.clear();
+  test_state->private_key_retries = 0;
+  return ssl_private_key_success;
+}
+
+static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
+    AsyncPrivateKeySign,
+    AsyncPrivateKeyDecrypt,
+    AsyncPrivateKeyComplete,
+};
+
+static bool InstallCertificate(SSL *ssl) {
+  bssl::UniquePtr<X509> x509;
+  bssl::UniquePtr<STACK_OF(X509)> chain;
+  bssl::UniquePtr<EVP_PKEY> pkey;
+  if (!GetCertificate(ssl, &x509, &chain, &pkey)) {
+    return false;
+  }
+
+  if (pkey) {
+    TestState *test_state = GetTestState(ssl);
+    const TestConfig *config = GetTestConfig(ssl);
+    if (config->async) {
+      test_state->private_key = std::move(pkey);
+      SSL_set_private_key_method(ssl, &g_async_private_key_method);
+    } else if (!SSL_use_PrivateKey(ssl, pkey.get())) {
+      return false;
+    }
+  }
+
+  if (x509 && !SSL_use_certificate(ssl, x509.get())) {
+    return false;
+  }
+
+  if (sk_X509_num(chain.get()) > 0 && !SSL_set1_chain(ssl, chain.get())) {
+    return false;
+  }
+
+  return true;
+}
+
+static enum ssl_select_cert_result_t SelectCertificateCallback(
+    const SSL_CLIENT_HELLO *client_hello) {
+  const TestConfig *config = GetTestConfig(client_hello->ssl);
+  GetTestState(client_hello->ssl)->early_callback_called = true;
+
+  if (!config->expected_server_name.empty()) {
+    const uint8_t *extension_data;
+    size_t extension_len;
+    CBS extension, server_name_list, host_name;
+    uint8_t name_type;
+
+    if (!SSL_early_callback_ctx_extension_get(
+            client_hello, TLSEXT_TYPE_server_name, &extension_data,
+            &extension_len)) {
+      fprintf(stderr, "Could not find server_name extension.\n");
+      return ssl_select_cert_error;
+    }
+
+    CBS_init(&extension, extension_data, extension_len);
+    if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
+        CBS_len(&extension) != 0 ||
+        !CBS_get_u8(&server_name_list, &name_type) ||
+        name_type != TLSEXT_NAMETYPE_host_name ||
+        !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
+        CBS_len(&server_name_list) != 0) {
+      fprintf(stderr, "Could not decode server_name extension.\n");
+      return ssl_select_cert_error;
+    }
+
+    if (!CBS_mem_equal(&host_name,
+                       (const uint8_t *)config->expected_server_name.data(),
+                       config->expected_server_name.size())) {
+      fprintf(stderr, "Server name mismatch.\n");
+    }
+  }
+
+  if (config->fail_early_callback) {
+    return ssl_select_cert_error;
+  }
+
+  // Install the certificate in the early callback.
+  if (config->use_early_callback) {
+    bool early_callback_ready =
+        GetTestState(client_hello->ssl)->early_callback_ready;
+    if (config->async && !early_callback_ready) {
+      // Install the certificate asynchronously.
+      return ssl_select_cert_retry;
+    }
+    if (!InstallCertificate(client_hello->ssl)) {
+      return ssl_select_cert_error;
+    }
+  }
+  return ssl_select_cert_success;
+}
+
+bssl::UniquePtr<SSL_CTX> TestConfig::SetupCtx(SSL_CTX *old_ctx) const {
+  bssl::UniquePtr<SSL_CTX> ssl_ctx(
+      SSL_CTX_new(is_dtls ? DTLS_method() : TLS_method()));
+  if (!ssl_ctx) {
+    return nullptr;
+  }
+
+  CRYPTO_once(&once, init_once);
+  SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool);
+
+  // Enable TLS 1.3 for tests.
+  if (!is_dtls &&
+      !SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION)) {
+    return nullptr;
+  }
+
+  std::string cipher_list = "ALL";
+  if (!cipher.empty()) {
+    cipher_list = cipher;
+    SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
+  }
+  if (!SSL_CTX_set_strict_cipher_list(ssl_ctx.get(), cipher_list.c_str())) {
+    return nullptr;
+  }
+
+  if (async && is_server) {
+    // Disable the internal session cache. To test asynchronous session lookup,
+    // we use an external session cache.
+    SSL_CTX_set_session_cache_mode(
+        ssl_ctx.get(), SSL_SESS_CACHE_BOTH | SSL_SESS_CACHE_NO_INTERNAL);
+    SSL_CTX_sess_set_get_cb(ssl_ctx.get(), GetSessionCallback);
+  } else {
+    SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
+  }
+
+  SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
+
+  if (use_old_client_cert_callback) {
+    SSL_CTX_set_client_cert_cb(ssl_ctx.get(), ClientCertCallback);
+  }
+
+  SSL_CTX_set_next_protos_advertised_cb(ssl_ctx.get(),
+                                        NextProtosAdvertisedCallback, NULL);
+  if (!select_next_proto.empty()) {
+    SSL_CTX_set_next_proto_select_cb(ssl_ctx.get(), NextProtoSelectCallback,
+                                     NULL);
+  }
+
+  if (!select_alpn.empty() || decline_alpn || select_empty_alpn) {
+    SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
+  }
+
+  SSL_CTX_set_channel_id_cb(ssl_ctx.get(), ChannelIdCallback);
+
+  SSL_CTX_set_current_time_cb(ssl_ctx.get(), CurrentTimeCallback);
+
+  SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
+  SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+
+  if (use_ticket_callback) {
+    SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
+  }
+
+  if (enable_client_custom_extension &&
+      !SSL_CTX_add_client_custom_ext(
+          ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
+          CustomExtensionFreeCallback, kCustomExtensionAddArg,
+          CustomExtensionParseCallback, kCustomExtensionParseArg)) {
+    return nullptr;
+  }
+
+  if (enable_server_custom_extension &&
+      !SSL_CTX_add_server_custom_ext(
+          ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
+          CustomExtensionFreeCallback, kCustomExtensionAddArg,
+          CustomExtensionParseCallback, kCustomExtensionParseArg)) {
+    return nullptr;
+  }
+
+  if (!use_custom_verify_callback) {
+    SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), CertVerifyCallback, NULL);
+  }
+
+  if (!signed_cert_timestamps.empty() &&
+      !SSL_CTX_set_signed_cert_timestamp_list(
+          ssl_ctx.get(), (const uint8_t *)signed_cert_timestamps.data(),
+          signed_cert_timestamps.size())) {
+    return nullptr;
+  }
+
+  if (!use_client_ca_list.empty()) {
+    if (use_client_ca_list == "<NULL>") {
+      SSL_CTX_set_client_CA_list(ssl_ctx.get(), nullptr);
+    } else if (use_client_ca_list == "<EMPTY>") {
+      bssl::UniquePtr<STACK_OF(X509_NAME)> names;
+      SSL_CTX_set_client_CA_list(ssl_ctx.get(), names.release());
+    } else {
+      bssl::UniquePtr<STACK_OF(X509_NAME)> names =
+          DecodeHexX509Names(use_client_ca_list);
+      SSL_CTX_set_client_CA_list(ssl_ctx.get(), names.release());
+    }
+  }
+
+  if (enable_grease) {
+    SSL_CTX_set_grease_enabled(ssl_ctx.get(), 1);
+  }
+
+  if (!expected_server_name.empty()) {
+    SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), ServerNameCallback);
+  }
+
+  if (!ticket_key.empty() &&
+      !SSL_CTX_set_tlsext_ticket_keys(ssl_ctx.get(), ticket_key.data(),
+                                      ticket_key.size())) {
+    return nullptr;
+  }
+
+  if (enable_early_data) {
+    SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
+  }
+
+  SSL_CTX_set_tls13_variant(ssl_ctx.get(),
+                            static_cast<enum tls13_variant_t>(tls13_variant));
+
+  if (allow_unknown_alpn_protos) {
+    SSL_CTX_set_allow_unknown_alpn_protos(ssl_ctx.get(), 1);
+  }
+
+  if (enable_ed25519) {
+    SSL_CTX_set_ed25519_enabled(ssl_ctx.get(), 1);
+  }
+  if (no_rsa_pss_rsae_certs) {
+    SSL_CTX_set_rsa_pss_rsae_certs_enabled(ssl_ctx.get(), 0);
+  }
+
+  if (!verify_prefs.empty()) {
+    std::vector<uint16_t> u16s(verify_prefs.begin(), verify_prefs.end());
+    if (!SSL_CTX_set_verify_algorithm_prefs(ssl_ctx.get(), u16s.data(),
+                                            u16s.size())) {
+      return nullptr;
+    }
+  }
+
+  SSL_CTX_set_msg_callback(ssl_ctx.get(), MessageCallback);
+
+  if (allow_false_start_without_alpn) {
+    SSL_CTX_set_false_start_allowed_without_alpn(ssl_ctx.get(), 1);
+  }
+
+  if (use_ocsp_callback) {
+    SSL_CTX_set_tlsext_status_cb(ssl_ctx.get(), LegacyOCSPCallback);
+  }
+
+  if (old_ctx) {
+    uint8_t keys[48];
+    if (!SSL_CTX_get_tlsext_ticket_keys(old_ctx, &keys, sizeof(keys)) ||
+        !SSL_CTX_set_tlsext_ticket_keys(ssl_ctx.get(), keys, sizeof(keys))) {
+      return nullptr;
+    }
+    CopySessions(ssl_ctx.get(), old_ctx);
+  }
+
+  if (install_cert_compression_algs &&
+      (!SSL_CTX_add_cert_compression_alg(
+           ssl_ctx.get(), 0xff02,
+           [](SSL *ssl, CBB *out, bssl::Span<const uint8_t> in) -> bool {
+             if (!CBB_add_u8(out, 1) || !CBB_add_u8(out, 2) ||
+                 !CBB_add_u8(out, 3) || !CBB_add_u8(out, 4) ||
+                 !CBB_add_bytes(out, in.data(), in.size())) {
+               return false;
+             }
+             return true;
+           },
+           [](SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
+              size_t uncompressed_len, bssl::Span<const uint8_t> in) -> bool {
+             if (in.size() < 4 || in[0] != 1 || in[1] != 2 || in[2] != 3 ||
+                 in[3] != 4 || uncompressed_len != in.size() - 4) {
+               return false;
+             }
+             const bssl::Span<const uint8_t> uncompressed(in.subspan(4));
+             out->reset(CRYPTO_BUFFER_new(uncompressed.data(),
+                                          uncompressed.size(), nullptr));
+             return true;
+           }) ||
+       !SSL_CTX_add_cert_compression_alg(
+           ssl_ctx.get(), 0xff01,
+           [](SSL *ssl, CBB *out, bssl::Span<const uint8_t> in) -> bool {
+             if (in.size() < 2 || in[0] != 0 || in[1] != 0) {
+               return false;
+             }
+             return CBB_add_bytes(out, in.data() + 2, in.size() - 2);
+           },
+           [](SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
+              size_t uncompressed_len, bssl::Span<const uint8_t> in) -> bool {
+             if (uncompressed_len != 2 + in.size()) {
+               return false;
+             }
+             std::unique_ptr<uint8_t[]> buf(new uint8_t[2 + in.size()]);
+             buf[0] = 0;
+             buf[1] = 0;
+             OPENSSL_memcpy(&buf[2], in.data(), in.size());
+             out->reset(CRYPTO_BUFFER_new(buf.get(), 2 + in.size(), nullptr));
+             return true;
+           }))) {
+    fprintf(stderr, "SSL_CTX_add_cert_compression_alg failed.\n");
+    abort();
+  }
+
+  return ssl_ctx;
+}
+
+static int DDoSCallback(const SSL_CLIENT_HELLO *client_hello) {
+  const TestConfig *config = GetTestConfig(client_hello->ssl);
+  return config->fail_ddos_callback ? 0 : 1;
+}
+
+static unsigned PskClientCallback(SSL *ssl, const char *hint,
+                                  char *out_identity, unsigned max_identity_len,
+                                  uint8_t *out_psk, unsigned max_psk_len) {
+  const TestConfig *config = GetTestConfig(ssl);
+
+  if (config->psk_identity.empty()) {
+    if (hint != nullptr) {
+      fprintf(stderr, "Server PSK hint was non-null.\n");
+      return 0;
+    }
+  } else if (hint == nullptr ||
+             strcmp(hint, config->psk_identity.c_str()) != 0) {
+    fprintf(stderr, "Server PSK hint did not match.\n");
+    return 0;
+  }
+
+  // Account for the trailing '\0' for the identity.
+  if (config->psk_identity.size() >= max_identity_len ||
+      config->psk.size() > max_psk_len) {
+    fprintf(stderr, "PSK buffers too small\n");
+    return 0;
+  }
+
+  BUF_strlcpy(out_identity, config->psk_identity.c_str(), max_identity_len);
+  OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size());
+  return config->psk.size();
+}
+
+static unsigned PskServerCallback(SSL *ssl, const char *identity,
+                                  uint8_t *out_psk, unsigned max_psk_len) {
+  const TestConfig *config = GetTestConfig(ssl);
+
+  if (strcmp(identity, config->psk_identity.c_str()) != 0) {
+    fprintf(stderr, "Client PSK identity did not match.\n");
+    return 0;
+  }
+
+  if (config->psk.size() > max_psk_len) {
+    fprintf(stderr, "PSK buffers too small\n");
+    return 0;
+  }
+
+  OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size());
+  return config->psk.size();
+}
+
+static ssl_verify_result_t CustomVerifyCallback(SSL *ssl, uint8_t *out_alert) {
+  const TestConfig *config = GetTestConfig(ssl);
+  if (!CheckVerifyCallback(ssl)) {
+    return ssl_verify_invalid;
+  }
+
+  if (config->async && !GetTestState(ssl)->custom_verify_ready) {
+    return ssl_verify_retry;
+  }
+
+  GetTestState(ssl)->cert_verified = true;
+  if (config->verify_fail) {
+    return ssl_verify_invalid;
+  }
+
+  return ssl_verify_ok;
+}
+
+static int CertCallback(SSL *ssl, void *arg) {
+  const TestConfig *config = GetTestConfig(ssl);
+
+  // Check the CertificateRequest metadata is as expected.
+  if (!SSL_is_server(ssl) && !CheckCertificateRequest(ssl)) {
+    return -1;
+  }
+
+  if (config->fail_cert_callback) {
+    return 0;
+  }
+
+  // The certificate will be installed via other means.
+  if (!config->async || config->use_early_callback) {
+    return 1;
+  }
+
+  if (!GetTestState(ssl)->cert_ready) {
+    return -1;
+  }
+  if (!InstallCertificate(ssl)) {
+    return 0;
+  }
+  return 1;
+}
+
+bssl::UniquePtr<SSL> TestConfig::NewSSL(
+    SSL_CTX *ssl_ctx, SSL_SESSION *session, bool is_resume,
+    std::unique_ptr<TestState> test_state) const {
+  bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx));
+  if (!ssl) {
+    return nullptr;
+  }
+
+  if (!SetTestConfig(ssl.get(), this)) {
+    return nullptr;
+  }
+  if (test_state != nullptr) {
+    if (!SetTestState(ssl.get(), std::move(test_state))) {
+      return nullptr;
+    }
+    GetTestState(ssl.get())->is_resume = is_resume;
+  }
+
+  if (fallback_scsv && !SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
+    return nullptr;
+  }
+  // Install the certificate synchronously if nothing else will handle it.
+  if (!use_early_callback && !use_old_client_cert_callback && !async &&
+      !InstallCertificate(ssl.get())) {
+    return nullptr;
+  }
+  if (!use_old_client_cert_callback) {
+    SSL_set_cert_cb(ssl.get(), CertCallback, nullptr);
+  }
+  int mode = SSL_VERIFY_NONE;
+  if (require_any_client_certificate) {
+    mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+  }
+  if (verify_peer) {
+    mode = SSL_VERIFY_PEER;
+  }
+  if (verify_peer_if_no_obc) {
+    // Set SSL_VERIFY_FAIL_IF_NO_PEER_CERT so testing whether client
+    // certificates were requested is easy.
+    mode = SSL_VERIFY_PEER | SSL_VERIFY_PEER_IF_NO_OBC |
+           SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+  }
+  if (use_custom_verify_callback) {
+    SSL_set_custom_verify(ssl.get(), mode, CustomVerifyCallback);
+  } else if (mode != SSL_VERIFY_NONE) {
+    SSL_set_verify(ssl.get(), mode, NULL);
+  }
+  if (false_start) {
+    SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_FALSE_START);
+  }
+  if (cbc_record_splitting) {
+    SSL_set_mode(ssl.get(), SSL_MODE_CBC_RECORD_SPLITTING);
+  }
+  if (partial_write) {
+    SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
+  }
+  if (no_tls13) {
+    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_3);
+  }
+  if (no_tls12) {
+    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_2);
+  }
+  if (no_tls11) {
+    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_1);
+  }
+  if (no_tls1) {
+    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1);
+  }
+  if (!expected_channel_id.empty() || enable_channel_id) {
+    SSL_set_tls_channel_id_enabled(ssl.get(), 1);
+  }
+  if (!send_channel_id.empty()) {
+    SSL_set_tls_channel_id_enabled(ssl.get(), 1);
+    if (!async) {
+      // The async case will be supplied by |ChannelIdCallback|.
+      bssl::UniquePtr<EVP_PKEY> pkey = LoadPrivateKey(send_channel_id);
+      if (!pkey || !SSL_set1_tls_channel_id(ssl.get(), pkey.get())) {
+        return nullptr;
+      }
+    }
+  }
+  if (!send_token_binding_params.empty()) {
+    SSL_set_token_binding_params(
+        ssl.get(),
+        reinterpret_cast<const uint8_t *>(send_token_binding_params.data()),
+        send_token_binding_params.length());
+  }
+  if (!host_name.empty() &&
+      !SSL_set_tlsext_host_name(ssl.get(), host_name.c_str())) {
+    return nullptr;
+  }
+  if (!advertise_alpn.empty() &&
+      SSL_set_alpn_protos(ssl.get(), (const uint8_t *)advertise_alpn.data(),
+                          advertise_alpn.size()) != 0) {
+    return nullptr;
+  }
+  if (!psk.empty()) {
+    SSL_set_psk_client_callback(ssl.get(), PskClientCallback);
+    SSL_set_psk_server_callback(ssl.get(), PskServerCallback);
+  }
+  if (!psk_identity.empty() &&
+      !SSL_use_psk_identity_hint(ssl.get(), psk_identity.c_str())) {
+    return nullptr;
+  }
+  if (!srtp_profiles.empty() &&
+      !SSL_set_srtp_profiles(ssl.get(), srtp_profiles.c_str())) {
+    return nullptr;
+  }
+  if (enable_ocsp_stapling) {
+    SSL_enable_ocsp_stapling(ssl.get());
+  }
+  if (enable_signed_cert_timestamps) {
+    SSL_enable_signed_cert_timestamps(ssl.get());
+  }
+  if (min_version != 0 &&
+      !SSL_set_min_proto_version(ssl.get(), (uint16_t)min_version)) {
+    return nullptr;
+  }
+  if (max_version != 0 &&
+      !SSL_set_max_proto_version(ssl.get(), (uint16_t)max_version)) {
+    return nullptr;
+  }
+  if (mtu != 0) {
+    SSL_set_options(ssl.get(), SSL_OP_NO_QUERY_MTU);
+    SSL_set_mtu(ssl.get(), mtu);
+  }
+  if (install_ddos_callback) {
+    SSL_CTX_set_dos_protection_cb(ssl_ctx, DDoSCallback);
+  }
+  SSL_set_shed_handshake_config(ssl.get(), true);
+  if (renegotiate_once) {
+    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_once);
+  }
+  if (renegotiate_freely || forbid_renegotiation_after_handshake) {
+    // |forbid_renegotiation_after_handshake| will disable renegotiation later.
+    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
+  }
+  if (renegotiate_ignore) {
+    SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_ignore);
+  }
+  if (!check_close_notify) {
+    SSL_set_quiet_shutdown(ssl.get(), 1);
+  }
+  if (p384_only) {
+    int nid = NID_secp384r1;
+    if (!SSL_set1_curves(ssl.get(), &nid, 1)) {
+      return nullptr;
+    }
+  }
+  if (enable_all_curves) {
+    static const int kAllCurves[] = {
+        NID_secp224r1, NID_X9_62_prime256v1, NID_secp384r1,
+        NID_secp521r1, NID_X25519,
+    };
+    if (!SSL_set1_curves(ssl.get(), kAllCurves,
+                         OPENSSL_ARRAY_SIZE(kAllCurves))) {
+      return nullptr;
+    }
+  }
+  if (initial_timeout_duration_ms > 0) {
+    DTLSv1_set_initial_timeout_duration(ssl.get(), initial_timeout_duration_ms);
+  }
+  if (max_cert_list > 0) {
+    SSL_set_max_cert_list(ssl.get(), max_cert_list);
+  }
+  if (retain_only_sha256_client_cert) {
+    SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1);
+  }
+  if (max_send_fragment > 0) {
+    SSL_set_max_send_fragment(ssl.get(), max_send_fragment);
+  }
+  if (dummy_pq_padding_len > 0 &&
+      !SSL_set_dummy_pq_padding_size(ssl.get(), dummy_pq_padding_len)) {
+    return nullptr;
+  }
+  if (!quic_transport_params.empty()) {
+    if (!SSL_set_quic_transport_params(
+            ssl.get(),
+            reinterpret_cast<const uint8_t *>(quic_transport_params.data()),
+            quic_transport_params.size())) {
+      return nullptr;
+    }
+  }
+
+  if (session != NULL) {
+    if (!is_server) {
+      if (SSL_set_session(ssl.get(), session) != 1) {
+        return nullptr;
+      }
+    } else if (async) {
+      // The internal session cache is disabled, so install the session
+      // manually.
+      SSL_SESSION_up_ref(session);
+      GetTestState(ssl.get())->pending_session.reset(session);
+    }
+  }
+
+  if (SSL_get_current_cipher(ssl.get()) != nullptr) {
+    fprintf(stderr, "non-null cipher before handshake\n");
+    return nullptr;
+  }
+
+  return ssl;
+}
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index d380007..930100e 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -18,6 +18,10 @@
 #include <string>
 #include <vector>
 
+#include <openssl/base.h>
+#include <openssl/x509.h>
+
+#include "test_state.h"
 
 struct TestConfig {
   int port = 0;
@@ -160,10 +164,27 @@
   bool decline_ocsp_callback = false;
   bool fail_ocsp_callback = false;
   bool install_cert_compression_algs = false;
+
+  bssl::UniquePtr<SSL_CTX> SetupCtx(SSL_CTX *old_ctx) const;
+
+  bssl::UniquePtr<SSL> NewSSL(SSL_CTX *ssl_ctx, SSL_SESSION *session,
+                              bool is_resume,
+                              std::unique_ptr<TestState> test_state) const;
 };
 
 bool ParseConfig(int argc, char **argv, TestConfig *out_initial,
                  TestConfig *out_resume, TestConfig *out_retry);
 
+bool SetTestConfig(SSL *ssl, const TestConfig *config);
+
+const TestConfig *GetTestConfig(const SSL *ssl);
+
+bool MoveTestConfig(SSL *dest, SSL *src);
+
+bool LoadCertificate(bssl::UniquePtr<X509> *out_x509,
+                     bssl::UniquePtr<STACK_OF(X509)> *out_chain,
+                     const std::string &file);
+
+bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(const std::string &file);
 
 #endif  // HEADER_TEST_CONFIG
diff --git a/ssl/test/test_state.cc b/ssl/test/test_state.cc
new file mode 100644
index 0000000..14bd4a1
--- /dev/null
+++ b/ssl/test/test_state.cc
@@ -0,0 +1,86 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "test_state.h"
+
+#include <openssl/ssl.h>
+
+#include "../../crypto/internal.h"
+#include "../internal.h"
+
+static CRYPTO_once_t g_once = CRYPTO_ONCE_INIT;
+static int g_state_index = 0;
+// Some code treats the zero time special, so initialize the clock to a
+// non-zero time.
+static timeval g_clock = { 1234, 1234 };
+
+static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                            int index, long argl, void *argp) {
+  delete ((TestState *)ptr);
+}
+
+static void init_once() {
+  g_state_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, TestStateExFree);
+  if (g_state_index < 0) {
+    abort();
+  }
+}
+
+struct timeval *GetClock() {
+  CRYPTO_once(&g_once, init_once);
+  return &g_clock;
+}
+
+void AdvanceClock(unsigned seconds) {
+  CRYPTO_once(&g_once, init_once);
+  g_clock.tv_sec += seconds;
+}
+
+bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state) {
+  CRYPTO_once(&g_once, init_once);
+  // |SSL_set_ex_data| takes ownership of |state| only on success.
+  if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) {
+    state.release();
+    return true;
+  }
+  return false;
+}
+
+TestState *GetTestState(const SSL *ssl) {
+  CRYPTO_once(&g_once, init_once);
+  return (TestState *)SSL_get_ex_data(ssl, g_state_index);
+}
+
+bool MoveTestState(SSL *dest, SSL *src) {
+  TestState *state = GetTestState(src);
+  if (!SSL_set_ex_data(src, g_state_index, nullptr) ||
+      !SSL_set_ex_data(dest, g_state_index, state)) {
+    return false;
+  }
+
+  return true;
+}
+
+static void ssl_ctx_add_session(SSL_SESSION *session, void *void_param) {
+  SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(void_param);
+  bssl::UniquePtr<SSL_SESSION> new_session = bssl::SSL_SESSION_dup(
+      session, SSL_SESSION_INCLUDE_NONAUTH | SSL_SESSION_INCLUDE_TICKET);
+  if (new_session != nullptr) {
+    SSL_CTX_add_session(ctx, new_session.get());
+  }
+}
+
+void CopySessions(SSL_CTX *dst, const SSL_CTX *src) {
+  lh_SSL_SESSION_doall_arg(src->sessions, ssl_ctx_add_session, dst);
+}
diff --git a/ssl/test/test_state.h b/ssl/test/test_state.h
new file mode 100644
index 0000000..3fe2972
--- /dev/null
+++ b/ssl/test/test_state.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef HEADER_TEST_STATE
+#define HEADER_TEST_STATE
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <openssl/base.h>
+
+struct TestState {
+  // async_bio is async BIO which pauses reads and writes.
+  BIO *async_bio = nullptr;
+  // packeted_bio is the packeted BIO which simulates read timeouts.
+  BIO *packeted_bio = nullptr;
+  bssl::UniquePtr<EVP_PKEY> channel_id;
+  bool cert_ready = false;
+  bssl::UniquePtr<SSL_SESSION> session;
+  bssl::UniquePtr<SSL_SESSION> pending_session;
+  bool early_callback_called = false;
+  bool handshake_done = false;
+  // private_key is the underlying private key used when testing custom keys.
+  bssl::UniquePtr<EVP_PKEY> private_key;
+  std::vector<uint8_t> private_key_result;
+  // private_key_retries is the number of times an asynchronous private key
+  // operation has been retried.
+  unsigned private_key_retries = 0;
+  bool got_new_session = false;
+  bssl::UniquePtr<SSL_SESSION> new_session;
+  bool ticket_decrypt_done = false;
+  bool alpn_select_done = false;
+  bool is_resume = false;
+  bool early_callback_ready = false;
+  bool custom_verify_ready = false;
+  std::string msg_callback_text;
+  bool msg_callback_ok = true;
+  // cert_verified is true if certificate verification has been driven to
+  // completion. This tests that the callback is not called again after this.
+  bool cert_verified = false;
+};
+
+bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state);
+
+TestState *GetTestState(const SSL *ssl);
+
+bool MoveTestState(SSL *dest, SSL *src);
+
+struct timeval *GetClock();
+
+void AdvanceClock(unsigned seconds);
+
+void CopySessions(SSL_CTX *dest, const SSL_CTX *src);
+
+#endif  // HEADER_TEST_STATE
