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