static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                                    SSL_CTX *client_ctx,
                                    const SSL_TEST_EXTRA_CONF *extra,
                                    CTX_DATA *server_ctx_data,
                                    CTX_DATA *server2_ctx_data,
                                    CTX_DATA *client_ctx_data)
{
    unsigned char *ticket_keys;
    size_t ticket_key_len;

    switch (extra->client.verify_callback) {
    case SSL_TEST_VERIFY_ACCEPT_ALL:
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb,
                                         NULL);
        break;
    case SSL_TEST_VERIFY_REJECT_ALL:
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb,
                                         NULL);
        break;
    default:
        break;
    }

    /* link the two contexts for SNI purposes */
    switch (extra->server.servername_callback) {
    case SSL_TEST_SERVERNAME_IGNORE_MISMATCH:
        SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_ignore_cb);
        SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx);
        break;
    case SSL_TEST_SERVERNAME_REJECT_MISMATCH:
        SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_reject_cb);
        SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx);
        break;
    default:
        break;
    }

    /*
     * The initial_ctx/session_ctx always handles the encrypt/decrypt of the
     * session ticket. This ticket_key callback is assigned to the second
     * session (assigned via SNI), and should never be invoked
     */
    if (server2_ctx != NULL)
        SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx,
                                         do_not_call_session_ticket_cb);

    if (extra->server.broken_session_ticket) {
        SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb);
    }
#ifndef OPENSSL_NO_NEXTPROTONEG
    if (extra->server.npn_protocols != NULL) {
        parse_protos(extra->server.npn_protocols,
                     &server_ctx_data->npn_protocols,
                     &server_ctx_data->npn_protocols_len);
        SSL_CTX_set_next_protos_advertised_cb(server_ctx, server_npn_cb,
                                              server_ctx_data);
    }
    if (extra->server2.npn_protocols != NULL) {
        parse_protos(extra->server2.npn_protocols,
                     &server2_ctx_data->npn_protocols,
                     &server2_ctx_data->npn_protocols_len);
        OPENSSL_assert(server2_ctx != NULL);
        SSL_CTX_set_next_protos_advertised_cb(server2_ctx, server_npn_cb,
                                              server2_ctx_data);
    }
    if (extra->client.npn_protocols != NULL) {
        parse_protos(extra->client.npn_protocols,
                     &client_ctx_data->npn_protocols,
                     &client_ctx_data->npn_protocols_len);
        SSL_CTX_set_next_proto_select_cb(client_ctx, client_npn_cb,
                                         client_ctx_data);
    }
    if (extra->server.alpn_protocols != NULL) {
        parse_protos(extra->server.alpn_protocols,
                     &server_ctx_data->alpn_protocols,
                     &server_ctx_data->alpn_protocols_len);
        SSL_CTX_set_alpn_select_cb(server_ctx, server_alpn_cb, server_ctx_data);
    }
    if (extra->server2.alpn_protocols != NULL) {
        OPENSSL_assert(server2_ctx != NULL);
        parse_protos(extra->server2.alpn_protocols,
                     &server2_ctx_data->alpn_protocols,
                     &server2_ctx_data->alpn_protocols_len);
        SSL_CTX_set_alpn_select_cb(server2_ctx, server_alpn_cb, server2_ctx_data);
    }
    if (extra->client.alpn_protocols != NULL) {
        unsigned char *alpn_protos = NULL;
        size_t alpn_protos_len;
        parse_protos(extra->client.alpn_protocols,
                     &alpn_protos, &alpn_protos_len);
        /* Reversed return value convention... */
        OPENSSL_assert(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos,
                                               alpn_protos_len) == 0);
        OPENSSL_free(alpn_protos);
    }
#endif
    /*
     * Use fixed session ticket keys so that we can decrypt a ticket created with
     * one CTX in another CTX. Don't address server2 for the moment.
     */
    ticket_key_len = SSL_CTX_set_tlsext_ticket_keys(server_ctx, NULL, 0);
    ticket_keys = OPENSSL_zalloc(ticket_key_len);
    OPENSSL_assert(ticket_keys != NULL);
    OPENSSL_assert(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys,
                                                  ticket_key_len) == 1);
    OPENSSL_free(ticket_keys);
}