/*
 * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 * Copyright 2005 Nokia. All rights reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "internal/e_os.h"
#include "internal/e_winsock.h"
#include "ssl_local.h"

#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
#include <openssl/ocsp.h>
#include <openssl/dh.h>
#include <openssl/async.h>
#include <openssl/kdf.h>
#include <openssl/ct.h>
#include <openssl/trace.h>
#include <openssl/core_names.h>
#include <openssl/provider.h>
#include "internal/cryptlib.h"
#include "internal/nelem.h"
#include "internal/refcount.h"
#include "internal/thread_once.h"
#include "internal/ktls.h"
#include "internal/to_hex.h"
#include "internal/ssl_unwrap.h"
#include "quic/quic_local.h"

#ifndef OPENSSL_NO_SSLKEYLOG
#include <sys/stat.h>
#include <fcntl.h>
#endif

static int ssl_undefined_function_3(SSL_CONNECTION *sc, unsigned char *r,
    unsigned char *s, size_t t, size_t *u)
{
    return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
}

static int ssl_undefined_function_4(SSL_CONNECTION *sc, int r)
{
    return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
}

static size_t ssl_undefined_function_5(SSL_CONNECTION *sc, const char *r,
    size_t s, unsigned char *t)
{
    return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
}

static int ssl_undefined_function_6(int r)
{
    return ssl_undefined_function(NULL);
}

static int ssl_undefined_function_7(SSL_CONNECTION *sc, unsigned char *r,
    size_t s, const char *t, size_t u,
    const unsigned char *v, size_t w, int x)
{
    return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
}

static int ssl_undefined_function_8(SSL_CONNECTION *sc)
{
    return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
}

const SSL3_ENC_METHOD ssl3_undef_enc_method = {
    ssl_undefined_function_8,
    ssl_undefined_function_3,
    ssl_undefined_function_4,
    ssl_undefined_function_5,
    NULL, /* client_finished_label */
    0, /* client_finished_label_len */
    NULL, /* server_finished_label */
    0, /* server_finished_label_len */
    ssl_undefined_function_6,
    ssl_undefined_function_7,
};

struct ssl_async_args {
    SSL *s;
    void *buf;
    size_t num;
    enum { READFUNC,
        WRITEFUNC,
        OTHERFUNC } type;
    union {
        int (*func_read)(SSL *, void *, size_t, size_t *);
        int (*func_write)(SSL *, const void *, size_t, size_t *);
        int (*func_other)(SSL *);
    } f;
};

static const struct {
    uint8_t mtype;
    uint8_t ord;
    int nid;
} dane_mds[] = {
    { DANETLS_MATCHING_FULL, 0, NID_undef },
    { DANETLS_MATCHING_2256, 1, NID_sha256 },
    { DANETLS_MATCHING_2512, 2, NID_sha512 },
};

static int dane_ctx_enable(struct dane_ctx_st *dctx)
{
    const EVP_MD **mdevp;
    uint8_t *mdord;
    uint8_t mdmax = DANETLS_MATCHING_LAST;
    int n = ((int)mdmax) + 1; /* int to handle PrivMatch(255) */
    size_t i;

    if (dctx->mdevp != NULL)
        return 1;

    mdevp = OPENSSL_calloc(n, sizeof(*mdevp));
    mdord = OPENSSL_calloc(n, sizeof(*mdord));

    if (mdord == NULL || mdevp == NULL) {
        OPENSSL_free(mdord);
        OPENSSL_free(mdevp);
        return 0;
    }

    /* Install default entries */
    for (i = 0; i < OSSL_NELEM(dane_mds); ++i) {
        const EVP_MD *md;

        if (dane_mds[i].nid == NID_undef || (md = EVP_get_digestbynid(dane_mds[i].nid)) == NULL)
            continue;
        mdevp[dane_mds[i].mtype] = md;
        mdord[dane_mds[i].mtype] = dane_mds[i].ord;
    }

    dctx->mdevp = mdevp;
    dctx->mdord = mdord;
    dctx->mdmax = mdmax;

    return 1;
}

static void dane_ctx_final(struct dane_ctx_st *dctx)
{
    OPENSSL_free(dctx->mdevp);
    dctx->mdevp = NULL;

    OPENSSL_free(dctx->mdord);
    dctx->mdord = NULL;
    dctx->mdmax = 0;
}

static void tlsa_free(danetls_record *t)
{
    if (t == NULL)
        return;
    OPENSSL_free(t->data);
    EVP_PKEY_free(t->spki);
    OPENSSL_free(t);
}

static void dane_final(SSL_DANE *dane)
{
    sk_danetls_record_pop_free(dane->trecs, tlsa_free);
    dane->trecs = NULL;

    OSSL_STACK_OF_X509_free(dane->certs);
    dane->certs = NULL;

    X509_free(dane->mcert);
    dane->mcert = NULL;
    dane->mtlsa = NULL;
    dane->mdpth = -1;
    dane->pdpth = -1;
}

/*
 * dane_copy - Copy dane configuration, sans verification state.
 */
static int ssl_dane_dup(SSL_CONNECTION *to, SSL_CONNECTION *from)
{
    int num;
    int i;

    if (!DANETLS_ENABLED(&from->dane))
        return 1;

    num = sk_danetls_record_num(from->dane.trecs);
    dane_final(&to->dane);
    to->dane.flags = from->dane.flags;
    to->dane.dctx = &SSL_CONNECTION_GET_CTX(to)->dane;
    to->dane.trecs = sk_danetls_record_new_reserve(NULL, num);

    if (to->dane.trecs == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        return 0;
    }

    for (i = 0; i < num; ++i) {
        danetls_record *t = sk_danetls_record_value(from->dane.trecs, i);

        if (SSL_dane_tlsa_add(SSL_CONNECTION_GET_SSL(to), t->usage,
                t->selector, t->mtype, t->data, t->dlen)
            <= 0)
            return 0;
    }
    return 1;
}

static int dane_mtype_set(struct dane_ctx_st *dctx,
    const EVP_MD *md, uint8_t mtype, uint8_t ord)
{
    int i;

    if (mtype == DANETLS_MATCHING_FULL && md != NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
        return 0;
    }

    if (mtype > dctx->mdmax) {
        const EVP_MD **mdevp;
        uint8_t *mdord;
        int n = ((int)mtype) + 1;

        mdevp = OPENSSL_realloc_array(dctx->mdevp, n, sizeof(*mdevp));
        if (mdevp == NULL)
            return -1;
        dctx->mdevp = mdevp;

        mdord = OPENSSL_realloc_array(dctx->mdord, n, sizeof(*mdord));
        if (mdord == NULL)
            return -1;
        dctx->mdord = mdord;

        /* Zero-fill any gaps */
        for (i = dctx->mdmax + 1; i < mtype; ++i) {
            mdevp[i] = NULL;
            mdord[i] = 0;
        }

        dctx->mdmax = mtype;
    }

    dctx->mdevp[mtype] = md;
    /* Coerce ordinal of disabled matching types to 0 */
    dctx->mdord[mtype] = (md == NULL) ? 0 : ord;

    return 1;
}

static const EVP_MD *tlsa_md_get(SSL_DANE *dane, uint8_t mtype)
{
    if (mtype > dane->dctx->mdmax)
        return NULL;
    return dane->dctx->mdevp[mtype];
}

static int dane_tlsa_add(SSL_DANE *dane,
    uint8_t usage,
    uint8_t selector,
    uint8_t mtype, const unsigned char *data, size_t dlen)
{
    danetls_record *t;
    const EVP_MD *md = NULL;
    int ilen = (int)dlen;
    int i;
    int num;
    int mdsize;

    if (dane->trecs == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED);
        return -1;
    }

    if (ilen < 0 || dlen != (size_t)ilen) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DATA_LENGTH);
        return 0;
    }

    if (usage > DANETLS_USAGE_LAST) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE);
        return 0;
    }

    if (selector > DANETLS_SELECTOR_LAST) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_SELECTOR);
        return 0;
    }

    if (mtype != DANETLS_MATCHING_FULL) {
        md = tlsa_md_get(dane, mtype);
        if (md == NULL) {
            ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE);
            return 0;
        }
    }

    if (md != NULL) {
        mdsize = EVP_MD_get_size(md);
        if (mdsize <= 0 || dlen != (size_t)mdsize) {
            ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
            return 0;
        }
    }
    if (!data) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA);
        return 0;
    }

    if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL)
        return -1;

    t->usage = usage;
    t->selector = selector;
    t->mtype = mtype;
    t->data = OPENSSL_malloc(dlen);
    if (t->data == NULL) {
        tlsa_free(t);
        return -1;
    }
    memcpy(t->data, data, dlen);
    t->dlen = dlen;

    /* Validate and cache full certificate or public key */
    if (mtype == DANETLS_MATCHING_FULL) {
        const unsigned char *p = data;
        X509 *cert = NULL;
        EVP_PKEY *pkey = NULL;

        switch (selector) {
        case DANETLS_SELECTOR_CERT:
            if (!d2i_X509(&cert, &p, ilen) || p < data || dlen != (size_t)(p - data)) {
                X509_free(cert);
                tlsa_free(t);
                ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
                return 0;
            }
            if (X509_get0_pubkey(cert) == NULL) {
                X509_free(cert);
                tlsa_free(t);
                ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
                return 0;
            }

            if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) {
                /*
                 * The Full(0) certificate decodes to a seemingly valid X.509
                 * object with a plausible key, so the TLSA record is well
                 * formed.  However, we don't actually need the certificate for
                 * usages PKIX-EE(1) or DANE-EE(3), because at least the EE
                 * certificate is always presented by the peer.  We discard the
                 * certificate, and just use the TLSA data as an opaque blob
                 * for matching the raw presented DER octets.
                 *
                 * DO NOT FREE `t` here, it will be added to the TLSA record
                 * list below!
                 */
                X509_free(cert);
                break;
            }

            /*
             * For usage DANE-TA(2), we support authentication via "2 0 0" TLSA
             * records that contain full certificates of trust-anchors that are
             * not present in the wire chain.  For usage PKIX-TA(0), we augment
             * the chain with untrusted Full(0) certificates from DNS, in case
             * they are missing from the chain.
             */
            if ((dane->certs == NULL && (dane->certs = sk_X509_new_null()) == NULL) || !sk_X509_push(dane->certs, cert)) {
                ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
                X509_free(cert);
                tlsa_free(t);
                return -1;
            }
            break;

        case DANETLS_SELECTOR_SPKI:
            if (!d2i_PUBKEY(&pkey, &p, ilen) || p < data || dlen != (size_t)(p - data)) {
                EVP_PKEY_free(pkey);
                tlsa_free(t);
                ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY);
                return 0;
            }

            /*
             * For usage DANE-TA(2), we support authentication via "2 1 0" TLSA
             * records that contain full bare keys of trust-anchors that are
             * not present in the wire chain.
             */
            if (usage == DANETLS_USAGE_DANE_TA)
                t->spki = pkey;
            else
                EVP_PKEY_free(pkey);
            break;
        }
    }

    /*-
     * Find the right insertion point for the new record.
     *
     * See crypto/x509/x509_vfy.c.  We sort DANE-EE(3) records first, so that
     * they can be processed first, as they require no chain building, and no
     * expiration or hostname checks.  Because DANE-EE(3) is numerically
     * largest, this is accomplished via descending sort by "usage".
     *
     * We also sort in descending order by matching ordinal to simplify
     * the implementation of digest agility in the verification code.
     *
     * The choice of order for the selector is not significant, so we
     * use the same descending order for consistency.
     */
    num = sk_danetls_record_num(dane->trecs);
    for (i = 0; i < num; ++i) {
        danetls_record *rec = sk_danetls_record_value(dane->trecs, i);

        if (rec->usage > usage)
            continue;
        if (rec->usage < usage)
            break;
        if (rec->selector > selector)
            continue;
        if (rec->selector < selector)
            break;
        if (dane->dctx->mdord[rec->mtype] > dane->dctx->mdord[mtype])
            continue;
        break;
    }

    if (!sk_danetls_record_insert(dane->trecs, t, i)) {
        tlsa_free(t);
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        return -1;
    }
    dane->umask |= DANETLS_USAGE_BIT(usage);

    return 1;
}

/*
 * Return 0 if there is only one version configured and it was disabled
 * at configure time.  Return 1 otherwise.
 */
static int ssl_check_allowed_versions(int min_version, int max_version)
{
    int minisdtls = 0, maxisdtls = 0;

    /* Figure out if we're doing DTLS versions or TLS versions */
    if (min_version == DTLS1_BAD_VER
        || min_version >> 8 == DTLS1_VERSION_MAJOR)
        minisdtls = 1;
    if (max_version == DTLS1_BAD_VER
        || max_version >> 8 == DTLS1_VERSION_MAJOR)
        maxisdtls = 1;
    /* A wildcard version of 0 could be DTLS or TLS. */
    if ((minisdtls && !maxisdtls && max_version != 0)
        || (maxisdtls && !minisdtls && min_version != 0)) {
        /* Mixing DTLS and TLS versions will lead to sadness; deny it. */
        return 0;
    }

    if (minisdtls || maxisdtls) {
        /* Do DTLS version checks. */
        if (min_version == 0)
            /* Ignore DTLS1_BAD_VER */
            min_version = DTLS1_VERSION;
        if (max_version == 0)
            max_version = DTLS1_2_VERSION;
#ifdef OPENSSL_NO_DTLS1_2
        if (max_version == DTLS1_2_VERSION)
            max_version = DTLS1_VERSION;
#endif
#ifdef OPENSSL_NO_DTLS1
        if (min_version == DTLS1_VERSION)
            min_version = DTLS1_2_VERSION;
#endif
        /* Done massaging versions; do the check. */
        if (0
#ifdef OPENSSL_NO_DTLS1
            || (DTLS_VERSION_GE(min_version, DTLS1_VERSION)
                && DTLS_VERSION_GE(DTLS1_VERSION, max_version))
#endif
#ifdef OPENSSL_NO_DTLS1_2
            || (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION)
                && DTLS_VERSION_GE(DTLS1_2_VERSION, max_version))
#endif
        )
            return 0;
    } else {
        /* Regular TLS version checks. */
        if (min_version == 0)
            min_version = TLS1_VERSION;
        if (max_version == 0)
            max_version = TLS1_3_VERSION;
#ifdef OPENSSL_NO_TLS1_3
        if (max_version == TLS1_3_VERSION)
            max_version = TLS1_2_VERSION;
#endif
#ifdef OPENSSL_NO_TLS1_2
        if (max_version == TLS1_2_VERSION)
            max_version = TLS1_1_VERSION;
#endif
#ifdef OPENSSL_NO_TLS1_1
        if (max_version == TLS1_1_VERSION)
            max_version = TLS1_VERSION;
#endif
#ifdef OPENSSL_NO_TLS1
        if (min_version == TLS1_VERSION)
            min_version = TLS1_1_VERSION;
#endif
#ifdef OPENSSL_NO_TLS1_1
        if (min_version == TLS1_1_VERSION)
            min_version = TLS1_2_VERSION;
#endif
#ifdef OPENSSL_NO_TLS1_2
        if (min_version == TLS1_2_VERSION)
            min_version = TLS1_3_VERSION;
#endif
        /* Done massaging versions; do the check. */
        if (0
#ifdef OPENSSL_NO_TLS1
            || (min_version <= TLS1_VERSION && TLS1_VERSION <= max_version)
#endif
#ifdef OPENSSL_NO_TLS1_1
            || (min_version <= TLS1_1_VERSION && TLS1_1_VERSION <= max_version)
#endif
#ifdef OPENSSL_NO_TLS1_2
            || (min_version <= TLS1_2_VERSION && TLS1_2_VERSION <= max_version)
#endif
#ifdef OPENSSL_NO_TLS1_3
            || (min_version <= TLS1_3_VERSION && TLS1_3_VERSION <= max_version)
#endif
        )
            return 0;
    }
    return 1;
}

#if defined(__TANDEM) && defined(OPENSSL_VPROC)
/*
 * Define a VPROC function for HP NonStop build ssl library.
 * This is used by platform version identification tools.
 * Do not inline this procedure or make it static.
 */
#define OPENSSL_VPROC_STRING_(x) x##_SSL
#define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x)
#define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC)
void OPENSSL_VPROC_FUNC(void) { }
#endif

int SSL_clear(SSL *s)
{
    if (s->method == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_METHOD_SPECIFIED);
        return 0;
    }

    return s->method->ssl_reset(s);
}

int ossl_ssl_connection_reset(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (ssl_clear_bad_session(sc)) {
        SSL_SESSION_free(sc->session);
        sc->session = NULL;
    }
    SSL_SESSION_free(sc->psksession);
    sc->psksession = NULL;
    OPENSSL_free(sc->psksession_id);
    sc->psksession_id = NULL;
    sc->psksession_id_len = 0;
    sc->hello_retry_request = SSL_HRR_NONE;
    sc->sent_tickets = 0;

    sc->error = 0;
    sc->hit = 0;
    sc->shutdown = 0;

    if (sc->renegotiate) {
        ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    ossl_statem_clear(sc);

    sc->version = s->method->version;
    sc->client_version = sc->version;
    sc->rwstate = SSL_NOTHING;

    BUF_MEM_free(sc->init_buf);
    sc->init_buf = NULL;
    sc->first_packet = 0;

    sc->key_update = SSL_KEY_UPDATE_NONE;
    memset(sc->ext.compress_certificate_from_peer, 0,
        sizeof(sc->ext.compress_certificate_from_peer));
    sc->ext.compress_certificate_sent = 0;

    EVP_MD_CTX_free(sc->pha_dgst);
    sc->pha_dgst = NULL;

    /* Reset DANE verification result state */
    sc->dane.mdpth = -1;
    sc->dane.pdpth = -1;
    X509_free(sc->dane.mcert);
    sc->dane.mcert = NULL;
    sc->dane.mtlsa = NULL;

    /* Clear the verification result peername */
    X509_VERIFY_PARAM_move_peername(sc->param, NULL);

    /* Clear any shared connection state */
    OPENSSL_free(sc->shared_sigalgs);
    sc->shared_sigalgs = NULL;
    sc->shared_sigalgslen = 0;

    /*
     * Check to see if we were changed into a different method, if so, revert
     * back.
     */
    if (s->method != s->defltmeth) {
        s->method->ssl_deinit(s);
        s->method = s->defltmeth;
        if (!s->method->ssl_init(s))
            return 0;
    } else {
        if (!s->method->ssl_clear(s))
            return 0;
    }

    ossl_quic_tls_clear(sc->qtls);

    if (!RECORD_LAYER_reset(&sc->rlayer))
        return 0;

    return 1;
}

#ifndef OPENSSL_NO_DEPRECATED_3_0
/** Used to change an SSL_CTXs default SSL method type */
int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
{
    STACK_OF(SSL_CIPHER) *sk;

    if (IS_QUIC_CTX(ctx)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
        return 0;
    }

    ctx->method = meth;

    if (!SSL_CTX_set_ciphersuites(ctx, OSSL_default_ciphersuites())) {
        ERR_raise(ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
        return 0;
    }
    sk = ssl_create_cipher_list(ctx,
        ctx->tls13_ciphersuites,
        &(ctx->cipher_list),
        &(ctx->cipher_list_by_id),
        OSSL_default_cipher_list(), ctx->cert);
    if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
        return 0;
    }
    return 1;
}
#endif

SSL *SSL_new(SSL_CTX *ctx)
{
    if (ctx == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_CTX);
        return NULL;
    }
    if (ctx->method == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
        return NULL;
    }
    return ctx->method->ssl_new(ctx);
}

int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method, int type)
{
    if (!SSL_CTX_up_ref(ctx))
        return 0;

    ssl->lock = CRYPTO_THREAD_lock_new();

    if (ssl->lock == NULL || !CRYPTO_NEW_REF(&ssl->references, 1))
        goto err;

    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data)) {
        CRYPTO_FREE_REF(&ssl->references);
        goto err;
    }

    ssl->ctx = ctx;
    ssl->type = type;
    ssl->defltmeth = ssl->method = method;

    return 1;

err:
    CRYPTO_THREAD_lock_free(ssl->lock);
    ssl->lock = NULL;
    SSL_CTX_free(ctx);
    return 0;
}

SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, SSL *user_ssl,
    const SSL_METHOD *method)
{
    SSL_CONNECTION *s;
    SSL *ssl;

    s = OPENSSL_zalloc(sizeof(*s));
    if (s == NULL)
        return NULL;

    ssl = &s->ssl;
    s->user_ssl = (user_ssl == NULL) ? ssl : user_ssl;

    if (!ossl_ssl_init(ssl, ctx, method, SSL_TYPE_SSL_CONNECTION)) {
        OPENSSL_free(s);
        s = NULL;
        ssl = NULL;
        goto sslerr;
    }

    RECORD_LAYER_init(&s->rlayer, s);

    s->options = ctx->options;

    s->dane.flags = ctx->dane.flags;
    if (method->version == ctx->method->version) {
        s->min_proto_version = ctx->min_proto_version;
        s->max_proto_version = ctx->max_proto_version;
    }

    s->mode = ctx->mode;
    s->max_cert_list = ctx->max_cert_list;
    s->max_early_data = ctx->max_early_data;
    s->recv_max_early_data = ctx->recv_max_early_data;

    s->num_tickets = ctx->num_tickets;
    s->pha_enabled = ctx->pha_enabled;

    /* Shallow copy of the ciphersuites stack */
    s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites);
    if (s->tls13_ciphersuites == NULL)
        goto cerr;

    /*
     * Earlier library versions used to copy the pointer to the CERT, not
     * its contents; only when setting new parameters for the per-SSL
     * copy, ssl_cert_new would be called (and the direct reference to
     * the per-SSL_CTX settings would be lost, but those still were
     * indirectly accessed for various purposes, and for that reason they
     * used to be known as s->ctx->default_cert). Now we don't look at the
     * SSL_CTX's CERT after having duplicated it once.
     */
    s->cert = ssl_cert_dup(ctx->cert);
    if (s->cert == NULL)
        goto sslerr;

    RECORD_LAYER_set_read_ahead(&s->rlayer, ctx->read_ahead);
    s->msg_callback = ctx->msg_callback;
    s->msg_callback_arg = ctx->msg_callback_arg;
    s->verify_mode = ctx->verify_mode;
    s->not_resumable_session_cb = ctx->not_resumable_session_cb;
    s->rlayer.record_padding_cb = ctx->record_padding_cb;
    s->rlayer.record_padding_arg = ctx->record_padding_arg;
    s->rlayer.block_padding = ctx->block_padding;
    s->rlayer.hs_padding = ctx->hs_padding;
    s->sid_ctx_length = ctx->sid_ctx_length;
    if (!ossl_assert(s->sid_ctx_length <= sizeof(s->sid_ctx)))
        goto err;
    memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
    s->verify_callback = ctx->default_verify_callback;
    s->generate_session_id = ctx->generate_session_id;

    s->param = X509_VERIFY_PARAM_new();
    if (s->param == NULL)
        goto asn1err;
    X509_VERIFY_PARAM_inherit(s->param, ctx->param);
    s->quiet_shutdown = IS_QUIC_CTX(ctx) ? 0 : ctx->quiet_shutdown;

    if (!IS_QUIC_CTX(ctx))
        s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode;

    s->max_send_fragment = ctx->max_send_fragment;
    s->split_send_fragment = ctx->split_send_fragment;
    s->max_pipelines = ctx->max_pipelines;
    s->rlayer.default_read_buf_len = ctx->default_read_buf_len;

    s->ext.debug_cb = 0;
    s->ext.debug_arg = NULL;
    s->ext.ticket_expected = 0;
    s->ext.status_type = ctx->ext.status_type;
    s->ext.status_expected = 0;
    s->ext.ocsp.ids = NULL;
    s->ext.ocsp.exts = NULL;
    s->ext.ocsp.resp = NULL;
    s->ext.ocsp.resp_len = 0;
    s->ext.ocsp.resp_ex = NULL;

    if (!SSL_CTX_up_ref(ctx))
        goto err;

    s->session_ctx = ctx;
    if (ctx->ext.supportedgroups != NULL) {
        size_t add = 0;

        if (ctx->ext.supportedgroups_len == 0)
            /* Add 1 so allocation won't fail */
            add = 1;
        s->ext.supportedgroups = OPENSSL_memdup(ctx->ext.supportedgroups,
            (ctx->ext.supportedgroups_len + add)
                * sizeof(*ctx->ext.supportedgroups));
        if (s->ext.supportedgroups == NULL) {
            s->ext.supportedgroups_len = 0;
            goto err;
        }
        s->ext.supportedgroups_len = ctx->ext.supportedgroups_len;
    }
    if (ctx->ext.keyshares != NULL) {
        size_t add = 0;

        if (ctx->ext.keyshares_len == 0)
            /* Add 1 so allocation won't fail */
            add = 1;
        s->ext.keyshares = OPENSSL_memdup(ctx->ext.keyshares,
            (ctx->ext.keyshares_len + add)
                * sizeof(*ctx->ext.keyshares));
        if (s->ext.keyshares == NULL) {
            s->ext.keyshares_len = 0;
            goto err;
        }
        s->ext.keyshares_len = ctx->ext.keyshares_len;
    }
    if (ctx->ext.tuples != NULL) {
        size_t add = 0;

        if (ctx->ext.tuples_len == 0)
            /* Add 1 so allocation won't fail */
            add = 1;
        s->ext.tuples = OPENSSL_memdup(ctx->ext.tuples,
            (ctx->ext.tuples_len + add)
                * sizeof(*ctx->ext.tuples));
        if (s->ext.tuples == NULL) {
            s->ext.tuples_len = 0;
            goto err;
        }
        s->ext.tuples_len = ctx->ext.tuples_len;
    }

#ifndef OPENSSL_NO_NEXTPROTONEG
    s->ext.npn = NULL;
#endif

    if (ctx->ext.alpn != NULL) {
        s->ext.alpn = OPENSSL_malloc(ctx->ext.alpn_len);
        if (s->ext.alpn == NULL) {
            s->ext.alpn_len = 0;
            goto err;
        }
        memcpy(s->ext.alpn, ctx->ext.alpn, ctx->ext.alpn_len);
        s->ext.alpn_len = ctx->ext.alpn_len;
    }

    s->verified_chain = NULL;
    s->verify_result = X509_V_OK;

    s->default_passwd_callback = ctx->default_passwd_callback;
    s->default_passwd_callback_userdata = ctx->default_passwd_callback_userdata;

    s->key_update = SSL_KEY_UPDATE_NONE;

    if (!IS_QUIC_CTX(ctx)) {
        s->allow_early_data_cb = ctx->allow_early_data_cb;
        s->allow_early_data_cb_data = ctx->allow_early_data_cb_data;
    }

    if (!method->ssl_init(ssl))
        goto sslerr;

    s->server = (method->ssl_accept == ssl_undefined_function) ? 0 : 1;

    if (!method->ssl_reset(ssl))
        goto sslerr;

#ifndef OPENSSL_NO_PSK
    s->psk_client_callback = ctx->psk_client_callback;
    s->psk_server_callback = ctx->psk_server_callback;
#endif
    s->psk_find_session_cb = ctx->psk_find_session_cb;
    s->psk_use_session_cb = ctx->psk_use_session_cb;

    s->async_cb = ctx->async_cb;
    s->async_cb_arg = ctx->async_cb_arg;

    s->job = NULL;

#ifndef OPENSSL_NO_COMP_ALG
    memcpy(s->cert_comp_prefs, ctx->cert_comp_prefs, sizeof(s->cert_comp_prefs));
#endif
    if (ctx->client_cert_type != NULL) {
        s->client_cert_type = OPENSSL_memdup(ctx->client_cert_type,
            ctx->client_cert_type_len);
        if (s->client_cert_type == NULL)
            goto sslerr;
        s->client_cert_type_len = ctx->client_cert_type_len;
    }
    if (ctx->server_cert_type != NULL) {
        s->server_cert_type = OPENSSL_memdup(ctx->server_cert_type,
            ctx->server_cert_type_len);
        if (s->server_cert_type == NULL)
            goto sslerr;
        s->server_cert_type_len = ctx->server_cert_type_len;
    }

#ifndef OPENSSL_NO_CT
    if (!SSL_set_ct_validation_callback(ssl, ctx->ct_validation_callback,
            ctx->ct_validation_callback_arg))
        goto sslerr;
#endif

#ifndef OPENSSL_NO_ECH
    if (!ossl_ech_conn_init(s, ctx, method))
        goto sslerr;
#endif

    s->ssl_pkey_num = SSL_PKEY_NUM + ctx->sigalg_list_len;
    return ssl;
cerr:
    ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
    goto err;
asn1err:
    ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB);
    goto err;
sslerr:
    ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
err:
    SSL_free(ssl);
    return NULL;
}

SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
{
    return ossl_ssl_connection_new_int(ctx, NULL, ctx->method);
}

int SSL_is_dtls(const SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
        return 0;
#endif

    if (sc == NULL)
        return 0;

    return SSL_CONNECTION_IS_DTLS(sc) ? 1 : 0;
}

int SSL_is_tls(const SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
        return 0;
#endif

    if (sc == NULL)
        return 0;

    return SSL_CONNECTION_IS_DTLS(sc) ? 0 : 1;
}

int SSL_is_quic(const SSL *s)
{
    return IS_QUIC(s);
}

int SSL_CTX_is_quic(const SSL_CTX *c)
{
    return IS_QUIC_CTX(c);
}

int SSL_CTX_is_server(const SSL_CTX *c)
{
    if (c == NULL || c->method == NULL)
        return 0;
    return (c->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
}

int SSL_up_ref(SSL *s)
{
    int i;

    if (CRYPTO_UP_REF(&s->references, &i) <= 0)
        return 0;

    REF_PRINT_COUNT("SSL", i, s);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
}

int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
    unsigned int sid_ctx_len)
{
    if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
        ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
        return 0;
    }
    ctx->sid_ctx_length = sid_ctx_len;
    memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);

    return 1;
}

int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
    unsigned int sid_ctx_len)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return 0;

    if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
        ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
        return 0;
    }
    sc->sid_ctx_length = sid_ctx_len;
    memcpy(sc->sid_ctx, sid_ctx, sid_ctx_len);

    return 1;
}

int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
{
    if (!CRYPTO_THREAD_write_lock(ctx->lock))
        return 0;
    ctx->generate_session_id = cb;
    CRYPTO_THREAD_unlock(ctx->lock);
    return 1;
}

int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL || !CRYPTO_THREAD_write_lock(ssl->lock))
        return 0;
    sc->generate_session_id = cb;
    CRYPTO_THREAD_unlock(ssl->lock);
    return 1;
}

int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
    unsigned int id_len)
{
    /*
     * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
     * we can "construct" a session to give us the desired check - i.e. to
     * find if there's a session in the hash table that would conflict with
     * any new session built out of this id/id_len and the ssl_version in use
     * by this SSL.
     */
    SSL_SESSION r, *p;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL || id_len > sizeof(r.session_id))
        return 0;

    r.ssl_version = sc->version;
    r.session_id_length = id_len;
    memcpy(r.session_id, id, id_len);

    if (!CRYPTO_THREAD_read_lock(sc->session_ctx->lock))
        return 0;
    p = lh_SSL_SESSION_retrieve(sc->session_ctx->sessions, &r);
    CRYPTO_THREAD_unlock(sc->session_ctx->lock);
    return (p != NULL);
}

int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
{
    return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
}

int SSL_set_purpose(SSL *s, int purpose)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_set_purpose(sc->param, purpose);
}

int SSL_CTX_set_trust(SSL_CTX *s, int trust)
{
    return X509_VERIFY_PARAM_set_trust(s->param, trust);
}

int SSL_set_trust(SSL *s, int trust)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_set_trust(sc->param, trust);
}

int SSL_set1_dnsname(SSL *s, const char *host)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_set1_host(sc->param, host, 0);
}

int SSL_add1_dnsname(SSL *s, const char *host)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_add1_host(sc->param, host, strlen(host));
}

int SSL_set1_ipaddr(SSL *s, const char *ipaddr)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_set1_ip_asc(sc->param, ipaddr);
}

int SSL_add1_ipaddr(SSL *s, const char *ipaddr)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_add1_ip_asc(sc->param, ipaddr);
}

#if !defined(OPENSSL_NO_DEPRECATED_4_0)
int SSL_set1_host(SSL *s, const char *host)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    /* clear hostname(s) and IP address in any case, also if host parses as an IP address */
    (void)X509_VERIFY_PARAM_set1_host(sc->param, NULL, 0);
    (void)X509_VERIFY_PARAM_set1_ip(sc->param, NULL, 0);
    if (host == NULL)
        return 1;

    /* If a host is provided and parses as an IP address, treat it as such. */
    return X509_VERIFY_PARAM_set1_ip_asc(sc->param, host)
        || X509_VERIFY_PARAM_set1_host(sc->param, host, 0);
}

int SSL_add1_host(SSL *s, const char *host)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    /* If a host is provided and parses as an IP address, treat it as such. */
    if (host != NULL) {
        ASN1_OCTET_STRING *ip;
        char *old_ip;

        ip = a2i_IPADDRESS(host);
        if (ip != NULL) {
            /* We didn't want it; only to check if it *is* an IP address */
            ASN1_OCTET_STRING_free(ip);

            old_ip = X509_VERIFY_PARAM_get1_ip_asc(sc->param);
            if (old_ip != NULL) {
                OPENSSL_free(old_ip);
                /* There can be only one IP address */
                ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
                    "IP address was already set");
                return 0;
            }

            return X509_VERIFY_PARAM_set1_ip_asc(sc->param, host);
        }
    }

    return X509_VERIFY_PARAM_add1_host(sc->param, host, 0);
}
#endif /* !defined(OPENSSL_NO_DEPRECATED_4_0) */

void SSL_set_hostflags(SSL *s, unsigned int flags)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    X509_VERIFY_PARAM_set_hostflags(sc->param, flags);
}

const char *SSL_get0_peername(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    return X509_VERIFY_PARAM_get0_peername(sc->param);
}

int SSL_CTX_dane_enable(SSL_CTX *ctx)
{
    return dane_ctx_enable(&ctx->dane);
}

unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags)
{
    unsigned long orig = ctx->dane.flags;

    ctx->dane.flags |= flags;
    return orig;
}

unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags)
{
    unsigned long orig = ctx->dane.flags;

    ctx->dane.flags &= ~flags;
    return orig;
}

int SSL_dane_enable(SSL *s, const char *basedomain)
{
    SSL_DANE *dane;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    dane = &sc->dane;
    if (s->ctx->dane.mdmax == 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED);
        return 0;
    }
    if (dane->trecs != NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DANE_ALREADY_ENABLED);
        return 0;
    }

    /*
     * Default SNI name.  This rejects empty names, while set1_host below
     * accepts them and disables hostname checks.  To avoid side-effects with
     * invalid input, set the SNI name first.
     */
    if (sc->ext.hostname == NULL) {
        if (!SSL_set_tlsext_host_name(s, basedomain)) {
            ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
            return -1;
        }
    }

    /* Primary RFC6125 reference identifier */
    if (!X509_VERIFY_PARAM_set1_host(sc->param, basedomain, 0)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
        return -1;
    }

    dane->mdpth = -1;
    dane->pdpth = -1;
    dane->dctx = &s->ctx->dane;
    dane->trecs = sk_danetls_record_new_null();

    if (dane->trecs == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        return -1;
    }
    return 1;
}

unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags)
{
    unsigned long orig;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return 0;

    orig = sc->dane.flags;

    sc->dane.flags |= flags;
    return orig;
}

unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags)
{
    unsigned long orig;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return 0;

    orig = sc->dane.flags;

    sc->dane.flags &= ~flags;
    return orig;
}

int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki)
{
    SSL_DANE *dane;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return -1;

    dane = &sc->dane;

    if (!DANETLS_ENABLED(dane) || sc->verify_result != X509_V_OK)
        return -1;
    if (dane->mtlsa) {
        if (mcert)
            *mcert = dane->mcert;
        if (mspki)
            *mspki = (dane->mcert == NULL) ? dane->mtlsa->spki : NULL;
    }
    return dane->mdpth;
}

int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
    uint8_t *mtype, const unsigned char **data, size_t *dlen)
{
    SSL_DANE *dane;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return -1;

    dane = &sc->dane;

    if (!DANETLS_ENABLED(dane) || sc->verify_result != X509_V_OK)
        return -1;
    if (dane->mtlsa) {
        if (usage)
            *usage = dane->mtlsa->usage;
        if (selector)
            *selector = dane->mtlsa->selector;
        if (mtype)
            *mtype = dane->mtlsa->mtype;
        if (data)
            *data = dane->mtlsa->data;
        if (dlen)
            *dlen = dane->mtlsa->dlen;
    }
    return dane->mdpth;
}

SSL_DANE *SSL_get0_dane(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    return &sc->dane;
}

int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
    uint8_t mtype, const unsigned char *data, size_t dlen)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return dane_tlsa_add(&sc->dane, usage, selector, mtype, data, dlen);
}

int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype,
    uint8_t ord)
{
    return dane_mtype_set(&ctx->dane, md, mtype, ord);
}

int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
{
    return X509_VERIFY_PARAM_set1(ctx->param, vpm);
}

int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_set1(sc->param, vpm);
}

X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx)
{
    return ctx->param;
}

X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return NULL;

    return sc->param;
}

void SSL_certs_clear(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    ssl_cert_clear_certs(sc->cert);
}

void SSL_free(SSL *s)
{
    int i;

    if (s == NULL)
        return;
    CRYPTO_DOWN_REF(&s->references, &i);
    REF_PRINT_COUNT("SSL", i, s);
    if (i > 0)
        return;
    REF_ASSERT_ISNT(i < 0);

    if (s->method != NULL)
        s->method->ssl_free(s);

    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
    SSL_CTX_free(s->ctx);
    CRYPTO_THREAD_lock_free(s->lock);
    CRYPTO_FREE_REF(&s->references);

    OPENSSL_free(s);
}

void ossl_ssl_connection_free(SSL *ssl)
{
    SSL_CONNECTION *s;

    s = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
    if (s == NULL)
        return;

    /*
     * Ignore return values. This could result in user callbacks being called
     * e.g. for the QUIC TLS record layer. So we do this early before we have
     * freed other things.
     */
    ssl_free_wbio_buffer(s);
    RECORD_LAYER_clear(&s->rlayer);

    X509_VERIFY_PARAM_free(s->param);
    dane_final(&s->dane);

    BUF_MEM_free(s->init_buf);

    /* add extra stuff */
    sk_SSL_CIPHER_free(s->cipher_list);
    sk_SSL_CIPHER_free(s->cipher_list_by_id);
    sk_SSL_CIPHER_free(s->tls13_ciphersuites);
    sk_SSL_CIPHER_free(s->peer_ciphers);

    /* Make the next call work :-) */
    if (s->session != NULL) {
        ssl_clear_bad_session(s);
        SSL_SESSION_free(s->session);
    }
    SSL_SESSION_free(s->psksession);
    OPENSSL_free(s->psksession_id);

    ssl_cert_free(s->cert);
    OPENSSL_free(s->shared_sigalgs);
    /* Free up if allocated */

    OPENSSL_free(s->ext.hostname);
    SSL_CTX_free(s->session_ctx);
    OPENSSL_free(s->ext.peer_ecpointformats);
    OPENSSL_free(s->ext.supportedgroups);
    OPENSSL_free(s->ext.keyshares);
    OPENSSL_free(s->ext.tuples);
    OPENSSL_free(s->ext.peer_supportedgroups);
    sk_X509_EXTENSION_pop_free(s->ext.ocsp.exts, X509_EXTENSION_free);

#ifndef OPENSSL_NO_OCSP
    OPENSSL_free(s->ext.ocsp.resp);
    s->ext.ocsp.resp = NULL;
    s->ext.ocsp.resp_len = 0;

    sk_OCSP_RESPID_pop_free(s->ext.ocsp.ids, OCSP_RESPID_free);
    sk_OCSP_RESPONSE_pop_free(s->ext.ocsp.resp_ex, OCSP_RESPONSE_free);
    s->ext.ocsp.resp_ex = NULL;
#endif
#ifndef OPENSSL_NO_CT
    SCT_LIST_free(s->scts);
    OPENSSL_free(s->ext.scts);
#endif
    OPENSSL_free(s->ext.alpn);
    OPENSSL_free(s->ext.tls13_cookie);
    if (s->clienthello != NULL)
        OPENSSL_free(s->clienthello->pre_proc_exts);
    OPENSSL_free(s->clienthello);
    OPENSSL_free(s->pha_context);
    EVP_MD_CTX_free(s->pha_dgst);

    sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
    sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free);

    OPENSSL_free(s->client_cert_type);
    OPENSSL_free(s->server_cert_type);

    OSSL_STACK_OF_X509_free(s->verified_chain);

    if (ssl->method != NULL)
        ssl->method->ssl_deinit(ssl);

    ASYNC_WAIT_CTX_free(s->waitctx);

#if !defined(OPENSSL_NO_NEXTPROTONEG)
    OPENSSL_free(s->ext.npn);
#endif

#ifndef OPENSSL_NO_SRTP
    sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
#endif

    /*
     * We do this late. We want to ensure that any other references we held to
     * these BIOs are freed first *before* we call BIO_free_all(), because
     * BIO_free_all() will only free each BIO in the chain if the number of
     * references to the first BIO have dropped to 0
     */
    BIO_free_all(s->wbio);
    s->wbio = NULL;
    BIO_free_all(s->rbio);
    s->rbio = NULL;
    OPENSSL_free(s->s3.tmp.valid_flags);
#ifndef OPENSSL_NO_ECH
    ossl_ech_conn_clear(&s->ext.ech);
#endif
}

void SSL_set0_rbio(SSL *s, BIO *rbio)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        ossl_quic_conn_set0_net_rbio(s, rbio);
        return;
    }
#endif

    if (sc == NULL)
        return;

    BIO_free_all(sc->rbio);
    sc->rbio = rbio;
    sc->rlayer.rrlmethod->set1_bio(sc->rlayer.rrl, sc->rbio);
}

void SSL_set0_wbio(SSL *s, BIO *wbio)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        ossl_quic_conn_set0_net_wbio(s, wbio);
        return;
    }
#endif

    if (sc == NULL)
        return;

    /*
     * If the output buffering BIO is still in place, remove it
     */
    if (sc->bbio != NULL)
        sc->wbio = BIO_pop(sc->wbio);

    BIO_free_all(sc->wbio);
    sc->wbio = wbio;

    /* Re-attach |bbio| to the new |wbio|. */
    if (sc->bbio != NULL)
        sc->wbio = BIO_push(sc->bbio, sc->wbio);

    sc->rlayer.wrlmethod->set1_bio(sc->rlayer.wrl, sc->wbio);
}

void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio)
{
    /*
     * For historical reasons, this function has many different cases in
     * ownership handling.
     */

    /* If nothing has changed, do nothing */
    if (rbio == SSL_get_rbio(s) && wbio == SSL_get_wbio(s))
        return;

    /*
     * If the two arguments are equal then one fewer reference is granted by the
     * caller than we want to take
     */
    if (rbio != NULL && rbio == wbio) {
        if (!BIO_up_ref(rbio))
            return;
    }

    /*
     * If only the wbio is changed only adopt one reference.
     */
    if (rbio == SSL_get_rbio(s)) {
        SSL_set0_wbio(s, wbio);
        return;
    }
    /*
     * There is an asymmetry here for historical reasons. If only the rbio is
     * changed AND the rbio and wbio were originally different, then we only
     * adopt one reference.
     */
    if (wbio == SSL_get_wbio(s) && SSL_get_rbio(s) != SSL_get_wbio(s)) {
        SSL_set0_rbio(s, rbio);
        return;
    }

    /* Otherwise, adopt both references. */
    SSL_set0_rbio(s, rbio);
    SSL_set0_wbio(s, wbio);
}

BIO *SSL_get_rbio(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_conn_get_net_rbio(s);
#endif

    if (sc == NULL)
        return NULL;

    return sc->rbio;
}

BIO *SSL_get_wbio(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_conn_get_net_wbio(s);
#endif

    if (sc == NULL)
        return NULL;

    if (sc->bbio != NULL) {
        /*
         * If |bbio| is active, the true caller-configured BIO is its
         * |next_bio|.
         */
        return BIO_next(sc->bbio);
    }
    return sc->wbio;
}

int SSL_get_fd(const SSL *s)
{
    return SSL_get_rfd(s);
}

int SSL_get_rfd(const SSL *s)
{
    int ret = -1;
    BIO *b, *r;

    b = SSL_get_rbio(s);
    r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
    if (r != NULL)
        BIO_get_fd(r, &ret);
    return ret;
}

int SSL_get_wfd(const SSL *s)
{
    int ret = -1;
    BIO *b, *r;

    b = SSL_get_wbio(s);
    r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
    if (r != NULL)
        BIO_get_fd(r, &ret);
    return ret;
}

#ifndef OPENSSL_NO_SOCK
static const BIO_METHOD *fd_method(SSL *s)
{
#ifndef OPENSSL_NO_DGRAM
    if (IS_QUIC(s))
        return BIO_s_datagram();
#endif

    return BIO_s_socket();
}

int SSL_set_fd(SSL *s, int fd)
{
    int ret = 0;
    BIO *bio = NULL;

    if (s->type == SSL_TYPE_QUIC_XSO) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
        goto err;
    }

    bio = BIO_new(fd_method(s));

    if (bio == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
        goto err;
    }
    BIO_set_fd(bio, fd, BIO_NOCLOSE);
    SSL_set_bio(s, bio, bio);
    ret = 1;
err:
    return ret;
}

int SSL_set_wfd(SSL *s, int fd)
{
    BIO *rbio = SSL_get_rbio(s);
    int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;

    if (s->type == SSL_TYPE_QUIC_XSO) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
        return 0;
    }

    if (rbio == NULL || BIO_method_type(rbio) != desired_type
        || (int)BIO_get_fd(rbio, NULL) != fd) {
        BIO *bio = BIO_new(fd_method(s));

        if (bio == NULL) {
            ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
            return 0;
        }
        BIO_set_fd(bio, fd, BIO_NOCLOSE);
        SSL_set0_wbio(s, bio);
    } else {
        if (!BIO_up_ref(rbio))
            return 0;
        SSL_set0_wbio(s, rbio);
    }
    return 1;
}

int SSL_set_rfd(SSL *s, int fd)
{
    BIO *wbio = SSL_get_wbio(s);
    int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;

    if (s->type == SSL_TYPE_QUIC_XSO) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
        return 0;
    }

    if (wbio == NULL || BIO_method_type(wbio) != desired_type
        || ((int)BIO_get_fd(wbio, NULL) != fd)) {
        BIO *bio = BIO_new(fd_method(s));

        if (bio == NULL) {
            ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
            return 0;
        }
        BIO_set_fd(bio, fd, BIO_NOCLOSE);
        SSL_set0_rbio(s, bio);
    } else {
        if (!BIO_up_ref(wbio))
            return 0;
        SSL_set0_rbio(s, wbio);
    }

    return 1;
}
#endif

/* return length of latest Finished message we sent, copy to 'buf' */
size_t SSL_get_finished(const SSL *s, void *buf, size_t count)
{
    size_t ret = 0;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    ret = sc->s3.tmp.finish_md_len;
    if (count > ret)
        count = ret;
    memcpy(buf, sc->s3.tmp.finish_md, count);
    return ret;
}

/* return length of latest Finished message we expected, copy to 'buf' */
size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count)
{
    size_t ret = 0;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    ret = sc->s3.tmp.peer_finish_md_len;
    if (count > ret)
        count = ret;
    memcpy(buf, sc->s3.tmp.peer_finish_md, count);
    return ret;
}

int SSL_get_verify_mode(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->verify_mode;
}

int SSL_get_verify_depth(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return X509_VERIFY_PARAM_get_depth(sc->param);
}

int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->verify_callback;
}

int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
{
    return ctx->verify_mode;
}

int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
{
    return X509_VERIFY_PARAM_get_depth(ctx->param);
}

int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *)
{
    return ctx->default_verify_callback;
}

void SSL_set_verify(SSL *s, int mode,
    int (*callback)(int ok, X509_STORE_CTX *ctx))
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->verify_mode = mode;
    if (callback != NULL)
        sc->verify_callback = callback;
}

void SSL_set_verify_depth(SSL *s, int depth)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    X509_VERIFY_PARAM_set_depth(sc->param, depth);
}

void SSL_set_read_ahead(SSL *s, int yes)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
    OSSL_PARAM options[2], *opts = options;

    if (sc == NULL)
        return;

    RECORD_LAYER_set_read_ahead(&sc->rlayer, yes);

    *opts++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD,
        &sc->rlayer.read_ahead);
    *opts = OSSL_PARAM_construct_end();

    /* Ignore return value */
    sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options);
}

int SSL_get_read_ahead(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    return RECORD_LAYER_get_read_ahead(&sc->rlayer);
}

int SSL_pending(const SSL *s)
{
    size_t pending = s->method->ssl_pending(s);

    /*
     * SSL_pending cannot work properly if read-ahead is enabled
     * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
     * impossible to fix since SSL_pending cannot report errors that may be
     * observed while scanning the new data. (Note that SSL_pending() is
     * often used as a boolean value, so we'd better not return -1.)
     *
     * SSL_pending also cannot work properly if the value >INT_MAX. In that case
     * we just return INT_MAX.
     */
    return pending < INT_MAX ? (int)pending : INT_MAX;
}

int SSL_has_pending(const SSL *s)
{
    /*
     * Similar to SSL_pending() but returns a 1 to indicate that we have
     * processed or unprocessed data available or 0 otherwise (as opposed to the
     * number of bytes available). Unlike SSL_pending() this will take into
     * account read_ahead data. A 1 return simply indicates that we have data.
     * That data may not result in any application data, or we may fail to parse
     * the records for some reason.
     */
    const SSL_CONNECTION *sc;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_has_pending(s);
#endif

    sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    /* Check buffered app data if any first */
    if (SSL_CONNECTION_IS_DTLS(sc)) {
        TLS_RECORD *rdata;
        pitem *item, *iter;

        iter = pqueue_iterator(sc->rlayer.d->buffered_app_data);
        while ((item = pqueue_next(&iter)) != NULL) {
            rdata = item->data;
            if (rdata->length > 0)
                return 1;
        }
    }

    if (RECORD_LAYER_processed_read_pending(&sc->rlayer))
        return 1;

    return RECORD_LAYER_read_pending(&sc->rlayer);
}

X509 *SSL_get1_peer_certificate(const SSL *s)
{
    X509 *r = SSL_get0_peer_certificate(s);

    if (r != NULL && !X509_up_ref(r))
        return NULL;

    return r;
}

X509 *SSL_get0_peer_certificate(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    if (sc->session == NULL)
        return NULL;
    else
        return sc->session->peer;
}

STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
{
    STACK_OF(X509) *r;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    if (sc->session == NULL)
        r = NULL;
    else
        r = sc->session->peer_chain;

    /*
     * If we are a client, cert_chain includes the peer's own certificate; if
     * we are a server, it does not.
     */

    return r;
}

/*
 * Now in theory, since the calling process own 't' it should be safe to
 * modify.  We need to be able to read f without being hassled
 */
int SSL_copy_session_id(SSL *t, const SSL *f)
{
    int i;
    /* TODO(QUIC FUTURE): Not allowed for QUIC currently. */
    SSL_CONNECTION *tsc = SSL_CONNECTION_FROM_SSL_ONLY(t);
    const SSL_CONNECTION *fsc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(f);

    if (tsc == NULL || fsc == NULL)
        return 0;

    /* Do we need to do SSL locking? */
    if (!SSL_set_session(t, SSL_get_session(f))) {
        return 0;
    }

    /*
     * what if we are setup for one protocol version but want to talk another
     */
    if (t->method != f->method) {
        t->method->ssl_deinit(t);
        t->method = f->method;
        if (t->method->ssl_init(t) == 0)
            return 0;
    }

    CRYPTO_UP_REF(&fsc->cert->references, &i);
    ssl_cert_free(tsc->cert);
    tsc->cert = fsc->cert;
    if (!SSL_set_session_id_context(t, fsc->sid_ctx, (int)fsc->sid_ctx_length)) {
        return 0;
    }

    return 1;
}

/* Fix this so it checks all the valid key/cert options */
int SSL_CTX_check_private_key(const SSL_CTX *ctx)
{
    if ((ctx == NULL) || (ctx->cert->key->x509 == NULL)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
        return 0;
    }
    if (ctx->cert->key->privatekey == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
        return 0;
    }
    return X509_check_private_key(ctx->cert->key->x509, ctx->cert->key->privatekey);
}

/* Fix this function so that it takes an optional type parameter */
int SSL_check_private_key(const SSL *ssl)
{
    const SSL_CONNECTION *sc;

    if ((sc = SSL_CONNECTION_FROM_CONST_SSL(ssl)) == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    if (sc->cert->key->x509 == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
        return 0;
    }
    if (sc->cert->key->privatekey == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
        return 0;
    }
    return X509_check_private_key(sc->cert->key->x509,
        sc->cert->key->privatekey);
}

int SSL_waiting_for_async(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->job)
        return 1;

    return 0;
}

int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds)
{
    ASYNC_WAIT_CTX *ctx;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if ((ctx = sc->waitctx) == NULL)
        return 0;
    return ASYNC_WAIT_CTX_get_all_fds(ctx, fds, numfds);
}

int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, size_t *numaddfds,
    OSSL_ASYNC_FD *delfd, size_t *numdelfds)
{
    ASYNC_WAIT_CTX *ctx;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if ((ctx = sc->waitctx) == NULL)
        return 0;
    return ASYNC_WAIT_CTX_get_changed_fds(ctx, addfd, numaddfds, delfd,
        numdelfds);
}

int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback)
{
    ctx->async_cb = callback;
    return 1;
}

int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg)
{
    ctx->async_cb_arg = arg;
    return 1;
}

int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    sc->async_cb = callback;
    return 1;
}

int SSL_set_async_callback_arg(SSL *s, void *arg)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    sc->async_cb_arg = arg;
    return 1;
}

int SSL_get_async_status(SSL *s, int *status)
{
    ASYNC_WAIT_CTX *ctx;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if ((ctx = sc->waitctx) == NULL)
        return 0;
    *status = ASYNC_WAIT_CTX_get_status(ctx);
    return 1;
}

/*
 * Reset the statem error_state to ERROR_STATE_NOERROR to avoid the
 * error sticking.
 * Designed to be called at the beginning of any function that
 * is expected to be followed by a call to SSL_get_error().
 * It returns 0 if the state machine is in the MSG_FLOW_ERROR state,
 * in this case the calling function can and should return immediately.
 */
static int ssl_reset_error_state(SSL_CONNECTION *sc)
{
    if (sc == NULL)
        return 1;

    if (sc->statem.state == MSG_FLOW_ERROR) {
        sc->statem.error_state = ERROR_STATE_SSL;
        return 0;
    }

    sc->statem.error_state = ERROR_STATE_NOERROR;
    return 1;
}

/*
 * Check if the connection failed into the MSG_FLOW_ERROR state during
 * the operation, if so, check the error stack and set the error_state
 * correspondently.
 * Designed to be called at the end of any function that
 * is expected to be followed by a call to SSL_get_error().
 */
static void ssl_update_error_state(SSL_CONNECTION *sc)
{
    unsigned long l;

    if (sc == NULL)
        return;

    if (sc->statem.state == MSG_FLOW_ERROR
        && sc->statem.error_state == ERROR_STATE_NOERROR) {
        l = ERR_peek_error();
        if (l == 0 || ERR_GET_LIB(l) == ERR_LIB_SYS)
            sc->statem.error_state = ERROR_STATE_SYSCALL;
        else
            sc->statem.error_state = ERROR_STATE_SSL;
    }
}

int SSL_accept(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        return s->method->ssl_accept(s);
    }
#endif

    if (sc == NULL)
        return 0;

    if (sc->handshake_func == NULL) {
        /* Not properly initialized yet */
        SSL_set_accept_state(s);
    }

    return SSL_do_handshake(s);
}

int SSL_connect(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        return s->method->ssl_connect(s);
    }
#endif

    if (sc == NULL)
        return 0;

    if (sc->handshake_func == NULL) {
        /* Not properly initialized yet */
        SSL_set_connect_state(s);
    }

    return SSL_do_handshake(s);
}

long SSL_get_default_timeout(const SSL *s)
{
    return (long int)ossl_time2seconds(s->method->get_timeout());
}

static int ssl_async_wait_ctx_cb(void *arg)
{
    SSL *s = (SSL *)arg;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->async_cb(s, sc->async_cb_arg);
}

static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
    int (*func)(void *))
{
    int ret;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->waitctx == NULL) {
        sc->waitctx = ASYNC_WAIT_CTX_new();
        if (sc->waitctx == NULL)
            return -1;
        if (sc->async_cb != NULL
            && !ASYNC_WAIT_CTX_set_callback(sc->waitctx, ssl_async_wait_ctx_cb, s))
            return -1;
    }

    sc->rwstate = SSL_NOTHING;
    switch (ASYNC_start_job(&sc->job, sc->waitctx, &ret, func, args,
        sizeof(struct ssl_async_args))) {
    case ASYNC_ERR:
        sc->rwstate = SSL_NOTHING;
        ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    case ASYNC_PAUSE:
        sc->rwstate = SSL_ASYNC_PAUSED;
        return -1;
    case ASYNC_NO_JOBS:
        sc->rwstate = SSL_ASYNC_NO_JOBS;
        return -1;
    case ASYNC_FINISH:
        sc->job = NULL;
        return ret;
    default:
        sc->rwstate = SSL_NOTHING;
        ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
        sc->statem.error_state = ERROR_STATE_SSL;
        /* Shouldn't happen */
        return -1;
    }
}

static int ssl_io_intern(void *vargs)
{
    struct ssl_async_args *args;
    SSL *s;
    void *buf;
    size_t num;
    SSL_CONNECTION *sc;

    args = (struct ssl_async_args *)vargs;
    s = args->s;
    buf = args->buf;
    num = args->num;
    if ((sc = SSL_CONNECTION_FROM_SSL(s)) == NULL)
        return -1;

    switch (args->type) {
    case READFUNC:
        return args->f.func_read(s, buf, num, &sc->asyncrw);
    case WRITEFUNC:
        return args->f.func_write(s, buf, num, &sc->asyncrw);
    case OTHERFUNC:
        return args->f.func_other(s);
    }
    return -1;
}

int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
    int ret;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return s->method->ssl_read(s, buf, num, readbytes);
#endif

    if (sc == NULL)
        return -1;

    if (ssl_reset_error_state(sc) == 0)
        return -1;

    if (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (sc->shutdown & SSL_RECEIVED_SHUTDOWN) {
        sc->rwstate = SSL_NOTHING;
        return 0;
    }

    if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
        || sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return 0;
    }
    /*
     * If we are a client and haven't received the ServerHello etc then we
     * better do that
     */
    if (!ossl_statem_check_finish_init(sc, 0))
        return -1;

    if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
        struct ssl_async_args args;

        args.s = s;
        args.buf = buf;
        args.num = num;
        args.type = READFUNC;
        args.f.func_read = s->method->ssl_read;

        ret = ssl_start_async_job(s, &args, ssl_io_intern);
        *readbytes = sc->asyncrw;
        ssl_update_error_state(sc);
        return ret;
    } else {
        ret = s->method->ssl_read(s, buf, num, readbytes);
        ssl_update_error_state(sc);
        return ret;
    }
}

int SSL_read(SSL *s, void *buf, int num)
{
    int ret;
    size_t readbytes;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (num < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        if (sc != NULL)
            sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    ret = ssl_read_internal(s, buf, (size_t)num, &readbytes);

    /*
     * The cast is safe here because ret should be <= INT_MAX because num is
     * <= INT_MAX
     */
    if (ret > 0)
        ret = (int)readbytes;

    return ret;
}

int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
{
    int ret;

    ret = ssl_read_internal(s, buf, num, readbytes);
    if (ret < 0)
        ret = 0;

    return ret;
}

int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes)
{
    int ret;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    /* TODO(QUIC 0RTT): 0-RTT support */
    if (sc == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return SSL_READ_EARLY_DATA_ERROR;
    }

    if (ssl_reset_error_state(sc) == 0)
        return 0;

    if (!sc->server) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return SSL_READ_EARLY_DATA_ERROR;
    }

    switch (sc->early_data_state) {
    case SSL_EARLY_DATA_NONE:
        if (!SSL_in_before(s)) {
            ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
            sc->statem.error_state = ERROR_STATE_SSL;
            return SSL_READ_EARLY_DATA_ERROR;
        }
        /* fall through */

    case SSL_EARLY_DATA_ACCEPT_RETRY:
        sc->early_data_state = SSL_EARLY_DATA_ACCEPTING;
        ret = SSL_accept(s);
        if (ret <= 0) {
            /* NBIO or error */
            sc->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY;
            return SSL_READ_EARLY_DATA_ERROR;
        }
        /* fall through */

    case SSL_EARLY_DATA_READ_RETRY:
        if (sc->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
            sc->early_data_state = SSL_EARLY_DATA_READING;
            ret = SSL_read_ex(s, buf, num, readbytes);
            /*
             * State machine will update early_data_state to
             * SSL_EARLY_DATA_FINISHED_READING if we get an EndOfEarlyData
             * message
             */
            if (ret > 0 || (ret <= 0 && sc->early_data_state != SSL_EARLY_DATA_FINISHED_READING)) {
                sc->early_data_state = SSL_EARLY_DATA_READ_RETRY;
                return ret > 0 ? SSL_READ_EARLY_DATA_SUCCESS
                               : SSL_READ_EARLY_DATA_ERROR;
            }
        } else {
            sc->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
        }
        *readbytes = 0;
        return SSL_READ_EARLY_DATA_FINISH;

    default:
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return SSL_READ_EARLY_DATA_ERROR;
    }
}

int SSL_get_early_data_status(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);

    /* TODO(QUIC 0RTT): 0-RTT support */
    if (sc == NULL)
        return 0;

    return sc->ext.early_data;
}

static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
    int ret;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return s->method->ssl_peek(s, buf, num, readbytes);
#endif

    if (sc == NULL)
        return 0;

    if (ssl_reset_error_state(sc) == 0)
        return -1;

    if (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (sc->shutdown & SSL_RECEIVED_SHUTDOWN) {
        return 0;
    }
    if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
        struct ssl_async_args args;

        args.s = s;
        args.buf = buf;
        args.num = num;
        args.type = READFUNC;
        args.f.func_read = s->method->ssl_peek;

        ret = ssl_start_async_job(s, &args, ssl_io_intern);
        *readbytes = sc->asyncrw;
        ssl_update_error_state(sc);
        return ret;
    } else {
        ret = s->method->ssl_peek(s, buf, num, readbytes);
        ssl_update_error_state(sc);
        return ret;
    }
}

int SSL_peek(SSL *s, void *buf, int num)
{
    int ret;
    size_t readbytes;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (num < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        if (sc != NULL)
            sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    ret = ssl_peek_internal(s, buf, (size_t)num, &readbytes);

    /*
     * The cast is safe here because ret should be <= INT_MAX because num is
     * <= INT_MAX
     */
    if (ret > 0)
        ret = (int)readbytes;

    return ret;
}

int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
{
    int ret;

    ret = ssl_peek_internal(s, buf, num, readbytes);
    if (ret < 0)
        ret = 0;

    return ret;
}

int ssl_write_internal(SSL *s, const void *buf, size_t num,
    uint64_t flags, size_t *written)
{
    int ret;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_write_flags(s, buf, num, flags, written);
#endif

    if (sc == NULL)
        return 0;

    if (ssl_reset_error_state(sc) == 0)
        return -1;

    if (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (sc->shutdown & SSL_SENT_SHUTDOWN) {
        sc->rwstate = SSL_NOTHING;
        ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (flags != 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_WRITE_FLAG);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
        || sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY
        || sc->early_data_state == SSL_EARLY_DATA_READ_RETRY) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return 0;
    }
    /* If we are a client and haven't sent the Finished we better do that */
    if (!ossl_statem_check_finish_init(sc, 1))
        return -1;

    if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
        struct ssl_async_args args;

        args.s = s;
        args.buf = (void *)buf;
        args.num = num;
        args.type = WRITEFUNC;
        args.f.func_write = s->method->ssl_write;

        ret = ssl_start_async_job(s, &args, ssl_io_intern);
        *written = sc->asyncrw;
        ssl_update_error_state(sc);
        return ret;
    } else {
        ret = s->method->ssl_write(s, buf, num, written);
        ssl_update_error_state(sc);
        return ret;
    }
}

ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
#ifndef OPENSSL_NO_KTLS
    ossl_ssize_t sbytes;
#endif
    int ret;

    if (sc == NULL)
        return 0;

    if (ssl_reset_error_state(sc) == 0)
        return -1;

    if (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (sc->shutdown & SSL_SENT_SHUTDOWN) {
        sc->rwstate = SSL_NOTHING;
        ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (!BIO_get_ktls_send(sc->wbio)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    /* If we have an alert to send, lets send it */
    if (sc->s3.alert_dispatch > 0) {
        ret = (ossl_ssize_t)s->method->ssl_dispatch_alert(s);
        ssl_update_error_state(sc);
        if (ret <= 0) {
            /* SSLfatal() already called if appropriate */
            return ret;
        }
        /* if it went, fall through and send more stuff */
    }

    sc->rwstate = SSL_WRITING;
    if (BIO_flush(sc->wbio) <= 0) {
        if (!BIO_should_retry(sc->wbio)) {
            sc->rwstate = SSL_NOTHING;
        } else {
#ifdef EAGAIN
            set_sys_error(EAGAIN);
#endif
        }
        return -1;
    }

#ifdef OPENSSL_NO_KTLS
    ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR,
        "can't call ktls_sendfile(), ktls disabled");
    sc->statem.error_state = ERROR_STATE_SSL;
    return -1;
#else
    ret = ktls_sendfile(SSL_get_wfd(s), fd, offset, size, &sbytes, flags);
    ssl_update_error_state(sc);
    BIO_clear_retry_flags(sc->wbio);
    if (ret < 0) {
        if (BIO_sock_should_retry(ret)) {
            BIO_set_retry_write(sc->wbio);
            return (sbytes > 0 ? sbytes : ret);
        } else {
            ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
                "ktls_sendfile failure");
            sc->statem.error_state = ERROR_STATE_SYSCALL;
        }
        return ret;
    }
    sc->rwstate = SSL_NOTHING;
    return sbytes;
#endif
}

int SSL_write(SSL *s, const void *buf, int num)
{
    int ret;
    size_t written;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (num < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        if (sc != NULL)
            sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    ret = ssl_write_internal(s, buf, (size_t)num, 0, &written);

    /*
     * The cast is safe here because ret should be <= INT_MAX because num is
     * <= INT_MAX
     */
    if (ret > 0)
        ret = (int)written;

    return ret;
}

int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written)
{
    return SSL_write_ex2(s, buf, num, 0, written);
}

int SSL_write_ex2(SSL *s, const void *buf, size_t num, uint64_t flags,
    size_t *written)
{
    int ret;

    ret = ssl_write_internal(s, buf, num, flags, written);
    if (ret < 0)
        ret = 0;

    return ret;
}

int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written)
{
    int ret, early_data_state;
    size_t writtmp;
    uint32_t partialwrite;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    /* TODO(QUIC 0RTT): This will need special handling for QUIC */
    if (sc == NULL)
        return 0;

    if (ssl_reset_error_state(sc) == 0)
        return 0;

    switch (sc->early_data_state) {
    case SSL_EARLY_DATA_NONE:
        if (sc->server
            || !SSL_in_before(s)
            || ((sc->session == NULL || sc->session->ext.max_early_data == 0)
                && (sc->psk_use_session_cb == NULL))) {
            ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
            sc->statem.error_state = ERROR_STATE_SSL;
            return 0;
        }
        /* fall through */

    case SSL_EARLY_DATA_CONNECT_RETRY:
        sc->early_data_state = SSL_EARLY_DATA_CONNECTING;
        ret = SSL_connect(s);
        if (ret <= 0) {
            /* NBIO or error */
            sc->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY;
            return 0;
        }
        /* fall through */

    case SSL_EARLY_DATA_WRITE_RETRY:
        sc->early_data_state = SSL_EARLY_DATA_WRITING;
        /*
         * We disable partial write for early data because we don't keep track
         * of how many bytes we've written between the SSL_write_ex() call and
         * the flush if the flush needs to be retried)
         */
        partialwrite = sc->mode & SSL_MODE_ENABLE_PARTIAL_WRITE;
        sc->mode &= ~SSL_MODE_ENABLE_PARTIAL_WRITE;
        ret = SSL_write_ex(s, buf, num, &writtmp);
        sc->mode |= partialwrite;
        if (!ret) {
            sc->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
            return ret;
        }
        sc->early_data_state = SSL_EARLY_DATA_WRITE_FLUSH;
        /* fall through */

    case SSL_EARLY_DATA_WRITE_FLUSH:
        /* The buffering BIO is still in place so we need to flush it */
        if (statem_flush(sc) != 1)
            return 0;
        *written = num;
        sc->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
        return 1;

    case SSL_EARLY_DATA_FINISHED_READING:
    case SSL_EARLY_DATA_READ_RETRY:
        early_data_state = sc->early_data_state;
        /* We are a server writing to an unauthenticated client */
        sc->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING;
        ret = SSL_write_ex(s, buf, num, written);
        /* The buffering BIO is still in place */
        if (ret)
            (void)BIO_flush(sc->wbio);
        sc->early_data_state = early_data_state;
        return ret;

    default:
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return 0;
    }
}

int SSL_shutdown(SSL *s)
{
    /*
     * Note that this function behaves differently from what one might
     * expect.  Return values are 0 for no success (yet), 1 for success; but
     * calling it once is usually not enough, even if blocking I/O is used
     * (see ssl3_shutdown).
     */
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
    int ret;

    if (ssl_reset_error_state(sc) == 0)
        return -1;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_conn_shutdown(s, 0, NULL, 0);
#endif

    if (sc == NULL)
        return -1;

    if (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (!SSL_in_init(s)) {
        if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
            struct ssl_async_args args;

            memset(&args, 0, sizeof(args));
            args.s = s;
            args.type = OTHERFUNC;
            args.f.func_other = s->method->ssl_shutdown;

            ret = ssl_start_async_job(s, &args, ssl_io_intern);
        } else {
            ret = s->method->ssl_shutdown(s);
        }
    } else {
        ERR_raise(ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    ssl_update_error_state(sc);
    return ret;
}

int SSL_key_update(SSL *s, int updatetype)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_key_update(s, updatetype);
#endif

    if (sc == NULL)
        return 0;

    if (!SSL_CONNECTION_IS_TLS13(sc)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
        return 0;
    }

    if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
        && updatetype != SSL_KEY_UPDATE_REQUESTED) {
        ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE);
        return 0;
    }

    if (!SSL_is_init_finished(s)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_STILL_IN_INIT);
        return 0;
    }

    if (RECORD_LAYER_write_pending(&sc->rlayer)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY);
        return 0;
    }

    ossl_statem_set_in_init(sc, 1);
    sc->key_update = updatetype;
    return 1;
}

int SSL_get_key_update_type(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_get_key_update_type(s);
#endif

    if (sc == NULL)
        return 0;

    return sc->key_update;
}

/*
 * Can we accept a renegotiation request?  If yes, set the flag and
 * return 1 if yes. If not, raise error and return 0.
 */
static int can_renegotiate(const SSL_CONNECTION *sc)
{
    if (SSL_CONNECTION_IS_TLS13(sc)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
        return 0;
    }

    if ((sc->options & SSL_OP_NO_RENEGOTIATION) != 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION);
        return 0;
    }

    return 1;
}

int SSL_renegotiate(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    if (!can_renegotiate(sc))
        return 0;

    sc->renegotiate = 1;
    sc->new_session = 1;
    return s->method->ssl_renegotiate(s);
}

int SSL_renegotiate_abbreviated(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    if (!can_renegotiate(sc))
        return 0;

    sc->renegotiate = 1;
    sc->new_session = 0;
    return s->method->ssl_renegotiate(s);
}

int SSL_renegotiate_pending(const SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    /*
     * becomes true when negotiation is requested; false again once a
     * handshake has finished
     */
    return (sc->renegotiate != 0);
}

int SSL_new_session_ticket(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    /* If we are in init because we're sending tickets, okay to send more. */
    if ((SSL_in_init(s) && sc->ext.extra_tickets_expected == 0)
        || SSL_IS_FIRST_HANDSHAKE(sc) || !sc->server
        || !SSL_CONNECTION_IS_TLS13(sc))
        return 0;
    sc->ext.extra_tickets_expected++;
    if (!RECORD_LAYER_write_pending(&sc->rlayer) && !SSL_in_init(s))
        ossl_statem_set_in_init(sc, 1);
    return 1;
}

long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
{
    return ossl_ctrl_internal(s, cmd, larg, parg, /*no_quic=*/0);
}

long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic)
{
    long l;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    /*
     * Routing of ctrl calls for QUIC is a little counterintuitive:
     *
     *   - Firstly (no_quic=0), we pass the ctrl directly to our QUIC
     *     implementation in case it wants to handle the ctrl specially.
     *
     *   - If our QUIC implementation does not care about the ctrl, it
     *     will reenter this function with no_quic=1 and we will try to handle
     *     it directly using the QCSO SSL object stub (not the handshake layer
     *     SSL object). This is important for e.g. the version configuration
     *     ctrls below, which must use s->defltmeth (and not sc->defltmeth).
     *
     *   - If we don't handle a ctrl here specially, then processing is
     *     redirected to the handshake layer SSL object.
     */
    if (!no_quic && IS_QUIC(s))
        return s->method->ssl_ctrl(s, cmd, larg, parg);

    if (sc == NULL)
        return 0;

    switch (cmd) {
    case SSL_CTRL_GET_READ_AHEAD:
        return RECORD_LAYER_get_read_ahead(&sc->rlayer);
    case SSL_CTRL_SET_READ_AHEAD:
        l = RECORD_LAYER_get_read_ahead(&sc->rlayer);
        RECORD_LAYER_set_read_ahead(&sc->rlayer, larg);
        return l;

    case SSL_CTRL_MODE: {
        OSSL_PARAM options[2], *opts = options;

        sc->mode |= larg;

        *opts++ = OSSL_PARAM_construct_uint32(OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE,
            &sc->mode);
        *opts = OSSL_PARAM_construct_end();

        /* Ignore return value */
        sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options);

        return sc->mode;
    }
    case SSL_CTRL_CLEAR_MODE:
        return (sc->mode &= ~larg);
    case SSL_CTRL_GET_MAX_CERT_LIST:
        return (long)sc->max_cert_list;
    case SSL_CTRL_SET_MAX_CERT_LIST:
        if (larg < 0)
            return 0;
        l = (long)sc->max_cert_list;
        sc->max_cert_list = (size_t)larg;
        return l;
    case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
        if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
            return 0;
#ifndef OPENSSL_NO_KTLS
        if (sc->wbio != NULL && BIO_get_ktls_send(sc->wbio))
            return 0;
#endif /* OPENSSL_NO_KTLS */
        sc->max_send_fragment = larg;
        if (sc->max_send_fragment < sc->split_send_fragment)
            sc->split_send_fragment = sc->max_send_fragment;
        sc->rlayer.wrlmethod->set_max_frag_len(sc->rlayer.wrl, larg);
        return 1;
    case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
        if ((size_t)larg > sc->max_send_fragment || larg == 0)
            return 0;
        sc->split_send_fragment = larg;
        return 1;
    case SSL_CTRL_SET_MAX_PIPELINES:
        if (larg < 1 || larg > SSL_MAX_PIPELINES)
            return 0;
        sc->max_pipelines = larg;
        if (sc->rlayer.rrlmethod->set_max_pipelines != NULL)
            sc->rlayer.rrlmethod->set_max_pipelines(sc->rlayer.rrl, (size_t)larg);
        return 1;
    case SSL_CTRL_GET_RI_SUPPORT:
        return sc->s3.send_connection_binding;
    case SSL_CTRL_SET_RETRY_VERIFY:
        sc->rwstate = SSL_RETRY_VERIFY;
        return 1;
    case SSL_CTRL_CERT_FLAGS:
        return (sc->cert->cert_flags |= larg);
    case SSL_CTRL_CLEAR_CERT_FLAGS:
        return (sc->cert->cert_flags &= ~larg);

    case SSL_CTRL_GET_RAW_CIPHERLIST:
        if (parg) {
            if (sc->s3.tmp.ciphers_raw == NULL)
                return 0;
            *(unsigned char **)parg = sc->s3.tmp.ciphers_raw;
            return (int)sc->s3.tmp.ciphers_rawlen;
        } else {
            return TLS_CIPHER_LEN;
        }
    case SSL_CTRL_GET_EXTMS_SUPPORT:
        if (!sc->session || SSL_in_init(s) || ossl_statem_get_in_handshake(sc))
            return -1;
        if (sc->session->flags & SSL_SESS_FLAG_EXTMS)
            return 1;
        else
            return 0;
    case SSL_CTRL_SET_MIN_PROTO_VERSION:
        return ssl_check_allowed_versions(larg, sc->max_proto_version)
            && ssl_set_version_bound(s->defltmeth->version, (int)larg,
                &sc->min_proto_version);
    case SSL_CTRL_GET_MIN_PROTO_VERSION:
        return sc->min_proto_version;
    case SSL_CTRL_SET_MAX_PROTO_VERSION:
        return ssl_check_allowed_versions(sc->min_proto_version, larg)
            && ssl_set_version_bound(s->defltmeth->version, (int)larg,
                &sc->max_proto_version);
    case SSL_CTRL_GET_MAX_PROTO_VERSION:
        return sc->max_proto_version;
    default:
        if (IS_QUIC(s))
            return SSL_ctrl((SSL *)sc, cmd, larg, parg);
        else
            return s->method->ssl_ctrl(s, cmd, larg, parg);
    }
}

long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
{
    return s->method->ssl_callback_ctrl(s, cmd, fp);
}

LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
{
    return ctx->sessions;
}

static int ssl_tsan_load(SSL_CTX *ctx, TSAN_QUALIFIER int *stat)
{
    int res = 0;

    if (ssl_tsan_lock(ctx)) {
        res = tsan_load(stat);
        ssl_tsan_unlock(ctx);
    }
    return res;
}

long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
{
    long l;

    /* For some cases with ctx == NULL or larg == 1 perform syntax checks */
    if (cmd == SSL_CTRL_SET_GROUPS_LIST && larg == 1)
        return tls1_set_groups_list(ctx, NULL, NULL, NULL, NULL, NULL, NULL, parg);
    if (ctx == NULL) {
        switch (cmd) {
        case SSL_CTRL_SET_SIGALGS_LIST:
        case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
            return tls1_set_sigalgs_list(ctx, NULL, parg, 0);
        default:
            return 0;
        }
    }

    switch (cmd) {
    case SSL_CTRL_GET_READ_AHEAD:
        return ctx->read_ahead;
    case SSL_CTRL_SET_READ_AHEAD:
        l = ctx->read_ahead;
        ctx->read_ahead = larg;
        return l;

    case SSL_CTRL_SET_MSG_CALLBACK_ARG:
        ctx->msg_callback_arg = parg;
        return 1;

    case SSL_CTRL_GET_MAX_CERT_LIST:
        return (long)ctx->max_cert_list;
    case SSL_CTRL_SET_MAX_CERT_LIST:
        if (larg < 0)
            return 0;
        l = (long)ctx->max_cert_list;
        ctx->max_cert_list = (size_t)larg;
        return l;

    case SSL_CTRL_SET_SESS_CACHE_SIZE:
        if (larg < 0)
            return 0;
        l = (long)ctx->session_cache_size;
        ctx->session_cache_size = (size_t)larg;
        return l;
    case SSL_CTRL_GET_SESS_CACHE_SIZE:
        return (long)ctx->session_cache_size;
    case SSL_CTRL_SET_SESS_CACHE_MODE:
        l = ctx->session_cache_mode;
        ctx->session_cache_mode = larg;
        return l;
    case SSL_CTRL_GET_SESS_CACHE_MODE:
        return ctx->session_cache_mode;

    case SSL_CTRL_SESS_NUMBER:
        return lh_SSL_SESSION_num_items(ctx->sessions);
    case SSL_CTRL_SESS_CONNECT:
        return ssl_tsan_load(ctx, &ctx->stats.sess_connect);
    case SSL_CTRL_SESS_CONNECT_GOOD:
        return ssl_tsan_load(ctx, &ctx->stats.sess_connect_good);
    case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
        return ssl_tsan_load(ctx, &ctx->stats.sess_connect_renegotiate);
    case SSL_CTRL_SESS_ACCEPT:
        return ssl_tsan_load(ctx, &ctx->stats.sess_accept);
    case SSL_CTRL_SESS_ACCEPT_GOOD:
        return ssl_tsan_load(ctx, &ctx->stats.sess_accept_good);
    case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
        return ssl_tsan_load(ctx, &ctx->stats.sess_accept_renegotiate);
    case SSL_CTRL_SESS_HIT:
        return ssl_tsan_load(ctx, &ctx->stats.sess_hit);
    case SSL_CTRL_SESS_CB_HIT:
        return ssl_tsan_load(ctx, &ctx->stats.sess_cb_hit);
    case SSL_CTRL_SESS_MISSES:
        return ssl_tsan_load(ctx, &ctx->stats.sess_miss);
    case SSL_CTRL_SESS_TIMEOUTS:
        return ssl_tsan_load(ctx, &ctx->stats.sess_timeout);
    case SSL_CTRL_SESS_CACHE_FULL:
        return ssl_tsan_load(ctx, &ctx->stats.sess_cache_full);
    case SSL_CTRL_MODE:
        return (ctx->mode |= larg);
    case SSL_CTRL_CLEAR_MODE:
        return (ctx->mode &= ~larg);
    case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
        if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
            return 0;
        ctx->max_send_fragment = larg;
        if (ctx->max_send_fragment < ctx->split_send_fragment)
            ctx->split_send_fragment = ctx->max_send_fragment;
        return 1;
    case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
        if ((size_t)larg > ctx->max_send_fragment || larg == 0)
            return 0;
        ctx->split_send_fragment = larg;
        return 1;
    case SSL_CTRL_SET_MAX_PIPELINES:
        if (larg < 1 || larg > SSL_MAX_PIPELINES)
            return 0;
        ctx->max_pipelines = larg;
        return 1;
    case SSL_CTRL_CERT_FLAGS:
        return (ctx->cert->cert_flags |= larg);
    case SSL_CTRL_CLEAR_CERT_FLAGS:
        return (ctx->cert->cert_flags &= ~larg);
    case SSL_CTRL_SET_MIN_PROTO_VERSION:
        return ssl_check_allowed_versions(larg, ctx->max_proto_version)
            && ssl_set_version_bound(ctx->method->version, (int)larg,
                &ctx->min_proto_version);
    case SSL_CTRL_GET_MIN_PROTO_VERSION:
        return ctx->min_proto_version;
    case SSL_CTRL_SET_MAX_PROTO_VERSION:
        return ssl_check_allowed_versions(ctx->min_proto_version, larg)
            && ssl_set_version_bound(ctx->method->version, (int)larg,
                &ctx->max_proto_version);
    case SSL_CTRL_GET_MAX_PROTO_VERSION:
        return ctx->max_proto_version;
    default:
        return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
    }
}

long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
{
    switch (cmd) {
    case SSL_CTRL_SET_MSG_CALLBACK:
        ctx->msg_callback = (void (*)(int write_p, int version, int content_type,
            const void *buf, size_t len, SSL *ssl,
            void *arg))(fp);
        return 1;

    default:
        return ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp);
    }
}

int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
{
    if (a->id > b->id)
        return 1;
    if (a->id < b->id)
        return -1;
    return 0;
}

int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
    const SSL_CIPHER *const *bp)
{
    if ((*ap)->id > (*bp)->id)
        return 1;
    if ((*ap)->id < (*bp)->id)
        return -1;
    return 0;
}

/*
 * return a STACK of the ciphers available for the SSL and in order of
 * preference
 */
STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc != NULL) {
        if (sc->cipher_list != NULL) {
            return sc->cipher_list;
        } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) {
            return s->ctx->cipher_list;
        }
    }
    return NULL;
}

STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL || !sc->server)
        return NULL;
    return sc->peer_ciphers;
}

STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
{
    STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
    int i;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    ciphers = SSL_get_ciphers(s);
    if (!ciphers)
        return NULL;
    if (!ssl_set_client_disabled(sc))
        return NULL;
    for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
        const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
        if (!ssl_cipher_disabled(sc, c, SSL_SECOP_CIPHER_SUPPORTED)) {
            if (!sk)
                sk = sk_SSL_CIPHER_new_null();
            if (!sk)
                return NULL;
            if (!sk_SSL_CIPHER_push(sk, c)) {
                sk_SSL_CIPHER_free(sk);
                return NULL;
            }
        }
    }
    return sk;
}

/** return a STACK of the ciphers available for the SSL and in order of
 * algorithm id */
STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL_CONNECTION *s)
{
    if (s != NULL) {
        if (s->cipher_list_by_id != NULL)
            return s->cipher_list_by_id;
        else if (s->ssl.ctx != NULL
            && s->ssl.ctx->cipher_list_by_id != NULL)
            return s->ssl.ctx->cipher_list_by_id;
    }
    return NULL;
}

/** The old interface to get the same thing as SSL_get_ciphers() */
const char *SSL_get_cipher_list(const SSL *s, int n)
{
    const SSL_CIPHER *c;
    STACK_OF(SSL_CIPHER) *sk;

    if (s == NULL)
        return NULL;
    sk = SSL_get_ciphers(s);
    if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n))
        return NULL;
    c = sk_SSL_CIPHER_value(sk, n);
    if (c == NULL)
        return NULL;
    return c->name;
}

/** return a STACK of the ciphers available for the SSL_CTX and in order of
 * preference */
STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx)
{
    if (ctx != NULL)
        return ctx->cipher_list;
    return NULL;
}

/*
 * Distinguish between ciphers controlled by set_ciphersuite() and
 * set_cipher_list() when counting.
 */
static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk)
{
    int i, num = 0;
    const SSL_CIPHER *c;

    if (sk == NULL)
        return 0;
    for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) {
        c = sk_SSL_CIPHER_value(sk, i);
        if (c->min_tls >= TLS1_3_VERSION)
            continue;
        num++;
    }
    return num;
}

/** specify the ciphers to be used by default by the SSL_CTX */
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
{
    STACK_OF(SSL_CIPHER) *sk;

    sk = ssl_create_cipher_list(ctx, ctx->tls13_ciphersuites,
        &ctx->cipher_list, &ctx->cipher_list_by_id, str,
        ctx->cert);
    /*
     * ssl_create_cipher_list may return an empty stack if it was unable to
     * find a cipher matching the given rule string (for example if the rule
     * string specifies a cipher which has been disabled). This is not an
     * error as far as ssl_create_cipher_list is concerned, and hence
     * ctx->cipher_list and ctx->cipher_list_by_id has been updated.
     */
    if (sk == NULL)
        return 0;
    if (ctx->method->num_ciphers() > 0 && cipher_list_tls12_num(sk) == 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH);
        return 0;
    }
    return 1;
}

/** specify the ciphers to be used by the SSL */
int SSL_set_cipher_list(SSL *s, const char *str)
{
    STACK_OF(SSL_CIPHER) *sk;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
    SSL_CTX *ctx;

    if (sc == NULL)
        return 0;

    ctx = s->ctx;
    sk = ssl_create_cipher_list(ctx, sc->tls13_ciphersuites,
        &sc->cipher_list, &sc->cipher_list_by_id, str,
        sc->cert);
    /* see comment in SSL_CTX_set_cipher_list */
    if (sk == NULL)
        return 0;
    if (ctx->method->num_ciphers() > 0 && cipher_list_tls12_num(sk) == 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH);
        return 0;
    }
    return 1;
}

char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
{
    char *p;
    STACK_OF(SSL_CIPHER) *clntsk, *srvrsk;
    const SSL_CIPHER *c;
    int i;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (size < 2 || buf == NULL)
        return NULL;

    buf[0] = '\0';

    if (sc == NULL || !sc->server)
        return NULL;

    p = buf;
    clntsk = sc->peer_ciphers;
    srvrsk = SSL_get_ciphers(s);

    if (clntsk == NULL || sk_SSL_CIPHER_num(clntsk) == 0
        || srvrsk == NULL || sk_SSL_CIPHER_num(srvrsk) == 0)
        return buf;

    for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) {
        int n;

        c = sk_SSL_CIPHER_value(clntsk, i);
        if (sk_SSL_CIPHER_find(srvrsk, c) < 0)
            continue;

        n = (int)OPENSSL_strnlen(c->name, size);
        if (n >= size)
            break;

        memcpy(p, c->name, n);
        p += n;
        *(p++) = ':';
        size -= n + 1;
    }

    /* No overlap */
    if (p != buf)
        p[-1] = '\0';

    return buf;
}

/**
 * Return the requested servername (SNI) value. Note that the behaviour varies
 * depending on:
 * - whether this is called by the client or the server,
 * - if we are before or during/after the handshake,
 * - if a resumption or normal handshake is being attempted/has occurred
 * - whether we have negotiated TLSv1.2 (or below) or TLSv1.3
 *
 * Note that only the host_name type is defined (RFC 3546).
 */
const char *SSL_get_servername(const SSL *s, int type)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
    int server;

    if (sc == NULL)
        return NULL;

    /*
     * If we don't know if we are the client or the server yet then we assume
     * client.
     */
    server = sc->handshake_func == NULL ? 0 : sc->server;

    if (type != TLSEXT_NAMETYPE_host_name)
        return NULL;

    if (server) {
        /**
         * Server side
         * In TLSv1.3 on the server SNI is not associated with the session
         * but in TLSv1.2 or below it is.
         *
         * Before the handshake:
         *  - return NULL
         *
         * During/after the handshake (TLSv1.2 or below resumption occurred):
         * - If a servername was accepted by the server in the original
         *   handshake then it will return that servername, or NULL otherwise.
         *
         * During/after the handshake (TLSv1.2 or below resumption did not occur):
         * - The function will return the servername requested by the client in
         *   this handshake or NULL if none was requested.
         */
        if (sc->hit && !SSL_CONNECTION_IS_TLS13(sc))
            return sc->session->ext.hostname;
    } else {
        /**
         * Client side
         *
         * Before the handshake:
         *  - If a servername has been set via a call to
         *    SSL_set_tlsext_host_name() then it will return that servername
         *  - If one has not been set, but a TLSv1.2 resumption is being
         *    attempted and the session from the original handshake had a
         *    servername accepted by the server then it will return that
         *    servername
         *  - Otherwise it returns NULL
         *
         * During/after the handshake (TLSv1.2 or below resumption occurred):
         * - If the session from the original handshake had a servername accepted
         *   by the server then it will return that servername.
         * - Otherwise it returns the servername set via
         *   SSL_set_tlsext_host_name() (or NULL if it was not called).
         *
         * During/after the handshake (TLSv1.2 or below resumption did not occur):
         * - It will return the servername set via SSL_set_tlsext_host_name()
         *   (or NULL if it was not called).
         */
        if (SSL_in_before(s)) {
            if (sc->ext.hostname == NULL
                && sc->session != NULL
                && sc->session->ssl_version != TLS1_3_VERSION)
                return sc->session->ext.hostname;
        } else {
            if (!SSL_CONNECTION_IS_TLS13(sc) && sc->hit
                && sc->session->ext.hostname != NULL)
                return sc->session->ext.hostname;
        }
    }

    return sc->ext.hostname;
}

int SSL_get_servername_type(const SSL *s)
{
    if (SSL_get_servername(s, TLSEXT_NAMETYPE_host_name) != NULL)
        return TLSEXT_NAMETYPE_host_name;
    return -1;
}

/*
 * SSL_select_next_proto implements the standard protocol selection. It is
 * expected that this function is called from the callback set by
 * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a
 * vector of 8-bit, length prefixed byte strings. The length byte itself is
 * not included in the length. A byte string of length 0 is invalid. No byte
 * string may be truncated. The current, but experimental algorithm for
 * selecting the protocol is: 1) If the server doesn't support NPN then this
 * is indicated to the callback. In this case, the client application has to
 * abort the connection or have a default application level protocol. 2) If
 * the server supports NPN, but advertises an empty list then the client
 * selects the first protocol in its list, but indicates via the API that this
 * fallback case was enacted. 3) Otherwise, the client finds the first
 * protocol in the server's list that it supports and selects this protocol.
 * This is because it's assumed that the server has better information about
 * which protocol a client should use. 4) If the client doesn't support any
 * of the server's advertised protocols, then this is treated the same as
 * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was
 * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
 */
int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
    const unsigned char *server,
    unsigned int server_len,
    const unsigned char *client, unsigned int client_len)
{
    PACKET cpkt, csubpkt, spkt, ssubpkt;

    if (!PACKET_buf_init(&cpkt, client, client_len)
        || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt)
        || PACKET_remaining(&csubpkt) == 0) {
        *out = NULL;
        *outlen = 0;
        return OPENSSL_NPN_NO_OVERLAP;
    }

    /*
     * Set the default opportunistic protocol. Will be overwritten if we find
     * a match.
     */
    *out = (unsigned char *)PACKET_data(&csubpkt);
    *outlen = (unsigned char)PACKET_remaining(&csubpkt);

    /*
     * For each protocol in server preference order, see if we support it.
     */
    if (PACKET_buf_init(&spkt, server, server_len)) {
        while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) {
            if (PACKET_remaining(&ssubpkt) == 0)
                continue; /* Invalid - ignore it */
            if (PACKET_buf_init(&cpkt, client, client_len)) {
                while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) {
                    if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt),
                            PACKET_remaining(&ssubpkt))) {
                        /* We found a match */
                        *out = (unsigned char *)PACKET_data(&ssubpkt);
                        *outlen = (unsigned char)PACKET_remaining(&ssubpkt);
                        return OPENSSL_NPN_NEGOTIATED;
                    }
                }
                /* Ignore spurious trailing bytes in the client list */
            } else {
                /* This should never happen */
                return OPENSSL_NPN_NO_OVERLAP;
            }
        }
        /* Ignore spurious trailing bytes in the server list */
    }

    /*
     * There's no overlap between our protocols and the server's list. We use
     * the default opportunistic protocol selected earlier
     */
    return OPENSSL_NPN_NO_OVERLAP;
}

#ifndef OPENSSL_NO_NEXTPROTONEG
/*
 * SSL_get0_next_proto_negotiated sets *data and *len to point to the
 * client's requested protocol for this connection and returns 0. If the
 * client didn't request any protocol, then *data is set to NULL. Note that
 * the client can request any protocol it chooses. The value returned from
 * this function need not be a member of the list of supported protocols
 * provided by the callback.
 */
void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
    unsigned *len)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL) {
        /* We have no other way to indicate error */
        *data = NULL;
        *len = 0;
        return;
    }

    *data = sc->ext.npn;
    if (*data == NULL) {
        *len = 0;
    } else {
        *len = (unsigned int)sc->ext.npn_len;
    }
}

/*
 * SSL_CTX_set_npn_advertised_cb sets a callback that is called when
 * a TLS server needs a list of supported protocols for Next Protocol
 * Negotiation. The returned list must be in wire format.  The list is
 * returned by setting |out| to point to it and |outlen| to its length. This
 * memory will not be modified, but one should assume that the SSL* keeps a
 * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it
 * wishes to advertise. Otherwise, no such extension will be included in the
 * ServerHello.
 */
void SSL_CTX_set_npn_advertised_cb(SSL_CTX *ctx,
    SSL_CTX_npn_advertised_cb_func cb,
    void *arg)
{
    if (IS_QUIC_CTX(ctx))
        /* NPN not allowed for QUIC */
        return;

    ctx->ext.npn_advertised_cb = cb;
    ctx->ext.npn_advertised_cb_arg = arg;
}

/*
 * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
 * client needs to select a protocol from the server's provided list. |out|
 * must be set to point to the selected protocol (which may be within |in|).
 * The length of the protocol name must be written into |outlen|. The
 * server's advertised protocols are provided in |in| and |inlen|. The
 * callback can assume that |in| is syntactically valid. The client must
 * select a protocol. It is fatal to the connection if this callback returns
 * a value other than SSL_TLSEXT_ERR_OK.
 */
void SSL_CTX_set_npn_select_cb(SSL_CTX *ctx,
    SSL_CTX_npn_select_cb_func cb,
    void *arg)
{
    if (IS_QUIC_CTX(ctx))
        /* NPN not allowed for QUIC */
        return;

    ctx->ext.npn_select_cb = cb;
    ctx->ext.npn_select_cb_arg = arg;
}
#endif

static int alpn_value_ok(const unsigned char *protos, unsigned int protos_len)
{
    unsigned int idx;

    if (protos_len < 2 || protos == NULL)
        return 0;

    for (idx = 0; idx < protos_len; idx += protos[idx] + 1) {
        if (protos[idx] == 0)
            return 0;
    }
    return idx == protos_len;
}
/*
 * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
 * length-prefixed strings). Returns 0 on success.
 */
int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
    unsigned int protos_len)
{
    unsigned char *alpn;

    if (protos_len == 0 || protos == NULL) {
        OPENSSL_free(ctx->ext.alpn);
        ctx->ext.alpn = NULL;
        ctx->ext.alpn_len = 0;
        return 0;
    }
    /* Not valid per RFC */
    if (!alpn_value_ok(protos, protos_len))
        return 1;

    alpn = OPENSSL_memdup(protos, protos_len);
    if (alpn == NULL)
        return 1;
    OPENSSL_free(ctx->ext.alpn);
    ctx->ext.alpn = alpn;
    ctx->ext.alpn_len = protos_len;

    return 0;
}

/*
 * SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
 * length-prefixed strings). Returns 0 on success.
 */
int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
    unsigned int protos_len)
{
    unsigned char *alpn;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return 1;

    if (protos_len == 0 || protos == NULL) {
        OPENSSL_free(sc->ext.alpn);
        sc->ext.alpn = NULL;
        sc->ext.alpn_len = 0;
        return 0;
    }
    /* Not valid per RFC */
    if (!alpn_value_ok(protos, protos_len))
        return 1;

    alpn = OPENSSL_memdup(protos, protos_len);
    if (alpn == NULL)
        return 1;
    OPENSSL_free(sc->ext.alpn);
    sc->ext.alpn = alpn;
    sc->ext.alpn_len = protos_len;

    return 0;
}

/*
 * SSL_CTX_set_get0_protos gets the ALPN protocol list on |ctx| to |protos|.
 */
void SSL_CTX_get0_alpn_protos(SSL_CTX *ctx, const unsigned char **protos,
    unsigned int *protos_len)
{
    unsigned char *p = NULL;
    unsigned int len = 0;

    if (ctx != NULL) {
        p = ctx->ext.alpn;
        len = (unsigned int)ctx->ext.alpn_len;
    }

    if (protos != NULL)
        *protos = p;
    if (protos_len != NULL)
        *protos_len = len;
}

/*
 * SSL_get0_alpn_protos gets the ALPN protocol list on |ssl| to |protos|.
 */
void SSL_get0_alpn_protos(SSL *ssl, const unsigned char **protos,
    unsigned int *protos_len)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
    unsigned char *p = NULL;
    unsigned int len = 0;

    if (sc != NULL) {
        p = sc->ext.alpn;
        len = (unsigned int)sc->ext.alpn_len;
    }

    if (protos != NULL)
        *protos = p;
    if (protos_len != NULL)
        *protos_len = len;
}

/*
 * SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is
 * called during ClientHello processing in order to select an ALPN protocol
 * from the client's list of offered protocols.
 */
void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
    SSL_CTX_alpn_select_cb_func cb,
    void *arg)
{
    ctx->ext.alpn_select_cb = cb;
    ctx->ext.alpn_select_cb_arg = arg;
}

/*
 * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
 * On return it sets |*data| to point to |*len| bytes of protocol name
 * (not including the leading length-prefix byte). If the server didn't
 * respond with a negotiated protocol then |*len| will be zero.
 */
void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
    unsigned int *len)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL) {
        /* We have no other way to indicate error */
        *data = NULL;
        *len = 0;
        return;
    }

    *data = sc->s3.alpn_selected;
    if (*data == NULL)
        *len = 0;
    else
        *len = (unsigned int)sc->s3.alpn_selected_len;
}

int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
    const char *label, size_t llen,
    const unsigned char *context, size_t contextlen,
    int use_context)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return -1;

    if (sc->session == NULL
        || (sc->version < TLS1_VERSION && sc->version != DTLS1_BAD_VER))
        return -1;

    return sc->ssl.method->ssl3_enc->export_keying_material(sc, out, olen, label,
        llen, context,
        contextlen,
        use_context);
}

int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
    const char *label, size_t llen,
    const unsigned char *context,
    size_t contextlen)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return -1;

    if (sc->version != TLS1_3_VERSION)
        return 0;

    return tls13_export_keying_material_early(sc, out, olen, label, llen,
        context, contextlen);
}

static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
    const unsigned char *session_id = a->session_id;
    unsigned long l;
    unsigned char tmp_storage[4];

    if (a->session_id_length < sizeof(tmp_storage)) {
        memset(tmp_storage, 0, sizeof(tmp_storage));
        memcpy(tmp_storage, a->session_id, a->session_id_length);
        session_id = tmp_storage;
    }

    l = (unsigned long)((unsigned long)session_id[0]) | ((unsigned long)session_id[1] << 8L) | ((unsigned long)session_id[2] << 16L) | ((unsigned long)session_id[3] << 24L);
    return l;
}

/*
 * NB: If this function (or indeed the hash function which uses a sort of
 * coarser function than this one) is changed, ensure
 * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on
 * being able to construct an SSL_SESSION that will collide with any existing
 * session with a matching session ID.
 */
static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
{
    if (a->ssl_version != b->ssl_version)
        return 1;
    if (a->session_id_length != b->session_id_length)
        return 1;
    return memcmp(a->session_id, b->session_id, a->session_id_length);
}

#ifndef OPENSSL_NO_SSLKEYLOG
/**
 * @brief Static initialization for a one-time action to initialize the SSL key log.
 */
static CRYPTO_ONCE ssl_keylog_once = CRYPTO_ONCE_STATIC_INIT;

/**
 * @brief Pointer to a read-write lock used to protect access to the key log.
 */
static CRYPTO_RWLOCK *keylog_lock = NULL;

/**
 * @brief Pointer to a BIO structure used for writing the key log information.
 */
static BIO *keylog_bio = NULL;

/**
 * @brief Initializes the SSLKEYLOGFILE lock.
 *
 * @return 1 on success, 0 on failure.
 */
DEFINE_RUN_ONCE_STATIC(ssl_keylog_init)
{
    keylog_lock = CRYPTO_THREAD_lock_new();
    if (keylog_lock == NULL)
        return 0;
    return 1;
}

/**
 * @brief checks when a BIO refcount has reached zero, and sets
 * keylog_cb to NULL if it has
 *
 * @returns 1 always
 */
static long check_keylog_bio_free(BIO *b, int oper, const char *argp,
    size_t len, int argi, long argl, int ret,
    size_t *processed)
{

    /*
     * Note we _dont_ take the keylog_lock here
     * This is intentional, because we only free the keylog lock
     * During SSL_CTX_free, in which we already possess the lock, so
     * There's no need to grab it again here
     */
    if (oper == BIO_CB_FREE)
        keylog_bio = NULL;
    return ret;
}

/**
 * @brief records ssl secrets to a file
 */
static void do_sslkeylogfile(const SSL *ssl, const char *line)
{
    if (keylog_lock == NULL)
        return;

    if (!CRYPTO_THREAD_write_lock(keylog_lock))
        return;
    if (keylog_bio != NULL) {
        BIO_printf(keylog_bio, "%s\n", line);
        (void)BIO_flush(keylog_bio);
    }
    CRYPTO_THREAD_unlock(keylog_lock);
}
#endif

/*
 * These wrapper functions should remain rather than redeclaring
 * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
 * variable. The reason is that the functions aren't static, they're exposed
 * via ssl.h.
 */

#ifndef OPENSSL_NO_SSLKEYLOG
static BIO *get_sslkeylog_bio(const char *keylogfile)
{
#ifdef _POSIX_C_SOURCE
    BIO *b;
    int fdno = -1;
    FILE *fp = NULL;

    fdno = open(keylogfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
    if (fdno < 0)
        return NULL;

    fp = fdopen(fdno, "a");
    if (fp == NULL) {
        close(fdno);
        return NULL;
    }

    if ((b = BIO_new_fp(fp, BIO_CLOSE)) == NULL)
        fclose(fp);
    return b;
#else
    return BIO_new_file(keylogfile, "a");
#endif
}
#endif

SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
    const SSL_METHOD *meth)
{
    SSL_CTX *ret = NULL;
#ifndef OPENSSL_NO_SSLKEYLOG
    const char *keylogfile = ossl_safe_getenv("SSLKEYLOGFILE");
#endif
#ifndef OPENSSL_NO_COMP_ALG
    int i;
#endif

    if (meth == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED);
        return NULL;
    }

    if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))
        return NULL;

    /* Doing this for the run once effect */
    if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
        goto err;
    }

    ret = OPENSSL_zalloc(sizeof(*ret));
    if (ret == NULL)
        return NULL;

    /* Init the reference counting before any call to SSL_CTX_free */
    if (!CRYPTO_NEW_REF(&ret->references, 1)) {
        OPENSSL_free(ret);
        return NULL;
    }

    ret->lock = CRYPTO_THREAD_lock_new();
    if (ret->lock == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }

#ifdef TSAN_REQUIRES_LOCKING
    ret->tsan_lock = CRYPTO_THREAD_lock_new();
    if (ret->tsan_lock == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }
#endif

    ret->libctx = libctx;
    if (propq != NULL) {
        ret->propq = OPENSSL_strdup(propq);
        if (ret->propq == NULL)
            goto err;
    }

    if ((ret->hmac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL)
        goto err;
    if ((ret->sha256 = EVP_MD_fetch(libctx, "SHA2-256", propq)) == NULL)
        goto err;
    if ((ret->tktenc = EVP_CIPHER_fetch(libctx, "AES-256-CBC", propq)) == NULL)
        goto err;
#if defined(OPENSSL_HAVE_TLS1PRF)
    if ((ret->tls1prf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_TLS1_PRF, propq)) == NULL)
        goto err;
#endif

    ret->method = meth;
    ret->min_proto_version = 0;
    ret->max_proto_version = 0;
    ret->mode = SSL_MODE_AUTO_RETRY;
    ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
    ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
    /* We take the system default. */
    ret->session_timeout = meth->get_timeout();
    ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
    ret->verify_mode = SSL_VERIFY_NONE;

    ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
    if (ret->sessions == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }
    ret->cert_store = X509_STORE_new();
    if (ret->cert_store == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB);
        goto err;
    }
#ifndef OPENSSL_NO_CT
    ret->ctlog_store = CTLOG_STORE_new_ex(libctx, propq);
    if (ret->ctlog_store == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CT_LIB);
        goto err;
    }
#endif

    /* initialize cipher/digest methods table */
    if (!ssl_load_ciphers(ret)) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }

    if (!ssl_load_groups(ret)) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }

    /* load provider sigalgs */
    if (!ssl_load_sigalgs(ret)) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }

    /* initialise sig algs */
    if (!ssl_setup_sigalgs(ret)) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }

    if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites())) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }

    if ((ret->cert = ssl_cert_new(SSL_PKEY_NUM + ret->sigalg_list_len)) == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }

    if (!ssl_create_cipher_list(ret,
            ret->tls13_ciphersuites,
            &ret->cipher_list, &ret->cipher_list_by_id,
            OSSL_default_cipher_list(), ret->cert)
        || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS);
        goto err;
    }

    ret->param = X509_VERIFY_PARAM_new();
    if (ret->param == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB);
        goto err;
    }

    if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }

    if ((ret->client_ca_names = sk_X509_NAME_new_null()) == NULL) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }

    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data)) {
        ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }

    if ((ret->ext.secure = OPENSSL_secure_zalloc(sizeof(*ret->ext.secure))) == NULL)
        goto err;

    /* No compression for DTLS */
    if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS))
        ret->comp_methods = SSL_COMP_get_compression_methods();

    ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
    ret->split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;

    /* Setup RFC5077 ticket keys */
    if ((RAND_bytes_ex(libctx, ret->ext.tick_key_name,
             sizeof(ret->ext.tick_key_name), 0)
            <= 0)
        || (RAND_priv_bytes_ex(libctx, ret->ext.secure->tick_hmac_key,
                sizeof(ret->ext.secure->tick_hmac_key), 0)
            <= 0)
        || (RAND_priv_bytes_ex(libctx, ret->ext.secure->tick_aes_key,
                sizeof(ret->ext.secure->tick_aes_key), 0)
            <= 0))
        ret->options |= SSL_OP_NO_TICKET;

    if (RAND_priv_bytes_ex(libctx, ret->ext.cookie_hmac_key,
            sizeof(ret->ext.cookie_hmac_key), 0)
        <= 0) {
        ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB);
        goto err;
    }

#ifndef OPENSSL_NO_SRP
    if (!ssl_ctx_srp_ctx_init_intern(ret)) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
        goto err;
    }
#endif

#ifndef OPENSSL_NO_COMP_ALG
    /*
     * Set the default order: brotli, zlib, zstd
     * Including only those enabled algorithms
     */
    memset(ret->cert_comp_prefs, 0, sizeof(ret->cert_comp_prefs));
    i = 0;
    if (ossl_comp_has_alg(TLSEXT_comp_cert_brotli))
        ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_brotli;
    if (ossl_comp_has_alg(TLSEXT_comp_cert_zlib))
        ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_zlib;
    if (ossl_comp_has_alg(TLSEXT_comp_cert_zstd))
        ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_zstd;
#endif
    /*
     * Disable compression by default to prevent CRIME. Applications can
     * re-enable compression by configuring
     * SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION);
     * or by using the SSL_CONF library. Similarly we also enable TLSv1.3
     * middlebox compatibility by default. This may be disabled by default in
     * a later OpenSSL version.
     */
    ret->options |= SSL_OP_NO_COMPRESSION | SSL_OP_ENABLE_MIDDLEBOX_COMPAT;

    ret->ext.status_type = TLSEXT_STATUSTYPE_nothing;

    /*
     * We cannot usefully set a default max_early_data here (which gets
     * propagated in SSL_new(), for the following reason: setting the
     * SSL field causes tls_construct_stoc_early_data() to tell the
     * client that early data will be accepted when constructing a TLS 1.3
     * session ticket, and the client will accordingly send us early data
     * when using that ticket (if the client has early data to send).
     * However, in order for the early data to actually be consumed by
     * the application, the application must also have calls to
     * SSL_read_early_data(); otherwise we'll just skip past the early data
     * and ignore it.  So, since the application must add calls to
     * SSL_read_early_data(), we also require them to add
     * calls to SSL_CTX_set_max_early_data() in order to use early data,
     * eliminating the bandwidth-wasting early data in the case described
     * above.
     */
    ret->max_early_data = 0;

    /*
     * Default recv_max_early_data is a fully loaded single record. Could be
     * split across multiple records in practice. We set this differently to
     * max_early_data so that, in the default case, we do not advertise any
     * support for early_data, but if a client were to send us some (e.g.
     * because of an old, stale ticket) then we will tolerate it and skip over
     * it.
     */
    ret->recv_max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;

    /* By default we send two session tickets automatically in TLSv1.3 */
    ret->num_tickets = 2;

#ifndef OPENSSL_NO_QUIC
    /* only create a cache for client CTX-es */
    if (meth == OSSL_QUIC_client_method())
        if ((ret->tokencache = ossl_quic_new_token_store()) == NULL)
            goto err;
    ret->domain_flags = 0;
    if (IS_QUIC_METHOD(meth)) {
#if defined(OPENSSL_THREADS)
        if (meth == OSSL_QUIC_client_thread_method())
            ret->domain_flags
                = SSL_DOMAIN_FLAG_MULTI_THREAD
                | SSL_DOMAIN_FLAG_THREAD_ASSISTED
                | SSL_DOMAIN_FLAG_BLOCKING;
        else
            ret->domain_flags
                = SSL_DOMAIN_FLAG_MULTI_THREAD
                | SSL_DOMAIN_FLAG_LEGACY_BLOCKING;
#else
        ret->domain_flags
            = SSL_DOMAIN_FLAG_SINGLE_THREAD
            | SSL_DOMAIN_FLAG_LEGACY_BLOCKING;
#endif
    }
#endif

    if (!ssl_ctx_system_config(ret)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_IN_SYSTEM_DEFAULT_CONFIG);
        goto err;
    }

#ifndef OPENSSL_NO_SSLKEYLOG
    if (keylogfile != NULL && strlen(keylogfile) != 0) {
        /* Make sure we have a global lock allocated */
        if (!RUN_ONCE(&ssl_keylog_once, ssl_keylog_init)) {
            /* use a trace message as a warning */
            OSSL_TRACE(TLS, "Unable to initialize keylog data\n");
            goto out;
        }

        /* Grab our global lock */
        if (!CRYPTO_THREAD_write_lock(keylog_lock)) {
            OSSL_TRACE(TLS, "Unable to acquire keylog write lock\n");
            goto out;
        } else {
            /*
             * If the bio for the requested keylog file hasn't been
             * created yet, go ahead and create it, and set it to append
             * if its already there.
             */
            if (keylog_bio == NULL) {
                keylog_bio = get_sslkeylog_bio(keylogfile);
                if (keylog_bio == NULL) {
                    OSSL_TRACE(TLS, "Unable to create keylog bio\n");
                    goto out;
                }
                BIO_set_callback_ex(keylog_bio, check_keylog_bio_free);
            } else {
                /* up our refcount for the already-created case */
                BIO_up_ref(keylog_bio);
            }
            /* If we have a bio now, assign the callback handler */
            if (keylog_bio != NULL)
                ret->do_sslkeylog = 1;
            /* unlock, and we're done */
            CRYPTO_THREAD_unlock(keylog_lock);
        }
    }
out:
#endif
    return ret;
err:
    SSL_CTX_free(ret);
#ifndef OPENSSL_NO_SSLKEYLOG
    BIO_free(keylog_bio);
#endif
    return NULL;
}

SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
{
    return SSL_CTX_new_ex(NULL, NULL, meth);
}

int SSL_CTX_up_ref(SSL_CTX *ctx)
{
    int i;

    if (CRYPTO_UP_REF(&ctx->references, &i) <= 0)
        return 0;

    REF_PRINT_COUNT("SSL_CTX", i, ctx);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
}

void SSL_CTX_free(SSL_CTX *a)
{
    int i;
    size_t j;

    if (a == NULL)
        return;

    CRYPTO_DOWN_REF(&a->references, &i);
    REF_PRINT_COUNT("SSL_CTX", i, a);
    if (i > 0)
        return;
    REF_ASSERT_ISNT(i < 0);

#ifndef OPENSSL_NO_SSLKEYLOG
    if (keylog_lock != NULL && CRYPTO_THREAD_write_lock(keylog_lock)) {
        if (a->do_sslkeylog == 1)
            BIO_free(keylog_bio);
        a->do_sslkeylog = 0;
        CRYPTO_THREAD_unlock(keylog_lock);
    }
#endif

    X509_VERIFY_PARAM_free(a->param);
    dane_ctx_final(&a->dane);

    /*
     * Free internal session cache. However: the remove_cb() may reference
     * the ex_data of SSL_CTX, thus the ex_data store can only be removed
     * after the sessions were flushed.
     * As the ex_data handling routines might also touch the session cache,
     * the most secure solution seems to be: empty (flush) the cache, then
     * free ex_data, then finally free the cache.
     * (See ticket [openssl.org #212].)
     */
    if (a->sessions != NULL)
        SSL_CTX_flush_sessions_ex(a, 0);

    EVP_MAC_free(a->hmac);
    EVP_MD_free(a->sha256);
    EVP_CIPHER_free(a->tktenc);
#ifdef OPENSSL_HAVE_TLS1PRF
    EVP_KDF_free(a->tls1prf);
#endif

    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
    lh_SSL_SESSION_free(a->sessions);
    X509_STORE_free(a->cert_store);
#ifndef OPENSSL_NO_CT
    CTLOG_STORE_free(a->ctlog_store);
#endif
    sk_SSL_CIPHER_free(a->cipher_list);
    sk_SSL_CIPHER_free(a->cipher_list_by_id);
    sk_SSL_CIPHER_free(a->tls13_ciphersuites);
    ssl_cert_free(a->cert);
    sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
    sk_X509_NAME_pop_free(a->client_ca_names, X509_NAME_free);
    OSSL_STACK_OF_X509_free(a->extra_certs);
    a->comp_methods = NULL;
#ifndef OPENSSL_NO_SRTP
    sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
#endif
#ifndef OPENSSL_NO_SRP
    ssl_ctx_srp_ctx_free_intern(a);
#endif

    OPENSSL_free(a->ext.supportedgroups);
    OPENSSL_free(a->ext.keyshares);
    OPENSSL_free(a->ext.tuples);
    OPENSSL_free(a->ext.alpn);
    OPENSSL_secure_clear_free(a->ext.secure, sizeof(*a->ext.secure));

    for (j = 0; j < SSL_ENC_NUM_IDX; j++)
        ssl_evp_cipher_free(a->ssl_cipher_methods[j]);
    for (j = 0; j < SSL_MD_NUM_IDX; j++)
        ssl_evp_md_free(a->ssl_digest_methods[j]);
    for (j = 0; j < a->group_list_len; j++) {
        OPENSSL_free(a->group_list[j].tlsname);
        OPENSSL_free(a->group_list[j].realname);
        OPENSSL_free(a->group_list[j].algorithm);
    }
    OPENSSL_free(a->group_list);
    for (j = 0; j < a->sigalg_list_len; j++) {
        OPENSSL_free(a->sigalg_list[j].name);
        OPENSSL_free(a->sigalg_list[j].sigalg_name);
        OPENSSL_free(a->sigalg_list[j].sigalg_oid);
        OPENSSL_free(a->sigalg_list[j].sig_name);
        OPENSSL_free(a->sigalg_list[j].sig_oid);
        OPENSSL_free(a->sigalg_list[j].hash_name);
        OPENSSL_free(a->sigalg_list[j].hash_oid);
        OPENSSL_free(a->sigalg_list[j].keytype);
        OPENSSL_free(a->sigalg_list[j].keytype_oid);
    }
    OPENSSL_free(a->sigalg_list);
    OPENSSL_free(a->ssl_cert_info);

    OPENSSL_free(a->sigalg_lookup_cache);
    OPENSSL_free(a->tls12_sigalgs);

    OPENSSL_free(a->client_cert_type);
    OPENSSL_free(a->server_cert_type);

    CRYPTO_THREAD_lock_free(a->lock);
    CRYPTO_FREE_REF(&a->references);
#ifdef TSAN_REQUIRES_LOCKING
    CRYPTO_THREAD_lock_free(a->tsan_lock);
#endif

    OPENSSL_free(a->propq);
#ifndef OPENSSL_NO_QLOG
    OPENSSL_free(a->qlog_title);
#endif

#ifndef OPENSSL_NO_QUIC
    ossl_quic_free_token_store(a->tokencache);
#endif

#ifndef OPENSSL_NO_ECH
    ossl_ech_ctx_clear(&a->ext.ech);
#endif

    OPENSSL_free(a);
}

void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
{
    ctx->default_passwd_callback = cb;
}

void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
{
    ctx->default_passwd_callback_userdata = u;
}

pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx)
{
    return ctx->default_passwd_callback;
}

void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx)
{
    return ctx->default_passwd_callback_userdata;
}

void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->default_passwd_callback = cb;
}

void SSL_set_default_passwd_cb_userdata(SSL *s, void *u)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->default_passwd_callback_userdata = u;
}

pem_password_cb *SSL_get_default_passwd_cb(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->default_passwd_callback;
}

void *SSL_get_default_passwd_cb_userdata(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->default_passwd_callback_userdata;
}

void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
    int (*cb)(X509_STORE_CTX *, void *),
    void *arg)
{
    ctx->app_verify_callback = cb;
    ctx->app_verify_arg = arg;
}

void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
    int (*cb)(int, X509_STORE_CTX *))
{
    ctx->verify_mode = mode;
    ctx->default_verify_callback = cb;
}

void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth)
{
    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}

void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg), void *arg)
{
    ssl_cert_set_cert_cb(c->cert, cb, arg);
}

void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    ssl_cert_set_cert_cb(sc->cert, cb, arg);
}

void ssl_set_masks(SSL_CONNECTION *s)
{
    CERT *c = s->cert;
    uint32_t *pvalid = s->s3.tmp.valid_flags;
    int rsa_enc, rsa_sign, dh_tmp, dsa_sign;
    unsigned long mask_k, mask_a;
    int have_ecc_cert, ecdsa_ok;

    if (c == NULL)
        return;

    dh_tmp = (c->dh_tmp != NULL
        || c->dh_tmp_cb != NULL
        || c->dh_tmp_auto
        || tls1_shared_group(s, TLS1_GROUPS_RETURN_TMP_ID,
               TLS1_GROUPS_FFDHE_GROUPS)
            != 0);

    rsa_enc = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID;
    rsa_sign = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID;
    dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_VALID;
    have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
    mask_k = 0;
    mask_a = 0;

    OSSL_TRACE4(TLS_CIPHER, "dh_tmp=%d rsa_enc=%d rsa_sign=%d dsa_sign=%d\n",
        dh_tmp, rsa_enc, rsa_sign, dsa_sign);

#ifndef OPENSSL_NO_GOST
    if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) {
        mask_k |= SSL_kGOST | SSL_kGOST18;
        mask_a |= SSL_aGOST12;
    }
    if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) {
        mask_k |= SSL_kGOST | SSL_kGOST18;
        mask_a |= SSL_aGOST12;
    }
    if (ssl_has_cert(s, SSL_PKEY_GOST01)) {
        mask_k |= SSL_kGOST;
        mask_a |= SSL_aGOST01;
    }
#endif

    if (rsa_enc)
        mask_k |= SSL_kRSA;

    if (dh_tmp)
        mask_k |= SSL_kDHE;

    /*
     * If we only have an RSA-PSS certificate allow RSA authentication
     * if TLS 1.2 or DTLS 1.2 and peer supports it.
     */

    if (rsa_enc || rsa_sign
        || (ssl_has_cert(s, SSL_PKEY_RSA_PSS_SIGN)
            && pvalid[SSL_PKEY_RSA_PSS_SIGN] & CERT_PKEY_EXPLICIT_SIGN
            && (SSL_version(&s->ssl) == XTLS(&s->ssl, 1, 2))))
        mask_a |= SSL_aRSA;

    if (dsa_sign) {
        mask_a |= SSL_aDSS;
    }

    mask_a |= SSL_aNULL;

    /*
     * You can do anything with an RPK key, since there's no cert to restrict it
     * But we need to check for private keys
     */
    if (pvalid[SSL_PKEY_RSA] & CERT_PKEY_RPK) {
        mask_a |= SSL_aRSA;
        mask_k |= SSL_kRSA;
    }
    if (pvalid[SSL_PKEY_ECC] & CERT_PKEY_RPK)
        mask_a |= SSL_aECDSA;
    if (SSL_version(&s->ssl) == XTLS(&s->ssl, 1, 2)) {
        if (pvalid[SSL_PKEY_RSA_PSS_SIGN] & CERT_PKEY_RPK)
            mask_a |= SSL_aRSA;
        if (pvalid[SSL_PKEY_ED25519] & CERT_PKEY_RPK
            || pvalid[SSL_PKEY_ED448] & CERT_PKEY_RPK)
            mask_a |= SSL_aECDSA;
    }

    /*
     * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites
     * depending on the key usage extension.
     */
    if (have_ecc_cert) {
        uint32_t ex_kusage;
        ex_kusage = X509_get_key_usage(c->pkeys[SSL_PKEY_ECC].x509);
        ecdsa_ok = ex_kusage & X509v3_KU_DIGITAL_SIGNATURE;
        if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
            ecdsa_ok = 0;
        if (ecdsa_ok)
            mask_a |= SSL_aECDSA;
    }
    /* Allow Ed25519 for TLS 1.2 and DTLS 1.2 if peer supports it */
    if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED25519)
        && pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN
        && (SSL_version(&s->ssl) == XTLS(&s->ssl, 1, 2)))
        mask_a |= SSL_aECDSA;

    /* Allow Ed448 for TLS 1.2 and DTLS 1.2 if peer supports it */
    if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED448)
        && pvalid[SSL_PKEY_ED448] & CERT_PKEY_EXPLICIT_SIGN
        && (SSL_version(&s->ssl) == XTLS(&s->ssl, 1, 2)))
        mask_a |= SSL_aECDSA;

    mask_k |= SSL_kECDHE;

#ifndef OPENSSL_NO_PSK
    mask_k |= SSL_kPSK;
    mask_a |= SSL_aPSK;
    if (mask_k & SSL_kRSA)
        mask_k |= SSL_kRSAPSK;
    if (mask_k & SSL_kDHE)
        mask_k |= SSL_kDHEPSK;
    if (mask_k & SSL_kECDHE)
        mask_k |= SSL_kECDHEPSK;
#endif

    s->s3.tmp.mask_k = mask_k;
    s->s3.tmp.mask_a = mask_a;
}

int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL_CONNECTION *s)
{
    if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aECDSA) {
        /* key usage, if present, must allow signing */
        if (!(X509_get_key_usage(x) & X509v3_KU_DIGITAL_SIGNATURE)) {
            ERR_raise(ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
            return 0;
        }
    }
    return 1; /* all checks are ok */
}

int ssl_get_server_cert_serverinfo(SSL_CONNECTION *s,
    const unsigned char **serverinfo,
    size_t *serverinfo_length)
{
    CERT_PKEY *cpk = s->s3.tmp.cert;
    *serverinfo_length = 0;

    if (cpk == NULL || cpk->serverinfo == NULL)
        return 0;

    *serverinfo = cpk->serverinfo;
    *serverinfo_length = cpk->serverinfo_length;
    return 1;
}

void ssl_update_cache(SSL_CONNECTION *s, int mode)
{
    int i;

    /*
     * If the session_id_length is 0, we are not supposed to cache it, and it
     * would be rather hard to do anyway :-). Also if the session has already
     * been marked as not_resumable we should not cache it for later reuse.
     */
    if (s->session->session_id_length == 0 || s->session->not_resumable)
        return;

    /*
     * If sid_ctx_length is 0 there is no specific application context
     * associated with this session, so when we try to resume it and
     * SSL_VERIFY_PEER is requested to verify the client identity, we have no
     * indication that this is actually a session for the proper application
     * context, and the *handshake* will fail, not just the resumption attempt.
     * Do not cache (on the server) these sessions that are not resumable
     * (clients can set SSL_VERIFY_PEER without needing a sid_ctx set).
     */
    if (s->server && s->session->sid_ctx_length == 0
        && (s->verify_mode & SSL_VERIFY_PEER) != 0)
        return;

    i = s->session_ctx->session_cache_mode;
    if ((i & mode) != 0
        && (!s->hit || SSL_CONNECTION_IS_TLS13(s))) {
        /*
         * Add the session to the internal cache. In server side TLSv1.3 we
         * normally don't do this because by default it's a full stateless ticket
         * with only a dummy session id so there is no reason to cache it,
         * unless:
         * - we are doing early_data, in which case we cache so that we can
         *   detect replays
         * - the application has set a remove_session_cb so needs to know about
         *   session timeout events
         * - SSL_OP_NO_TICKET is set in which case it is a stateful ticket
         */
        if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0
            && (!SSL_CONNECTION_IS_TLS13(s)
                || !s->server
                || (s->max_early_data > 0
                    && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0)
                || s->session_ctx->remove_session_cb != NULL
                || (s->options & SSL_OP_NO_TICKET) != 0))
            SSL_CTX_add_session(s->session_ctx, s->session);

        /*
         * Add the session to the external cache. We do this even in server side
         * TLSv1.3 without early data because some applications just want to
         * know about the creation of a session and aren't doing a full cache.
         */
        if (s->session_ctx->new_session_cb != NULL && SSL_SESSION_up_ref(s->session)) {
            if (!s->session_ctx->new_session_cb(SSL_CONNECTION_GET_USER_SSL(s),
                    s->session))
                SSL_SESSION_free(s->session);
        }
    }

    /* auto flush every 255 connections */
    if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
        TSAN_QUALIFIER int *stat;

        if (mode & SSL_SESS_CACHE_CLIENT)
            stat = &s->session_ctx->stats.sess_connect_good;
        else
            stat = &s->session_ctx->stats.sess_accept_good;
        if ((ssl_tsan_load(s->session_ctx, stat) & 0xff) == 0xff)
            SSL_CTX_flush_sessions_ex(s->session_ctx, time(NULL));
    }
}

const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx)
{
    return ctx->method;
}

const SSL_METHOD *SSL_get_ssl_method(const SSL *s)
{
    return s->method;
}

int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
{
    int ret = 1;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    /* Not allowed for QUIC */
    if (sc == NULL
        || (s->type != SSL_TYPE_SSL_CONNECTION && s->method != meth)
        || (s->type == SSL_TYPE_SSL_CONNECTION && IS_QUIC_METHOD(meth)))
        return 0;

    if (s->method != meth) {
        const SSL_METHOD *sm = s->method;
        int (*hf)(SSL *) = sc->handshake_func;

        if (sm->version == meth->version)
            s->method = meth;
        else {
            sm->ssl_deinit(s);
            s->method = meth;
            ret = s->method->ssl_init(s);
        }

        if (hf == sm->ssl_connect)
            sc->handshake_func = meth->ssl_connect;
        else if (hf == sm->ssl_accept)
            sc->handshake_func = meth->ssl_accept;
    }
    return ret;
}

int SSL_get_error(const SSL *s, int i)
{
    return ossl_ssl_get_error(s, i, /*check_err=*/1);
}

int ossl_ssl_get_error(const SSL *s, int i, int check_err)
{
    int reason;
    BIO *bio;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (i > 0)
        return SSL_ERROR_NONE;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        reason = ossl_quic_get_error(s, i);
        if (reason != SSL_ERROR_NONE)
            return reason;
    }
#endif

    if (sc == NULL)
        return SSL_ERROR_SSL;

    if (check_err != 0) {
        if (sc->statem.error_state == ERROR_STATE_SSL)
            return SSL_ERROR_SSL;
        if (sc->statem.error_state == ERROR_STATE_SYSCALL)
            return SSL_ERROR_SYSCALL;
    }

#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
#endif
    {
        if (SSL_want_read(s)) {
            bio = SSL_get_rbio(s);
            if (BIO_should_read(bio))
                return SSL_ERROR_WANT_READ;
            else if (BIO_should_write(bio))
                /*
                 * This one doesn't make too much sense ... We never try to
                 * write to the rbio, and an application program where rbio and
                 * wbio are separate couldn't even know what it should wait for.
                 * However if we ever set s->rwstate incorrectly (so that we
                 * have SSL_want_read(s) instead of SSL_want_write(s)) and rbio
                 * and wbio *are* the same, this test works around that bug; so
                 * it might be safer to keep it.
                 */
                return SSL_ERROR_WANT_WRITE;
            else if (BIO_should_io_special(bio)) {
                reason = BIO_get_retry_reason(bio);
                if (reason == BIO_RR_CONNECT)
                    return SSL_ERROR_WANT_CONNECT;
                else if (reason == BIO_RR_ACCEPT)
                    return SSL_ERROR_WANT_ACCEPT;
                else
                    return SSL_ERROR_SYSCALL; /* unknown */
            }
        }

        if (SSL_want_write(s)) {
            /*
             * Access wbio directly - in order to use the buffered bio if
             * present
             */
            bio = sc->wbio;
            if (BIO_should_write(bio))
                return SSL_ERROR_WANT_WRITE;
            else if (BIO_should_read(bio))
                /*
                 * See above (SSL_want_read(s) with BIO_should_write(bio))
                 */
                return SSL_ERROR_WANT_READ;
            else if (BIO_should_io_special(bio)) {
                reason = BIO_get_retry_reason(bio);
                if (reason == BIO_RR_CONNECT)
                    return SSL_ERROR_WANT_CONNECT;
                else if (reason == BIO_RR_ACCEPT)
                    return SSL_ERROR_WANT_ACCEPT;
                else
                    return SSL_ERROR_SYSCALL;
            }
        }
    }

    if (SSL_want_x509_lookup(s))
        return SSL_ERROR_WANT_X509_LOOKUP;
    if (SSL_want_retry_verify(s))
        return SSL_ERROR_WANT_RETRY_VERIFY;
    if (SSL_want_async(s))
        return SSL_ERROR_WANT_ASYNC;
    if (SSL_want_async_job(s))
        return SSL_ERROR_WANT_ASYNC_JOB;
    if (SSL_want_client_hello_cb(s))
        return SSL_ERROR_WANT_CLIENT_HELLO_CB;

    if ((sc->shutdown & SSL_RECEIVED_SHUTDOWN) && (sc->s3.warn_alert == SSL_AD_CLOSE_NOTIFY))
        return SSL_ERROR_ZERO_RETURN;

    return SSL_ERROR_SYSCALL;
}

static int ssl_do_handshake_intern(void *vargs)
{
    struct ssl_async_args *args = (struct ssl_async_args *)vargs;
    SSL *s = args->s;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return -1;

    return sc->handshake_func(s);
}

int SSL_do_handshake(SSL *s)
{
    int ret = 1;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_do_handshake(s);
#endif

    if (sc == NULL)
        return -1;

    if (ssl_reset_error_state(sc) == 0)
        return -1;

    sc->statem.error_state = ERROR_STATE_NOERROR;

    if (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
        sc->statem.error_state = ERROR_STATE_SSL;
        return -1;
    }

    if (!ossl_statem_check_finish_init(sc, -1)) {
        ssl_update_error_state(sc);
        return -1;
    }

    s->method->ssl_renegotiate_check(s, 0);

    if (SSL_in_init(s) || SSL_in_before(s)) {
        if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
            struct ssl_async_args args;

            memset(&args, 0, sizeof(args));
            args.s = s;

            ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern);
        } else {
            ret = sc->handshake_func(s);
        }
    }

    ssl_update_error_state(sc);
    return ret;
}

void SSL_set_accept_state(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        /* We suppress errors because this is a void function */
        (void)ossl_quic_set_accept_state(s, 0 /* suppress errors */);
        return;
    }
#endif

    sc->server = 1;
    sc->shutdown = 0;
    ossl_statem_clear(sc);
    sc->handshake_func = s->method->ssl_accept;
    /* Ignore return value. Its a void public API function */
    RECORD_LAYER_reset(&sc->rlayer);
}

void SSL_set_connect_state(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s)) {
        /* We suppress errors because this is a void function */
        (void)ossl_quic_set_connect_state(s, 0 /* suppress errors */);
        return;
    }
#endif

    sc->server = 0;
    sc->shutdown = 0;
    ossl_statem_clear(sc);
    sc->handshake_func = s->method->ssl_connect;
    /* Ignore return value. Its a void public API function */
    RECORD_LAYER_reset(&sc->rlayer);
}

int ssl_undefined_function(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc != NULL)
        sc->statem.error_state = ERROR_STATE_SSL;
    ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
}

int ssl_undefined_void_function(void)
{
    ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
}

const char *ssl_protocol_to_string(int version)
{
    switch (version) {
    case TLS1_3_VERSION:
        return "TLSv1.3";

    case TLS1_2_VERSION:
        return "TLSv1.2";

    case TLS1_1_VERSION:
        return "TLSv1.1";

    case TLS1_VERSION:
        return "TLSv1";

    case SSL3_VERSION:
        return "SSLv3";

    case DTLS1_BAD_VER:
        return "DTLSv0.9";

    case DTLS1_VERSION:
        return "DTLSv1";

    case DTLS1_2_VERSION:
        return "DTLSv1.2";

    default:
        return "unknown";
    }
}

const char *SSL_get_version(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    /* We only support QUICv1 - so if its QUIC its QUICv1 */
    if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
        return "QUICv1";
#endif

    if (sc == NULL)
        return NULL;

    return ssl_protocol_to_string(sc->version);
}

__owur int SSL_get_handshake_rtt(const SSL *s, uint64_t *rtt)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return -1;
    if (sc->ts_msg_write.t <= 0 || sc->ts_msg_read.t <= 0)
        return 0; /* data not (yet) available */
    if (sc->ts_msg_read.t < sc->ts_msg_write.t)
        return -1;

    *rtt = ossl_time2us(ossl_time_subtract(sc->ts_msg_read, sc->ts_msg_write));
    return 1;
}

static int dup_ca_names(STACK_OF(X509_NAME) **dst, STACK_OF(X509_NAME) *src)
{
    STACK_OF(X509_NAME) *sk;
    X509_NAME *xn;
    int i;

    if (src == NULL) {
        *dst = NULL;
        return 1;
    }

    if ((sk = sk_X509_NAME_new_null()) == NULL)
        return 0;
    for (i = 0; i < sk_X509_NAME_num(src); i++) {
        xn = X509_NAME_dup(sk_X509_NAME_value(src, i));
        if (xn == NULL) {
            sk_X509_NAME_pop_free(sk, X509_NAME_free);
            return 0;
        }
        if (sk_X509_NAME_insert(sk, xn, i) == 0) {
            X509_NAME_free(xn);
            sk_X509_NAME_pop_free(sk, X509_NAME_free);
            return 0;
        }
    }
    *dst = sk;

    return 1;
}

SSL *SSL_dup(SSL *s)
{
    SSL *ret;
    int i;
    /* TODO(QUIC FUTURE): Add an SSL_METHOD function for duplication */
    SSL_CONNECTION *retsc;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return NULL;

    /* If we're not quiescent, just up_ref! */
    if (!SSL_in_init(s) || !SSL_in_before(s)) {
        CRYPTO_UP_REF(&s->references, &i);
        return s;
    }

    /*
     * Otherwise, copy configuration state, and session if set.
     */
    if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL)
        return NULL;
    if ((retsc = SSL_CONNECTION_FROM_SSL_ONLY(ret)) == NULL)
        goto err;

    if (sc->session != NULL) {
        /*
         * Arranges to share the same session via up_ref.  This "copies"
         * session-id, SSL_METHOD, sid_ctx, and 'cert'
         */
        if (!SSL_copy_session_id(ret, s))
            goto err;
    } else {
        /*
         * No session has been established yet, so we have to expect that
         * s->cert or ret->cert will be changed later -- they should not both
         * point to the same object, and thus we can't use
         * SSL_copy_session_id.
         */
        if (!SSL_set_ssl_method(ret, s->method))
            goto err;

        if (sc->cert != NULL) {
            ssl_cert_free(retsc->cert);
            retsc->cert = ssl_cert_dup(sc->cert);
            if (retsc->cert == NULL)
                goto err;
        }

        if (!SSL_set_session_id_context(ret, sc->sid_ctx,
                (int)sc->sid_ctx_length))
            goto err;
    }

    if (!ssl_dane_dup(retsc, sc))
        goto err;
    retsc->version = sc->version;
    retsc->options = sc->options;
    retsc->min_proto_version = sc->min_proto_version;
    retsc->max_proto_version = sc->max_proto_version;
    retsc->mode = sc->mode;
    SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s));
    SSL_set_read_ahead(ret, SSL_get_read_ahead(s));
    retsc->msg_callback = sc->msg_callback;
    retsc->msg_callback_arg = sc->msg_callback_arg;
    SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s));
    SSL_set_verify_depth(ret, SSL_get_verify_depth(s));
    retsc->generate_session_id = sc->generate_session_id;

    SSL_set_info_callback(ret, SSL_get_info_callback(s));

    /* copy app data, a little dangerous perhaps */
    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
        goto err;

    retsc->server = sc->server;
    if (sc->handshake_func) {
        if (sc->server)
            SSL_set_accept_state(ret);
        else
            SSL_set_connect_state(ret);
    }
    retsc->shutdown = sc->shutdown;
    retsc->hit = sc->hit;

    retsc->default_passwd_callback = sc->default_passwd_callback;
    retsc->default_passwd_callback_userdata = sc->default_passwd_callback_userdata;

    X509_VERIFY_PARAM_inherit(retsc->param, sc->param);

    /* dup the cipher_list and cipher_list_by_id stacks */
    if (sc->cipher_list != NULL) {
        if ((retsc->cipher_list = sk_SSL_CIPHER_dup(sc->cipher_list)) == NULL)
            goto err;
    }
    if (sc->cipher_list_by_id != NULL)
        if ((retsc->cipher_list_by_id = sk_SSL_CIPHER_dup(sc->cipher_list_by_id))
            == NULL)
            goto err;

    /* Dup the client_CA list */
    if (!dup_ca_names(&retsc->ca_names, sc->ca_names)
        || !dup_ca_names(&retsc->client_ca_names, sc->client_ca_names))
        goto err;

    return ret;

err:
    SSL_free(ret);
    return NULL;
}

X509 *SSL_get_certificate(const SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    if (sc->cert != NULL)
        return sc->cert->key->x509;
    else
        return NULL;
}

EVP_PKEY *SSL_get_privatekey(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    if (sc->cert != NULL)
        return sc->cert->key->privatekey;
    else
        return NULL;
}

X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx)
{
    if (ctx->cert != NULL)
        return ctx->cert->key->x509;
    else
        return NULL;
}

EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx)
{
    if (ctx->cert != NULL)
        return ctx->cert->key->privatekey;
    else
        return NULL;
}

const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    if ((sc->session != NULL) && (sc->session->cipher != NULL))
        return sc->session->cipher;
    return NULL;
}

const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->s3.tmp.new_cipher;
}

const COMP_METHOD *SSL_get_current_compression(const SSL *s)
{
#ifndef OPENSSL_NO_COMP
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);

    if (sc == NULL)
        return NULL;

    return sc->rlayer.wrlmethod->get_compression(sc->rlayer.wrl);
#else
    return NULL;
#endif
}

const COMP_METHOD *SSL_get_current_expansion(const SSL *s)
{
#ifndef OPENSSL_NO_COMP
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);

    if (sc == NULL)
        return NULL;

    return sc->rlayer.rrlmethod->get_compression(sc->rlayer.rrl);
#else
    return NULL;
#endif
}

int ssl_init_wbio_buffer(SSL_CONNECTION *s)
{
    BIO *bbio;

    if (s->bbio != NULL) {
        /* Already buffered. */
        return 1;
    }

    bbio = BIO_new(BIO_f_buffer());
    if (bbio == NULL || BIO_set_read_buffer_size(bbio, 1) <= 0) {
        BIO_free(bbio);
        ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
        return 0;
    }
    s->bbio = bbio;
    s->wbio = BIO_push(bbio, s->wbio);

    s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio);

    return 1;
}

int ssl_free_wbio_buffer(SSL_CONNECTION *s)
{
    /* callers ensure s is never null */
    if (s->bbio == NULL)
        return 1;

    s->wbio = BIO_pop(s->wbio);
    s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio);

    BIO_free(s->bbio);
    s->bbio = NULL;

    return 1;
}

void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode)
{
    ctx->quiet_shutdown = mode;
}

int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx)
{
    return ctx->quiet_shutdown;
}

void SSL_set_quiet_shutdown(SSL *s, int mode)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    /* Not supported with QUIC */
    if (sc == NULL)
        return;

    sc->quiet_shutdown = mode;
}

int SSL_get_quiet_shutdown(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);

    /* Not supported with QUIC */
    if (sc == NULL)
        return 0;

    return sc->quiet_shutdown;
}

void SSL_set_shutdown(SSL *s, int mode)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    /* Not supported with QUIC */
    if (sc == NULL)
        return;

    sc->shutdown = mode;
}

int SSL_get_shutdown(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);

#ifndef OPENSSL_NO_QUIC
    /* QUIC: Just indicate whether the connection was shutdown cleanly. */
    if (IS_QUIC(s))
        return ossl_quic_get_shutdown(s);
#endif

    if (sc == NULL)
        return 0;

    return sc->shutdown;
}

int SSL_version(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    /* We only support QUICv1 - so if its QUIC its QUICv1 */
    if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
        return OSSL_QUIC1_VERSION;
#endif
    if (sc == NULL)
        return 0;

    return sc->version;
}

int SSL_client_version(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    /* We only support QUICv1 - so if its QUIC its QUICv1 */
    if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
        return OSSL_QUIC1_VERSION;
#endif
    if (sc == NULL)
        return 0;

    return sc->client_version;
}

SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
{
    return ssl->ctx;
}

SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
{
    CERT *new_cert;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);

    /* TODO(QUIC FUTURE): Add support for QUIC */
    if (sc == NULL)
        return NULL;

    if (ssl->ctx == ctx)
        return ssl->ctx;
    if (ctx == NULL)
        ctx = sc->session_ctx;
    new_cert = ssl_cert_dup(ctx->cert);
    if (new_cert == NULL)
        goto err;
    if (!custom_exts_copy_conn(&new_cert->custext, &sc->cert->custext))
        goto err;
    if (!custom_exts_copy_flags(&new_cert->custext, &sc->cert->custext))
        goto err;

    /*
     * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
     * so setter APIs must prevent invalid lengths from entering the system.
     */
    if (!ossl_assert(sc->sid_ctx_length <= sizeof(sc->sid_ctx)))
        goto err;
    if (!SSL_CTX_up_ref(ctx))
        goto err;

    /*
     * If the session ID context matches that of the parent SSL_CTX,
     * inherit it from the new SSL_CTX as well. If however the context does
     * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
     * leave it unchanged.
     */
    if ((ssl->ctx != NULL) && (sc->sid_ctx_length == ssl->ctx->sid_ctx_length) && (memcmp(sc->sid_ctx, ssl->ctx->sid_ctx, sc->sid_ctx_length) == 0)) {
        sc->sid_ctx_length = ctx->sid_ctx_length;
        memcpy(&sc->sid_ctx, &ctx->sid_ctx, sizeof(sc->sid_ctx));
    }

    ssl_cert_free(sc->cert);
    sc->cert = new_cert;
    SSL_CTX_free(ssl->ctx); /* decrement reference count */
    ssl->ctx = ctx;

    return ssl->ctx;

err:
    ssl_cert_free(new_cert);
    return NULL;
}

int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
{
    return X509_STORE_set_default_paths_ex(ctx->cert_store, ctx->libctx,
        ctx->propq);
}

int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx)
{
    X509_LOOKUP *lookup;

    lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_hash_dir());
    if (lookup == NULL)
        return 0;

    /* We ignore errors, in case the directory doesn't exist */
    ERR_set_mark();

    X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);

    ERR_pop_to_mark();

    return 1;
}

int SSL_CTX_set_default_verify_file(SSL_CTX *ctx)
{
    X509_LOOKUP *lookup;

    lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_file());
    if (lookup == NULL)
        return 0;

    /* We ignore errors, in case the file doesn't exist */
    ERR_set_mark();

    X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, ctx->libctx,
        ctx->propq);

    ERR_pop_to_mark();

    return 1;
}

int SSL_CTX_set_default_verify_store(SSL_CTX *ctx)
{
    X509_LOOKUP *lookup;

    lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_store());
    if (lookup == NULL)
        return 0;

    /* We ignore errors, in case the directory doesn't exist */
    ERR_set_mark();

    X509_LOOKUP_add_store_ex(lookup, NULL, ctx->libctx, ctx->propq);

    ERR_pop_to_mark();

    return 1;
}

int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile)
{
    return X509_STORE_load_file_ex(ctx->cert_store, CAfile, ctx->libctx,
        ctx->propq);
}

int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath)
{
    return X509_STORE_load_path(ctx->cert_store, CApath);
}

int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore)
{
    return X509_STORE_load_store_ex(ctx->cert_store, CAstore, ctx->libctx,
        ctx->propq);
}

int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
    const char *CApath)
{
    if (CAfile == NULL && CApath == NULL)
        return 0;
    if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile))
        return 0;
    if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath))
        return 0;
    return 1;
}

void SSL_set_info_callback(SSL *ssl,
    void (*cb)(const SSL *ssl, int type, int val))
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return;

    sc->info_callback = cb;
}

/*
 * One compiler (Diab DCC) doesn't like argument names in returned function
 * pointer.
 */
void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /* ssl */,
    int /* type */,
    int /* val */)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL)
        return NULL;

    return sc->info_callback;
}

void SSL_set_verify_result(SSL *ssl, long arg)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return;

    sc->verify_result = arg;
}

long SSL_get_verify_result(const SSL *ssl)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL)
        return 0;

    return sc->verify_result;
}

size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL)
        return 0;

    if (outlen == 0)
        return sizeof(sc->s3.client_random);
    if (outlen > sizeof(sc->s3.client_random))
        outlen = sizeof(sc->s3.client_random);
    memcpy(out, sc->s3.client_random, outlen);
    return outlen;
}

size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL)
        return 0;

    if (outlen == 0)
        return sizeof(sc->s3.server_random);
    if (outlen > sizeof(sc->s3.server_random))
        outlen = sizeof(sc->s3.server_random);
    memcpy(out, sc->s3.server_random, outlen);
    return outlen;
}

size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
    unsigned char *out, size_t outlen)
{
    if (outlen == 0)
        return session->master_key_length;
    if (outlen > session->master_key_length)
        outlen = session->master_key_length;
    memcpy(out, session->master_key, outlen);
    return outlen;
}

int SSL_SESSION_set1_master_key(SSL_SESSION *sess, const unsigned char *in,
    size_t len)
{
    if (len > sizeof(sess->master_key))
        return 0;

    memcpy(sess->master_key, in, len);
    sess->master_key_length = len;
    return 1;
}

int SSL_set_ex_data(SSL *s, int idx, void *arg)
{
    return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
}

void *SSL_get_ex_data(const SSL *s, int idx)
{
    return CRYPTO_get_ex_data(&s->ex_data, idx);
}

int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg)
{
    return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
}

void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx)
{
    return CRYPTO_get_ex_data(&s->ex_data, idx);
}

X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
{
    return ctx->cert_store;
}

void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store)
{
    X509_STORE_free(ctx->cert_store);
    ctx->cert_store = store;
}

void SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store)
{
    if (store != NULL && !X509_STORE_up_ref(store))
        return;

    SSL_CTX_set_cert_store(ctx, store);
}

int SSL_want(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_want(s);
#endif

    if (sc == NULL)
        return SSL_NOTHING;

    return sc->rwstate;
}

#ifndef OPENSSL_NO_PSK
int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
{
    if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG);
        return 0;
    }
    OPENSSL_free(ctx->cert->psk_identity_hint);
    if (identity_hint != NULL) {
        ctx->cert->psk_identity_hint = OPENSSL_strdup(identity_hint);
        if (ctx->cert->psk_identity_hint == NULL)
            return 0;
    } else
        ctx->cert->psk_identity_hint = NULL;
    return 1;
}

int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG);
        return 0;
    }
    OPENSSL_free(sc->cert->psk_identity_hint);
    if (identity_hint != NULL) {
        sc->cert->psk_identity_hint = OPENSSL_strdup(identity_hint);
        if (sc->cert->psk_identity_hint == NULL)
            return 0;
    } else
        sc->cert->psk_identity_hint = NULL;
    return 1;
}

const char *SSL_get_psk_identity_hint(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL || sc->session == NULL)
        return NULL;

    return sc->session->psk_identity_hint;
}

const char *SSL_get_psk_identity(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL || sc->session == NULL)
        return NULL;

    return sc->session->psk_identity;
}

void SSL_set_psk_client_callback(SSL *s, SSL_psk_client_cb_func cb)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->psk_client_callback = cb;
}

void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb)
{
    ctx->psk_client_callback = cb;
}

void SSL_set_psk_server_callback(SSL *s, SSL_psk_server_cb_func cb)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->psk_server_callback = cb;
}

void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb)
{
    ctx->psk_server_callback = cb;
}
#endif

void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->psk_find_session_cb = cb;
}

void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx,
    SSL_psk_find_session_cb_func cb)
{
    ctx->psk_find_session_cb = cb;
}

void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->psk_use_session_cb = cb;
}

void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx,
    SSL_psk_use_session_cb_func cb)
{
    ctx->psk_use_session_cb = cb;
}

void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
    void (*cb)(int write_p, int version,
        int content_type, const void *buf,
        size_t len, SSL *ssl, void *arg))
{
    SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}

void SSL_set_msg_callback(SSL *ssl,
    void (*cb)(int write_p, int version,
        int content_type, const void *buf,
        size_t len, SSL *ssl, void *arg))
{
    SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}

void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx,
    int (*cb)(SSL *ssl,
        int
            is_forward_secure))
{
    SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB,
        (void (*)(void))cb);
}

void SSL_set_not_resumable_session_callback(SSL *ssl,
    int (*cb)(SSL *ssl,
        int is_forward_secure))
{
    SSL_callback_ctrl(ssl, SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB,
        (void (*)(void))cb);
}

void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx,
    size_t (*cb)(SSL *ssl, int type,
        size_t len, void *arg))
{
    ctx->record_padding_cb = cb;
}

void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg)
{
    ctx->record_padding_arg = arg;
}

void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx)
{
    return ctx->record_padding_arg;
}

int SSL_CTX_set_block_padding_ex(SSL_CTX *ctx, size_t app_block_size,
    size_t hs_block_size)
{
    if (IS_QUIC_CTX(ctx) && (app_block_size > 1 || hs_block_size > 1))
        return 0;

    /* block size of 0 or 1 is basically no padding */
    if (app_block_size == 1) {
        ctx->block_padding = 0;
    } else if (app_block_size <= SSL3_RT_MAX_PLAIN_LENGTH) {
        ctx->block_padding = app_block_size;
    } else {
        return 0;
    }
    if (hs_block_size == 1) {
        ctx->hs_padding = 0;
    } else if (hs_block_size <= SSL3_RT_MAX_PLAIN_LENGTH) {
        ctx->hs_padding = hs_block_size;
    } else {
        return 0;
    }
    return 1;
}

int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size)
{
    return SSL_CTX_set_block_padding_ex(ctx, block_size, block_size);
}

int SSL_set_record_padding_callback(SSL *ssl,
    size_t (*cb)(SSL *ssl, int type,
        size_t len, void *arg))
{
    BIO *b;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);

    if (sc == NULL)
        return 0;

    b = SSL_get_wbio(ssl);
    if (b == NULL || !BIO_get_ktls_send(b)) {
        sc->rlayer.record_padding_cb = cb;
        return 1;
    }
    return 0;
}

void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return;

    sc->rlayer.record_padding_arg = arg;
}

void *SSL_get_record_padding_callback_arg(const SSL *ssl)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl);

    if (sc == NULL)
        return NULL;

    return sc->rlayer.record_padding_arg;
}

int SSL_set_block_padding_ex(SSL *ssl, size_t app_block_size,
    size_t hs_block_size)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL
        || (IS_QUIC(ssl)
            && (app_block_size > 1 || hs_block_size > 1)))
        return 0;

    /* block size of 0 or 1 is basically no padding */
    if (app_block_size == 1) {
        sc->rlayer.block_padding = 0;
    } else if (app_block_size <= SSL3_RT_MAX_PLAIN_LENGTH) {
        sc->rlayer.block_padding = app_block_size;
    } else {
        return 0;
    }
    if (hs_block_size == 1) {
        sc->rlayer.hs_padding = 0;
    } else if (hs_block_size <= SSL3_RT_MAX_PLAIN_LENGTH) {
        sc->rlayer.hs_padding = hs_block_size;
    } else {
        return 0;
    }
    return 1;
}

int SSL_set_block_padding(SSL *ssl, size_t block_size)
{
    return SSL_set_block_padding_ex(ssl, block_size, block_size);
}

int SSL_set_num_tickets(SSL *s, size_t num_tickets)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    sc->num_tickets = num_tickets;

    return 1;
}

size_t SSL_get_num_tickets(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->num_tickets;
}

int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets)
{
    ctx->num_tickets = num_tickets;

    return 1;
}

size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx)
{
    return ctx->num_tickets;
}

/* Retrieve handshake hashes */
int ssl_handshake_hash(SSL_CONNECTION *s,
    unsigned char *out, size_t outlen,
    size_t *hashlen)
{
    EVP_MD_CTX *ctx = NULL;
    EVP_MD_CTX *hdgst = s->s3.handshake_dgst;
    int hashleni = EVP_MD_CTX_get_size(hdgst);
    int ret = 0;

    if (hashleni < 0 || (size_t)hashleni > outlen) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    ctx = EVP_MD_CTX_new();
    if (ctx == NULL) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
        || EVP_DigestFinal_ex(ctx, out, NULL) <= 0) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    *hashlen = hashleni;

    ret = 1;
err:
    EVP_MD_CTX_free(ctx);
    return ret;
}

int SSL_session_reused(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->hit;
}

int SSL_is_server(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->server;
}

#ifndef OPENSSL_NO_DEPRECATED_1_1_0
void SSL_set_debug(SSL *s, int debug)
{
    /* Old function was do-nothing anyway... */
    (void)s;
    (void)debug;
}
#endif

void SSL_set_security_level(SSL *s, int level)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->cert->sec_level = level;
}

int SSL_get_security_level(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->cert->sec_level;
}

void SSL_set_security_callback(SSL *s,
    int (*cb)(const SSL *s, const SSL_CTX *ctx,
        int op, int bits, int nid,
        void *other, void *ex))
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->cert->sec_cb = cb;
}

int (*SSL_get_security_callback(const SSL *s))(const SSL *s,
    const SSL_CTX *ctx, int op,
    int bits, int nid, void *other,
    void *ex)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->cert->sec_cb;
}

void SSL_set0_security_ex_data(SSL *s, void *ex)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return;

    sc->cert->sec_ex = ex;
}

void *SSL_get0_security_ex_data(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->cert->sec_ex;
}

void SSL_CTX_set_security_level(SSL_CTX *ctx, int level)
{
    ctx->cert->sec_level = level;
}

int SSL_CTX_get_security_level(const SSL_CTX *ctx)
{
    return ctx->cert->sec_level;
}

void SSL_CTX_set_security_callback(SSL_CTX *ctx,
    int (*cb)(const SSL *s, const SSL_CTX *ctx,
        int op, int bits, int nid,
        void *other, void *ex))
{
    ctx->cert->sec_cb = cb;
}

int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx))(const SSL *s,
    const SSL_CTX *ctx,
    int op, int bits,
    int nid,
    void *other,
    void *ex)
{
    return ctx->cert->sec_cb;
}

void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex)
{
    ctx->cert->sec_ex = ex;
}

void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx)
{
    return ctx->cert->sec_ex;
}

uint64_t SSL_CTX_get_options(const SSL_CTX *ctx)
{
    return ctx->options;
}

uint64_t SSL_get_options(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_get_options(s);
#endif

    if (sc == NULL)
        return 0;

    return sc->options;
}

uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t op)
{
    return ctx->options |= op;
}

uint64_t SSL_set_options(SSL *s, uint64_t op)
{
    SSL_CONNECTION *sc;
    OSSL_PARAM options[2], *opts = options;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_set_options(s, op);
#endif

    sc = SSL_CONNECTION_FROM_SSL(s);
    if (sc == NULL)
        return 0;

    sc->options |= op;

    *opts++ = OSSL_PARAM_construct_uint64(OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS,
        &sc->options);
    *opts = OSSL_PARAM_construct_end();

    /* Ignore return value */
    sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options);
    sc->rlayer.wrlmethod->set_options(sc->rlayer.wrl, options);

    return sc->options;
}

uint64_t SSL_CTX_clear_options(SSL_CTX *ctx, uint64_t op)
{
    return ctx->options &= ~op;
}

uint64_t SSL_clear_options(SSL *s, uint64_t op)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
    OSSL_PARAM options[2], *opts = options;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_clear_options(s, op);
#endif

    if (sc == NULL)
        return 0;

    sc->options &= ~op;

    *opts++ = OSSL_PARAM_construct_uint64(OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS,
        &sc->options);
    *opts = OSSL_PARAM_construct_end();

    /* Ignore return value */
    sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options);
    sc->rlayer.wrlmethod->set_options(sc->rlayer.wrl, options);

    return sc->options;
}

STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return NULL;

    return sc->verified_chain;
}

IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);

#ifndef OPENSSL_NO_CT

/*
 * Moves SCTs from the |src| stack to the |dst| stack.
 * The source of each SCT will be set to |origin|.
 * If |dst| points to a NULL pointer, a new stack will be created and owned by
 * the caller.
 * Returns the number of SCTs moved, or a negative integer if an error occurs.
 * The |dst| stack is created and possibly partially populated even in case
 * of error, likewise the |src| stack may be left in an intermediate state.
 */
static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src,
    sct_source_t origin)
{
    int scts_moved = 0;
    SCT *sct = NULL;

    if (*dst == NULL) {
        *dst = sk_SCT_new_null();
        if (*dst == NULL) {
            ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
            goto err;
        }
    }

    while ((sct = sk_SCT_pop(src)) != NULL) {
        if (SCT_set_source(sct, origin) != 1)
            goto err;

        if (!sk_SCT_push(*dst, sct))
            goto err;
        scts_moved += 1;
    }

    return scts_moved;
err:
    SCT_free(sct);
    return -1;
}

/*
 * Look for data collected during ServerHello and parse if found.
 * Returns the number of SCTs extracted.
 */
static int ct_extract_tls_extension_scts(SSL_CONNECTION *s)
{
    int scts_extracted = 0;

    if (s->ext.scts != NULL) {
        const unsigned char *p = s->ext.scts;
        STACK_OF(SCT) *scts = o2i_SCT_LIST(NULL, &p, s->ext.scts_len);

        scts_extracted = ct_move_scts(&s->scts, scts, SCT_SOURCE_TLS_EXTENSION);

        SCT_LIST_free(scts);
    }

    return scts_extracted;
}

/*
 * Checks for an OCSP response and then attempts to extract any SCTs found if it
 * contains an SCT X509 extension. They will be stored in |s->scts|.
 * Returns:
 * - The number of SCTs extracted, assuming an OCSP response exists.
 * - 0 if no OCSP response exists or it contains no SCTs.
 * - A negative integer if an error occurs.
 */
static int ct_extract_ocsp_response_scts(SSL_CONNECTION *s)
{
#ifndef OPENSSL_NO_OCSP
    int scts_extracted = 0;
    OCSP_BASICRESP *br = NULL;
    OCSP_RESPONSE *rsp = NULL;
    STACK_OF(SCT) *scts = NULL;
    int ret;
    int i, j;

    if (s->ext.ocsp.resp_ex == NULL)
        goto err;

    for (j = 0; j < sk_OCSP_RESPONSE_num(s->ext.ocsp.resp_ex); j++) {
        rsp = sk_OCSP_RESPONSE_value(s->ext.ocsp.resp_ex, j);
        if (rsp == NULL)
            goto err;

        br = OCSP_response_get1_basic(rsp);
        if (br == NULL)
            goto err;

        for (i = 0; i < OCSP_resp_count(br); ++i) {
            OCSP_SINGLERESP *single = OCSP_resp_get0(br, i);

            if (single == NULL)
                continue;

            scts = OCSP_SINGLERESP_get1_ext_d2i(single,
                NID_ct_cert_scts, NULL, NULL);
            if (scts == NULL) {
                scts_extracted = -1;
                goto err;
            }

            ret = ct_move_scts(&s->scts, scts,
                SCT_SOURCE_OCSP_STAPLED_RESPONSE);

            SCT_LIST_free(scts);

            if (ret < 0) {
                scts_extracted = -1;
                goto err;
            }

            scts_extracted += ret;
        }

        OCSP_BASICRESP_free(br);
        /* to assure that is not freed twice */
        br = NULL;
    }
err:
    OCSP_BASICRESP_free(br);
    return scts_extracted;
#else
    /* Behave as if no OCSP response exists */
    return 0;
#endif
}

/*
 * Attempts to extract SCTs from the peer certificate.
 * Return the number of SCTs extracted, or a negative integer if an error
 * occurs.
 */
static int ct_extract_x509v3_extension_scts(SSL_CONNECTION *s)
{
    int scts_extracted = 0;
    X509 *cert = s->session != NULL ? s->session->peer : NULL;

    if (cert != NULL) {
        STACK_OF(SCT) *scts = X509_get_ext_d2i(cert, NID_ct_precert_scts, NULL, NULL);

        scts_extracted = ct_move_scts(&s->scts, scts, SCT_SOURCE_X509V3_EXTENSION);

        SCT_LIST_free(scts);
    }

    return scts_extracted;
}

/*
 * Attempts to find all received SCTs by checking TLS extensions, the OCSP
 * response (if it exists) and X509v3 extensions in the certificate.
 * Returns NULL if an error occurs.
 */
const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return NULL;

    if (!sc->scts_parsed) {
        if (ct_extract_tls_extension_scts(sc) < 0 || ct_extract_ocsp_response_scts(sc) < 0 || ct_extract_x509v3_extension_scts(sc) < 0)
            goto err;

        sc->scts_parsed = 1;
    }
    return sc->scts;
err:
    return NULL;
}

static int ct_permissive(const CT_POLICY_EVAL_CTX *ctx,
    const STACK_OF(SCT) *scts, void *unused_arg)
{
    return 1;
}

static int ct_strict(const CT_POLICY_EVAL_CTX *ctx,
    const STACK_OF(SCT) *scts, void *unused_arg)
{
    int count = scts != NULL ? sk_SCT_num(scts) : 0;
    int i;

    for (i = 0; i < count; ++i) {
        SCT *sct = sk_SCT_value(scts, i);
        int status = SCT_get_validation_status(sct);

        if (status == SCT_VALIDATION_STATUS_VALID)
            return 1;
    }
    ERR_raise(ERR_LIB_SSL, SSL_R_NO_VALID_SCTS);
    return 0;
}

int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback,
    void *arg)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    /*
     * Since code exists that uses the custom extension handler for CT, look
     * for this and throw an error if they have already registered to use CT.
     */
    if (callback != NULL && SSL_CTX_has_client_custom_ext(s->ctx, TLSEXT_TYPE_signed_certificate_timestamp)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED);
        return 0;
    }

    if (callback != NULL) {
        /*
         * If we are validating CT, then we MUST accept SCTs served via OCSP
         */
        if (!SSL_set_tlsext_status_type(s, TLSEXT_STATUSTYPE_ocsp))
            return 0;
    }

    sc->ct_validation_callback = callback;
    sc->ct_validation_callback_arg = arg;

    return 1;
}

int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx,
    ssl_ct_validation_cb callback, void *arg)
{
    /*
     * Since code exists that uses the custom extension handler for CT, look for
     * this and throw an error if they have already registered to use CT.
     */
    if (callback != NULL && SSL_CTX_has_client_custom_ext(ctx, TLSEXT_TYPE_signed_certificate_timestamp)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED);
        return 0;
    }

    ctx->ct_validation_callback = callback;
    ctx->ct_validation_callback_arg = arg;
    return 1;
}

int SSL_ct_is_enabled(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->ct_validation_callback != NULL;
}

int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx)
{
    return ctx->ct_validation_callback != NULL;
}

int ssl_validate_ct(SSL_CONNECTION *s)
{
    int ret = 0;
    X509 *cert = s->session != NULL ? s->session->peer : NULL;
    X509 *issuer;
    SSL_DANE *dane = &s->dane;
    CT_POLICY_EVAL_CTX *ctx = NULL;
    const STACK_OF(SCT) *scts;

    /*
     * If no callback is set, the peer is anonymous, or its chain is invalid,
     * skip SCT validation - just return success.  Applications that continue
     * handshakes without certificates, with unverified chains, or pinned leaf
     * certificates are outside the scope of the WebPKI and CT.
     *
     * The above exclusions notwithstanding the vast majority of peers will
     * have rather ordinary certificate chains validated by typical
     * applications that perform certificate verification and therefore will
     * process SCTs when enabled.
     */
    if (s->ct_validation_callback == NULL || cert == NULL || s->verify_result != X509_V_OK || s->verified_chain == NULL || sk_X509_num(s->verified_chain) <= 1)
        return 1;

    /*
     * CT not applicable for chains validated via DANE-TA(2) or DANE-EE(3)
     * trust-anchors.  See https://tools.ietf.org/html/rfc7671#section-4.2
     */
    if (DANETLS_ENABLED(dane) && dane->mtlsa != NULL) {
        switch (dane->mtlsa->usage) {
        case DANETLS_USAGE_DANE_TA:
        case DANETLS_USAGE_DANE_EE:
            return 1;
        }
    }

    ctx = CT_POLICY_EVAL_CTX_new_ex(SSL_CONNECTION_GET_CTX(s)->libctx,
        SSL_CONNECTION_GET_CTX(s)->propq);
    if (ctx == NULL) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CT_LIB);
        goto end;
    }

    issuer = sk_X509_value(s->verified_chain, 1);
    CT_POLICY_EVAL_CTX_set1_cert(ctx, cert);
    CT_POLICY_EVAL_CTX_set1_issuer(ctx, issuer);
    CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ctx,
        SSL_CONNECTION_GET_CTX(s)->ctlog_store);
    CT_POLICY_EVAL_CTX_set_time(
        ctx, (uint64_t)SSL_SESSION_get_time_ex(s->session) * 1000);

    scts = SSL_get0_peer_scts(SSL_CONNECTION_GET_SSL(s));

    /*
     * This function returns success (> 0) only when all the SCTs are valid, 0
     * when some are invalid, and < 0 on various internal errors (out of
     * memory, etc.).  Having some, or even all, invalid SCTs is not sufficient
     * reason to abort the handshake, that decision is up to the callback.
     * Therefore, we error out only in the unexpected case that the return
     * value is negative.
     *
     * XXX: One might well argue that the return value of this function is an
     * unfortunate design choice.  Its job is only to determine the validation
     * status of each of the provided SCTs.  So long as it correctly separates
     * the wheat from the chaff it should return success.  Failure in this case
     * ought to correspond to an inability to carry out its duties.
     */
    if (SCT_LIST_validate(scts, ctx) < 0) {
        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_SCT_VERIFICATION_FAILED);
        goto end;
    }

    ret = s->ct_validation_callback(ctx, scts, s->ct_validation_callback_arg);
    if (ret < 0)
        ret = 0; /* This function returns 0 on failure */
    if (!ret)
        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_CALLBACK_FAILED);

end:
    CT_POLICY_EVAL_CTX_free(ctx);
    /*
     * With SSL_VERIFY_NONE the session may be cached and reused despite a
     * failure return code here.  Also the application may wish the complete
     * the handshake, and then disconnect cleanly at a higher layer, after
     * checking the verification status of the completed connection.
     *
     * We therefore force a certificate verification failure which will be
     * visible via SSL_get_verify_result() and cached as part of any resumed
     * session.
     *
     * Note: the permissive callback is for information gathering only, always
     * returns success, and does not affect verification status.  Only the
     * strict callback or a custom application-specified callback can trigger
     * connection failure or record a verification error.
     */
    if (ret <= 0)
        s->verify_result = X509_V_ERR_NO_VALID_SCTS;
    return ret;
}

int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode)
{
    switch (validation_mode) {
    default:
        ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE);
        return 0;
    case SSL_CT_VALIDATION_PERMISSIVE:
        return SSL_CTX_set_ct_validation_callback(ctx, ct_permissive, NULL);
    case SSL_CT_VALIDATION_STRICT:
        return SSL_CTX_set_ct_validation_callback(ctx, ct_strict, NULL);
    }
}

int SSL_enable_ct(SSL *s, int validation_mode)
{
    switch (validation_mode) {
    default:
        ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE);
        return 0;
    case SSL_CT_VALIDATION_PERMISSIVE:
        return SSL_set_ct_validation_callback(s, ct_permissive, NULL);
    case SSL_CT_VALIDATION_STRICT:
        return SSL_set_ct_validation_callback(s, ct_strict, NULL);
    }
}

int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx)
{
    return CTLOG_STORE_load_default_file(ctx->ctlog_store);
}

int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
{
    return CTLOG_STORE_load_file(ctx->ctlog_store, path);
}

void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs)
{
    CTLOG_STORE_free(ctx->ctlog_store);
    ctx->ctlog_store = logs;
}

const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx)
{
    return ctx->ctlog_store;
}

#endif /* OPENSSL_NO_CT */

void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn cb,
    void *arg)
{
    c->client_hello_cb = cb;
    c->client_hello_cb_arg = arg;
}

void SSL_CTX_set_new_pending_conn_cb(SSL_CTX *c, SSL_new_pending_conn_cb_fn cb,
    void *arg)
{
    c->new_pending_conn_cb = cb;
    c->new_pending_conn_arg = arg;
}

#ifndef OPENSSL_NO_DEPRECATED_4_0
int SSL_client_hello_isv2(SSL *s)
{
    return 0;
}
#endif

unsigned int SSL_client_hello_get0_legacy_version(SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL)
        return 0;
    return sc->clienthello->legacy_version;
}

size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL)
        return 0;
    if (out != NULL)
        *out = sc->clienthello->random;
    return SSL3_RANDOM_SIZE;
}

size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL)
        return 0;
    if (out != NULL)
        *out = sc->clienthello->session_id;
    return sc->clienthello->session_id_len;
}

size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL)
        return 0;
    if (out != NULL)
        *out = PACKET_data(&sc->clienthello->ciphersuites);
    return PACKET_remaining(&sc->clienthello->ciphersuites);
}

size_t SSL_client_hello_get0_compression_methods(SSL *s, const unsigned char **out)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL)
        return 0;
    if (out != NULL)
        *out = sc->clienthello->compressions;
    return sc->clienthello->compressions_len;
}

int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen)
{
    RAW_EXTENSION *ext;
    int *present;
    size_t num = 0, i;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL || out == NULL || outlen == NULL)
        return 0;
    for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) {
        ext = sc->clienthello->pre_proc_exts + i;
        if (ext->present)
            num++;
    }
    if (num == 0) {
        *out = NULL;
        *outlen = 0;
        return 1;
    }
    if ((present = OPENSSL_malloc_array(num, sizeof(*present))) == NULL)
        return 0;
    for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) {
        ext = sc->clienthello->pre_proc_exts + i;
        if (ext->present) {
            if (ext->received_order >= num)
                goto err;
            present[ext->received_order] = ext->type;
        }
    }
    *out = present;
    *outlen = num;
    return 1;
err:
    OPENSSL_free(present);
    return 0;
}

int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts, size_t *num_exts)
{
    RAW_EXTENSION *ext;
    size_t num = 0, i;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL || num_exts == NULL)
        return 0;
    for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) {
        ext = sc->clienthello->pre_proc_exts + i;
        if (ext->present)
            num++;
    }
    if (num == 0) {
        *num_exts = 0;
        return 1;
    }
    if (exts == NULL) {
        *num_exts = num;
        return 1;
    }
    if (*num_exts < num)
        return 0;
    for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) {
        ext = sc->clienthello->pre_proc_exts + i;
        if (ext->present) {
            if (ext->received_order >= num)
                return 0;
            exts[ext->received_order] = ext->type;
        }
    }
    *num_exts = num;
    return 1;
}

int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out,
    size_t *outlen)
{
    size_t i;
    RAW_EXTENSION *r;
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (sc->clienthello == NULL)
        return 0;
    for (i = 0; i < sc->clienthello->pre_proc_exts_len; ++i) {
        r = sc->clienthello->pre_proc_exts + i;
        if (r->present && r->type == type) {
            if (out != NULL)
                *out = PACKET_data(&r->data);
            if (outlen != NULL)
                *outlen = PACKET_remaining(&r->data);
            return 1;
        }
    }
    return 0;
}

int SSL_free_buffers(SSL *ssl)
{
    RECORD_LAYER *rl;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);

    if (sc == NULL)
        return 0;

    rl = &sc->rlayer;

    return rl->rrlmethod->free_buffers(rl->rrl)
        && rl->wrlmethod->free_buffers(rl->wrl);
}

int SSL_alloc_buffers(SSL *ssl)
{
    RECORD_LAYER *rl;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

    if (sc == NULL)
        return 0;

    /* QUIC always has buffers allocated. */
    if (IS_QUIC(ssl))
        return 1;

    rl = &sc->rlayer;

    return rl->rrlmethod->alloc_buffers(rl->rrl)
        && rl->wrlmethod->alloc_buffers(rl->wrl);
}

void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb)
{
    ctx->keylog_callback = cb;
}

SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx)
{
    return ctx->keylog_callback;
}

static int nss_keylog_int(const char *prefix,
    SSL_CONNECTION *sc,
    const uint8_t *parameter_1,
    size_t parameter_1_len,
    const uint8_t *parameter_2,
    size_t parameter_2_len)
{
    char *out = NULL;
    char *cursor = NULL;
    size_t out_len = 0, i, prefix_len;
    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc);

#ifndef OPENSSL_NO_SSLKEYLOG
    if (sctx->keylog_callback == NULL && sctx->do_sslkeylog == 0)
        return 1;
#else
    if (sctx->keylog_callback == NULL)
        return 1;
#endif

    /*
     * Our output buffer will contain the following strings, rendered with
     * space characters in between, terminated by a NULL character: first the
     * prefix, then the first parameter, then the second parameter. The
     * meaning of each parameter depends on the specific key material being
     * logged. Note that the first and second parameters are encoded in
     * hexadecimal, so we need a buffer that is twice their lengths.
     */
    prefix_len = strlen(prefix);
    out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3;
    if ((out = cursor = OPENSSL_malloc(out_len)) == NULL)
        return 0;

    memcpy(cursor, prefix, prefix_len);
    cursor += prefix_len;
    *cursor++ = ' ';

    for (i = 0; i < parameter_1_len; ++i)
        cursor += ossl_to_lowerhex(cursor, parameter_1[i]);
    *cursor++ = ' ';

    for (i = 0; i < parameter_2_len; ++i)
        cursor += ossl_to_lowerhex(cursor, parameter_2[i]);
    *cursor = '\0';

#ifndef OPENSSL_NO_SSLKEYLOG
    if (sctx->do_sslkeylog == 1)
        do_sslkeylogfile(SSL_CONNECTION_GET_SSL(sc), (const char *)out);
#endif
    if (sctx->keylog_callback != NULL)
        sctx->keylog_callback(SSL_CONNECTION_GET_USER_SSL(sc), (const char *)out);
    OPENSSL_clear_free(out, out_len);
    return 1;
}

int ssl_log_rsa_client_key_exchange(SSL_CONNECTION *sc,
    const uint8_t *encrypted_premaster,
    size_t encrypted_premaster_len,
    const uint8_t *premaster,
    size_t premaster_len)
{
    if (encrypted_premaster_len < 8) {
        SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    /* We only want the first 8 bytes of the encrypted premaster as a tag. */
    return nss_keylog_int("RSA",
        sc,
        encrypted_premaster,
        8,
        premaster,
        premaster_len);
}

int ssl_log_secret(SSL_CONNECTION *sc,
    const char *label,
    const uint8_t *secret,
    size_t secret_len)
{
    return nss_keylog_int(label,
        sc,
        sc->s3.client_random,
        SSL3_RANDOM_SIZE,
        secret,
        secret_len);
}

int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites)
{
    if (PACKET_remaining(cipher_suites) == 0) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_CIPHERS_SPECIFIED);
        return 0;
    }

    if (PACKET_remaining(cipher_suites) % TLS_CIPHER_LEN != 0) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
        return 0;
    }

    OPENSSL_free(s->s3.tmp.ciphers_raw);
    s->s3.tmp.ciphers_raw = NULL;
    s->s3.tmp.ciphers_rawlen = 0;

    if (!PACKET_memdup(cipher_suites, &s->s3.tmp.ciphers_raw,
            &s->s3.tmp.ciphers_rawlen)) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
        return 0;
    }
    return 1;
}

int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len,
    int isv2format, STACK_OF(SSL_CIPHER) **sk,
    STACK_OF(SSL_CIPHER) **scsvs)
{
    PACKET pkt;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL || isv2format)
        return 0;

    if (!PACKET_buf_init(&pkt, bytes, len))
        return 0;
    return ossl_bytes_to_cipher_list(sc, &pkt, sk, scsvs, 0);
}

int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites,
    STACK_OF(SSL_CIPHER) **skp,
    STACK_OF(SSL_CIPHER) **scsvs_out,
    int fatal)
{
    const SSL_CIPHER *c;
    STACK_OF(SSL_CIPHER) *sk = NULL;
    STACK_OF(SSL_CIPHER) *scsvs = NULL;
    int n = TLS_CIPHER_LEN;
    unsigned char cipher[TLS_CIPHER_LEN];

    if (PACKET_remaining(cipher_suites) == 0) {
        if (fatal)
            SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_CIPHERS_SPECIFIED);
        else
            ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHERS_SPECIFIED);
        return 0;
    }

    if (PACKET_remaining(cipher_suites) % n != 0) {
        if (fatal)
            SSLfatal(s, SSL_AD_DECODE_ERROR,
                SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
        else
            ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
        return 0;
    }

    sk = sk_SSL_CIPHER_new_null();
    scsvs = sk_SSL_CIPHER_new_null();
    if (sk == NULL || scsvs == NULL) {
        if (fatal)
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
        else
            ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
        goto err;
    }

    while (PACKET_copy_bytes(cipher_suites, cipher, n)) {
        c = ssl_get_cipher_by_char(s, cipher, 1);
        if (c != NULL) {
            if ((c->valid && !sk_SSL_CIPHER_push(sk, c)) || (!c->valid && !sk_SSL_CIPHER_push(scsvs, c))) {
                if (fatal)
                    SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
                else
                    ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
                goto err;
            }
        }
    }
    if (PACKET_remaining(cipher_suites) > 0) {
        if (fatal)
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH);
        else
            ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        goto err;
    }

    if (skp != NULL)
        *skp = sk;
    else
        sk_SSL_CIPHER_free(sk);
    if (scsvs_out != NULL)
        *scsvs_out = scsvs;
    else
        sk_SSL_CIPHER_free(scsvs);
    return 1;
err:
    sk_SSL_CIPHER_free(sk);
    sk_SSL_CIPHER_free(scsvs);
    return 0;
}

int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data)
{
    ctx->max_early_data = max_early_data;

    return 1;
}

uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx)
{
    return ctx->max_early_data;
}

int SSL_set_max_early_data(SSL *s, uint32_t max_early_data)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    sc->max_early_data = max_early_data;

    return 1;
}

uint32_t SSL_get_max_early_data(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->max_early_data;
}

int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data)
{
    ctx->recv_max_early_data = recv_max_early_data;

    return 1;
}

uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx)
{
    return ctx->recv_max_early_data;
}

int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    sc->recv_max_early_data = recv_max_early_data;

    return 1;
}

uint32_t SSL_get_recv_max_early_data(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->recv_max_early_data;
}

__owur unsigned int ssl_get_max_send_fragment(const SSL_CONNECTION *sc)
{
    /* Return any active Max Fragment Len extension */
    if (sc->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(sc->session))
        return GET_MAX_FRAGMENT_LENGTH(sc->session);

    /* return current SSL connection setting */
    return (unsigned int)sc->max_send_fragment;
}

__owur unsigned int ssl_get_split_send_fragment(const SSL_CONNECTION *sc)
{
    /* Return a value regarding an active Max Fragment Len extension */
    if (sc->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(sc->session)
        && sc->split_send_fragment > GET_MAX_FRAGMENT_LENGTH(sc->session))
        return GET_MAX_FRAGMENT_LENGTH(sc->session);

    /* else limit |split_send_fragment| to current |max_send_fragment| */
    if (sc->split_send_fragment > sc->max_send_fragment)
        return (unsigned int)sc->max_send_fragment;

    /* return current SSL connection setting */
    return (unsigned int)sc->split_send_fragment;
}

int SSL_stateless(SSL *s)
{
    int ret;
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return 0;

    /* Ensure there is no state left over from a previous invocation */
    if (!SSL_clear(s))
        return 0;

    ERR_clear_error();

    sc->s3.flags |= TLS1_FLAGS_STATELESS;
    ret = SSL_accept(s);
    sc->s3.flags &= ~TLS1_FLAGS_STATELESS;

    if (ret > 0 && sc->ext.cookieok)
        return 1;

    if (sc->hello_retry_request == SSL_HRR_PENDING && !ossl_statem_in_error(sc))
        return 0;

    return -1;
}

void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val)
{
    ctx->pha_enabled = val;
}

void SSL_set_post_handshake_auth(SSL *ssl, int val)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);

    if (sc == NULL)
        return;

    sc->pha_enabled = val;
}

int SSL_verify_client_post_handshake(SSL *ssl)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(ssl)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
        return 0;
    }
#endif

    if (sc == NULL)
        return 0;

    if (!SSL_CONNECTION_IS_TLS13(sc)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
        return 0;
    }
    if (!sc->server) {
        ERR_raise(ERR_LIB_SSL, SSL_R_NOT_SERVER);
        return 0;
    }

    if (!SSL_is_init_finished(ssl)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_STILL_IN_INIT);
        return 0;
    }

    switch (sc->post_handshake_auth) {
    case SSL_PHA_NONE:
        ERR_raise(ERR_LIB_SSL, SSL_R_EXTENSION_NOT_RECEIVED);
        return 0;
    default:
    case SSL_PHA_EXT_SENT:
        ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
        return 0;
    case SSL_PHA_EXT_RECEIVED:
        break;
    case SSL_PHA_REQUEST_PENDING:
        ERR_raise(ERR_LIB_SSL, SSL_R_REQUEST_PENDING);
        return 0;
    case SSL_PHA_REQUESTED:
        ERR_raise(ERR_LIB_SSL, SSL_R_REQUEST_SENT);
        return 0;
    }

    sc->post_handshake_auth = SSL_PHA_REQUEST_PENDING;

    /* checks verify_mode and algorithm_auth */
    if (!send_certificate_request(sc)) {
        sc->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */
        ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CONFIG);
        return 0;
    }

    ossl_statem_set_in_init(sc, 1);
    return 1;
}

int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx,
    SSL_CTX_generate_session_ticket_fn gen_cb,
    SSL_CTX_decrypt_session_ticket_fn dec_cb,
    void *arg)
{
    ctx->generate_ticket_cb = gen_cb;
    ctx->decrypt_ticket_cb = dec_cb;
    ctx->ticket_cb_data = arg;
    return 1;
}

void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx,
    SSL_allow_early_data_cb_fn cb,
    void *arg)
{
    ctx->allow_early_data_cb = cb;
    ctx->allow_early_data_cb_data = arg;
}

void SSL_set_allow_early_data_cb(SSL *s,
    SSL_allow_early_data_cb_fn cb,
    void *arg)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);

    if (sc == NULL)
        return;

    sc->allow_early_data_cb = cb;
    sc->allow_early_data_cb_data = arg;
}

const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx,
    const char *name,
    const char *properties)
{
    const EVP_CIPHER *ciph;

    ERR_set_mark();
    ciph = EVP_CIPHER_fetch(libctx, name, properties);
    if (ciph != NULL) {
        OSSL_PARAM params[2];
        int decrypt_only = 0;

        params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_DECRYPT_ONLY,
            &decrypt_only);
        params[1] = OSSL_PARAM_construct_end();
        if (EVP_CIPHER_get_params((EVP_CIPHER *)ciph, params)
            && decrypt_only) {
            /* If a cipher is decrypt-only, it is unusable */
            EVP_CIPHER_free((EVP_CIPHER *)ciph);
            ciph = NULL;
        }
    }
    ERR_pop_to_mark();
    return ciph;
}

int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher)
{
    /* Don't up-ref an implicit EVP_CIPHER */
    if (EVP_CIPHER_get0_provider(cipher) == NULL)
        return 1;

    /*
     * The cipher was explicitly fetched and therefore it is safe to cast
     * away the const
     */
    return EVP_CIPHER_up_ref((EVP_CIPHER *)cipher);
}

void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
{
    if (cipher == NULL)
        return;

    if (EVP_CIPHER_get0_provider(cipher) != NULL) {
        /*
         * The cipher was explicitly fetched and therefore it is safe to cast
         * away the const
         */
        EVP_CIPHER_free((EVP_CIPHER *)cipher);
    }
}

int ssl_evp_md_up_ref(const EVP_MD *md)
{
    /* Don't up-ref an implicit EVP_MD */
    if (EVP_MD_get0_provider(md) == NULL)
        return 1;

    /*
     * The digest was explicitly fetched and therefore it is safe to cast
     * away the const
     */
    return EVP_MD_up_ref((EVP_MD *)md);
}

void ssl_evp_md_free(const EVP_MD *md)
{
    if (md == NULL)
        return;

    if (EVP_MD_get0_provider(md) != NULL) {
        /*
         * The digest was explicitly fetched and therefore it is safe to cast
         * away the const
         */
        EVP_MD_free((EVP_MD *)md);
    }
}

int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    if (!ssl_security(sc, SSL_SECOP_TMP_DH,
            EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
        return 0;
    }
    EVP_PKEY_free(sc->cert->dh_tmp);
    sc->cert->dh_tmp = dhpkey;
    return 1;
}

int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey)
{
    if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
            EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
        return 0;
    }
    EVP_PKEY_free(ctx->cert->dh_tmp);
    ctx->cert->dh_tmp = dhpkey;
    return 1;
}

/* QUIC-specific methods which are supported on QUIC connections only. */
int SSL_handle_events(SSL *s)
{
    SSL_CONNECTION *sc;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_handle_events(s);
#endif

    sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
    if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc))
        /*
         * DTLSv1_handle_timeout returns 0 if the timer wasn't expired yet,
         * which we consider a success case. Theoretically DTLSv1_handle_timeout
         * can also return 0 if s is NULL or not a DTLS object, but we've
         * already ruled out those possibilities above, so this is not possible
         * here. Thus the only failure cases are where DTLSv1_handle_timeout
         * returns -1.
         */
        return DTLSv1_handle_timeout(s) >= 0;

    return 1;
}

int SSL_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)
{
    SSL_CONNECTION *sc;

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_get_event_timeout(s, tv, is_infinite);
#endif

    sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
    if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc)
        && DTLSv1_get_timeout(s, tv)) {
        *is_infinite = 0;
        return 1;
    }

    tv->tv_sec = 1000000;
    tv->tv_usec = 0;
    *is_infinite = 1;
    return 1;
}

int SSL_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_get_rpoll_descriptor(s, desc);
#endif

    if (sc == NULL || sc->rbio == NULL)
        return 0;

    return BIO_get_rpoll_descriptor(sc->rbio, desc);
}

int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_get_wpoll_descriptor(s, desc);
#endif

    if (sc == NULL || sc->wbio == NULL)
        return 0;

    return BIO_get_wpoll_descriptor(sc->wbio, desc);
}

int SSL_net_read_desired(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return SSL_want_read(s);

    return ossl_quic_get_net_read_desired(s);
#else
    return SSL_want_read(s);
#endif
}

int SSL_net_write_desired(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return SSL_want_write(s);

    return ossl_quic_get_net_write_desired(s);
#else
    return SSL_want_write(s);
#endif
}

int SSL_set_blocking_mode(SSL *s, int blocking)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return 0;

    return ossl_quic_conn_set_blocking_mode(s, blocking);
#else
    return 0;
#endif
}

int SSL_get_blocking_mode(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return -1;

    return ossl_quic_conn_get_blocking_mode(s);
#else
    return -1;
#endif
}

int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return 0;

    return ossl_quic_conn_set_initial_peer_addr(s, peer_addr);
#else
    return 0;
#endif
}

int SSL_shutdown_ex(SSL *ssl, uint64_t flags,
    const SSL_SHUTDOWN_EX_ARGS *args,
    size_t args_len)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return SSL_shutdown(ssl);

    return ossl_quic_conn_shutdown(ssl, flags, args, args_len);
#else
    return SSL_shutdown(ssl);
#endif
}

int SSL_stream_conclude(SSL *ssl, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return 0;

    return ossl_quic_conn_stream_conclude(ssl);
#else
    return 0;
#endif
}

SSL *SSL_new_stream(SSL *s, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return NULL;

    return ossl_quic_conn_stream_new(s, flags);
#else
    return NULL;
#endif
}

SSL *SSL_get0_connection(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return s;

    return ossl_quic_get0_connection(s);
#else
    return s;
#endif
}

int SSL_is_connection(SSL *s)
{
    return SSL_get0_connection(s) == s;
}

SSL *SSL_get0_listener(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return NULL;

    return ossl_quic_get0_listener(s);
#else
    return NULL;
#endif
}

SSL *SSL_get0_domain(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return NULL;

    return ossl_quic_get0_domain(s);
#else
    return NULL;
#endif
}

int SSL_is_listener(SSL *s)
{
    return SSL_get0_listener(s) == s;
}

int SSL_is_domain(SSL *s)
{
    return SSL_get0_domain(s) == s;
}

int SSL_get_stream_type(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return SSL_STREAM_TYPE_BIDI;

    return ossl_quic_get_stream_type(s);
#else
    return SSL_STREAM_TYPE_BIDI;
#endif
}

uint64_t SSL_get_stream_id(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return UINT64_MAX;

    return ossl_quic_get_stream_id(s);
#else
    return UINT64_MAX;
#endif
}

int SSL_is_stream_local(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return -1;

    return ossl_quic_is_stream_local(s);
#else
    return -1;
#endif
}

int SSL_set_default_stream_mode(SSL *s, uint32_t mode)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return 0;

    return ossl_quic_set_default_stream_mode(s, mode);
#else
    return 0;
#endif
}

int SSL_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return 0;

    return ossl_quic_set_incoming_stream_policy(s, policy, aec);
#else
    return 0;
#endif
}

SSL *SSL_accept_stream(SSL *s, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return NULL;

    return ossl_quic_accept_stream(s, flags);
#else
    return NULL;
#endif
}

size_t SSL_get_accept_stream_queue_len(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return 0;

    return ossl_quic_get_accept_stream_queue_len(s);
#else
    return 0;
#endif
}

int SSL_stream_reset(SSL *s,
    const SSL_STREAM_RESET_ARGS *args,
    size_t args_len)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return 0;

    return ossl_quic_stream_reset(s, args, args_len);
#else
    return 0;
#endif
}

int SSL_get_stream_read_state(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return SSL_STREAM_STATE_NONE;

    return ossl_quic_get_stream_read_state(s);
#else
    return SSL_STREAM_STATE_NONE;
#endif
}

int SSL_get_stream_write_state(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return SSL_STREAM_STATE_NONE;

    return ossl_quic_get_stream_write_state(s);
#else
    return SSL_STREAM_STATE_NONE;
#endif
}

int SSL_get_stream_read_error_code(SSL *s, uint64_t *app_error_code)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return -1;

    return ossl_quic_get_stream_read_error_code(s, app_error_code);
#else
    return -1;
#endif
}

int SSL_get_stream_write_error_code(SSL *s, uint64_t *app_error_code)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return -1;

    return ossl_quic_get_stream_write_error_code(s, app_error_code);
#else
    return -1;
#endif
}

int SSL_get_conn_close_info(SSL *s, SSL_CONN_CLOSE_INFO *info,
    size_t info_len)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(s))
        return -1;

    return ossl_quic_get_conn_close_info(s, info, info_len);
#else
    return -1;
#endif
}

int SSL_get_value_uint(SSL *s, uint32_t class_, uint32_t id,
    uint64_t *value)
{
#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_get_value_uint(s, class_, id, value);
#endif

    ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL);
    return 0;
}

int SSL_set_value_uint(SSL *s, uint32_t class_, uint32_t id,
    uint64_t value)
{
#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(s))
        return ossl_quic_set_value_uint(s, class_, id, value);
#endif

    ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL);
    return 0;
}

SSL *SSL_new_listener(SSL_CTX *ctx, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC_CTX(ctx))
        return NULL;

    return ossl_quic_new_listener(ctx, flags);
#else
    return NULL;
#endif
}

SSL *SSL_new_listener_from(SSL *ssl, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return NULL;

    return ossl_quic_new_listener_from(ssl, flags);
#else
    return NULL;
#endif
}

SSL *SSL_new_from_listener(SSL *ssl, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return NULL;

    return ossl_quic_new_from_listener(ssl, flags);
#else
    return NULL;
#endif
}

SSL *SSL_accept_connection(SSL *ssl, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return NULL;

    return ossl_quic_accept_connection(ssl, flags);
#else
    return NULL;
#endif
}

size_t SSL_get_accept_connection_queue_len(SSL *ssl)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return 0;

    return ossl_quic_get_accept_connection_queue_len(ssl);
#else
    return 0;
#endif
}

int SSL_get_peer_addr(SSL *ssl, BIO_ADDR *peer_addr)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return 0;

    return ossl_quic_get_peer_addr(ssl, peer_addr);
#else
    return 0;
#endif
}

int SSL_listen_ex(SSL *listener, SSL *new_conn)
{
#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(listener) && IS_QUIC(new_conn))
        return ossl_quic_peeloff_conn(listener, new_conn);
    else
#endif
        ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
            "SSL_listen_ex only operates on QUIC SSL objects");
    return 0;
}

int SSL_listen(SSL *ssl)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC(ssl))
        return 0;

    return ossl_quic_listen(ssl);
#else
    return 0;
#endif
}

SSL *SSL_new_domain(SSL_CTX *ctx, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
    if (!IS_QUIC_CTX(ctx))
        return NULL;

    return ossl_quic_new_domain(ctx, flags);
#else
    return NULL;
#endif
}

int ossl_adjust_domain_flags(uint64_t domain_flags, uint64_t *p_domain_flags)
{
    if ((domain_flags & ~OSSL_QUIC_SUPPORTED_DOMAIN_FLAGS) != 0) {
        ERR_raise_data(ERR_LIB_SSL, ERR_R_UNSUPPORTED,
            "unsupported domain flag requested");
        return 0;
    }

    if ((domain_flags & SSL_DOMAIN_FLAG_THREAD_ASSISTED) != 0)
        domain_flags |= SSL_DOMAIN_FLAG_MULTI_THREAD;

    if ((domain_flags & (SSL_DOMAIN_FLAG_MULTI_THREAD | SSL_DOMAIN_FLAG_SINGLE_THREAD)) == 0)
        domain_flags |= SSL_DOMAIN_FLAG_MULTI_THREAD;

    if ((domain_flags & SSL_DOMAIN_FLAG_SINGLE_THREAD) != 0
        && (domain_flags & SSL_DOMAIN_FLAG_MULTI_THREAD) != 0) {
        ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
            "mutually exclusive domain flags specified");
        return 0;
    }

    /*
     * Note: We treat MULTI_THREAD as a no-op in non-threaded builds, but
     * not THREAD_ASSISTED.
     */
#ifndef OPENSSL_THREADS
    if ((domain_flags & SSL_DOMAIN_FLAG_THREAD_ASSISTED) != 0) {
        ERR_raise_data(ERR_LIB_SSL, ERR_R_UNSUPPORTED,
            "thread assisted mode not available in this build");
        return 0;
    }
#endif

    *p_domain_flags = domain_flags;
    return 1;
}

int SSL_CTX_set_domain_flags(SSL_CTX *ctx, uint64_t domain_flags)
{
#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC_CTX(ctx)) {
        if (!ossl_adjust_domain_flags(domain_flags, &domain_flags))
            return 0;

        ctx->domain_flags = domain_flags;
        return 1;
    }
#endif

    ERR_raise_data(ERR_LIB_SSL, ERR_R_UNSUPPORTED,
        "domain flags unsupported on this kind of SSL_CTX");
    return 0;
}

int SSL_CTX_get_domain_flags(const SSL_CTX *ctx, uint64_t *domain_flags)
{
#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC_CTX(ctx)) {
        if (domain_flags != NULL)
            *domain_flags = ctx->domain_flags;

        return 1;
    }
#endif

    ERR_raise_data(ERR_LIB_SSL, ERR_R_UNSUPPORTED,
        "domain flags unsupported on this kind of SSL_CTX");
    return 0;
}

int SSL_get_domain_flags(const SSL *ssl, uint64_t *domain_flags)
{
#ifndef OPENSSL_NO_QUIC
    if (IS_QUIC(ssl))
        return ossl_quic_get_domain_flags(ssl, domain_flags);
#endif

    return 0;
}

int SSL_add_expected_rpk(SSL *s, EVP_PKEY *rpk)
{
    unsigned char *data = NULL;
    SSL_DANE *dane = SSL_get0_dane(s);
    int ret;

    if (dane == NULL || dane->dctx == NULL)
        return 0;
    if ((ret = i2d_PUBKEY(rpk, &data)) <= 0)
        return 0;

    ret = SSL_dane_tlsa_add(s, DANETLS_USAGE_DANE_EE,
              DANETLS_SELECTOR_SPKI,
              DANETLS_MATCHING_FULL,
              data, (size_t)ret)
        > 0;
    OPENSSL_free(data);
    return ret;
}

EVP_PKEY *SSL_get0_peer_rpk(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL || sc->session == NULL)
        return NULL;
    return sc->session->peer_rpk;
}

int SSL_get_negotiated_client_cert_type(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->ext.client_cert_type;
}

int SSL_get_negotiated_server_cert_type(const SSL *s)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->ext.server_cert_type;
}

static int validate_cert_type(const unsigned char *val, size_t len)
{
    size_t i;
    int saw_rpk = 0;
    int saw_x509 = 0;

    if (val == NULL && len == 0)
        return 1;

    if (val == NULL || len == 0)
        return 0;

    for (i = 0; i < len; i++) {
        switch (val[i]) {
        case TLSEXT_cert_type_rpk:
            if (saw_rpk)
                return 0;
            saw_rpk = 1;
            break;
        case TLSEXT_cert_type_x509:
            if (saw_x509)
                return 0;
            saw_x509 = 1;
            break;
        case TLSEXT_cert_type_pgp:
        case TLSEXT_cert_type_1609dot2:
        default:
            return 0;
        }
    }
    return 1;
}

static int set_cert_type(unsigned char **cert_type,
    size_t *cert_type_len,
    const unsigned char *val,
    size_t len)
{
    unsigned char *tmp = NULL;

    if (!validate_cert_type(val, len))
        return 0;

    if (val != NULL && (tmp = OPENSSL_memdup(val, len)) == NULL)
        return 0;

    OPENSSL_free(*cert_type);
    *cert_type = tmp;
    *cert_type_len = len;
    return 1;
}

int SSL_set1_client_cert_type(SSL *s, const unsigned char *val, size_t len)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return set_cert_type(&sc->client_cert_type, &sc->client_cert_type_len,
        val, len);
}

int SSL_set1_server_cert_type(SSL *s, const unsigned char *val, size_t len)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return set_cert_type(&sc->server_cert_type, &sc->server_cert_type_len,
        val, len);
}

int SSL_CTX_set1_client_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len)
{
    return set_cert_type(&ctx->client_cert_type, &ctx->client_cert_type_len,
        val, len);
}

int SSL_CTX_set1_server_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len)
{
    return set_cert_type(&ctx->server_cert_type, &ctx->server_cert_type_len,
        val, len);
}

int SSL_get0_client_cert_type(const SSL *s, unsigned char **t, size_t *len)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (t == NULL || len == NULL || sc == NULL)
        return 0;

    *t = sc->client_cert_type;
    *len = sc->client_cert_type_len;
    return 1;
}

int SSL_get0_server_cert_type(const SSL *s, unsigned char **t, size_t *len)
{
    const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);

    if (t == NULL || len == NULL || sc == NULL)
        return 0;

    *t = sc->server_cert_type;
    *len = sc->server_cert_type_len;
    return 1;
}

int SSL_CTX_get0_client_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len)
{
    if (t == NULL || len == NULL)
        return 0;

    *t = ctx->client_cert_type;
    *len = ctx->client_cert_type_len;
    return 1;
}

int SSL_CTX_get0_server_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len)
{
    if (t == NULL || len == NULL)
        return 0;

    *t = ctx->server_cert_type;
    *len = ctx->server_cert_type_len;
    return 1;
}

/*
 * RFC 8701 GREASE - returns a GREASE value (0x?A?A pattern) for the given
 * index.  Seeds are generated lazily on first use and remain stable for the
 * lifetime of the connection so that HelloRetryRequest replays get identical
 * values.
 */
uint16_t ossl_grease_value(SSL_CONNECTION *s, int index)
{
    uint16_t ret;

    if (index < 0 || index > OSSL_GREASE_LAST_INDEX)
        return 0x0A0A;

    if (!s->ext.grease_seeded) {
        if (RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx,
                s->ext.grease_seed,
                sizeof(s->ext.grease_seed), 0)
            <= 0)
            memset(s->ext.grease_seed, 0x42, sizeof(s->ext.grease_seed));
        s->ext.grease_seeded = 1;
    }

    /* Map seed byte to 0x?A?A pattern */
    ret = (s->ext.grease_seed[index] & 0xf0) | 0x0a;
    ret |= ret << 8;

    /* Ensure EXT2 differs from EXT1 */
    if (index == OSSL_GREASE_EXT2
        && ret == ossl_grease_value(s, OSSL_GREASE_EXT1))
        ret ^= 0x1010;

    return ret;
}
