11cb0ef41Sopenharmony_ci/*
21cb0ef41Sopenharmony_ci * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
31cb0ef41Sopenharmony_ci * Copyright 2005 Nokia. All rights reserved.
41cb0ef41Sopenharmony_ci *
51cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
61cb0ef41Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
71cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at
81cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html
91cb0ef41Sopenharmony_ci */
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#if defined(__TANDEM) && defined(_SPT_MODEL_)
121cb0ef41Sopenharmony_ci# include <spthread.h>
131cb0ef41Sopenharmony_ci# include <spt_extensions.h> /* timeval */
141cb0ef41Sopenharmony_ci#endif
151cb0ef41Sopenharmony_ci#include <stdio.h>
161cb0ef41Sopenharmony_ci#include <openssl/rand.h>
171cb0ef41Sopenharmony_ci#include <openssl/engine.h>
181cb0ef41Sopenharmony_ci#include "internal/refcount.h"
191cb0ef41Sopenharmony_ci#include "internal/cryptlib.h"
201cb0ef41Sopenharmony_ci#include "ssl_local.h"
211cb0ef41Sopenharmony_ci#include "statem/statem_local.h"
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_cistatic void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
241cb0ef41Sopenharmony_cistatic void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
251cb0ef41Sopenharmony_cistatic int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciDEFINE_STACK_OF(SSL_SESSION)
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci__owur static int sess_timedout(time_t t, SSL_SESSION *ss)
301cb0ef41Sopenharmony_ci{
311cb0ef41Sopenharmony_ci    /* if timeout overflowed, it can never timeout! */
321cb0ef41Sopenharmony_ci    if (ss->timeout_ovf)
331cb0ef41Sopenharmony_ci        return 0;
341cb0ef41Sopenharmony_ci    return t > ss->calc_timeout;
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci/*
381cb0ef41Sopenharmony_ci * Returns -1/0/+1 as other XXXcmp-type functions
391cb0ef41Sopenharmony_ci * Takes overflow of calculated timeout into consideration
401cb0ef41Sopenharmony_ci */
411cb0ef41Sopenharmony_ci__owur static int timeoutcmp(SSL_SESSION *a, SSL_SESSION *b)
421cb0ef41Sopenharmony_ci{
431cb0ef41Sopenharmony_ci    /* if only one overflowed, then it is greater */
441cb0ef41Sopenharmony_ci    if (a->timeout_ovf && !b->timeout_ovf)
451cb0ef41Sopenharmony_ci        return 1;
461cb0ef41Sopenharmony_ci    if (!a->timeout_ovf && b->timeout_ovf)
471cb0ef41Sopenharmony_ci        return -1;
481cb0ef41Sopenharmony_ci    /* No overflow, or both overflowed, so straight compare is safe */
491cb0ef41Sopenharmony_ci    if (a->calc_timeout < b->calc_timeout)
501cb0ef41Sopenharmony_ci        return -1;
511cb0ef41Sopenharmony_ci    if (a->calc_timeout > b->calc_timeout)
521cb0ef41Sopenharmony_ci        return 1;
531cb0ef41Sopenharmony_ci    return 0;
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci/*
571cb0ef41Sopenharmony_ci * Calculates effective timeout, saving overflow state
581cb0ef41Sopenharmony_ci * Locking must be done by the caller of this function
591cb0ef41Sopenharmony_ci */
601cb0ef41Sopenharmony_civoid ssl_session_calculate_timeout(SSL_SESSION *ss)
611cb0ef41Sopenharmony_ci{
621cb0ef41Sopenharmony_ci    /* Force positive timeout */
631cb0ef41Sopenharmony_ci    if (ss->timeout < 0)
641cb0ef41Sopenharmony_ci        ss->timeout = 0;
651cb0ef41Sopenharmony_ci    ss->calc_timeout = ss->time + ss->timeout;
661cb0ef41Sopenharmony_ci    /*
671cb0ef41Sopenharmony_ci     * |timeout| is always zero or positive, so the check for
681cb0ef41Sopenharmony_ci     * overflow only needs to consider if |time| is positive
691cb0ef41Sopenharmony_ci     */
701cb0ef41Sopenharmony_ci    ss->timeout_ovf = ss->time > 0 && ss->calc_timeout < ss->time;
711cb0ef41Sopenharmony_ci    /*
721cb0ef41Sopenharmony_ci     * N.B. Realistic overflow can only occur in our lifetimes on a
731cb0ef41Sopenharmony_ci     *      32-bit machine in January 2038.
741cb0ef41Sopenharmony_ci     *      However, There are no controls to limit the |timeout|
751cb0ef41Sopenharmony_ci     *      value, except to keep it positive.
761cb0ef41Sopenharmony_ci     */
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci/*
801cb0ef41Sopenharmony_ci * SSL_get_session() and SSL_get1_session() are problematic in TLS1.3 because,
811cb0ef41Sopenharmony_ci * unlike in earlier protocol versions, the session ticket may not have been
821cb0ef41Sopenharmony_ci * sent yet even though a handshake has finished. The session ticket data could
831cb0ef41Sopenharmony_ci * come in sometime later...or even change if multiple session ticket messages
841cb0ef41Sopenharmony_ci * are sent from the server. The preferred way for applications to obtain
851cb0ef41Sopenharmony_ci * a resumable session is to use SSL_CTX_sess_set_new_cb().
861cb0ef41Sopenharmony_ci */
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ciSSL_SESSION *SSL_get_session(const SSL *ssl)
891cb0ef41Sopenharmony_ci/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
901cb0ef41Sopenharmony_ci{
911cb0ef41Sopenharmony_ci    return ssl->session;
921cb0ef41Sopenharmony_ci}
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ciSSL_SESSION *SSL_get1_session(SSL *ssl)
951cb0ef41Sopenharmony_ci/* variant of SSL_get_session: caller really gets something */
961cb0ef41Sopenharmony_ci{
971cb0ef41Sopenharmony_ci    SSL_SESSION *sess;
981cb0ef41Sopenharmony_ci    /*
991cb0ef41Sopenharmony_ci     * Need to lock this all up rather than just use CRYPTO_add so that
1001cb0ef41Sopenharmony_ci     * somebody doesn't free ssl->session between when we check it's non-null
1011cb0ef41Sopenharmony_ci     * and when we up the reference count.
1021cb0ef41Sopenharmony_ci     */
1031cb0ef41Sopenharmony_ci    if (!CRYPTO_THREAD_read_lock(ssl->lock))
1041cb0ef41Sopenharmony_ci        return NULL;
1051cb0ef41Sopenharmony_ci    sess = ssl->session;
1061cb0ef41Sopenharmony_ci    if (sess)
1071cb0ef41Sopenharmony_ci        SSL_SESSION_up_ref(sess);
1081cb0ef41Sopenharmony_ci    CRYPTO_THREAD_unlock(ssl->lock);
1091cb0ef41Sopenharmony_ci    return sess;
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ciint SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
1131cb0ef41Sopenharmony_ci{
1141cb0ef41Sopenharmony_ci    return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_civoid *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
1181cb0ef41Sopenharmony_ci{
1191cb0ef41Sopenharmony_ci    return CRYPTO_get_ex_data(&s->ex_data, idx);
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ciSSL_SESSION *SSL_SESSION_new(void)
1231cb0ef41Sopenharmony_ci{
1241cb0ef41Sopenharmony_ci    SSL_SESSION *ss;
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci    if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))
1271cb0ef41Sopenharmony_ci        return NULL;
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci    ss = OPENSSL_zalloc(sizeof(*ss));
1301cb0ef41Sopenharmony_ci    if (ss == NULL) {
1311cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
1321cb0ef41Sopenharmony_ci        return NULL;
1331cb0ef41Sopenharmony_ci    }
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci    ss->verify_result = 1;      /* avoid 0 (= X509_V_OK) just in case */
1361cb0ef41Sopenharmony_ci    ss->references = 1;
1371cb0ef41Sopenharmony_ci    ss->timeout = 60 * 5 + 4;   /* 5 minute timeout by default */
1381cb0ef41Sopenharmony_ci    ss->time = time(NULL);
1391cb0ef41Sopenharmony_ci    ssl_session_calculate_timeout(ss);
1401cb0ef41Sopenharmony_ci    ss->lock = CRYPTO_THREAD_lock_new();
1411cb0ef41Sopenharmony_ci    if (ss->lock == NULL) {
1421cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
1431cb0ef41Sopenharmony_ci        OPENSSL_free(ss);
1441cb0ef41Sopenharmony_ci        return NULL;
1451cb0ef41Sopenharmony_ci    }
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data)) {
1481cb0ef41Sopenharmony_ci        CRYPTO_THREAD_lock_free(ss->lock);
1491cb0ef41Sopenharmony_ci        OPENSSL_free(ss);
1501cb0ef41Sopenharmony_ci        return NULL;
1511cb0ef41Sopenharmony_ci    }
1521cb0ef41Sopenharmony_ci    return ss;
1531cb0ef41Sopenharmony_ci}
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ciSSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
1561cb0ef41Sopenharmony_ci{
1571cb0ef41Sopenharmony_ci    return ssl_session_dup(src, 1);
1581cb0ef41Sopenharmony_ci}
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci/*
1611cb0ef41Sopenharmony_ci * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
1621cb0ef41Sopenharmony_ci * ticket == 0 then no ticket information is duplicated, otherwise it is.
1631cb0ef41Sopenharmony_ci */
1641cb0ef41Sopenharmony_ciSSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
1651cb0ef41Sopenharmony_ci{
1661cb0ef41Sopenharmony_ci    SSL_SESSION *dest;
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci    dest = OPENSSL_malloc(sizeof(*dest));
1691cb0ef41Sopenharmony_ci    if (dest == NULL) {
1701cb0ef41Sopenharmony_ci        goto err;
1711cb0ef41Sopenharmony_ci    }
1721cb0ef41Sopenharmony_ci    memcpy(dest, src, sizeof(*dest));
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci    /*
1751cb0ef41Sopenharmony_ci     * Set the various pointers to NULL so that we can call SSL_SESSION_free in
1761cb0ef41Sopenharmony_ci     * the case of an error whilst halfway through constructing dest
1771cb0ef41Sopenharmony_ci     */
1781cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_PSK
1791cb0ef41Sopenharmony_ci    dest->psk_identity_hint = NULL;
1801cb0ef41Sopenharmony_ci    dest->psk_identity = NULL;
1811cb0ef41Sopenharmony_ci#endif
1821cb0ef41Sopenharmony_ci    dest->ext.hostname = NULL;
1831cb0ef41Sopenharmony_ci    dest->ext.tick = NULL;
1841cb0ef41Sopenharmony_ci    dest->ext.alpn_selected = NULL;
1851cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_SRP
1861cb0ef41Sopenharmony_ci    dest->srp_username = NULL;
1871cb0ef41Sopenharmony_ci#endif
1881cb0ef41Sopenharmony_ci    dest->peer_chain = NULL;
1891cb0ef41Sopenharmony_ci    dest->peer = NULL;
1901cb0ef41Sopenharmony_ci    dest->ticket_appdata = NULL;
1911cb0ef41Sopenharmony_ci    memset(&dest->ex_data, 0, sizeof(dest->ex_data));
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci    /* As the copy is not in the cache, we remove the associated pointers */
1941cb0ef41Sopenharmony_ci    dest->prev = NULL;
1951cb0ef41Sopenharmony_ci    dest->next = NULL;
1961cb0ef41Sopenharmony_ci    dest->owner = NULL;
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci    dest->references = 1;
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci    dest->lock = CRYPTO_THREAD_lock_new();
2011cb0ef41Sopenharmony_ci    if (dest->lock == NULL) {
2021cb0ef41Sopenharmony_ci        OPENSSL_free(dest);
2031cb0ef41Sopenharmony_ci        dest = NULL;
2041cb0ef41Sopenharmony_ci        goto err;
2051cb0ef41Sopenharmony_ci    }
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data))
2081cb0ef41Sopenharmony_ci        goto err;
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci    if (src->peer != NULL) {
2111cb0ef41Sopenharmony_ci        if (!X509_up_ref(src->peer))
2121cb0ef41Sopenharmony_ci            goto err;
2131cb0ef41Sopenharmony_ci        dest->peer = src->peer;
2141cb0ef41Sopenharmony_ci    }
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci    if (src->peer_chain != NULL) {
2171cb0ef41Sopenharmony_ci        dest->peer_chain = X509_chain_up_ref(src->peer_chain);
2181cb0ef41Sopenharmony_ci        if (dest->peer_chain == NULL)
2191cb0ef41Sopenharmony_ci            goto err;
2201cb0ef41Sopenharmony_ci    }
2211cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_PSK
2221cb0ef41Sopenharmony_ci    if (src->psk_identity_hint) {
2231cb0ef41Sopenharmony_ci        dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint);
2241cb0ef41Sopenharmony_ci        if (dest->psk_identity_hint == NULL) {
2251cb0ef41Sopenharmony_ci            goto err;
2261cb0ef41Sopenharmony_ci        }
2271cb0ef41Sopenharmony_ci    }
2281cb0ef41Sopenharmony_ci    if (src->psk_identity) {
2291cb0ef41Sopenharmony_ci        dest->psk_identity = OPENSSL_strdup(src->psk_identity);
2301cb0ef41Sopenharmony_ci        if (dest->psk_identity == NULL) {
2311cb0ef41Sopenharmony_ci            goto err;
2321cb0ef41Sopenharmony_ci        }
2331cb0ef41Sopenharmony_ci    }
2341cb0ef41Sopenharmony_ci#endif
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
2371cb0ef41Sopenharmony_ci                            &dest->ex_data, &src->ex_data)) {
2381cb0ef41Sopenharmony_ci        goto err;
2391cb0ef41Sopenharmony_ci    }
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci    if (src->ext.hostname) {
2421cb0ef41Sopenharmony_ci        dest->ext.hostname = OPENSSL_strdup(src->ext.hostname);
2431cb0ef41Sopenharmony_ci        if (dest->ext.hostname == NULL) {
2441cb0ef41Sopenharmony_ci            goto err;
2451cb0ef41Sopenharmony_ci        }
2461cb0ef41Sopenharmony_ci    }
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci    if (ticket != 0 && src->ext.tick != NULL) {
2491cb0ef41Sopenharmony_ci        dest->ext.tick =
2501cb0ef41Sopenharmony_ci            OPENSSL_memdup(src->ext.tick, src->ext.ticklen);
2511cb0ef41Sopenharmony_ci        if (dest->ext.tick == NULL)
2521cb0ef41Sopenharmony_ci            goto err;
2531cb0ef41Sopenharmony_ci    } else {
2541cb0ef41Sopenharmony_ci        dest->ext.tick_lifetime_hint = 0;
2551cb0ef41Sopenharmony_ci        dest->ext.ticklen = 0;
2561cb0ef41Sopenharmony_ci    }
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci    if (src->ext.alpn_selected != NULL) {
2591cb0ef41Sopenharmony_ci        dest->ext.alpn_selected = OPENSSL_memdup(src->ext.alpn_selected,
2601cb0ef41Sopenharmony_ci                                                 src->ext.alpn_selected_len);
2611cb0ef41Sopenharmony_ci        if (dest->ext.alpn_selected == NULL)
2621cb0ef41Sopenharmony_ci            goto err;
2631cb0ef41Sopenharmony_ci    }
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_SRP
2661cb0ef41Sopenharmony_ci    if (src->srp_username) {
2671cb0ef41Sopenharmony_ci        dest->srp_username = OPENSSL_strdup(src->srp_username);
2681cb0ef41Sopenharmony_ci        if (dest->srp_username == NULL) {
2691cb0ef41Sopenharmony_ci            goto err;
2701cb0ef41Sopenharmony_ci        }
2711cb0ef41Sopenharmony_ci    }
2721cb0ef41Sopenharmony_ci#endif
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci    if (src->ticket_appdata != NULL) {
2751cb0ef41Sopenharmony_ci        dest->ticket_appdata =
2761cb0ef41Sopenharmony_ci            OPENSSL_memdup(src->ticket_appdata, src->ticket_appdata_len);
2771cb0ef41Sopenharmony_ci        if (dest->ticket_appdata == NULL)
2781cb0ef41Sopenharmony_ci            goto err;
2791cb0ef41Sopenharmony_ci    }
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci    return dest;
2821cb0ef41Sopenharmony_ci err:
2831cb0ef41Sopenharmony_ci    ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
2841cb0ef41Sopenharmony_ci    SSL_SESSION_free(dest);
2851cb0ef41Sopenharmony_ci    return NULL;
2861cb0ef41Sopenharmony_ci}
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ciconst unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
2891cb0ef41Sopenharmony_ci{
2901cb0ef41Sopenharmony_ci    if (len)
2911cb0ef41Sopenharmony_ci        *len = (unsigned int)s->session_id_length;
2921cb0ef41Sopenharmony_ci    return s->session_id;
2931cb0ef41Sopenharmony_ci}
2941cb0ef41Sopenharmony_ciconst unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s,
2951cb0ef41Sopenharmony_ci                                                unsigned int *len)
2961cb0ef41Sopenharmony_ci{
2971cb0ef41Sopenharmony_ci    if (len != NULL)
2981cb0ef41Sopenharmony_ci        *len = (unsigned int)s->sid_ctx_length;
2991cb0ef41Sopenharmony_ci    return s->sid_ctx;
3001cb0ef41Sopenharmony_ci}
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ciunsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
3031cb0ef41Sopenharmony_ci{
3041cb0ef41Sopenharmony_ci    return s->compress_meth;
3051cb0ef41Sopenharmony_ci}
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci/*
3081cb0ef41Sopenharmony_ci * SSLv3/TLSv1 has 32 bytes (256 bits) of session ID space. As such, filling
3091cb0ef41Sopenharmony_ci * the ID with random junk repeatedly until we have no conflict is going to
3101cb0ef41Sopenharmony_ci * complete in one iteration pretty much "most" of the time (btw:
3111cb0ef41Sopenharmony_ci * understatement). So, if it takes us 10 iterations and we still can't avoid
3121cb0ef41Sopenharmony_ci * a conflict - well that's a reasonable point to call it quits. Either the
3131cb0ef41Sopenharmony_ci * RAND code is broken or someone is trying to open roughly very close to
3141cb0ef41Sopenharmony_ci * 2^256 SSL sessions to our server. How you might store that many sessions
3151cb0ef41Sopenharmony_ci * is perhaps a more interesting question ...
3161cb0ef41Sopenharmony_ci */
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci#define MAX_SESS_ID_ATTEMPTS 10
3191cb0ef41Sopenharmony_cistatic int def_generate_session_id(SSL *ssl, unsigned char *id,
3201cb0ef41Sopenharmony_ci                                   unsigned int *id_len)
3211cb0ef41Sopenharmony_ci{
3221cb0ef41Sopenharmony_ci    unsigned int retry = 0;
3231cb0ef41Sopenharmony_ci    do
3241cb0ef41Sopenharmony_ci        if (RAND_bytes_ex(ssl->ctx->libctx, id, *id_len, 0) <= 0)
3251cb0ef41Sopenharmony_ci            return 0;
3261cb0ef41Sopenharmony_ci    while (SSL_has_matching_session_id(ssl, id, *id_len) &&
3271cb0ef41Sopenharmony_ci           (++retry < MAX_SESS_ID_ATTEMPTS)) ;
3281cb0ef41Sopenharmony_ci    if (retry < MAX_SESS_ID_ATTEMPTS)
3291cb0ef41Sopenharmony_ci        return 1;
3301cb0ef41Sopenharmony_ci    /* else - woops a session_id match */
3311cb0ef41Sopenharmony_ci    /*
3321cb0ef41Sopenharmony_ci     * XXX We should also check the external cache -- but the probability of
3331cb0ef41Sopenharmony_ci     * a collision is negligible, and we could not prevent the concurrent
3341cb0ef41Sopenharmony_ci     * creation of sessions with identical IDs since we currently don't have
3351cb0ef41Sopenharmony_ci     * means to atomically check whether a session ID already exists and make
3361cb0ef41Sopenharmony_ci     * a reservation for it if it does not (this problem applies to the
3371cb0ef41Sopenharmony_ci     * internal cache as well).
3381cb0ef41Sopenharmony_ci     */
3391cb0ef41Sopenharmony_ci    return 0;
3401cb0ef41Sopenharmony_ci}
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ciint ssl_generate_session_id(SSL *s, SSL_SESSION *ss)
3431cb0ef41Sopenharmony_ci{
3441cb0ef41Sopenharmony_ci    unsigned int tmp;
3451cb0ef41Sopenharmony_ci    GEN_SESSION_CB cb = def_generate_session_id;
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci    switch (s->version) {
3481cb0ef41Sopenharmony_ci    case SSL3_VERSION:
3491cb0ef41Sopenharmony_ci    case TLS1_VERSION:
3501cb0ef41Sopenharmony_ci    case TLS1_1_VERSION:
3511cb0ef41Sopenharmony_ci    case TLS1_2_VERSION:
3521cb0ef41Sopenharmony_ci    case TLS1_3_VERSION:
3531cb0ef41Sopenharmony_ci    case DTLS1_BAD_VER:
3541cb0ef41Sopenharmony_ci    case DTLS1_VERSION:
3551cb0ef41Sopenharmony_ci    case DTLS1_2_VERSION:
3561cb0ef41Sopenharmony_ci        ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
3571cb0ef41Sopenharmony_ci        break;
3581cb0ef41Sopenharmony_ci    default:
3591cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNSUPPORTED_SSL_VERSION);
3601cb0ef41Sopenharmony_ci        return 0;
3611cb0ef41Sopenharmony_ci    }
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci    /*-
3641cb0ef41Sopenharmony_ci     * If RFC5077 ticket, use empty session ID (as server).
3651cb0ef41Sopenharmony_ci     * Note that:
3661cb0ef41Sopenharmony_ci     * (a) ssl_get_prev_session() does lookahead into the
3671cb0ef41Sopenharmony_ci     *     ClientHello extensions to find the session ticket.
3681cb0ef41Sopenharmony_ci     *     When ssl_get_prev_session() fails, statem_srvr.c calls
3691cb0ef41Sopenharmony_ci     *     ssl_get_new_session() in tls_process_client_hello().
3701cb0ef41Sopenharmony_ci     *     At that point, it has not yet parsed the extensions,
3711cb0ef41Sopenharmony_ci     *     however, because of the lookahead, it already knows
3721cb0ef41Sopenharmony_ci     *     whether a ticket is expected or not.
3731cb0ef41Sopenharmony_ci     *
3741cb0ef41Sopenharmony_ci     * (b) statem_clnt.c calls ssl_get_new_session() before parsing
3751cb0ef41Sopenharmony_ci     *     ServerHello extensions, and before recording the session
3761cb0ef41Sopenharmony_ci     *     ID received from the server, so this block is a noop.
3771cb0ef41Sopenharmony_ci     */
3781cb0ef41Sopenharmony_ci    if (s->ext.ticket_expected) {
3791cb0ef41Sopenharmony_ci        ss->session_id_length = 0;
3801cb0ef41Sopenharmony_ci        return 1;
3811cb0ef41Sopenharmony_ci    }
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ci    /* Choose which callback will set the session ID */
3841cb0ef41Sopenharmony_ci    if (!CRYPTO_THREAD_read_lock(s->lock))
3851cb0ef41Sopenharmony_ci        return 0;
3861cb0ef41Sopenharmony_ci    if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) {
3871cb0ef41Sopenharmony_ci        CRYPTO_THREAD_unlock(s->lock);
3881cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR,
3891cb0ef41Sopenharmony_ci                 SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
3901cb0ef41Sopenharmony_ci        return 0;
3911cb0ef41Sopenharmony_ci    }
3921cb0ef41Sopenharmony_ci    if (s->generate_session_id)
3931cb0ef41Sopenharmony_ci        cb = s->generate_session_id;
3941cb0ef41Sopenharmony_ci    else if (s->session_ctx->generate_session_id)
3951cb0ef41Sopenharmony_ci        cb = s->session_ctx->generate_session_id;
3961cb0ef41Sopenharmony_ci    CRYPTO_THREAD_unlock(s->session_ctx->lock);
3971cb0ef41Sopenharmony_ci    CRYPTO_THREAD_unlock(s->lock);
3981cb0ef41Sopenharmony_ci    /* Choose a session ID */
3991cb0ef41Sopenharmony_ci    memset(ss->session_id, 0, ss->session_id_length);
4001cb0ef41Sopenharmony_ci    tmp = (int)ss->session_id_length;
4011cb0ef41Sopenharmony_ci    if (!cb(s, ss->session_id, &tmp)) {
4021cb0ef41Sopenharmony_ci        /* The callback failed */
4031cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR,
4041cb0ef41Sopenharmony_ci                 SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
4051cb0ef41Sopenharmony_ci        return 0;
4061cb0ef41Sopenharmony_ci    }
4071cb0ef41Sopenharmony_ci    /*
4081cb0ef41Sopenharmony_ci     * Don't allow the callback to set the session length to zero. nor
4091cb0ef41Sopenharmony_ci     * set it higher than it was.
4101cb0ef41Sopenharmony_ci     */
4111cb0ef41Sopenharmony_ci    if (tmp == 0 || tmp > ss->session_id_length) {
4121cb0ef41Sopenharmony_ci        /* The callback set an illegal length */
4131cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR,
4141cb0ef41Sopenharmony_ci                 SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
4151cb0ef41Sopenharmony_ci        return 0;
4161cb0ef41Sopenharmony_ci    }
4171cb0ef41Sopenharmony_ci    ss->session_id_length = tmp;
4181cb0ef41Sopenharmony_ci    /* Finally, check for a conflict */
4191cb0ef41Sopenharmony_ci    if (SSL_has_matching_session_id(s, ss->session_id,
4201cb0ef41Sopenharmony_ci                                    (unsigned int)ss->session_id_length)) {
4211cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_CONFLICT);
4221cb0ef41Sopenharmony_ci        return 0;
4231cb0ef41Sopenharmony_ci    }
4241cb0ef41Sopenharmony_ci
4251cb0ef41Sopenharmony_ci    return 1;
4261cb0ef41Sopenharmony_ci}
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ciint ssl_get_new_session(SSL *s, int session)
4291cb0ef41Sopenharmony_ci{
4301cb0ef41Sopenharmony_ci    /* This gets used by clients and servers. */
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci    SSL_SESSION *ss = NULL;
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci    if ((ss = SSL_SESSION_new()) == NULL) {
4351cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
4361cb0ef41Sopenharmony_ci        return 0;
4371cb0ef41Sopenharmony_ci    }
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci    /* If the context has a default timeout, use it */
4401cb0ef41Sopenharmony_ci    if (s->session_ctx->session_timeout == 0)
4411cb0ef41Sopenharmony_ci        ss->timeout = SSL_get_default_timeout(s);
4421cb0ef41Sopenharmony_ci    else
4431cb0ef41Sopenharmony_ci        ss->timeout = s->session_ctx->session_timeout;
4441cb0ef41Sopenharmony_ci    ssl_session_calculate_timeout(ss);
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci    SSL_SESSION_free(s->session);
4471cb0ef41Sopenharmony_ci    s->session = NULL;
4481cb0ef41Sopenharmony_ci
4491cb0ef41Sopenharmony_ci    if (session) {
4501cb0ef41Sopenharmony_ci        if (SSL_IS_TLS13(s)) {
4511cb0ef41Sopenharmony_ci            /*
4521cb0ef41Sopenharmony_ci             * We generate the session id while constructing the
4531cb0ef41Sopenharmony_ci             * NewSessionTicket in TLSv1.3.
4541cb0ef41Sopenharmony_ci             */
4551cb0ef41Sopenharmony_ci            ss->session_id_length = 0;
4561cb0ef41Sopenharmony_ci        } else if (!ssl_generate_session_id(s, ss)) {
4571cb0ef41Sopenharmony_ci            /* SSLfatal() already called */
4581cb0ef41Sopenharmony_ci            SSL_SESSION_free(ss);
4591cb0ef41Sopenharmony_ci            return 0;
4601cb0ef41Sopenharmony_ci        }
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci    } else {
4631cb0ef41Sopenharmony_ci        ss->session_id_length = 0;
4641cb0ef41Sopenharmony_ci    }
4651cb0ef41Sopenharmony_ci
4661cb0ef41Sopenharmony_ci    if (s->sid_ctx_length > sizeof(ss->sid_ctx)) {
4671cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
4681cb0ef41Sopenharmony_ci        SSL_SESSION_free(ss);
4691cb0ef41Sopenharmony_ci        return 0;
4701cb0ef41Sopenharmony_ci    }
4711cb0ef41Sopenharmony_ci    memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
4721cb0ef41Sopenharmony_ci    ss->sid_ctx_length = s->sid_ctx_length;
4731cb0ef41Sopenharmony_ci    s->session = ss;
4741cb0ef41Sopenharmony_ci    ss->ssl_version = s->version;
4751cb0ef41Sopenharmony_ci    ss->verify_result = X509_V_OK;
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ci    /* If client supports extended master secret set it in session */
4781cb0ef41Sopenharmony_ci    if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS)
4791cb0ef41Sopenharmony_ci        ss->flags |= SSL_SESS_FLAG_EXTMS;
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_ci    return 1;
4821cb0ef41Sopenharmony_ci}
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ciSSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
4851cb0ef41Sopenharmony_ci                                  size_t sess_id_len)
4861cb0ef41Sopenharmony_ci{
4871cb0ef41Sopenharmony_ci    SSL_SESSION *ret = NULL;
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci    if ((s->session_ctx->session_cache_mode
4901cb0ef41Sopenharmony_ci         & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) {
4911cb0ef41Sopenharmony_ci        SSL_SESSION data;
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci        data.ssl_version = s->version;
4941cb0ef41Sopenharmony_ci        if (!ossl_assert(sess_id_len <= SSL_MAX_SSL_SESSION_ID_LENGTH))
4951cb0ef41Sopenharmony_ci            return NULL;
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ci        memcpy(data.session_id, sess_id, sess_id_len);
4981cb0ef41Sopenharmony_ci        data.session_id_length = sess_id_len;
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci        if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock))
5011cb0ef41Sopenharmony_ci            return NULL;
5021cb0ef41Sopenharmony_ci        ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data);
5031cb0ef41Sopenharmony_ci        if (ret != NULL) {
5041cb0ef41Sopenharmony_ci            /* don't allow other threads to steal it: */
5051cb0ef41Sopenharmony_ci            SSL_SESSION_up_ref(ret);
5061cb0ef41Sopenharmony_ci        }
5071cb0ef41Sopenharmony_ci        CRYPTO_THREAD_unlock(s->session_ctx->lock);
5081cb0ef41Sopenharmony_ci        if (ret == NULL)
5091cb0ef41Sopenharmony_ci            ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_miss);
5101cb0ef41Sopenharmony_ci    }
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci    if (ret == NULL && s->session_ctx->get_session_cb != NULL) {
5131cb0ef41Sopenharmony_ci        int copy = 1;
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci        ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, &copy);
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci        if (ret != NULL) {
5181cb0ef41Sopenharmony_ci            ssl_tsan_counter(s->session_ctx,
5191cb0ef41Sopenharmony_ci                             &s->session_ctx->stats.sess_cb_hit);
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci            /*
5221cb0ef41Sopenharmony_ci             * Increment reference count now if the session callback asks us
5231cb0ef41Sopenharmony_ci             * to do so (note that if the session structures returned by the
5241cb0ef41Sopenharmony_ci             * callback are shared between threads, it must handle the
5251cb0ef41Sopenharmony_ci             * reference count itself [i.e. copy == 0], or things won't be
5261cb0ef41Sopenharmony_ci             * thread-safe).
5271cb0ef41Sopenharmony_ci             */
5281cb0ef41Sopenharmony_ci            if (copy)
5291cb0ef41Sopenharmony_ci                SSL_SESSION_up_ref(ret);
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci            /*
5321cb0ef41Sopenharmony_ci             * Add the externally cached session to the internal cache as
5331cb0ef41Sopenharmony_ci             * well if and only if we are supposed to.
5341cb0ef41Sopenharmony_ci             */
5351cb0ef41Sopenharmony_ci            if ((s->session_ctx->session_cache_mode &
5361cb0ef41Sopenharmony_ci                 SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0) {
5371cb0ef41Sopenharmony_ci                /*
5381cb0ef41Sopenharmony_ci                 * Either return value of SSL_CTX_add_session should not
5391cb0ef41Sopenharmony_ci                 * interrupt the session resumption process. The return
5401cb0ef41Sopenharmony_ci                 * value is intentionally ignored.
5411cb0ef41Sopenharmony_ci                 */
5421cb0ef41Sopenharmony_ci                (void)SSL_CTX_add_session(s->session_ctx, ret);
5431cb0ef41Sopenharmony_ci            }
5441cb0ef41Sopenharmony_ci        }
5451cb0ef41Sopenharmony_ci    }
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci    return ret;
5481cb0ef41Sopenharmony_ci}
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci/*-
5511cb0ef41Sopenharmony_ci * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
5521cb0ef41Sopenharmony_ci * connection. It is only called by servers.
5531cb0ef41Sopenharmony_ci *
5541cb0ef41Sopenharmony_ci *   hello: The parsed ClientHello data
5551cb0ef41Sopenharmony_ci *
5561cb0ef41Sopenharmony_ci * Returns:
5571cb0ef41Sopenharmony_ci *   -1: fatal error
5581cb0ef41Sopenharmony_ci *    0: no session found
5591cb0ef41Sopenharmony_ci *    1: a session may have been found.
5601cb0ef41Sopenharmony_ci *
5611cb0ef41Sopenharmony_ci * Side effects:
5621cb0ef41Sopenharmony_ci *   - If a session is found then s->session is pointed at it (after freeing an
5631cb0ef41Sopenharmony_ci *     existing session if need be) and s->verify_result is set from the session.
5641cb0ef41Sopenharmony_ci *   - Both for new and resumed sessions, s->ext.ticket_expected is set to 1
5651cb0ef41Sopenharmony_ci *     if the server should issue a new session ticket (to 0 otherwise).
5661cb0ef41Sopenharmony_ci */
5671cb0ef41Sopenharmony_ciint ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
5681cb0ef41Sopenharmony_ci{
5691cb0ef41Sopenharmony_ci    /* This is used only by servers. */
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ci    SSL_SESSION *ret = NULL;
5721cb0ef41Sopenharmony_ci    int fatal = 0;
5731cb0ef41Sopenharmony_ci    int try_session_cache = 0;
5741cb0ef41Sopenharmony_ci    SSL_TICKET_STATUS r;
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci    if (SSL_IS_TLS13(s)) {
5771cb0ef41Sopenharmony_ci        /*
5781cb0ef41Sopenharmony_ci         * By default we will send a new ticket. This can be overridden in the
5791cb0ef41Sopenharmony_ci         * ticket processing.
5801cb0ef41Sopenharmony_ci         */
5811cb0ef41Sopenharmony_ci        s->ext.ticket_expected = 1;
5821cb0ef41Sopenharmony_ci        if (!tls_parse_extension(s, TLSEXT_IDX_psk_kex_modes,
5831cb0ef41Sopenharmony_ci                                 SSL_EXT_CLIENT_HELLO, hello->pre_proc_exts,
5841cb0ef41Sopenharmony_ci                                 NULL, 0)
5851cb0ef41Sopenharmony_ci                || !tls_parse_extension(s, TLSEXT_IDX_psk, SSL_EXT_CLIENT_HELLO,
5861cb0ef41Sopenharmony_ci                                        hello->pre_proc_exts, NULL, 0))
5871cb0ef41Sopenharmony_ci            return -1;
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci        ret = s->session;
5901cb0ef41Sopenharmony_ci    } else {
5911cb0ef41Sopenharmony_ci        /* sets s->ext.ticket_expected */
5921cb0ef41Sopenharmony_ci        r = tls_get_ticket_from_client(s, hello, &ret);
5931cb0ef41Sopenharmony_ci        switch (r) {
5941cb0ef41Sopenharmony_ci        case SSL_TICKET_FATAL_ERR_MALLOC:
5951cb0ef41Sopenharmony_ci        case SSL_TICKET_FATAL_ERR_OTHER:
5961cb0ef41Sopenharmony_ci            fatal = 1;
5971cb0ef41Sopenharmony_ci            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
5981cb0ef41Sopenharmony_ci            goto err;
5991cb0ef41Sopenharmony_ci        case SSL_TICKET_NONE:
6001cb0ef41Sopenharmony_ci        case SSL_TICKET_EMPTY:
6011cb0ef41Sopenharmony_ci            if (hello->session_id_len > 0) {
6021cb0ef41Sopenharmony_ci                try_session_cache = 1;
6031cb0ef41Sopenharmony_ci                ret = lookup_sess_in_cache(s, hello->session_id,
6041cb0ef41Sopenharmony_ci                                           hello->session_id_len);
6051cb0ef41Sopenharmony_ci            }
6061cb0ef41Sopenharmony_ci            break;
6071cb0ef41Sopenharmony_ci        case SSL_TICKET_NO_DECRYPT:
6081cb0ef41Sopenharmony_ci        case SSL_TICKET_SUCCESS:
6091cb0ef41Sopenharmony_ci        case SSL_TICKET_SUCCESS_RENEW:
6101cb0ef41Sopenharmony_ci            break;
6111cb0ef41Sopenharmony_ci        }
6121cb0ef41Sopenharmony_ci    }
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ci    if (ret == NULL)
6151cb0ef41Sopenharmony_ci        goto err;
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci    /* Now ret is non-NULL and we own one of its reference counts. */
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci    /* Check TLS version consistency */
6201cb0ef41Sopenharmony_ci    if (ret->ssl_version != s->version)
6211cb0ef41Sopenharmony_ci        goto err;
6221cb0ef41Sopenharmony_ci
6231cb0ef41Sopenharmony_ci    if (ret->sid_ctx_length != s->sid_ctx_length
6241cb0ef41Sopenharmony_ci        || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
6251cb0ef41Sopenharmony_ci        /*
6261cb0ef41Sopenharmony_ci         * We have the session requested by the client, but we don't want to
6271cb0ef41Sopenharmony_ci         * use it in this context.
6281cb0ef41Sopenharmony_ci         */
6291cb0ef41Sopenharmony_ci        goto err;               /* treat like cache miss */
6301cb0ef41Sopenharmony_ci    }
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci    if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
6331cb0ef41Sopenharmony_ci        /*
6341cb0ef41Sopenharmony_ci         * We can't be sure if this session is being used out of context,
6351cb0ef41Sopenharmony_ci         * which is especially important for SSL_VERIFY_PEER. The application
6361cb0ef41Sopenharmony_ci         * should have used SSL[_CTX]_set_session_id_context. For this error
6371cb0ef41Sopenharmony_ci         * case, we generate an error instead of treating the event like a
6381cb0ef41Sopenharmony_ci         * cache miss (otherwise it would be easy for applications to
6391cb0ef41Sopenharmony_ci         * effectively disable the session cache by accident without anyone
6401cb0ef41Sopenharmony_ci         * noticing).
6411cb0ef41Sopenharmony_ci         */
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_ci        SSLfatal(s, SSL_AD_INTERNAL_ERROR,
6441cb0ef41Sopenharmony_ci                 SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
6451cb0ef41Sopenharmony_ci        fatal = 1;
6461cb0ef41Sopenharmony_ci        goto err;
6471cb0ef41Sopenharmony_ci    }
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci    if (sess_timedout(time(NULL), ret)) {
6501cb0ef41Sopenharmony_ci        ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_timeout);
6511cb0ef41Sopenharmony_ci        if (try_session_cache) {
6521cb0ef41Sopenharmony_ci            /* session was from the cache, so remove it */
6531cb0ef41Sopenharmony_ci            SSL_CTX_remove_session(s->session_ctx, ret);
6541cb0ef41Sopenharmony_ci        }
6551cb0ef41Sopenharmony_ci        goto err;
6561cb0ef41Sopenharmony_ci    }
6571cb0ef41Sopenharmony_ci
6581cb0ef41Sopenharmony_ci    /* Check extended master secret extension consistency */
6591cb0ef41Sopenharmony_ci    if (ret->flags & SSL_SESS_FLAG_EXTMS) {
6601cb0ef41Sopenharmony_ci        /* If old session includes extms, but new does not: abort handshake */
6611cb0ef41Sopenharmony_ci        if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS)) {
6621cb0ef41Sopenharmony_ci            SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INCONSISTENT_EXTMS);
6631cb0ef41Sopenharmony_ci            fatal = 1;
6641cb0ef41Sopenharmony_ci            goto err;
6651cb0ef41Sopenharmony_ci        }
6661cb0ef41Sopenharmony_ci    } else if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) {
6671cb0ef41Sopenharmony_ci        /* If new session includes extms, but old does not: do not resume */
6681cb0ef41Sopenharmony_ci        goto err;
6691cb0ef41Sopenharmony_ci    }
6701cb0ef41Sopenharmony_ci
6711cb0ef41Sopenharmony_ci    if (!SSL_IS_TLS13(s)) {
6721cb0ef41Sopenharmony_ci        /* We already did this for TLS1.3 */
6731cb0ef41Sopenharmony_ci        SSL_SESSION_free(s->session);
6741cb0ef41Sopenharmony_ci        s->session = ret;
6751cb0ef41Sopenharmony_ci    }
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci    ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_hit);
6781cb0ef41Sopenharmony_ci    s->verify_result = s->session->verify_result;
6791cb0ef41Sopenharmony_ci    return 1;
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_ci err:
6821cb0ef41Sopenharmony_ci    if (ret != NULL) {
6831cb0ef41Sopenharmony_ci        SSL_SESSION_free(ret);
6841cb0ef41Sopenharmony_ci        /* In TLSv1.3 s->session was already set to ret, so we NULL it out */
6851cb0ef41Sopenharmony_ci        if (SSL_IS_TLS13(s))
6861cb0ef41Sopenharmony_ci            s->session = NULL;
6871cb0ef41Sopenharmony_ci
6881cb0ef41Sopenharmony_ci        if (!try_session_cache) {
6891cb0ef41Sopenharmony_ci            /*
6901cb0ef41Sopenharmony_ci             * The session was from a ticket, so we should issue a ticket for
6911cb0ef41Sopenharmony_ci             * the new session
6921cb0ef41Sopenharmony_ci             */
6931cb0ef41Sopenharmony_ci            s->ext.ticket_expected = 1;
6941cb0ef41Sopenharmony_ci        }
6951cb0ef41Sopenharmony_ci    }
6961cb0ef41Sopenharmony_ci    if (fatal)
6971cb0ef41Sopenharmony_ci        return -1;
6981cb0ef41Sopenharmony_ci
6991cb0ef41Sopenharmony_ci    return 0;
7001cb0ef41Sopenharmony_ci}
7011cb0ef41Sopenharmony_ci
7021cb0ef41Sopenharmony_ciint SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
7031cb0ef41Sopenharmony_ci{
7041cb0ef41Sopenharmony_ci    int ret = 0;
7051cb0ef41Sopenharmony_ci    SSL_SESSION *s;
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ci    /*
7081cb0ef41Sopenharmony_ci     * add just 1 reference count for the SSL_CTX's session cache even though
7091cb0ef41Sopenharmony_ci     * it has two ways of access: each session is in a doubly linked list and
7101cb0ef41Sopenharmony_ci     * an lhash
7111cb0ef41Sopenharmony_ci     */
7121cb0ef41Sopenharmony_ci    SSL_SESSION_up_ref(c);
7131cb0ef41Sopenharmony_ci    /*
7141cb0ef41Sopenharmony_ci     * if session c is in already in cache, we take back the increment later
7151cb0ef41Sopenharmony_ci     */
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ci    if (!CRYPTO_THREAD_write_lock(ctx->lock)) {
7181cb0ef41Sopenharmony_ci        SSL_SESSION_free(c);
7191cb0ef41Sopenharmony_ci        return 0;
7201cb0ef41Sopenharmony_ci    }
7211cb0ef41Sopenharmony_ci    s = lh_SSL_SESSION_insert(ctx->sessions, c);
7221cb0ef41Sopenharmony_ci
7231cb0ef41Sopenharmony_ci    /*
7241cb0ef41Sopenharmony_ci     * s != NULL iff we already had a session with the given PID. In this
7251cb0ef41Sopenharmony_ci     * case, s == c should hold (then we did not really modify
7261cb0ef41Sopenharmony_ci     * ctx->sessions), or we're in trouble.
7271cb0ef41Sopenharmony_ci     */
7281cb0ef41Sopenharmony_ci    if (s != NULL && s != c) {
7291cb0ef41Sopenharmony_ci        /* We *are* in trouble ... */
7301cb0ef41Sopenharmony_ci        SSL_SESSION_list_remove(ctx, s);
7311cb0ef41Sopenharmony_ci        SSL_SESSION_free(s);
7321cb0ef41Sopenharmony_ci        /*
7331cb0ef41Sopenharmony_ci         * ... so pretend the other session did not exist in cache (we cannot
7341cb0ef41Sopenharmony_ci         * handle two SSL_SESSION structures with identical session ID in the
7351cb0ef41Sopenharmony_ci         * same cache, which could happen e.g. when two threads concurrently
7361cb0ef41Sopenharmony_ci         * obtain the same session from an external cache)
7371cb0ef41Sopenharmony_ci         */
7381cb0ef41Sopenharmony_ci        s = NULL;
7391cb0ef41Sopenharmony_ci    } else if (s == NULL &&
7401cb0ef41Sopenharmony_ci               lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) {
7411cb0ef41Sopenharmony_ci        /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */
7421cb0ef41Sopenharmony_ci
7431cb0ef41Sopenharmony_ci        /*
7441cb0ef41Sopenharmony_ci         * ... so take back the extra reference and also don't add
7451cb0ef41Sopenharmony_ci         * the session to the SSL_SESSION_list at this time
7461cb0ef41Sopenharmony_ci         */
7471cb0ef41Sopenharmony_ci        s = c;
7481cb0ef41Sopenharmony_ci    }
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ci    /* Adjust last used time, and add back into the cache at the appropriate spot */
7511cb0ef41Sopenharmony_ci    if (ctx->session_cache_mode & SSL_SESS_CACHE_UPDATE_TIME) {
7521cb0ef41Sopenharmony_ci        c->time = time(NULL);
7531cb0ef41Sopenharmony_ci        ssl_session_calculate_timeout(c);
7541cb0ef41Sopenharmony_ci    }
7551cb0ef41Sopenharmony_ci
7561cb0ef41Sopenharmony_ci    if (s == NULL) {
7571cb0ef41Sopenharmony_ci        /*
7581cb0ef41Sopenharmony_ci         * new cache entry -- remove old ones if cache has become too large
7591cb0ef41Sopenharmony_ci         * delete cache entry *before* add, so we don't remove the one we're adding!
7601cb0ef41Sopenharmony_ci         */
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_ci        ret = 1;
7631cb0ef41Sopenharmony_ci
7641cb0ef41Sopenharmony_ci        if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
7651cb0ef41Sopenharmony_ci            while (SSL_CTX_sess_number(ctx) >= SSL_CTX_sess_get_cache_size(ctx)) {
7661cb0ef41Sopenharmony_ci                if (!remove_session_lock(ctx, ctx->session_cache_tail, 0))
7671cb0ef41Sopenharmony_ci                    break;
7681cb0ef41Sopenharmony_ci                else
7691cb0ef41Sopenharmony_ci                    ssl_tsan_counter(ctx, &ctx->stats.sess_cache_full);
7701cb0ef41Sopenharmony_ci            }
7711cb0ef41Sopenharmony_ci        }
7721cb0ef41Sopenharmony_ci    }
7731cb0ef41Sopenharmony_ci
7741cb0ef41Sopenharmony_ci    SSL_SESSION_list_add(ctx, c);
7751cb0ef41Sopenharmony_ci
7761cb0ef41Sopenharmony_ci    if (s != NULL) {
7771cb0ef41Sopenharmony_ci        /*
7781cb0ef41Sopenharmony_ci         * existing cache entry -- decrement previously incremented reference
7791cb0ef41Sopenharmony_ci         * count because it already takes into account the cache
7801cb0ef41Sopenharmony_ci         */
7811cb0ef41Sopenharmony_ci
7821cb0ef41Sopenharmony_ci        SSL_SESSION_free(s);    /* s == c */
7831cb0ef41Sopenharmony_ci        ret = 0;
7841cb0ef41Sopenharmony_ci    }
7851cb0ef41Sopenharmony_ci    CRYPTO_THREAD_unlock(ctx->lock);
7861cb0ef41Sopenharmony_ci    return ret;
7871cb0ef41Sopenharmony_ci}
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ciint SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
7901cb0ef41Sopenharmony_ci{
7911cb0ef41Sopenharmony_ci    return remove_session_lock(ctx, c, 1);
7921cb0ef41Sopenharmony_ci}
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_cistatic int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
7951cb0ef41Sopenharmony_ci{
7961cb0ef41Sopenharmony_ci    SSL_SESSION *r;
7971cb0ef41Sopenharmony_ci    int ret = 0;
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci    if ((c != NULL) && (c->session_id_length != 0)) {
8001cb0ef41Sopenharmony_ci        if (lck) {
8011cb0ef41Sopenharmony_ci            if (!CRYPTO_THREAD_write_lock(ctx->lock))
8021cb0ef41Sopenharmony_ci                return 0;
8031cb0ef41Sopenharmony_ci        }
8041cb0ef41Sopenharmony_ci        if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) {
8051cb0ef41Sopenharmony_ci            ret = 1;
8061cb0ef41Sopenharmony_ci            r = lh_SSL_SESSION_delete(ctx->sessions, r);
8071cb0ef41Sopenharmony_ci            SSL_SESSION_list_remove(ctx, r);
8081cb0ef41Sopenharmony_ci        }
8091cb0ef41Sopenharmony_ci        c->not_resumable = 1;
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci        if (lck)
8121cb0ef41Sopenharmony_ci            CRYPTO_THREAD_unlock(ctx->lock);
8131cb0ef41Sopenharmony_ci
8141cb0ef41Sopenharmony_ci        if (ctx->remove_session_cb != NULL)
8151cb0ef41Sopenharmony_ci            ctx->remove_session_cb(ctx, c);
8161cb0ef41Sopenharmony_ci
8171cb0ef41Sopenharmony_ci        if (ret)
8181cb0ef41Sopenharmony_ci            SSL_SESSION_free(r);
8191cb0ef41Sopenharmony_ci    }
8201cb0ef41Sopenharmony_ci    return ret;
8211cb0ef41Sopenharmony_ci}
8221cb0ef41Sopenharmony_ci
8231cb0ef41Sopenharmony_civoid SSL_SESSION_free(SSL_SESSION *ss)
8241cb0ef41Sopenharmony_ci{
8251cb0ef41Sopenharmony_ci    int i;
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci    if (ss == NULL)
8281cb0ef41Sopenharmony_ci        return;
8291cb0ef41Sopenharmony_ci    CRYPTO_DOWN_REF(&ss->references, &i, ss->lock);
8301cb0ef41Sopenharmony_ci    REF_PRINT_COUNT("SSL_SESSION", ss);
8311cb0ef41Sopenharmony_ci    if (i > 0)
8321cb0ef41Sopenharmony_ci        return;
8331cb0ef41Sopenharmony_ci    REF_ASSERT_ISNT(i < 0);
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ci    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci    OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key));
8381cb0ef41Sopenharmony_ci    OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id));
8391cb0ef41Sopenharmony_ci    X509_free(ss->peer);
8401cb0ef41Sopenharmony_ci    sk_X509_pop_free(ss->peer_chain, X509_free);
8411cb0ef41Sopenharmony_ci    OPENSSL_free(ss->ext.hostname);
8421cb0ef41Sopenharmony_ci    OPENSSL_free(ss->ext.tick);
8431cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_PSK
8441cb0ef41Sopenharmony_ci    OPENSSL_free(ss->psk_identity_hint);
8451cb0ef41Sopenharmony_ci    OPENSSL_free(ss->psk_identity);
8461cb0ef41Sopenharmony_ci#endif
8471cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_SRP
8481cb0ef41Sopenharmony_ci    OPENSSL_free(ss->srp_username);
8491cb0ef41Sopenharmony_ci#endif
8501cb0ef41Sopenharmony_ci    OPENSSL_free(ss->ext.alpn_selected);
8511cb0ef41Sopenharmony_ci    OPENSSL_free(ss->ticket_appdata);
8521cb0ef41Sopenharmony_ci    CRYPTO_THREAD_lock_free(ss->lock);
8531cb0ef41Sopenharmony_ci    OPENSSL_clear_free(ss, sizeof(*ss));
8541cb0ef41Sopenharmony_ci}
8551cb0ef41Sopenharmony_ci
8561cb0ef41Sopenharmony_ciint SSL_SESSION_up_ref(SSL_SESSION *ss)
8571cb0ef41Sopenharmony_ci{
8581cb0ef41Sopenharmony_ci    int i;
8591cb0ef41Sopenharmony_ci
8601cb0ef41Sopenharmony_ci    if (CRYPTO_UP_REF(&ss->references, &i, ss->lock) <= 0)
8611cb0ef41Sopenharmony_ci        return 0;
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ci    REF_PRINT_COUNT("SSL_SESSION", ss);
8641cb0ef41Sopenharmony_ci    REF_ASSERT_ISNT(i < 2);
8651cb0ef41Sopenharmony_ci    return ((i > 1) ? 1 : 0);
8661cb0ef41Sopenharmony_ci}
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_ciint SSL_set_session(SSL *s, SSL_SESSION *session)
8691cb0ef41Sopenharmony_ci{
8701cb0ef41Sopenharmony_ci    ssl_clear_bad_session(s);
8711cb0ef41Sopenharmony_ci    if (s->ctx->method != s->method) {
8721cb0ef41Sopenharmony_ci        if (!SSL_set_ssl_method(s, s->ctx->method))
8731cb0ef41Sopenharmony_ci            return 0;
8741cb0ef41Sopenharmony_ci    }
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ci    if (session != NULL) {
8771cb0ef41Sopenharmony_ci        SSL_SESSION_up_ref(session);
8781cb0ef41Sopenharmony_ci        s->verify_result = session->verify_result;
8791cb0ef41Sopenharmony_ci    }
8801cb0ef41Sopenharmony_ci    SSL_SESSION_free(s->session);
8811cb0ef41Sopenharmony_ci    s->session = session;
8821cb0ef41Sopenharmony_ci
8831cb0ef41Sopenharmony_ci    return 1;
8841cb0ef41Sopenharmony_ci}
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ciint SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
8871cb0ef41Sopenharmony_ci                        unsigned int sid_len)
8881cb0ef41Sopenharmony_ci{
8891cb0ef41Sopenharmony_ci    if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
8901cb0ef41Sopenharmony_ci      ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_TOO_LONG);
8911cb0ef41Sopenharmony_ci      return 0;
8921cb0ef41Sopenharmony_ci    }
8931cb0ef41Sopenharmony_ci    s->session_id_length = sid_len;
8941cb0ef41Sopenharmony_ci    if (sid != s->session_id)
8951cb0ef41Sopenharmony_ci        memcpy(s->session_id, sid, sid_len);
8961cb0ef41Sopenharmony_ci    return 1;
8971cb0ef41Sopenharmony_ci}
8981cb0ef41Sopenharmony_ci
8991cb0ef41Sopenharmony_cilong SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
9001cb0ef41Sopenharmony_ci{
9011cb0ef41Sopenharmony_ci    time_t new_timeout = (time_t)t;
9021cb0ef41Sopenharmony_ci
9031cb0ef41Sopenharmony_ci    if (s == NULL || t < 0)
9041cb0ef41Sopenharmony_ci        return 0;
9051cb0ef41Sopenharmony_ci    if (s->owner != NULL) {
9061cb0ef41Sopenharmony_ci        if (!CRYPTO_THREAD_write_lock(s->owner->lock))
9071cb0ef41Sopenharmony_ci            return 0;
9081cb0ef41Sopenharmony_ci        s->timeout = new_timeout;
9091cb0ef41Sopenharmony_ci        ssl_session_calculate_timeout(s);
9101cb0ef41Sopenharmony_ci        SSL_SESSION_list_add(s->owner, s);
9111cb0ef41Sopenharmony_ci        CRYPTO_THREAD_unlock(s->owner->lock);
9121cb0ef41Sopenharmony_ci    } else {
9131cb0ef41Sopenharmony_ci        s->timeout = new_timeout;
9141cb0ef41Sopenharmony_ci        ssl_session_calculate_timeout(s);
9151cb0ef41Sopenharmony_ci    }
9161cb0ef41Sopenharmony_ci    return 1;
9171cb0ef41Sopenharmony_ci}
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_cilong SSL_SESSION_get_timeout(const SSL_SESSION *s)
9201cb0ef41Sopenharmony_ci{
9211cb0ef41Sopenharmony_ci    if (s == NULL)
9221cb0ef41Sopenharmony_ci        return 0;
9231cb0ef41Sopenharmony_ci    return (long)s->timeout;
9241cb0ef41Sopenharmony_ci}
9251cb0ef41Sopenharmony_ci
9261cb0ef41Sopenharmony_cilong SSL_SESSION_get_time(const SSL_SESSION *s)
9271cb0ef41Sopenharmony_ci{
9281cb0ef41Sopenharmony_ci    if (s == NULL)
9291cb0ef41Sopenharmony_ci        return 0;
9301cb0ef41Sopenharmony_ci    return (long)s->time;
9311cb0ef41Sopenharmony_ci}
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_cilong SSL_SESSION_set_time(SSL_SESSION *s, long t)
9341cb0ef41Sopenharmony_ci{
9351cb0ef41Sopenharmony_ci    time_t new_time = (time_t)t;
9361cb0ef41Sopenharmony_ci
9371cb0ef41Sopenharmony_ci    if (s == NULL)
9381cb0ef41Sopenharmony_ci        return 0;
9391cb0ef41Sopenharmony_ci    if (s->owner != NULL) {
9401cb0ef41Sopenharmony_ci        if (!CRYPTO_THREAD_write_lock(s->owner->lock))
9411cb0ef41Sopenharmony_ci            return 0;
9421cb0ef41Sopenharmony_ci        s->time = new_time;
9431cb0ef41Sopenharmony_ci        ssl_session_calculate_timeout(s);
9441cb0ef41Sopenharmony_ci        SSL_SESSION_list_add(s->owner, s);
9451cb0ef41Sopenharmony_ci        CRYPTO_THREAD_unlock(s->owner->lock);
9461cb0ef41Sopenharmony_ci    } else {
9471cb0ef41Sopenharmony_ci        s->time = new_time;
9481cb0ef41Sopenharmony_ci        ssl_session_calculate_timeout(s);
9491cb0ef41Sopenharmony_ci    }
9501cb0ef41Sopenharmony_ci    return t;
9511cb0ef41Sopenharmony_ci}
9521cb0ef41Sopenharmony_ci
9531cb0ef41Sopenharmony_ciint SSL_SESSION_get_protocol_version(const SSL_SESSION *s)
9541cb0ef41Sopenharmony_ci{
9551cb0ef41Sopenharmony_ci    return s->ssl_version;
9561cb0ef41Sopenharmony_ci}
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ciint SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version)
9591cb0ef41Sopenharmony_ci{
9601cb0ef41Sopenharmony_ci    s->ssl_version = version;
9611cb0ef41Sopenharmony_ci    return 1;
9621cb0ef41Sopenharmony_ci}
9631cb0ef41Sopenharmony_ci
9641cb0ef41Sopenharmony_ciconst SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s)
9651cb0ef41Sopenharmony_ci{
9661cb0ef41Sopenharmony_ci    return s->cipher;
9671cb0ef41Sopenharmony_ci}
9681cb0ef41Sopenharmony_ci
9691cb0ef41Sopenharmony_ciint SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher)
9701cb0ef41Sopenharmony_ci{
9711cb0ef41Sopenharmony_ci    s->cipher = cipher;
9721cb0ef41Sopenharmony_ci    return 1;
9731cb0ef41Sopenharmony_ci}
9741cb0ef41Sopenharmony_ci
9751cb0ef41Sopenharmony_ciconst char *SSL_SESSION_get0_hostname(const SSL_SESSION *s)
9761cb0ef41Sopenharmony_ci{
9771cb0ef41Sopenharmony_ci    return s->ext.hostname;
9781cb0ef41Sopenharmony_ci}
9791cb0ef41Sopenharmony_ci
9801cb0ef41Sopenharmony_ciint SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname)
9811cb0ef41Sopenharmony_ci{
9821cb0ef41Sopenharmony_ci    OPENSSL_free(s->ext.hostname);
9831cb0ef41Sopenharmony_ci    if (hostname == NULL) {
9841cb0ef41Sopenharmony_ci        s->ext.hostname = NULL;
9851cb0ef41Sopenharmony_ci        return 1;
9861cb0ef41Sopenharmony_ci    }
9871cb0ef41Sopenharmony_ci    s->ext.hostname = OPENSSL_strdup(hostname);
9881cb0ef41Sopenharmony_ci
9891cb0ef41Sopenharmony_ci    return s->ext.hostname != NULL;
9901cb0ef41Sopenharmony_ci}
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ciint SSL_SESSION_has_ticket(const SSL_SESSION *s)
9931cb0ef41Sopenharmony_ci{
9941cb0ef41Sopenharmony_ci    return (s->ext.ticklen > 0) ? 1 : 0;
9951cb0ef41Sopenharmony_ci}
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ciunsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s)
9981cb0ef41Sopenharmony_ci{
9991cb0ef41Sopenharmony_ci    return s->ext.tick_lifetime_hint;
10001cb0ef41Sopenharmony_ci}
10011cb0ef41Sopenharmony_ci
10021cb0ef41Sopenharmony_civoid SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick,
10031cb0ef41Sopenharmony_ci                             size_t *len)
10041cb0ef41Sopenharmony_ci{
10051cb0ef41Sopenharmony_ci    *len = s->ext.ticklen;
10061cb0ef41Sopenharmony_ci    if (tick != NULL)
10071cb0ef41Sopenharmony_ci        *tick = s->ext.tick;
10081cb0ef41Sopenharmony_ci}
10091cb0ef41Sopenharmony_ci
10101cb0ef41Sopenharmony_ciuint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s)
10111cb0ef41Sopenharmony_ci{
10121cb0ef41Sopenharmony_ci    return s->ext.max_early_data;
10131cb0ef41Sopenharmony_ci}
10141cb0ef41Sopenharmony_ci
10151cb0ef41Sopenharmony_ciint SSL_SESSION_set_max_early_data(SSL_SESSION *s, uint32_t max_early_data)
10161cb0ef41Sopenharmony_ci{
10171cb0ef41Sopenharmony_ci    s->ext.max_early_data = max_early_data;
10181cb0ef41Sopenharmony_ci
10191cb0ef41Sopenharmony_ci    return 1;
10201cb0ef41Sopenharmony_ci}
10211cb0ef41Sopenharmony_ci
10221cb0ef41Sopenharmony_civoid SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s,
10231cb0ef41Sopenharmony_ci                                    const unsigned char **alpn,
10241cb0ef41Sopenharmony_ci                                    size_t *len)
10251cb0ef41Sopenharmony_ci{
10261cb0ef41Sopenharmony_ci    *alpn = s->ext.alpn_selected;
10271cb0ef41Sopenharmony_ci    *len = s->ext.alpn_selected_len;
10281cb0ef41Sopenharmony_ci}
10291cb0ef41Sopenharmony_ci
10301cb0ef41Sopenharmony_ciint SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, const unsigned char *alpn,
10311cb0ef41Sopenharmony_ci                                   size_t len)
10321cb0ef41Sopenharmony_ci{
10331cb0ef41Sopenharmony_ci    OPENSSL_free(s->ext.alpn_selected);
10341cb0ef41Sopenharmony_ci    if (alpn == NULL || len == 0) {
10351cb0ef41Sopenharmony_ci        s->ext.alpn_selected = NULL;
10361cb0ef41Sopenharmony_ci        s->ext.alpn_selected_len = 0;
10371cb0ef41Sopenharmony_ci        return 1;
10381cb0ef41Sopenharmony_ci    }
10391cb0ef41Sopenharmony_ci    s->ext.alpn_selected = OPENSSL_memdup(alpn, len);
10401cb0ef41Sopenharmony_ci    if (s->ext.alpn_selected == NULL) {
10411cb0ef41Sopenharmony_ci        s->ext.alpn_selected_len = 0;
10421cb0ef41Sopenharmony_ci        return 0;
10431cb0ef41Sopenharmony_ci    }
10441cb0ef41Sopenharmony_ci    s->ext.alpn_selected_len = len;
10451cb0ef41Sopenharmony_ci
10461cb0ef41Sopenharmony_ci    return 1;
10471cb0ef41Sopenharmony_ci}
10481cb0ef41Sopenharmony_ci
10491cb0ef41Sopenharmony_ciX509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
10501cb0ef41Sopenharmony_ci{
10511cb0ef41Sopenharmony_ci    return s->peer;
10521cb0ef41Sopenharmony_ci}
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_ciint SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
10551cb0ef41Sopenharmony_ci                                unsigned int sid_ctx_len)
10561cb0ef41Sopenharmony_ci{
10571cb0ef41Sopenharmony_ci    if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
10581cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
10591cb0ef41Sopenharmony_ci        return 0;
10601cb0ef41Sopenharmony_ci    }
10611cb0ef41Sopenharmony_ci    s->sid_ctx_length = sid_ctx_len;
10621cb0ef41Sopenharmony_ci    if (sid_ctx != s->sid_ctx)
10631cb0ef41Sopenharmony_ci        memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_ci    return 1;
10661cb0ef41Sopenharmony_ci}
10671cb0ef41Sopenharmony_ci
10681cb0ef41Sopenharmony_ciint SSL_SESSION_is_resumable(const SSL_SESSION *s)
10691cb0ef41Sopenharmony_ci{
10701cb0ef41Sopenharmony_ci    /*
10711cb0ef41Sopenharmony_ci     * In the case of EAP-FAST, we can have a pre-shared "ticket" without a
10721cb0ef41Sopenharmony_ci     * session ID.
10731cb0ef41Sopenharmony_ci     */
10741cb0ef41Sopenharmony_ci    return !s->not_resumable
10751cb0ef41Sopenharmony_ci           && (s->session_id_length > 0 || s->ext.ticklen > 0);
10761cb0ef41Sopenharmony_ci}
10771cb0ef41Sopenharmony_ci
10781cb0ef41Sopenharmony_cilong SSL_CTX_set_timeout(SSL_CTX *s, long t)
10791cb0ef41Sopenharmony_ci{
10801cb0ef41Sopenharmony_ci    long l;
10811cb0ef41Sopenharmony_ci    if (s == NULL)
10821cb0ef41Sopenharmony_ci        return 0;
10831cb0ef41Sopenharmony_ci    l = s->session_timeout;
10841cb0ef41Sopenharmony_ci    s->session_timeout = t;
10851cb0ef41Sopenharmony_ci    return l;
10861cb0ef41Sopenharmony_ci}
10871cb0ef41Sopenharmony_ci
10881cb0ef41Sopenharmony_cilong SSL_CTX_get_timeout(const SSL_CTX *s)
10891cb0ef41Sopenharmony_ci{
10901cb0ef41Sopenharmony_ci    if (s == NULL)
10911cb0ef41Sopenharmony_ci        return 0;
10921cb0ef41Sopenharmony_ci    return s->session_timeout;
10931cb0ef41Sopenharmony_ci}
10941cb0ef41Sopenharmony_ci
10951cb0ef41Sopenharmony_ciint SSL_set_session_secret_cb(SSL *s,
10961cb0ef41Sopenharmony_ci                              tls_session_secret_cb_fn tls_session_secret_cb,
10971cb0ef41Sopenharmony_ci                              void *arg)
10981cb0ef41Sopenharmony_ci{
10991cb0ef41Sopenharmony_ci    if (s == NULL)
11001cb0ef41Sopenharmony_ci        return 0;
11011cb0ef41Sopenharmony_ci    s->ext.session_secret_cb = tls_session_secret_cb;
11021cb0ef41Sopenharmony_ci    s->ext.session_secret_cb_arg = arg;
11031cb0ef41Sopenharmony_ci    return 1;
11041cb0ef41Sopenharmony_ci}
11051cb0ef41Sopenharmony_ci
11061cb0ef41Sopenharmony_ciint SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
11071cb0ef41Sopenharmony_ci                                  void *arg)
11081cb0ef41Sopenharmony_ci{
11091cb0ef41Sopenharmony_ci    if (s == NULL)
11101cb0ef41Sopenharmony_ci        return 0;
11111cb0ef41Sopenharmony_ci    s->ext.session_ticket_cb = cb;
11121cb0ef41Sopenharmony_ci    s->ext.session_ticket_cb_arg = arg;
11131cb0ef41Sopenharmony_ci    return 1;
11141cb0ef41Sopenharmony_ci}
11151cb0ef41Sopenharmony_ci
11161cb0ef41Sopenharmony_ciint SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
11171cb0ef41Sopenharmony_ci{
11181cb0ef41Sopenharmony_ci    if (s->version >= TLS1_VERSION) {
11191cb0ef41Sopenharmony_ci        OPENSSL_free(s->ext.session_ticket);
11201cb0ef41Sopenharmony_ci        s->ext.session_ticket = NULL;
11211cb0ef41Sopenharmony_ci        s->ext.session_ticket =
11221cb0ef41Sopenharmony_ci            OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
11231cb0ef41Sopenharmony_ci        if (s->ext.session_ticket == NULL) {
11241cb0ef41Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
11251cb0ef41Sopenharmony_ci            return 0;
11261cb0ef41Sopenharmony_ci        }
11271cb0ef41Sopenharmony_ci
11281cb0ef41Sopenharmony_ci        if (ext_data != NULL) {
11291cb0ef41Sopenharmony_ci            s->ext.session_ticket->length = ext_len;
11301cb0ef41Sopenharmony_ci            s->ext.session_ticket->data = s->ext.session_ticket + 1;
11311cb0ef41Sopenharmony_ci            memcpy(s->ext.session_ticket->data, ext_data, ext_len);
11321cb0ef41Sopenharmony_ci        } else {
11331cb0ef41Sopenharmony_ci            s->ext.session_ticket->length = 0;
11341cb0ef41Sopenharmony_ci            s->ext.session_ticket->data = NULL;
11351cb0ef41Sopenharmony_ci        }
11361cb0ef41Sopenharmony_ci
11371cb0ef41Sopenharmony_ci        return 1;
11381cb0ef41Sopenharmony_ci    }
11391cb0ef41Sopenharmony_ci
11401cb0ef41Sopenharmony_ci    return 0;
11411cb0ef41Sopenharmony_ci}
11421cb0ef41Sopenharmony_ci
11431cb0ef41Sopenharmony_civoid SSL_CTX_flush_sessions(SSL_CTX *s, long t)
11441cb0ef41Sopenharmony_ci{
11451cb0ef41Sopenharmony_ci    STACK_OF(SSL_SESSION) *sk;
11461cb0ef41Sopenharmony_ci    SSL_SESSION *current;
11471cb0ef41Sopenharmony_ci    unsigned long i;
11481cb0ef41Sopenharmony_ci
11491cb0ef41Sopenharmony_ci    if (!CRYPTO_THREAD_write_lock(s->lock))
11501cb0ef41Sopenharmony_ci        return;
11511cb0ef41Sopenharmony_ci
11521cb0ef41Sopenharmony_ci    sk = sk_SSL_SESSION_new_null();
11531cb0ef41Sopenharmony_ci    i = lh_SSL_SESSION_get_down_load(s->sessions);
11541cb0ef41Sopenharmony_ci    lh_SSL_SESSION_set_down_load(s->sessions, 0);
11551cb0ef41Sopenharmony_ci
11561cb0ef41Sopenharmony_ci    /*
11571cb0ef41Sopenharmony_ci     * Iterate over the list from the back (oldest), and stop
11581cb0ef41Sopenharmony_ci     * when a session can no longer be removed.
11591cb0ef41Sopenharmony_ci     * Add the session to a temporary list to be freed outside
11601cb0ef41Sopenharmony_ci     * the SSL_CTX lock.
11611cb0ef41Sopenharmony_ci     * But still do the remove_session_cb() within the lock.
11621cb0ef41Sopenharmony_ci     */
11631cb0ef41Sopenharmony_ci    while (s->session_cache_tail != NULL) {
11641cb0ef41Sopenharmony_ci        current = s->session_cache_tail;
11651cb0ef41Sopenharmony_ci        if (t == 0 || sess_timedout((time_t)t, current)) {
11661cb0ef41Sopenharmony_ci            lh_SSL_SESSION_delete(s->sessions, current);
11671cb0ef41Sopenharmony_ci            SSL_SESSION_list_remove(s, current);
11681cb0ef41Sopenharmony_ci            current->not_resumable = 1;
11691cb0ef41Sopenharmony_ci            if (s->remove_session_cb != NULL)
11701cb0ef41Sopenharmony_ci                s->remove_session_cb(s, current);
11711cb0ef41Sopenharmony_ci            /*
11721cb0ef41Sopenharmony_ci             * Throw the session on a stack, it's entirely plausible
11731cb0ef41Sopenharmony_ci             * that while freeing outside the critical section, the
11741cb0ef41Sopenharmony_ci             * session could be re-added, so avoid using the next/prev
11751cb0ef41Sopenharmony_ci             * pointers. If the stack failed to create, or the session
11761cb0ef41Sopenharmony_ci             * couldn't be put on the stack, just free it here
11771cb0ef41Sopenharmony_ci             */
11781cb0ef41Sopenharmony_ci            if (sk == NULL || !sk_SSL_SESSION_push(sk, current))
11791cb0ef41Sopenharmony_ci                SSL_SESSION_free(current);
11801cb0ef41Sopenharmony_ci        } else {
11811cb0ef41Sopenharmony_ci            break;
11821cb0ef41Sopenharmony_ci        }
11831cb0ef41Sopenharmony_ci    }
11841cb0ef41Sopenharmony_ci
11851cb0ef41Sopenharmony_ci    lh_SSL_SESSION_set_down_load(s->sessions, i);
11861cb0ef41Sopenharmony_ci    CRYPTO_THREAD_unlock(s->lock);
11871cb0ef41Sopenharmony_ci
11881cb0ef41Sopenharmony_ci    sk_SSL_SESSION_pop_free(sk, SSL_SESSION_free);
11891cb0ef41Sopenharmony_ci}
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ciint ssl_clear_bad_session(SSL *s)
11921cb0ef41Sopenharmony_ci{
11931cb0ef41Sopenharmony_ci    if ((s->session != NULL) &&
11941cb0ef41Sopenharmony_ci        !(s->shutdown & SSL_SENT_SHUTDOWN) &&
11951cb0ef41Sopenharmony_ci        !(SSL_in_init(s) || SSL_in_before(s))) {
11961cb0ef41Sopenharmony_ci        SSL_CTX_remove_session(s->session_ctx, s->session);
11971cb0ef41Sopenharmony_ci        return 1;
11981cb0ef41Sopenharmony_ci    } else
11991cb0ef41Sopenharmony_ci        return 0;
12001cb0ef41Sopenharmony_ci}
12011cb0ef41Sopenharmony_ci
12021cb0ef41Sopenharmony_ci/* locked by SSL_CTX in the calling function */
12031cb0ef41Sopenharmony_cistatic void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
12041cb0ef41Sopenharmony_ci{
12051cb0ef41Sopenharmony_ci    if ((s->next == NULL) || (s->prev == NULL))
12061cb0ef41Sopenharmony_ci        return;
12071cb0ef41Sopenharmony_ci
12081cb0ef41Sopenharmony_ci    if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) {
12091cb0ef41Sopenharmony_ci        /* last element in list */
12101cb0ef41Sopenharmony_ci        if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) {
12111cb0ef41Sopenharmony_ci            /* only one element in list */
12121cb0ef41Sopenharmony_ci            ctx->session_cache_head = NULL;
12131cb0ef41Sopenharmony_ci            ctx->session_cache_tail = NULL;
12141cb0ef41Sopenharmony_ci        } else {
12151cb0ef41Sopenharmony_ci            ctx->session_cache_tail = s->prev;
12161cb0ef41Sopenharmony_ci            s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
12171cb0ef41Sopenharmony_ci        }
12181cb0ef41Sopenharmony_ci    } else {
12191cb0ef41Sopenharmony_ci        if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) {
12201cb0ef41Sopenharmony_ci            /* first element in list */
12211cb0ef41Sopenharmony_ci            ctx->session_cache_head = s->next;
12221cb0ef41Sopenharmony_ci            s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
12231cb0ef41Sopenharmony_ci        } else {
12241cb0ef41Sopenharmony_ci            /* middle of list */
12251cb0ef41Sopenharmony_ci            s->next->prev = s->prev;
12261cb0ef41Sopenharmony_ci            s->prev->next = s->next;
12271cb0ef41Sopenharmony_ci        }
12281cb0ef41Sopenharmony_ci    }
12291cb0ef41Sopenharmony_ci    s->prev = s->next = NULL;
12301cb0ef41Sopenharmony_ci    s->owner = NULL;
12311cb0ef41Sopenharmony_ci}
12321cb0ef41Sopenharmony_ci
12331cb0ef41Sopenharmony_cistatic void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
12341cb0ef41Sopenharmony_ci{
12351cb0ef41Sopenharmony_ci    SSL_SESSION *next;
12361cb0ef41Sopenharmony_ci
12371cb0ef41Sopenharmony_ci    if ((s->next != NULL) && (s->prev != NULL))
12381cb0ef41Sopenharmony_ci        SSL_SESSION_list_remove(ctx, s);
12391cb0ef41Sopenharmony_ci
12401cb0ef41Sopenharmony_ci    if (ctx->session_cache_head == NULL) {
12411cb0ef41Sopenharmony_ci        ctx->session_cache_head = s;
12421cb0ef41Sopenharmony_ci        ctx->session_cache_tail = s;
12431cb0ef41Sopenharmony_ci        s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
12441cb0ef41Sopenharmony_ci        s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
12451cb0ef41Sopenharmony_ci    } else {
12461cb0ef41Sopenharmony_ci        if (timeoutcmp(s, ctx->session_cache_head) >= 0) {
12471cb0ef41Sopenharmony_ci            /*
12481cb0ef41Sopenharmony_ci             * if we timeout after (or the same time as) the first
12491cb0ef41Sopenharmony_ci             * session, put us first - usual case
12501cb0ef41Sopenharmony_ci             */
12511cb0ef41Sopenharmony_ci            s->next = ctx->session_cache_head;
12521cb0ef41Sopenharmony_ci            s->next->prev = s;
12531cb0ef41Sopenharmony_ci            s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
12541cb0ef41Sopenharmony_ci            ctx->session_cache_head = s;
12551cb0ef41Sopenharmony_ci        } else if (timeoutcmp(s, ctx->session_cache_tail) < 0) {
12561cb0ef41Sopenharmony_ci            /* if we timeout before the last session, put us last */
12571cb0ef41Sopenharmony_ci            s->prev = ctx->session_cache_tail;
12581cb0ef41Sopenharmony_ci            s->prev->next = s;
12591cb0ef41Sopenharmony_ci            s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
12601cb0ef41Sopenharmony_ci            ctx->session_cache_tail = s;
12611cb0ef41Sopenharmony_ci        } else {
12621cb0ef41Sopenharmony_ci            /*
12631cb0ef41Sopenharmony_ci             * we timeout somewhere in-between - if there is only
12641cb0ef41Sopenharmony_ci             * one session in the cache it will be caught above
12651cb0ef41Sopenharmony_ci             */
12661cb0ef41Sopenharmony_ci            next = ctx->session_cache_head->next;
12671cb0ef41Sopenharmony_ci            while (next != (SSL_SESSION*)&(ctx->session_cache_tail)) {
12681cb0ef41Sopenharmony_ci                if (timeoutcmp(s, next) >= 0) {
12691cb0ef41Sopenharmony_ci                    s->next = next;
12701cb0ef41Sopenharmony_ci                    s->prev = next->prev;
12711cb0ef41Sopenharmony_ci                    next->prev->next = s;
12721cb0ef41Sopenharmony_ci                    next->prev = s;
12731cb0ef41Sopenharmony_ci                    break;
12741cb0ef41Sopenharmony_ci                }
12751cb0ef41Sopenharmony_ci                next = next->next;
12761cb0ef41Sopenharmony_ci            }
12771cb0ef41Sopenharmony_ci        }
12781cb0ef41Sopenharmony_ci    }
12791cb0ef41Sopenharmony_ci    s->owner = ctx;
12801cb0ef41Sopenharmony_ci}
12811cb0ef41Sopenharmony_ci
12821cb0ef41Sopenharmony_civoid SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
12831cb0ef41Sopenharmony_ci                             int (*cb) (struct ssl_st *ssl, SSL_SESSION *sess))
12841cb0ef41Sopenharmony_ci{
12851cb0ef41Sopenharmony_ci    ctx->new_session_cb = cb;
12861cb0ef41Sopenharmony_ci}
12871cb0ef41Sopenharmony_ci
12881cb0ef41Sopenharmony_ciint (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) {
12891cb0ef41Sopenharmony_ci    return ctx->new_session_cb;
12901cb0ef41Sopenharmony_ci}
12911cb0ef41Sopenharmony_ci
12921cb0ef41Sopenharmony_civoid SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
12931cb0ef41Sopenharmony_ci                                void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess))
12941cb0ef41Sopenharmony_ci{
12951cb0ef41Sopenharmony_ci    ctx->remove_session_cb = cb;
12961cb0ef41Sopenharmony_ci}
12971cb0ef41Sopenharmony_ci
12981cb0ef41Sopenharmony_civoid (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx,
12991cb0ef41Sopenharmony_ci                                                  SSL_SESSION *sess) {
13001cb0ef41Sopenharmony_ci    return ctx->remove_session_cb;
13011cb0ef41Sopenharmony_ci}
13021cb0ef41Sopenharmony_ci
13031cb0ef41Sopenharmony_civoid SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
13041cb0ef41Sopenharmony_ci                             SSL_SESSION *(*cb) (struct ssl_st *ssl,
13051cb0ef41Sopenharmony_ci                                                 const unsigned char *data,
13061cb0ef41Sopenharmony_ci                                                 int len, int *copy))
13071cb0ef41Sopenharmony_ci{
13081cb0ef41Sopenharmony_ci    ctx->get_session_cb = cb;
13091cb0ef41Sopenharmony_ci}
13101cb0ef41Sopenharmony_ci
13111cb0ef41Sopenharmony_ciSSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl,
13121cb0ef41Sopenharmony_ci                                                       const unsigned char
13131cb0ef41Sopenharmony_ci                                                       *data, int len,
13141cb0ef41Sopenharmony_ci                                                       int *copy) {
13151cb0ef41Sopenharmony_ci    return ctx->get_session_cb;
13161cb0ef41Sopenharmony_ci}
13171cb0ef41Sopenharmony_ci
13181cb0ef41Sopenharmony_civoid SSL_CTX_set_info_callback(SSL_CTX *ctx,
13191cb0ef41Sopenharmony_ci                               void (*cb) (const SSL *ssl, int type, int val))
13201cb0ef41Sopenharmony_ci{
13211cb0ef41Sopenharmony_ci    ctx->info_callback = cb;
13221cb0ef41Sopenharmony_ci}
13231cb0ef41Sopenharmony_ci
13241cb0ef41Sopenharmony_civoid (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
13251cb0ef41Sopenharmony_ci                                                 int val) {
13261cb0ef41Sopenharmony_ci    return ctx->info_callback;
13271cb0ef41Sopenharmony_ci}
13281cb0ef41Sopenharmony_ci
13291cb0ef41Sopenharmony_civoid SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
13301cb0ef41Sopenharmony_ci                                int (*cb) (SSL *ssl, X509 **x509,
13311cb0ef41Sopenharmony_ci                                           EVP_PKEY **pkey))
13321cb0ef41Sopenharmony_ci{
13331cb0ef41Sopenharmony_ci    ctx->client_cert_cb = cb;
13341cb0ef41Sopenharmony_ci}
13351cb0ef41Sopenharmony_ci
13361cb0ef41Sopenharmony_ciint (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
13371cb0ef41Sopenharmony_ci                                                 EVP_PKEY **pkey) {
13381cb0ef41Sopenharmony_ci    return ctx->client_cert_cb;
13391cb0ef41Sopenharmony_ci}
13401cb0ef41Sopenharmony_ci
13411cb0ef41Sopenharmony_civoid SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
13421cb0ef41Sopenharmony_ci                                    int (*cb) (SSL *ssl,
13431cb0ef41Sopenharmony_ci                                               unsigned char *cookie,
13441cb0ef41Sopenharmony_ci                                               unsigned int *cookie_len))
13451cb0ef41Sopenharmony_ci{
13461cb0ef41Sopenharmony_ci    ctx->app_gen_cookie_cb = cb;
13471cb0ef41Sopenharmony_ci}
13481cb0ef41Sopenharmony_ci
13491cb0ef41Sopenharmony_civoid SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
13501cb0ef41Sopenharmony_ci                                  int (*cb) (SSL *ssl,
13511cb0ef41Sopenharmony_ci                                             const unsigned char *cookie,
13521cb0ef41Sopenharmony_ci                                             unsigned int cookie_len))
13531cb0ef41Sopenharmony_ci{
13541cb0ef41Sopenharmony_ci    ctx->app_verify_cookie_cb = cb;
13551cb0ef41Sopenharmony_ci}
13561cb0ef41Sopenharmony_ci
13571cb0ef41Sopenharmony_ciint SSL_SESSION_set1_ticket_appdata(SSL_SESSION *ss, const void *data, size_t len)
13581cb0ef41Sopenharmony_ci{
13591cb0ef41Sopenharmony_ci    OPENSSL_free(ss->ticket_appdata);
13601cb0ef41Sopenharmony_ci    ss->ticket_appdata_len = 0;
13611cb0ef41Sopenharmony_ci    if (data == NULL || len == 0) {
13621cb0ef41Sopenharmony_ci        ss->ticket_appdata = NULL;
13631cb0ef41Sopenharmony_ci        return 1;
13641cb0ef41Sopenharmony_ci    }
13651cb0ef41Sopenharmony_ci    ss->ticket_appdata = OPENSSL_memdup(data, len);
13661cb0ef41Sopenharmony_ci    if (ss->ticket_appdata != NULL) {
13671cb0ef41Sopenharmony_ci        ss->ticket_appdata_len = len;
13681cb0ef41Sopenharmony_ci        return 1;
13691cb0ef41Sopenharmony_ci    }
13701cb0ef41Sopenharmony_ci    return 0;
13711cb0ef41Sopenharmony_ci}
13721cb0ef41Sopenharmony_ci
13731cb0ef41Sopenharmony_ciint SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len)
13741cb0ef41Sopenharmony_ci{
13751cb0ef41Sopenharmony_ci    *data = ss->ticket_appdata;
13761cb0ef41Sopenharmony_ci    *len = ss->ticket_appdata_len;
13771cb0ef41Sopenharmony_ci    return 1;
13781cb0ef41Sopenharmony_ci}
13791cb0ef41Sopenharmony_ci
13801cb0ef41Sopenharmony_civoid SSL_CTX_set_stateless_cookie_generate_cb(
13811cb0ef41Sopenharmony_ci    SSL_CTX *ctx,
13821cb0ef41Sopenharmony_ci    int (*cb) (SSL *ssl,
13831cb0ef41Sopenharmony_ci               unsigned char *cookie,
13841cb0ef41Sopenharmony_ci               size_t *cookie_len))
13851cb0ef41Sopenharmony_ci{
13861cb0ef41Sopenharmony_ci    ctx->gen_stateless_cookie_cb = cb;
13871cb0ef41Sopenharmony_ci}
13881cb0ef41Sopenharmony_ci
13891cb0ef41Sopenharmony_civoid SSL_CTX_set_stateless_cookie_verify_cb(
13901cb0ef41Sopenharmony_ci    SSL_CTX *ctx,
13911cb0ef41Sopenharmony_ci    int (*cb) (SSL *ssl,
13921cb0ef41Sopenharmony_ci               const unsigned char *cookie,
13931cb0ef41Sopenharmony_ci               size_t cookie_len))
13941cb0ef41Sopenharmony_ci{
13951cb0ef41Sopenharmony_ci    ctx->verify_stateless_cookie_cb = cb;
13961cb0ef41Sopenharmony_ci}
13971cb0ef41Sopenharmony_ci
13981cb0ef41Sopenharmony_ciIMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
1399