/*
 * Copyright 1995-2025 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 <stdio.h>
#include "ssl_local.h"
#include "internal/e_os.h"
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
#include <openssl/ocsp.h>
#include <openssl/dh.h>
#include <openssl/engine.h>
#include <openssl/async.h>
#include <openssl/ct.h>
#include <openssl/trace.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "internal/nelem.h"
#include "internal/refcount.h"
#include "internal/ktls.h"
#include "quic/quic_local.h"

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));
}

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_zalloc(n * sizeof(*mdevp));
    mdord = OPENSSL_zalloc(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(dctx->mdevp, n * sizeof(*mdevp));
        if (mdevp == NULL)
            return -1;
        dctx->mdevp = mdevp;

        mdord = OPENSSL_realloc(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;

    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 && dlen != (size_t)EVP_MD_get_size(md)) {
        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 certifiate 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 = SSL3_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 (max_version == TLS1_VERSION)
            max_version = SSL3_VERSION;
#endif
#ifdef OPENSSL_NO_SSL3
        if (min_version == SSL3_VERSION)
            min_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_SSL3
            || (min_version <= SSL3_VERSION && SSL3_VERSION <= max_version)
#endif
#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;
    }

    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)
{
    ssl->type = type;

    ssl->lock = CRYPTO_THREAD_lock_new();
    if (ssl->lock == NULL)
        return 0;

    if (!CRYPTO_NEW_REF(&ssl->references, 1)) {
        CRYPTO_THREAD_lock_free(ssl->lock);
        return 0;
    }

    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data)) {
        CRYPTO_THREAD_lock_free(ssl->lock);
        CRYPTO_FREE_REF(&ssl->references);
        ssl->lock = NULL;
        return 0;
    }

    SSL_CTX_up_ref(ctx);
    ssl->ctx = ctx;

    ssl->defltmeth = ssl->method = method;

    return 1;
}

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->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;
    SSL_CTX_up_ref(ctx);
    s->session_ctx = ctx;
    if (ctx->ext.ecpointformats) {
        s->ext.ecpointformats =
            OPENSSL_memdup(ctx->ext.ecpointformats,
                           ctx->ext.ecpointformats_len);
        if (!s->ext.ecpointformats) {
            s->ext.ecpointformats_len = 0;
            goto err;
        }
        s->ext.ecpointformats_len =
            ctx->ext.ecpointformats_len;
    }
    if (ctx->ext.supportedgroups) {
        s->ext.supportedgroups =
            OPENSSL_memdup(ctx->ext.supportedgroups,
                           ctx->ext.supportedgroups_len
                                * sizeof(*ctx->ext.supportedgroups));
        if (!s->ext.supportedgroups) {
            s->ext.supportedgroups_len = 0;
            goto err;
        }
        s->ext.supportedgroups_len = ctx->ext.supportedgroups_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

    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)
{
#ifndef OPENSSL_NO_QUIC
    if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
        return 1;
#endif
    return 0;
}

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_host(SSL *s, const char *hostname)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    /* If a hostname is provided and parses as an IP address,
     * treat it as such. */
    if (hostname != NULL
        && X509_VERIFY_PARAM_set1_ip_asc(sc->param, hostname) == 1)
        return 1;

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

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

    if (sc == NULL)
        return 0;

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

        ip = a2i_IPADDRESS(hostname);
        if (ip) {
            /* 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)
            {
                OPENSSL_free(old_ip);
                /* There can be only one IP address */
                return 0;
            }

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

    return X509_VERIFY_PARAM_add1_host(sc->param, hostname, 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);

    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);

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

    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;

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

    /* Ignore return value */
    ssl_free_wbio_buffer(s);

    /* Ignore return value */
    RECORD_LAYER_clear(&s->rlayer);

    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.ecpointformats);
    OPENSSL_free(s->ext.peer_ecpointformats);
    OPENSSL_free(s->ext.supportedgroups);
    OPENSSL_free(s->ext.peer_supportedgroups);
    sk_X509_EXTENSION_pop_free(s->ext.ocsp.exts, X509_EXTENSION_free);
#ifndef OPENSSL_NO_OCSP
    sk_OCSP_RESPID_pop_free(s->ext.ocsp.ids, OCSP_RESPID_free);
#endif
#ifndef OPENSSL_NO_CT
    SCT_LIST_free(s->scts);
    OPENSSL_free(s->ext.scts);
#endif
    OPENSSL_free(s->ext.ocsp.resp);
    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);
}

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)
        BIO_up_ref(rbio);

    /*
     * 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 {
        BIO_up_ref(rbio);
        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 {
        BIO_up_ref(wbio);
        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.q);
        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 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;
}

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);
        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);
        /* 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)
{
    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 (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        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);
        return 0;
    }
    /*
     * If we are a client and haven't received the ServerHello etc then we
     * better do that
     */
    ossl_statem_check_finish_init(sc, 0);

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

        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;
        return ret;
    } else {
        return s->method->ssl_read(s, buf, num, readbytes);
    }
}

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

    if (num < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        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 = 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 || !sc->server) {
        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        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);
            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);
        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)
{
    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 (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        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;
        int ret;

        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;
        return ret;
    } else {
        return s->method->ssl_peek(s, buf, num, readbytes);
    }
}

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

    if (num < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        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 = 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, size_t *written)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

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

    if (sc == NULL)
        return 0;

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

    if (sc->shutdown & SSL_SENT_SHUTDOWN) {
        sc->rwstate = SSL_NOTHING;
        ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
        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);
        return 0;
    }
    /* If we are a client and haven't sent the Finished we better do that */
    ossl_statem_check_finish_init(sc, 1);

    if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
        int ret;
        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;
        return ret;
    } else {
        return s->method->ssl_write(s, buf, num, written);
    }
}

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

    if (sc == NULL)
        return 0;

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

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

    if (!BIO_get_ktls_send(sc->wbio)) {
        ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        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);
        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");
    return -1;
#else
    ret = ktls_sendfile(SSL_get_wfd(s), fd, offset, size, flags);
    if (ret < 0) {
#if defined(EAGAIN) && defined(EINTR) && defined(EBUSY)
        if ((get_last_sys_error() == EAGAIN) ||
            (get_last_sys_error() == EINTR) ||
            (get_last_sys_error() == EBUSY))
            BIO_set_retry_write(sc->wbio);
        else
#endif
            ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
        return ret;
    }
    sc->rwstate = SSL_NOTHING;
    return ret;
#endif
}

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

    if (num < 0) {
        ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
        return -1;
    }

    ret = ssl_write_internal(s, buf, (size_t)num, &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)
{
    int ret = ssl_write_internal(s, buf, num, 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;

    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);
            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);
        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);

#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);
        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;

            return ssl_start_async_job(s, &args, ssl_io_intern);
        } else {
            return s->method->ssl_shutdown(s);
        }
    } else {
        ERR_raise(ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT);
        return -1;
    }
}

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 perform syntax checks */
    if (ctx == NULL) {
        switch (cmd) {
        case SSL_CTRL_SET_GROUPS_LIST:
            return tls1_set_groups_list(ctx, NULL, NULL, parg);
        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, 0)) {
            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 (sc == NULL)
        return NULL;

    if (!sc->server
            || sc->peer_ciphers == NULL
            || size < 2)
        return NULL;

    p = buf;
    clntsk = sc->peer_ciphers;
    srvrsk = SSL_get_ciphers(s);
    if (clntsk == NULL || srvrsk == NULL)
        return NULL;

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

    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)
        return NULL;

    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, const 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_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);
}

/*
 * 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.
 */

SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
                        const SSL_METHOD *meth)
{
    SSL_CTX *ret = NULL;
#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;
    }

    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 these aren't available from the provider we'll get NULL returns.
     * That's fine but will cause errors later if SSLv3 is negotiated
     */
    ret->md5 = ssl_evp_md_fetch(libctx, NID_md5, propq);
    ret->sha1 = ssl_evp_md_fetch(libctx, NID_sha1, propq);

    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_ENGINE
# ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
#  define eng_strx(x)     #x
#  define eng_str(x)      eng_strx(x)
    /* Use specific client engine automatically... ignore errors */
    {
        ENGINE *eng;
        eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
        if (!eng) {
            ERR_clear_error();
            ENGINE_load_builtin_engines();
            eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
        }
        if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng))
            ERR_clear_error();
    }
# endif
#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;

    ssl_ctx_system_config(ret);

    return ret;
 err:
    SSL_CTX_free(ret);
    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);

    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(a, 0);

    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
#ifndef OPENSSL_NO_ENGINE
    tls_engine_finish(a->client_cert_engine);
#endif

    OPENSSL_free(a->ext.ecpointformats);
    OPENSSL_free(a->ext.supportedgroups);
    OPENSSL_free(a->ext.supported_groups_default);
    OPENSSL_free(a->ext.alpn);
    OPENSSL_secure_free(a->ext.secure);

    ssl_evp_md_free(a->md5);
    ssl_evp_md_free(a->sha1);

    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);

    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);

    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 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
                && TLS1_get_version(&s->ssl) == TLS1_2_VERSION))
        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 (TLS1_get_version(&s->ssl) == TLS1_2_VERSION) {
        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 if peer supports it */
    if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED25519)
            && pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN
            && TLS1_get_version(&s->ssl) == TLS1_2_VERSION)
            mask_a |= SSL_aECDSA;

    /* Allow Ed448 for TLS 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
            && TLS1_get_version(&s->ssl) == TLS1_2_VERSION)
            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(s->session_ctx, (unsigned long)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;
    unsigned long l;
    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;

    /*
     * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
     * where we do encode the error
     */
    if (check_err && (l = ERR_peek_error()) != 0) {
        if (ERR_GET_LIB(l) == ERR_LIB_SYS)
            return SSL_ERROR_SYSCALL;
        else
            return SSL_ERROR_SSL;
    }

#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 (sc->handshake_func == NULL) {
        ERR_raise(ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
        return -1;
    }

    ossl_statem_check_finish_init(sc, -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);
        }
    }
    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)) {
        ossl_quic_set_accept_state(s);
        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)) {
        ossl_quic_set_connect_state(s);
        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)
{
    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;
}

int ssl_undefined_const_function(const SSL *s)
{
    return 0;
}

const SSL_METHOD *ssl_bad_method(int ver)
{
    ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return NULL;
}

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 a 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) {
        return NULL;
    }

    if (!custom_exts_copy_flags(&new_cert->custext, &sc->cert->custext)) {
        ssl_cert_free(new_cert);
        return NULL;
    }

    ssl_cert_free(sc->cert);
    sc->cert = new_cert;

    /*
     * 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)))
        return NULL;

    /*
     * 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_CTX_up_ref(ctx);
    SSL_CTX_free(ssl->ctx);     /* decrement reference count */
    ssl->ctx = ctx;

    return ssl->ctx;
}

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);
    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(SSL_CTX *ctx, size_t block_size)
{
    if (IS_QUIC_CTX(ctx) && block_size > 1)
        return 0;

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

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(SSL *ssl, size_t block_size)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);

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

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

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;
    const unsigned char *p;
    OCSP_BASICRESP *br = NULL;
    OCSP_RESPONSE *rsp = NULL;
    STACK_OF(SCT) *scts = NULL;
    int i;

    if (s->ext.ocsp.resp == NULL || s->ext.ocsp.resp_len == 0)
        goto err;

    p = s->ext.ocsp.resp;
    rsp = d2i_OCSP_RESPONSE(NULL, &p, (int)s->ext.ocsp.resp_len);
    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);
        scts_extracted =
            ct_move_scts(&s->scts, scts, SCT_SOURCE_OCSP_STAPLED_RESPONSE);
        if (scts_extracted < 0)
            goto err;
    }
 err:
    SCT_LIST_free(scts);
    OCSP_BASICRESP_free(br);
    OCSP_RESPONSE_free(rsp);
    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(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 re-used 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;
}

int SSL_client_hello_isv2(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->isv2;
}

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(sizeof(*present) * num)) == 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;
    size_t i;
    size_t prefix_len;
    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc);

    if (sctx->keylog_callback == NULL)
        return 1;

    /*
     * 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;

    strcpy(cursor, prefix);
    cursor += prefix_len;
    *cursor++ = ' ';

    for (i = 0; i < parameter_1_len; i++) {
        sprintf(cursor, "%02x", parameter_1[i]);
        cursor += 2;
    }
    *cursor++ = ' ';

    for (i = 0; i < parameter_2_len; i++) {
        sprintf(cursor, "%02x", parameter_2[i]);
        cursor += 2;
    }
    *cursor = '\0';

    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);
}

#define SSLV2_CIPHER_LEN    3

int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites, int sslv2format)
{
    int n;

    n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN;

    if (PACKET_remaining(cipher_suites) == 0) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_CIPHERS_SPECIFIED);
        return 0;
    }

    if (PACKET_remaining(cipher_suites) % n != 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 (sslv2format) {
        size_t numciphers = PACKET_remaining(cipher_suites) / n;
        PACKET sslv2ciphers = *cipher_suites;
        unsigned int leadbyte;
        unsigned char *raw;

        /*
         * We store the raw ciphers list in SSLv3+ format so we need to do some
         * preprocessing to convert the list first. If there are any SSLv2 only
         * ciphersuites with a non-zero leading byte then we are going to
         * slightly over allocate because we won't store those. But that isn't a
         * problem.
         */
        raw = OPENSSL_malloc(numciphers * TLS_CIPHER_LEN);
        s->s3.tmp.ciphers_raw = raw;
        if (raw == NULL) {
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
            return 0;
        }
        for (s->s3.tmp.ciphers_rawlen = 0;
             PACKET_remaining(&sslv2ciphers) > 0;
             raw += TLS_CIPHER_LEN) {
            if (!PACKET_get_1(&sslv2ciphers, &leadbyte)
                    || (leadbyte == 0
                        && !PACKET_copy_bytes(&sslv2ciphers, raw,
                                              TLS_CIPHER_LEN))
                    || (leadbyte != 0
                        && !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) {
                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_PACKET);
                OPENSSL_free(s->s3.tmp.ciphers_raw);
                s->s3.tmp.ciphers_raw = NULL;
                s->s3.tmp.ciphers_rawlen = 0;
                return 0;
            }
            if (leadbyte == 0)
                s->s3.tmp.ciphers_rawlen += TLS_CIPHER_LEN;
        }
    } else 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)
        return 0;

    if (!PACKET_buf_init(&pkt, bytes, len))
        return 0;
    return ossl_bytes_to_cipher_list(sc, &pkt, sk, scsvs, isv2format, 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 sslv2format, int fatal)
{
    const SSL_CIPHER *c;
    STACK_OF(SSL_CIPHER) *sk = NULL;
    STACK_OF(SSL_CIPHER) *scsvs = NULL;
    int n;
    /* 3 = SSLV2_CIPHER_LEN > TLS_CIPHER_LEN = 2. */
    unsigned char cipher[SSLV2_CIPHER_LEN];

    n = sslv2format ? SSLV2_CIPHER_LEN : 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)) {
        /*
         * SSLv3 ciphers wrapped in an SSLv2-compatible ClientHello have the
         * first byte set to zero, while true SSLv2 ciphers have a non-zero
         * first byte. We don't support any true SSLv2 ciphers, so skip them.
         */
        if (sslv2format && cipher[0] != '\0')
            continue;

        /* For SSLv2-compat, ignore leading 0-byte. */
        c = ssl_get_cipher_by_char(s, sslv2format ? &cipher[1] : 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 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 sc->max_send_fragment;

    /* return current SSL connection setting */
    return 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,
                                       int nid,
                                       const char *properties)
{
    const EVP_CIPHER *ciph;

    ciph = tls_get_cipher_from_engine(nid);
    if (ciph != NULL)
        return ciph;

    /*
     * If there is no engine cipher then we do an explicit fetch. This may fail
     * and that could be ok
     */
    ERR_set_mark();
    ciph = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties);
    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);
    }
}

const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx,
                               int nid,
                               const char *properties)
{
    const EVP_MD *md;

    md = tls_get_digest_from_engine(nid);
    if (md != NULL)
        return md;

    /* Otherwise we do an explicit fetch */
    ERR_set_mark();
    md = EVP_MD_fetch(libctx, OBJ_nid2sn(nid), properties);
    ERR_pop_to_mark();
    return md;
}

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;
}

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_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)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_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)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

    if (sc == NULL)
        return 0;

    return sc->ext.client_cert_type;
}

int SSL_get_negotiated_server_cert_type(const SSL *s)
{
    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_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);

    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);

    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)
        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)
        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;
}
