1*f4fe6251Sjsing /* $OpenBSD: ssl_sess.c,v 1.128 2024/07/22 14:47:15 jsing Exp $ */ 25b37fcf3Sryker /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 35b37fcf3Sryker * All rights reserved. 45b37fcf3Sryker * 55b37fcf3Sryker * This package is an SSL implementation written 65b37fcf3Sryker * by Eric Young (eay@cryptsoft.com). 75b37fcf3Sryker * The implementation was written so as to conform with Netscapes SSL. 85b37fcf3Sryker * 95b37fcf3Sryker * This library is free for commercial and non-commercial use as long as 105b37fcf3Sryker * the following conditions are aheared to. The following conditions 115b37fcf3Sryker * apply to all code found in this distribution, be it the RC4, RSA, 125b37fcf3Sryker * lhash, DES, etc., code; not just the SSL code. The SSL documentation 135b37fcf3Sryker * included with this distribution is covered by the same copyright terms 145b37fcf3Sryker * except that the holder is Tim Hudson (tjh@cryptsoft.com). 155b37fcf3Sryker * 165b37fcf3Sryker * Copyright remains Eric Young's, and as such any Copyright notices in 175b37fcf3Sryker * the code are not to be removed. 185b37fcf3Sryker * If this package is used in a product, Eric Young should be given attribution 195b37fcf3Sryker * as the author of the parts of the library used. 205b37fcf3Sryker * This can be in the form of a textual message at program startup or 215b37fcf3Sryker * in documentation (online or textual) provided with the package. 225b37fcf3Sryker * 235b37fcf3Sryker * Redistribution and use in source and binary forms, with or without 245b37fcf3Sryker * modification, are permitted provided that the following conditions 255b37fcf3Sryker * are met: 265b37fcf3Sryker * 1. Redistributions of source code must retain the copyright 275b37fcf3Sryker * notice, this list of conditions and the following disclaimer. 285b37fcf3Sryker * 2. Redistributions in binary form must reproduce the above copyright 295b37fcf3Sryker * notice, this list of conditions and the following disclaimer in the 305b37fcf3Sryker * documentation and/or other materials provided with the distribution. 315b37fcf3Sryker * 3. All advertising materials mentioning features or use of this software 325b37fcf3Sryker * must display the following acknowledgement: 335b37fcf3Sryker * "This product includes cryptographic software written by 345b37fcf3Sryker * Eric Young (eay@cryptsoft.com)" 355b37fcf3Sryker * The word 'cryptographic' can be left out if the rouines from the library 365b37fcf3Sryker * being used are not cryptographic related :-). 375b37fcf3Sryker * 4. If you include any Windows specific code (or a derivative thereof) from 385b37fcf3Sryker * the apps directory (application code) you must include an acknowledgement: 395b37fcf3Sryker * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 405b37fcf3Sryker * 415b37fcf3Sryker * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 425b37fcf3Sryker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 435b37fcf3Sryker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 445b37fcf3Sryker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 455b37fcf3Sryker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 465b37fcf3Sryker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 475b37fcf3Sryker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 485b37fcf3Sryker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 495b37fcf3Sryker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 505b37fcf3Sryker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 515b37fcf3Sryker * SUCH DAMAGE. 525b37fcf3Sryker * 535b37fcf3Sryker * The licence and distribution terms for any publically available version or 545b37fcf3Sryker * derivative of this code cannot be changed. i.e. this code cannot simply be 555b37fcf3Sryker * copied and put under another distribution licence 565b37fcf3Sryker * [including the GNU Public Licence.] 575b37fcf3Sryker */ 580a5d6edeSdjm /* ==================================================================== 590a5d6edeSdjm * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 600a5d6edeSdjm * 610a5d6edeSdjm * Redistribution and use in source and binary forms, with or without 620a5d6edeSdjm * modification, are permitted provided that the following conditions 630a5d6edeSdjm * are met: 640a5d6edeSdjm * 650a5d6edeSdjm * 1. Redistributions of source code must retain the above copyright 660a5d6edeSdjm * notice, this list of conditions and the following disclaimer. 670a5d6edeSdjm * 680a5d6edeSdjm * 2. Redistributions in binary form must reproduce the above copyright 690a5d6edeSdjm * notice, this list of conditions and the following disclaimer in 700a5d6edeSdjm * the documentation and/or other materials provided with the 710a5d6edeSdjm * distribution. 720a5d6edeSdjm * 730a5d6edeSdjm * 3. All advertising materials mentioning features or use of this 740a5d6edeSdjm * software must display the following acknowledgment: 750a5d6edeSdjm * "This product includes software developed by the OpenSSL Project 760a5d6edeSdjm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 770a5d6edeSdjm * 780a5d6edeSdjm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 790a5d6edeSdjm * endorse or promote products derived from this software without 800a5d6edeSdjm * prior written permission. For written permission, please contact 810a5d6edeSdjm * openssl-core@openssl.org. 820a5d6edeSdjm * 830a5d6edeSdjm * 5. Products derived from this software may not be called "OpenSSL" 840a5d6edeSdjm * nor may "OpenSSL" appear in their names without prior written 850a5d6edeSdjm * permission of the OpenSSL Project. 860a5d6edeSdjm * 870a5d6edeSdjm * 6. Redistributions of any form whatsoever must retain the following 880a5d6edeSdjm * acknowledgment: 890a5d6edeSdjm * "This product includes software developed by the OpenSSL Project 900a5d6edeSdjm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 910a5d6edeSdjm * 920a5d6edeSdjm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 930a5d6edeSdjm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 940a5d6edeSdjm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 950a5d6edeSdjm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 960a5d6edeSdjm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 970a5d6edeSdjm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 980a5d6edeSdjm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 990a5d6edeSdjm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1000a5d6edeSdjm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1010a5d6edeSdjm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1020a5d6edeSdjm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1030a5d6edeSdjm * OF THE POSSIBILITY OF SUCH DAMAGE. 1040a5d6edeSdjm * ==================================================================== 1050a5d6edeSdjm * 1060a5d6edeSdjm * This product includes cryptographic software written by Eric Young 1070a5d6edeSdjm * (eay@cryptsoft.com). This product includes software written by Tim 1080a5d6edeSdjm * Hudson (tjh@cryptsoft.com). 1090a5d6edeSdjm * 1100a5d6edeSdjm */ 1110a5d6edeSdjm /* ==================================================================== 1120a5d6edeSdjm * Copyright 2005 Nokia. All rights reserved. 1130a5d6edeSdjm * 1140a5d6edeSdjm * The portions of the attached software ("Contribution") is developed by 1150a5d6edeSdjm * Nokia Corporation and is licensed pursuant to the OpenSSL open source 1160a5d6edeSdjm * license. 1170a5d6edeSdjm * 1180a5d6edeSdjm * The Contribution, originally written by Mika Kousa and Pasi Eronen of 1190a5d6edeSdjm * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 1200a5d6edeSdjm * support (see RFC 4279) to OpenSSL. 1210a5d6edeSdjm * 1220a5d6edeSdjm * No patent licenses or other rights except those expressly stated in 1230a5d6edeSdjm * the OpenSSL open source license shall be deemed granted or received 1240a5d6edeSdjm * expressly, by implication, estoppel, or otherwise. 1250a5d6edeSdjm * 1260a5d6edeSdjm * No assurances are provided by Nokia that the Contribution does not 1270a5d6edeSdjm * infringe the patent or other intellectual property rights of any third 1280a5d6edeSdjm * party or that the license provides you with all the necessary rights 1290a5d6edeSdjm * to make use of the Contribution. 1300a5d6edeSdjm * 1310a5d6edeSdjm * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 1320a5d6edeSdjm * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 1330a5d6edeSdjm * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 1340a5d6edeSdjm * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 1350a5d6edeSdjm * OTHERWISE. 1360a5d6edeSdjm */ 1375b37fcf3Sryker 138913ec974Sbeck #include <openssl/lhash.h> 139f4dd87b5Sjsing #include <openssl/opensslconf.h> 1409c1df9efSjsing 141c9675a23Stb #include "ssl_local.h" 1425b37fcf3Sryker 1435b37fcf3Sryker static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); 1445b37fcf3Sryker static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); 145913ec974Sbeck static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); 1465b37fcf3Sryker 147ba5406e9Sbeck /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ 148dbea66cdSguenther SSL_SESSION * 149dbea66cdSguenther SSL_get_session(const SSL *ssl) 1505b37fcf3Sryker { 1515b37fcf3Sryker return (ssl->session); 1525b37fcf3Sryker } 15371e04849Sbeck LSSL_ALIAS(SSL_get_session); 1545b37fcf3Sryker 155ba5406e9Sbeck /* variant of SSL_get_session: caller really gets something */ 156dbea66cdSguenther SSL_SESSION * 157dbea66cdSguenther SSL_get1_session(SSL *ssl) 158ba5406e9Sbeck { 159ba5406e9Sbeck SSL_SESSION *sess; 1609c1df9efSjsing 1619c1df9efSjsing /* 1629c1df9efSjsing * Need to lock this all up rather than just use CRYPTO_add so that 163ba5406e9Sbeck * somebody doesn't free ssl->session between when we check it's 1649c1df9efSjsing * non-null and when we up the reference count. 1659c1df9efSjsing */ 166cdc51833Smarkus CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); 167ba5406e9Sbeck sess = ssl->session; 168ba5406e9Sbeck if (sess) 169ba5406e9Sbeck sess->references++; 170cdc51833Smarkus CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); 1719c1df9efSjsing 172ba5406e9Sbeck return (sess); 173ba5406e9Sbeck } 17471e04849Sbeck LSSL_ALIAS(SSL_get1_session); 175ba5406e9Sbeck 17635fb0677Sjsing int 17735fb0677Sjsing SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 178ba5406e9Sbeck CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 1795b37fcf3Sryker { 1809c1df9efSjsing return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, 1819c1df9efSjsing argl, argp, new_func, dup_func, free_func); 1825b37fcf3Sryker } 18371e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_ex_new_index); 1845b37fcf3Sryker 18535fb0677Sjsing int 18635fb0677Sjsing SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) 1875b37fcf3Sryker { 1887e086035Sjsing return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); 1895b37fcf3Sryker } 19071e04849Sbeck LSSL_ALIAS(SSL_SESSION_set_ex_data); 1915b37fcf3Sryker 192dbea66cdSguenther void * 193dbea66cdSguenther SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) 1945b37fcf3Sryker { 1957e086035Sjsing return (CRYPTO_get_ex_data(&s->ex_data, idx)); 1965b37fcf3Sryker } 19771e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_ex_data); 1985b37fcf3Sryker 199d309fe46Stb uint32_t 200d309fe46Stb SSL_SESSION_get_max_early_data(const SSL_SESSION *s) 201d309fe46Stb { 202d309fe46Stb return 0; 203d309fe46Stb } 20471e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_max_early_data); 205d309fe46Stb 206d309fe46Stb int 207d309fe46Stb SSL_SESSION_set_max_early_data(SSL_SESSION *s, uint32_t max_early_data) 208d309fe46Stb { 209d309fe46Stb return 1; 210d309fe46Stb } 21171e04849Sbeck LSSL_ALIAS(SSL_SESSION_set_max_early_data); 212d309fe46Stb 213dbea66cdSguenther SSL_SESSION * 214dbea66cdSguenther SSL_SESSION_new(void) 2155b37fcf3Sryker { 2165b37fcf3Sryker SSL_SESSION *ss; 2175b37fcf3Sryker 218e68eaf89Sbeck if (!OPENSSL_init_ssl(0, NULL)) { 219e68eaf89Sbeck SSLerrorx(SSL_R_LIBRARY_BUG); 220e68eaf89Sbeck return(NULL); 221e68eaf89Sbeck } 222e68eaf89Sbeck 2238462f404Sjsing if ((ss = calloc(1, sizeof(*ss))) == NULL) { 224c9d7abb7Sbeck SSLerrorx(ERR_R_MALLOC_FAILURE); 2258462f404Sjsing return (NULL); 2268462f404Sjsing } 2275b37fcf3Sryker 228ba5406e9Sbeck ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ 2295b37fcf3Sryker ss->references = 1; 230b5ddb6d5Stb ss->timeout = 60 * 5 + 4; /* 5 minutes 4 seconds timeout by default */ 231aa8444d1Sguenther ss->time = time(NULL); 2327e086035Sjsing ss->prev = NULL; 2337e086035Sjsing ss->next = NULL; 2344fcf65c5Sdjm ss->tlsext_hostname = NULL; 23535fb0677Sjsing 236ad618767Sjsing ss->peer_cert_type = -1; 237ad618767Sjsing 2387e086035Sjsing ss->tlsext_ecpointformatlist_length = 0; 2397e086035Sjsing ss->tlsext_ecpointformatlist = NULL; 2407e086035Sjsing ss->tlsext_supportedgroups_length = 0; 2417e086035Sjsing ss->tlsext_supportedgroups = NULL; 2429c1df9efSjsing 2437e086035Sjsing CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); 2449c1df9efSjsing 2455b37fcf3Sryker return (ss); 2465b37fcf3Sryker } 24771e04849Sbeck LSSL_ALIAS(SSL_SESSION_new); 2485b37fcf3Sryker 249ed031ec4Stb SSL_SESSION * 250ed031ec4Stb ssl_session_dup(SSL_SESSION *sess, int include_ticket) 251ed031ec4Stb { 252ed031ec4Stb SSL_SESSION *copy; 253ed031ec4Stb CBS cbs; 254ed031ec4Stb 255ed031ec4Stb if ((copy = calloc(1, sizeof(*copy))) == NULL) { 256ed031ec4Stb SSLerrorx(ERR_R_MALLOC_FAILURE); 257ed031ec4Stb goto err; 258ed031ec4Stb } 259ed031ec4Stb 260ed031ec4Stb copy->ssl_version = sess->ssl_version; 261ed031ec4Stb 262ed031ec4Stb CBS_init(&cbs, sess->master_key, sess->master_key_length); 263ed031ec4Stb if (!CBS_write_bytes(&cbs, copy->master_key, sizeof(copy->master_key), 264ed031ec4Stb ©->master_key_length)) 265ed031ec4Stb goto err; 266ed031ec4Stb 267ed031ec4Stb CBS_init(&cbs, sess->session_id, sess->session_id_length); 268ed031ec4Stb if (!CBS_write_bytes(&cbs, copy->session_id, sizeof(copy->session_id), 269ed031ec4Stb ©->session_id_length)) 270ed031ec4Stb goto err; 271ed031ec4Stb 272ed031ec4Stb CBS_init(&cbs, sess->sid_ctx, sess->sid_ctx_length); 273ed031ec4Stb if (!CBS_write_bytes(&cbs, copy->sid_ctx, sizeof(copy->sid_ctx), 274ed031ec4Stb ©->sid_ctx_length)) 275ed031ec4Stb goto err; 276ed031ec4Stb 277ed031ec4Stb if (sess->peer_cert != NULL) { 278ed031ec4Stb if (!X509_up_ref(sess->peer_cert)) 279ed031ec4Stb goto err; 280ed031ec4Stb copy->peer_cert = sess->peer_cert; 281ed031ec4Stb } 282ed031ec4Stb copy->peer_cert_type = sess->peer_cert_type; 283ed031ec4Stb 284ed031ec4Stb copy->verify_result = sess->verify_result; 285ed031ec4Stb 286ed031ec4Stb copy->timeout = sess->timeout; 287ed031ec4Stb copy->time = sess->time; 288ed031ec4Stb copy->references = 1; 289ed031ec4Stb 290*f4fe6251Sjsing copy->cipher_value = sess->cipher_value; 291ed031ec4Stb 292ed031ec4Stb if (sess->tlsext_hostname != NULL) { 293ed031ec4Stb copy->tlsext_hostname = strdup(sess->tlsext_hostname); 294ed031ec4Stb if (copy->tlsext_hostname == NULL) 295ed031ec4Stb goto err; 296ed031ec4Stb } 297ed031ec4Stb 298ed031ec4Stb if (include_ticket) { 299ed031ec4Stb CBS_init(&cbs, sess->tlsext_tick, sess->tlsext_ticklen); 300ed031ec4Stb if (!CBS_stow(&cbs, ©->tlsext_tick, ©->tlsext_ticklen)) 301ed031ec4Stb goto err; 302ed031ec4Stb copy->tlsext_tick_lifetime_hint = 303ed031ec4Stb sess->tlsext_tick_lifetime_hint; 304ed031ec4Stb 305ed031ec4Stb /* 306ed031ec4Stb * XXX - copy sess->resumption_master_secret and all other 307ed031ec4Stb * TLSv1.3 info here. 308ed031ec4Stb */ 309ed031ec4Stb } 310ed031ec4Stb 311ed031ec4Stb if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, copy, 312ed031ec4Stb ©->ex_data)) 313ed031ec4Stb goto err; 314ed031ec4Stb 315ed031ec4Stb if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ©->ex_data, 316ed031ec4Stb &sess->ex_data)) 317ed031ec4Stb goto err; 318ed031ec4Stb 319ed031ec4Stb /* Omit prev/next: the new session gets its own slot in the cache. */ 320ed031ec4Stb 321ed031ec4Stb copy->not_resumable = sess->not_resumable; 322ed031ec4Stb 323ed031ec4Stb CBS_init(&cbs, sess->tlsext_ecpointformatlist, 324ed031ec4Stb sess->tlsext_ecpointformatlist_length); 325ed031ec4Stb if (!CBS_stow(&cbs, ©->tlsext_ecpointformatlist, 326ed031ec4Stb ©->tlsext_ecpointformatlist_length)) 327ed031ec4Stb goto err; 328ed031ec4Stb 329ed031ec4Stb if (sess->tlsext_supportedgroups != NULL) { 330ed031ec4Stb if ((copy->tlsext_supportedgroups = calloc(sizeof(uint16_t), 331ed031ec4Stb sess->tlsext_supportedgroups_length)) == NULL) 332ed031ec4Stb goto err; 333ed031ec4Stb memcpy(copy->tlsext_supportedgroups, 334ed031ec4Stb sess->tlsext_supportedgroups, 335ed031ec4Stb sizeof(uint16_t) * sess->tlsext_supportedgroups_length); 336ed031ec4Stb copy->tlsext_supportedgroups_length = 337ed031ec4Stb sess->tlsext_supportedgroups_length; 338ed031ec4Stb } 339ed031ec4Stb 340ed031ec4Stb return copy; 341ed031ec4Stb 342ed031ec4Stb err: 343ed031ec4Stb SSL_SESSION_free(copy); 344ed031ec4Stb 345ed031ec4Stb return NULL; 346ed031ec4Stb } 347ed031ec4Stb 348dbea66cdSguenther const unsigned char * 34905ce10daSjsing SSL_SESSION_get_id(const SSL_SESSION *ss, unsigned int *len) 3504fcf65c5Sdjm { 35105ce10daSjsing if (len != NULL) 3527c24ca9eStb *len = (unsigned int)ss->session_id_length; 35305ce10daSjsing return ss->session_id; 35405ce10daSjsing } 35571e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_id); 35605ce10daSjsing 35705ce10daSjsing const unsigned char * 35805ce10daSjsing SSL_SESSION_get0_id_context(const SSL_SESSION *ss, unsigned int *len) 35905ce10daSjsing { 36005ce10daSjsing if (len != NULL) 36105ce10daSjsing *len = (unsigned int)ss->sid_ctx_length; 36205ce10daSjsing return ss->sid_ctx; 3634fcf65c5Sdjm } 36471e04849Sbeck LSSL_ALIAS(SSL_SESSION_get0_id_context); 3654fcf65c5Sdjm 36635fb0677Sjsing unsigned int 36705ce10daSjsing SSL_SESSION_get_compress_id(const SSL_SESSION *ss) 3685cdd308eSdjm { 369e5b4af74Stedu return 0; 3705cdd308eSdjm } 37171e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_compress_id); 3725cdd308eSdjm 3731a87ffccStb unsigned long 3741a87ffccStb SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) 3751a87ffccStb { 3761a87ffccStb return s->tlsext_tick_lifetime_hint; 3771a87ffccStb } 37871e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_ticket_lifetime_hint); 3791a87ffccStb 3801a87ffccStb int 3811a87ffccStb SSL_SESSION_has_ticket(const SSL_SESSION *s) 3821a87ffccStb { 3831a87ffccStb return (s->tlsext_ticklen > 0) ? 1 : 0; 3841a87ffccStb } 38571e04849Sbeck LSSL_ALIAS(SSL_SESSION_has_ticket); 3861a87ffccStb 3879c1df9efSjsing /* 38846f2cc82Sjsing * SSLv3/TLSv1 has 32 bytes (256 bits) of session ID space. As such, filling 38946f2cc82Sjsing * the ID with random gunk repeatedly until we have no conflict is going to 39046f2cc82Sjsing * complete in one iteration pretty much "most" of the time (btw: 39146f2cc82Sjsing * understatement). So, if it takes us 10 iterations and we still can't avoid 39246f2cc82Sjsing * a conflict - well that's a reasonable point to call it quits. Either the 39346f2cc82Sjsing * arc4random code is broken or someone is trying to open roughly very close to 39446f2cc82Sjsing * 2^128 (or 2^256) SSL sessions to our server. How you might store that many 39546f2cc82Sjsing * sessions is perhaps a more interesting question... 3969c1df9efSjsing */ 397da347917Sbeck 398da347917Sbeck #define MAX_SESS_ID_ATTEMPTS 10 3999c1df9efSjsing 40035fb0677Sjsing static int 4019c1df9efSjsing def_generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len) 402da347917Sbeck { 403da347917Sbeck unsigned int retry = 0; 4049c1df9efSjsing 4059c1df9efSjsing do { 4062a423e6aSjsing arc4random_buf(id, *id_len); 4079c1df9efSjsing } while (SSL_has_matching_session_id(ssl, id, *id_len) && 408da347917Sbeck (++retry < MAX_SESS_ID_ATTEMPTS)); 4099c1df9efSjsing 410da347917Sbeck if (retry < MAX_SESS_ID_ATTEMPTS) 411da347917Sbeck return 1; 4129c1df9efSjsing 413da347917Sbeck /* else - woops a session_id match */ 414da347917Sbeck /* XXX We should also check the external cache -- 415da347917Sbeck * but the probability of a collision is negligible, and 416da347917Sbeck * we could not prevent the concurrent creation of sessions 417da347917Sbeck * with identical IDs since we currently don't have means 418da347917Sbeck * to atomically check whether a session ID already exists 419da347917Sbeck * and make a reservation for it if it does not 420da347917Sbeck * (this problem applies to the internal cache as well). 421da347917Sbeck */ 422da347917Sbeck return 0; 423da347917Sbeck } 424da347917Sbeck 42535fb0677Sjsing int 42635fb0677Sjsing ssl_get_new_session(SSL *s, int session) 4275b37fcf3Sryker { 428da347917Sbeck unsigned int tmp; 4295b37fcf3Sryker SSL_SESSION *ss = NULL; 430da347917Sbeck GEN_SESSION_CB cb = def_generate_session_id; 4315b37fcf3Sryker 4329c1df9efSjsing /* This gets used by clients and servers. */ 4339c1df9efSjsing 4349c1df9efSjsing if ((ss = SSL_SESSION_new()) == NULL) 4359c1df9efSjsing return (0); 4365b37fcf3Sryker 4375b37fcf3Sryker /* If the context has a default timeout, use it */ 4380a5d6edeSdjm if (s->session_ctx->session_timeout == 0) 4395b37fcf3Sryker ss->timeout = SSL_get_default_timeout(s); 440913ec974Sbeck else 4410a5d6edeSdjm ss->timeout = s->session_ctx->session_timeout; 4425b37fcf3Sryker 44335fb0677Sjsing if (s->session != NULL) { 4445b37fcf3Sryker SSL_SESSION_free(s->session); 4455b37fcf3Sryker s->session = NULL; 4465b37fcf3Sryker } 4475b37fcf3Sryker 44835fb0677Sjsing if (session) { 449bbf55693Sguenther switch (s->version) { 450bbf55693Sguenther case TLS1_VERSION: 451bbf55693Sguenther case TLS1_1_VERSION: 452bbf55693Sguenther case TLS1_2_VERSION: 453bbf55693Sguenther case DTLS1_VERSION: 454e9d01b14Sjsing case DTLS1_2_VERSION: 455bbf55693Sguenther ss->ssl_version = s->version; 4565b37fcf3Sryker ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 457bbf55693Sguenther break; 458bbf55693Sguenther default: 459c9d7abb7Sbeck SSLerror(s, SSL_R_UNSUPPORTED_SSL_VERSION); 4605b37fcf3Sryker SSL_SESSION_free(ss); 4615b37fcf3Sryker return (0); 4625b37fcf3Sryker } 4639c1df9efSjsing 4649c1df9efSjsing /* If RFC4507 ticket use empty session ID. */ 4656f7f653bSjsing if (s->tlsext_ticket_expected) { 4664fcf65c5Sdjm ss->session_id_length = 0; 4674fcf65c5Sdjm goto sess_id_done; 4684fcf65c5Sdjm } 4699c1df9efSjsing 4709c1df9efSjsing /* Choose which callback will set the session ID. */ 4715b37fcf3Sryker CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 4726f7f653bSjsing if (s->generate_session_id) 4736f7f653bSjsing cb = s->generate_session_id; 4746f7f653bSjsing else if (s->session_ctx->generate_session_id) 4756f7f653bSjsing cb = s->session_ctx->generate_session_id; 4765b37fcf3Sryker CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 4779c1df9efSjsing 4789c1df9efSjsing /* Choose a session ID. */ 479da347917Sbeck tmp = ss->session_id_length; 48035fb0677Sjsing if (!cb(s, ss->session_id, &tmp)) { 481da347917Sbeck /* The callback failed */ 482c9d7abb7Sbeck SSLerror(s, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); 483da347917Sbeck SSL_SESSION_free(ss); 484da347917Sbeck return (0); 485da347917Sbeck } 4869c1df9efSjsing 4879c1df9efSjsing /* 4889c1df9efSjsing * Don't allow the callback to set the session length to zero. 4899c1df9efSjsing * nor set it higher than it was. 4909c1df9efSjsing */ 491aca06622Stb if (tmp == 0 || tmp > ss->session_id_length) { 492da347917Sbeck /* The callback set an illegal length */ 493c9d7abb7Sbeck SSLerror(s, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); 494da347917Sbeck SSL_SESSION_free(ss); 495da347917Sbeck return (0); 496da347917Sbeck } 497da347917Sbeck ss->session_id_length = tmp; 4989c1df9efSjsing 4999c1df9efSjsing /* Finally, check for a conflict. */ 500da347917Sbeck if (SSL_has_matching_session_id(s, ss->session_id, 50135fb0677Sjsing ss->session_id_length)) { 502c9d7abb7Sbeck SSLerror(s, SSL_R_SSL_SESSION_ID_CONFLICT); 503da347917Sbeck SSL_SESSION_free(ss); 504da347917Sbeck return (0); 5055b37fcf3Sryker } 5069c1df9efSjsing 5074fcf65c5Sdjm sess_id_done: 5084fcf65c5Sdjm if (s->tlsext_hostname) { 50974a2cbdcSbeck ss->tlsext_hostname = strdup(s->tlsext_hostname); 5104fcf65c5Sdjm if (ss->tlsext_hostname == NULL) { 511c9d7abb7Sbeck SSLerror(s, ERR_R_INTERNAL_ERROR); 5124fcf65c5Sdjm SSL_SESSION_free(ss); 5134fcf65c5Sdjm return 0; 5144fcf65c5Sdjm } 5154fcf65c5Sdjm } 51635fb0677Sjsing } else { 5175b37fcf3Sryker ss->session_id_length = 0; 5185b37fcf3Sryker } 5195b37fcf3Sryker 52035fb0677Sjsing if (s->sid_ctx_length > sizeof ss->sid_ctx) { 521c9d7abb7Sbeck SSLerror(s, ERR_R_INTERNAL_ERROR); 522cf5de1f6Smarkus SSL_SESSION_free(ss); 523cf5de1f6Smarkus return 0; 524cf5de1f6Smarkus } 5259c1df9efSjsing 526913ec974Sbeck memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); 527913ec974Sbeck ss->sid_ctx_length = s->sid_ctx_length; 5285b37fcf3Sryker s->session = ss; 5295b37fcf3Sryker ss->ssl_version = s->version; 530ba5406e9Sbeck ss->verify_result = X509_V_OK; 5315b37fcf3Sryker 5325b37fcf3Sryker return (1); 5335b37fcf3Sryker } 5345b37fcf3Sryker 53573ea8b0bStb static SSL_SESSION * 53673ea8b0bStb ssl_session_from_cache(SSL *s, CBS *session_id) 53773ea8b0bStb { 53873ea8b0bStb SSL_SESSION *sess; 53973ea8b0bStb SSL_SESSION data; 54073ea8b0bStb 5416f7f653bSjsing if ((s->session_ctx->session_cache_mode & 54273ea8b0bStb SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) 54373ea8b0bStb return NULL; 54473ea8b0bStb 545a71df539Stb memset(&data, 0, sizeof(data)); 546a71df539Stb 54773ea8b0bStb data.ssl_version = s->version; 548dcb88a9cStb 549dcb88a9cStb if (!CBS_write_bytes(session_id, data.session_id, 550dcb88a9cStb sizeof(data.session_id), &data.session_id_length)) 551dcb88a9cStb return NULL; 55273ea8b0bStb 55373ea8b0bStb CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 5546f7f653bSjsing sess = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); 55573ea8b0bStb if (sess != NULL) 55673ea8b0bStb CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); 55773ea8b0bStb CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 55873ea8b0bStb 55973ea8b0bStb if (sess == NULL) 5606f7f653bSjsing s->session_ctx->stats.sess_miss++; 56173ea8b0bStb 56273ea8b0bStb return sess; 56373ea8b0bStb } 56473ea8b0bStb 56573ea8b0bStb static SSL_SESSION * 56673ea8b0bStb ssl_session_from_callback(SSL *s, CBS *session_id) 56773ea8b0bStb { 56873ea8b0bStb SSL_SESSION *sess; 56973ea8b0bStb int copy; 57073ea8b0bStb 5716f7f653bSjsing if (s->session_ctx->get_session_cb == NULL) 57273ea8b0bStb return NULL; 57373ea8b0bStb 57473ea8b0bStb copy = 1; 5756f7f653bSjsing if ((sess = s->session_ctx->get_session_cb(s, 57673ea8b0bStb CBS_data(session_id), CBS_len(session_id), ©)) == NULL) 57773ea8b0bStb return NULL; 57873ea8b0bStb /* 57973ea8b0bStb * The copy handler may have set copy == 0 to indicate that the session 58073ea8b0bStb * structures are shared between threads and that it handles the 58173ea8b0bStb * reference count itself. If it didn't set copy to zero, we must 58273ea8b0bStb * increment the reference count. 58373ea8b0bStb */ 58473ea8b0bStb if (copy) 58573ea8b0bStb CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); 58673ea8b0bStb 5876f7f653bSjsing s->session_ctx->stats.sess_cb_hit++; 588de6dfec6Stb 58973ea8b0bStb /* Add the externally cached session to the internal cache as well. */ 5906f7f653bSjsing if (!(s->session_ctx->session_cache_mode & 59173ea8b0bStb SSL_SESS_CACHE_NO_INTERNAL_STORE)) { 59273ea8b0bStb /* 59373ea8b0bStb * The following should not return 1, 59473ea8b0bStb * otherwise, things are very strange. 59573ea8b0bStb */ 59673ea8b0bStb SSL_CTX_add_session(s->session_ctx, sess); 59773ea8b0bStb } 59873ea8b0bStb 59973ea8b0bStb return sess; 60073ea8b0bStb } 60173ea8b0bStb 60273ea8b0bStb static SSL_SESSION * 60373ea8b0bStb ssl_session_by_id(SSL *s, CBS *session_id) 60473ea8b0bStb { 60573ea8b0bStb SSL_SESSION *sess; 60673ea8b0bStb 60773ea8b0bStb if (CBS_len(session_id) == 0) 60873ea8b0bStb return NULL; 60973ea8b0bStb 61073ea8b0bStb if ((sess = ssl_session_from_cache(s, session_id)) == NULL) 61173ea8b0bStb sess = ssl_session_from_callback(s, session_id); 61273ea8b0bStb 61373ea8b0bStb return sess; 61473ea8b0bStb } 61573ea8b0bStb 6169c1df9efSjsing /* 6176e180e32Stb * ssl_get_prev_session attempts to find an SSL_SESSION to be used to resume 6186e180e32Stb * this connection. It is only called by servers. 6195cdd308eSdjm * 6205cdd308eSdjm * session_id: points at the session ID in the ClientHello. This code will 6215cdd308eSdjm * read past the end of this in order to parse out the session ticket 6225cdd308eSdjm * extension, if any. 623307759eeSjsing * ext_block: a CBS for the ClientHello extensions block. 6246e180e32Stb * alert: alert that the caller should send in case of failure. 6255cdd308eSdjm * 6265cdd308eSdjm * Returns: 6275cdd308eSdjm * -1: error 6285cdd308eSdjm * 0: a session may have been found. 6295cdd308eSdjm * 6305cdd308eSdjm * Side effects: 6319c1df9efSjsing * - If a session is found then s->session is pointed at it (after freeing 6329c1df9efSjsing * an existing session if need be) and s->verify_result is set from the 6339c1df9efSjsing * session. 6346f7f653bSjsing * - For both new and resumed sessions, s->tlsext_ticket_expected 6356e180e32Stb * indicates whether the server should issue a new session ticket or not. 6365cdd308eSdjm */ 63735fb0677Sjsing int 6389a3f7535Stb ssl_get_prev_session(SSL *s, CBS *session_id, CBS *ext_block, int *alert) 6395b37fcf3Sryker { 64009480eb4Stb SSL_SESSION *sess = NULL; 6419a3f7535Stb int alert_desc = SSL_AD_INTERNAL_ERROR, fatal = 0; 64273ea8b0bStb int ticket_decrypted = 0; 6435b37fcf3Sryker 6449c1df9efSjsing /* This is used only by servers. */ 6459c1df9efSjsing 6468890443aSjsing if (CBS_len(session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) 647913ec974Sbeck goto err; 6485cdd308eSdjm 6496f7f653bSjsing /* Sets s->tlsext_ticket_expected. */ 650a4c79661Stb switch (tls1_process_ticket(s, ext_block, &alert_desc, &sess)) { 65112abb213Stb case TLS1_TICKET_FATAL_ERROR: 6524fcf65c5Sdjm fatal = 1; 6534fcf65c5Sdjm goto err; 65412abb213Stb case TLS1_TICKET_NONE: 65512abb213Stb case TLS1_TICKET_EMPTY: 65673ea8b0bStb if ((sess = ssl_session_by_id(s, session_id)) == NULL) 65773ea8b0bStb goto err; 65873ea8b0bStb break; 65912abb213Stb case TLS1_TICKET_NOT_DECRYPTED: 660a4c79661Stb goto err; 66112abb213Stb case TLS1_TICKET_DECRYPTED: 66273ea8b0bStb ticket_decrypted = 1; 663a4c79661Stb 664a4c79661Stb /* 665a4c79661Stb * The session ID is used by some clients to detect that the 666a4c79661Stb * ticket has been accepted so we copy it into sess. 667a4c79661Stb */ 668a4c79661Stb if (!CBS_write_bytes(session_id, sess->session_id, 669ef6795cfStb sizeof(sess->session_id), &sess->session_id_length)) { 670a4c79661Stb fatal = 1; 671a4c79661Stb goto err; 672a4c79661Stb } 6735cdd308eSdjm break; 6745cdd308eSdjm default: 6750b321686Sderaadt SSLerror(s, ERR_R_INTERNAL_ERROR); 676034e32e4Sjsing fatal = 1; 6770b321686Sderaadt goto err; 6784fcf65c5Sdjm } 6795cdd308eSdjm 68009480eb4Stb /* Now sess is non-NULL and we own one of its reference counts. */ 681913ec974Sbeck 68209480eb4Stb if (sess->sid_ctx_length != s->sid_ctx_length || 6832d126708Stb timingsafe_memcmp(sess->sid_ctx, s->sid_ctx, 6842d126708Stb sess->sid_ctx_length) != 0) { 6852d126708Stb /* 6862d126708Stb * We have the session requested by the client, but we don't 6872d126708Stb * want to use it in this context. Treat it like a cache miss. 6882d126708Stb */ 6892d126708Stb goto err; 690913ec974Sbeck } 6914fcf65c5Sdjm 69235fb0677Sjsing if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { 6939c1df9efSjsing /* 6949c1df9efSjsing * We can't be sure if this session is being used out of 6954fcf65c5Sdjm * context, which is especially important for SSL_VERIFY_PEER. 6969c1df9efSjsing * The application should have used 6979c1df9efSjsing * SSL[_CTX]_set_session_id_context. 6984fcf65c5Sdjm * 6994fcf65c5Sdjm * For this error case, we generate an error instead of treating 7004fcf65c5Sdjm * the event like a cache miss (otherwise it would be easy for 7014fcf65c5Sdjm * applications to effectively disable the session cache by 7024fcf65c5Sdjm * accident without anyone noticing). 7034fcf65c5Sdjm */ 704c9d7abb7Sbeck SSLerror(s, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); 7054fcf65c5Sdjm fatal = 1; 7064fcf65c5Sdjm goto err; 7075b37fcf3Sryker } 7085b37fcf3Sryker 70909480eb4Stb if (sess->timeout < (time(NULL) - sess->time)) { 7106f7f653bSjsing s->session_ctx->stats.sess_timeout++; 71173ea8b0bStb if (!ticket_decrypted) { 7122d126708Stb /* The session was from the cache, so remove it. */ 71309480eb4Stb SSL_CTX_remove_session(s->session_ctx, sess); 7145cdd308eSdjm } 715913ec974Sbeck goto err; 7165b37fcf3Sryker } 7175b37fcf3Sryker 7186f7f653bSjsing s->session_ctx->stats.sess_hit++; 7195b37fcf3Sryker 7205b37fcf3Sryker SSL_SESSION_free(s->session); 72109480eb4Stb s->session = sess; 722ba5406e9Sbeck s->verify_result = s->session->verify_result; 7232d126708Stb 7245cdd308eSdjm return 1; 725913ec974Sbeck 726913ec974Sbeck err: 72709480eb4Stb SSL_SESSION_free(sess); 72873ea8b0bStb if (ticket_decrypted) { 7299c1df9efSjsing /* 73073ea8b0bStb * The session was from a ticket. Issue a ticket for the new 73173ea8b0bStb * session. 7329c1df9efSjsing */ 7336f7f653bSjsing s->tlsext_ticket_expected = 1; 7345cdd308eSdjm } 7359a3f7535Stb if (fatal) { 7369a3f7535Stb *alert = alert_desc; 737913ec974Sbeck return -1; 738e8f311bdStb } 739913ec974Sbeck return 0; 7405b37fcf3Sryker } 7415b37fcf3Sryker 74235fb0677Sjsing int 74335fb0677Sjsing SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) 7445b37fcf3Sryker { 7455b37fcf3Sryker int ret = 0; 7465b37fcf3Sryker SSL_SESSION *s; 7475b37fcf3Sryker 7489c1df9efSjsing /* 7499c1df9efSjsing * Add just 1 reference count for the SSL_CTX's session cache 750ba5406e9Sbeck * even though it has two ways of access: each session is in a 7519c1df9efSjsing * doubly linked list and an lhash. 7529c1df9efSjsing */ 7535b37fcf3Sryker CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); 7545b37fcf3Sryker 7559c1df9efSjsing /* 7569c1df9efSjsing * If session c is in already in cache, we take back the increment 7579c1df9efSjsing * later. 7589c1df9efSjsing */ 7595b37fcf3Sryker CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 7606f7f653bSjsing s = lh_SSL_SESSION_insert(ctx->sessions, c); 7615b37fcf3Sryker 7629c1df9efSjsing /* 7639c1df9efSjsing * s != NULL iff we already had a session with the given PID. 764ba5406e9Sbeck * In this case, s == c should hold (then we did not really modify 7656f7f653bSjsing * ctx->sessions), or we're in trouble. 7669c1df9efSjsing */ 76735fb0677Sjsing if (s != NULL && s != c) { 768ba5406e9Sbeck /* We *are* in trouble ... */ 769ba5406e9Sbeck SSL_SESSION_list_remove(ctx, s); 770ba5406e9Sbeck SSL_SESSION_free(s); 7719c1df9efSjsing /* 7729c1df9efSjsing * ... so pretend the other session did not exist in cache 773ba5406e9Sbeck * (we cannot handle two SSL_SESSION structures with identical 774ba5406e9Sbeck * session ID in the same cache, which could happen e.g. when 7759c1df9efSjsing * two threads concurrently obtain the same session from an 7769c1df9efSjsing * external cache). 7779c1df9efSjsing */ 778ba5406e9Sbeck s = NULL; 779ba5406e9Sbeck } 780ba5406e9Sbeck 781ba5406e9Sbeck /* Put at the head of the queue unless it is already in the cache */ 7825b37fcf3Sryker if (s == NULL) 7835b37fcf3Sryker SSL_SESSION_list_add(ctx, c); 7845b37fcf3Sryker 78535fb0677Sjsing if (s != NULL) { 7869c1df9efSjsing /* 7879c1df9efSjsing * existing cache entry -- decrement previously incremented 7889c1df9efSjsing * reference count because it already takes into account the 7899c1df9efSjsing * cache. 7909c1df9efSjsing */ 791ba5406e9Sbeck SSL_SESSION_free(s); /* s == c */ 7925b37fcf3Sryker ret = 0; 79335fb0677Sjsing } else { 7949c1df9efSjsing /* 7959c1df9efSjsing * New cache entry -- remove old ones if cache has become 7969c1df9efSjsing * too large. 7979c1df9efSjsing */ 798ba5406e9Sbeck 7995b37fcf3Sryker ret = 1; 8005b37fcf3Sryker 80135fb0677Sjsing if (SSL_CTX_sess_get_cache_size(ctx) > 0) { 8025b37fcf3Sryker while (SSL_CTX_sess_number(ctx) > 80335fb0677Sjsing SSL_CTX_sess_get_cache_size(ctx)) { 804913ec974Sbeck if (!remove_session_lock(ctx, 8056f7f653bSjsing ctx->session_cache_tail, 0)) 8065b37fcf3Sryker break; 8075b37fcf3Sryker else 8086f7f653bSjsing ctx->stats.sess_cache_full++; 8095b37fcf3Sryker } 8105b37fcf3Sryker } 8115b37fcf3Sryker } 8125b37fcf3Sryker CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 8135b37fcf3Sryker return (ret); 8145b37fcf3Sryker } 81571e04849Sbeck LSSL_ALIAS(SSL_CTX_add_session); 8165b37fcf3Sryker 81735fb0677Sjsing int 81835fb0677Sjsing SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) 819913ec974Sbeck { 820913ec974Sbeck return remove_session_lock(ctx, c, 1); 821913ec974Sbeck } 82271e04849Sbeck LSSL_ALIAS(SSL_CTX_remove_session); 823913ec974Sbeck 82435fb0677Sjsing static int 82535fb0677Sjsing remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) 8265b37fcf3Sryker { 8275b37fcf3Sryker SSL_SESSION *r; 8285b37fcf3Sryker int ret = 0; 8295b37fcf3Sryker 8308744b8fcStb if (c == NULL || c->session_id_length == 0) 8318744b8fcStb return 0; 8328744b8fcStb 83335fb0677Sjsing if (lck) 83435fb0677Sjsing CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 8356f7f653bSjsing if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { 8365b37fcf3Sryker ret = 1; 8376f7f653bSjsing r = lh_SSL_SESSION_delete(ctx->sessions, c); 8385b37fcf3Sryker SSL_SESSION_list_remove(ctx, c); 8395b37fcf3Sryker } 84035fb0677Sjsing if (lck) 84135fb0677Sjsing CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 8425b37fcf3Sryker 84335fb0677Sjsing if (ret) { 8447e086035Sjsing r->not_resumable = 1; 8456f7f653bSjsing if (ctx->remove_session_cb != NULL) 8466f7f653bSjsing ctx->remove_session_cb(ctx, r); 8475b37fcf3Sryker SSL_SESSION_free(r); 8485b37fcf3Sryker } 8498744b8fcStb 8508744b8fcStb return ret; 8515b37fcf3Sryker } 8525b37fcf3Sryker 85335fb0677Sjsing void 85435fb0677Sjsing SSL_SESSION_free(SSL_SESSION *ss) 8555b37fcf3Sryker { 8565b37fcf3Sryker int i; 8575b37fcf3Sryker 858913ec974Sbeck if (ss == NULL) 859913ec974Sbeck return; 860913ec974Sbeck 8615b37fcf3Sryker i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); 86235fb0677Sjsing if (i > 0) 86335fb0677Sjsing return; 8645b37fcf3Sryker 8657e086035Sjsing CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); 8665b37fcf3Sryker 8670f777b12Sjsing explicit_bzero(ss->master_key, sizeof ss->master_key); 8680f777b12Sjsing explicit_bzero(ss->session_id, sizeof ss->session_id); 86947dd5b40Sjsing 870666c9986Sjsing X509_free(ss->peer_cert); 87147dd5b40Sjsing 8726f3a6cb1Sbeck free(ss->tlsext_hostname); 8736f3a6cb1Sbeck free(ss->tlsext_tick); 8747e086035Sjsing free(ss->tlsext_ecpointformatlist); 8757e086035Sjsing free(ss->tlsext_supportedgroups); 8768462f404Sjsing 8774bcd03dbStb tls13_secret_cleanup(&ss->resumption_master_secret); 8784bcd03dbStb 8798f2be08bSjsing freezero(ss, sizeof(*ss)); 8805b37fcf3Sryker } 88171e04849Sbeck LSSL_ALIAS(SSL_SESSION_free); 8825b37fcf3Sryker 88335fb0677Sjsing int 884c6d61022Sjsing SSL_SESSION_up_ref(SSL_SESSION *ss) 885c6d61022Sjsing { 886c8993338Stb return CRYPTO_add(&ss->references, 1, CRYPTO_LOCK_SSL_SESSION) > 1; 887c6d61022Sjsing } 88871e04849Sbeck LSSL_ALIAS(SSL_SESSION_up_ref); 889c6d61022Sjsing 890c6d61022Sjsing int 89135fb0677Sjsing SSL_set_session(SSL *s, SSL_SESSION *session) 8925b37fcf3Sryker { 89391532218Sjsing const SSL_METHOD *method; 8945b37fcf3Sryker 89591532218Sjsing if (session == NULL) { 89691532218Sjsing SSL_SESSION_free(s->session); 89791532218Sjsing s->session = NULL; 89891532218Sjsing 89991532218Sjsing return SSL_set_ssl_method(s, s->ctx->method); 90091532218Sjsing } 90191532218Sjsing 9029fef1c44Sjsing if ((method = ssl_get_method(session->ssl_version)) == NULL) { 903c9d7abb7Sbeck SSLerror(s, SSL_R_UNABLE_TO_FIND_SSL_METHOD); 9045b37fcf3Sryker return (0); 9055b37fcf3Sryker } 9065b37fcf3Sryker 90791532218Sjsing if (!SSL_set_ssl_method(s, method)) 9085b37fcf3Sryker return (0); 9095b37fcf3Sryker 9105b37fcf3Sryker CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); 9115b37fcf3Sryker SSL_SESSION_free(s->session); 9125b37fcf3Sryker s->session = session; 913ce6fc090Sbeck s->verify_result = s->session->verify_result; 914913ec974Sbeck 91591532218Sjsing return (1); 9165b37fcf3Sryker } 91771e04849Sbeck LSSL_ALIAS(SSL_set_session); 9185b37fcf3Sryker 91929e4fea2Sjsing size_t 92029e4fea2Sjsing SSL_SESSION_get_master_key(const SSL_SESSION *ss, unsigned char *out, 92129e4fea2Sjsing size_t max_out) 92229e4fea2Sjsing { 92329e4fea2Sjsing size_t len = ss->master_key_length; 92429e4fea2Sjsing 92529e4fea2Sjsing if (out == NULL) 92629e4fea2Sjsing return len; 92729e4fea2Sjsing 92829e4fea2Sjsing if (len > max_out) 92929e4fea2Sjsing len = max_out; 93029e4fea2Sjsing 93129e4fea2Sjsing memcpy(out, ss->master_key, len); 93229e4fea2Sjsing 93329e4fea2Sjsing return len; 93429e4fea2Sjsing } 93571e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_master_key); 93629e4fea2Sjsing 93735fb0677Sjsing long 93835fb0677Sjsing SSL_SESSION_set_timeout(SSL_SESSION *s, long t) 9395b37fcf3Sryker { 94035fb0677Sjsing if (s == NULL) 94135fb0677Sjsing return (0); 9425b37fcf3Sryker s->timeout = t; 9435b37fcf3Sryker return (1); 9445b37fcf3Sryker } 94571e04849Sbeck LSSL_ALIAS(SSL_SESSION_set_timeout); 9465b37fcf3Sryker 94735fb0677Sjsing long 94835fb0677Sjsing SSL_SESSION_get_timeout(const SSL_SESSION *s) 9495b37fcf3Sryker { 95035fb0677Sjsing if (s == NULL) 95135fb0677Sjsing return (0); 9525b37fcf3Sryker return (s->timeout); 9535b37fcf3Sryker } 95471e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_timeout); 9555b37fcf3Sryker 956aa8444d1Sguenther /* XXX 2038 */ 95735fb0677Sjsing long 95835fb0677Sjsing SSL_SESSION_get_time(const SSL_SESSION *s) 9595b37fcf3Sryker { 96035fb0677Sjsing if (s == NULL) 96135fb0677Sjsing return (0); 9625b37fcf3Sryker return (s->time); 9635b37fcf3Sryker } 96471e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_time); 9655b37fcf3Sryker 966aa8444d1Sguenther /* XXX 2038 */ 96735fb0677Sjsing long 96835fb0677Sjsing SSL_SESSION_set_time(SSL_SESSION *s, long t) 9695b37fcf3Sryker { 97035fb0677Sjsing if (s == NULL) 97135fb0677Sjsing return (0); 9725b37fcf3Sryker s->time = t; 9735b37fcf3Sryker return (t); 9745b37fcf3Sryker } 97571e04849Sbeck LSSL_ALIAS(SSL_SESSION_set_time); 9765b37fcf3Sryker 977274bd5fbStb int 9785d90759aStb SSL_SESSION_get_protocol_version(const SSL_SESSION *s) 979274bd5fbStb { 980274bd5fbStb return s->ssl_version; 981274bd5fbStb } 98271e04849Sbeck LSSL_ALIAS(SSL_SESSION_get_protocol_version); 983274bd5fbStb 9842d36c056Stb const SSL_CIPHER * 9852d36c056Stb SSL_SESSION_get0_cipher(const SSL_SESSION *s) 9862d36c056Stb { 987*f4fe6251Sjsing return ssl3_get_cipher_by_value(s->cipher_value); 9882d36c056Stb } 98971e04849Sbeck LSSL_ALIAS(SSL_SESSION_get0_cipher); 9902d36c056Stb 991dbea66cdSguenther X509 * 992dbea66cdSguenther SSL_SESSION_get0_peer(SSL_SESSION *s) 9935cdd308eSdjm { 994666c9986Sjsing return s->peer_cert; 9955cdd308eSdjm } 99671e04849Sbeck LSSL_ALIAS(SSL_SESSION_get0_peer); 9975cdd308eSdjm 99835fb0677Sjsing int 99925ba64d1Stb SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, 100025ba64d1Stb unsigned int sid_len) 100125ba64d1Stb { 100225ba64d1Stb if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { 100325ba64d1Stb SSLerrorx(SSL_R_SSL_SESSION_ID_TOO_LONG); 100425ba64d1Stb return 0; 100525ba64d1Stb } 100625ba64d1Stb s->session_id_length = sid_len; 100725ba64d1Stb memmove(s->session_id, sid, sid_len); 100825ba64d1Stb return 1; 100925ba64d1Stb } 101071e04849Sbeck LSSL_ALIAS(SSL_SESSION_set1_id); 101125ba64d1Stb 101225ba64d1Stb int 101335fb0677Sjsing SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, 10145cdd308eSdjm unsigned int sid_ctx_len) 10155cdd308eSdjm { 101635fb0677Sjsing if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { 1017c9d7abb7Sbeck SSLerrorx(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); 10185cdd308eSdjm return 0; 10195cdd308eSdjm } 10205cdd308eSdjm s->sid_ctx_length = sid_ctx_len; 10215cdd308eSdjm memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); 10225cdd308eSdjm 10235cdd308eSdjm return 1; 10245cdd308eSdjm } 102571e04849Sbeck LSSL_ALIAS(SSL_SESSION_set1_id_context); 10265cdd308eSdjm 10275b7f4dd6Stb int 10285b7f4dd6Stb SSL_SESSION_is_resumable(const SSL_SESSION *s) 10295b7f4dd6Stb { 10305b7f4dd6Stb return 0; 10315b7f4dd6Stb } 103271e04849Sbeck LSSL_ALIAS(SSL_SESSION_is_resumable); 10335b7f4dd6Stb 103435fb0677Sjsing long 103535fb0677Sjsing SSL_CTX_set_timeout(SSL_CTX *s, long t) 1036913ec974Sbeck { 1037913ec974Sbeck long l; 10389c1df9efSjsing 103935fb0677Sjsing if (s == NULL) 104035fb0677Sjsing return (0); 1041913ec974Sbeck l = s->session_timeout; 1042913ec974Sbeck s->session_timeout = t; 10439c1df9efSjsing 1044913ec974Sbeck return (l); 1045913ec974Sbeck } 104671e04849Sbeck LSSL_ALIAS(SSL_CTX_set_timeout); 1047913ec974Sbeck 104835fb0677Sjsing long 104935fb0677Sjsing SSL_CTX_get_timeout(const SSL_CTX *s) 1050913ec974Sbeck { 105135fb0677Sjsing if (s == NULL) 105235fb0677Sjsing return (0); 1053913ec974Sbeck return (s->session_timeout); 1054913ec974Sbeck } 105571e04849Sbeck LSSL_ALIAS(SSL_CTX_get_timeout); 1056913ec974Sbeck 105735fb0677Sjsing int 10589c1df9efSjsing SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, 10599c1df9efSjsing void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, 10609c1df9efSjsing SSL_CIPHER **cipher, void *arg), void *arg) 10610a5d6edeSdjm { 106235fb0677Sjsing if (s == NULL) 106335fb0677Sjsing return (0); 10646f7f653bSjsing s->tls_session_secret_cb = tls_session_secret_cb; 10656f7f653bSjsing s->tls_session_secret_cb_arg = arg; 10660a5d6edeSdjm return (1); 10670a5d6edeSdjm } 106871e04849Sbeck LSSL_ALIAS(SSL_set_session_secret_cb); 10690a5d6edeSdjm 107035fb0677Sjsing int 107135fb0677Sjsing SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, 10720a5d6edeSdjm void *arg) 10730a5d6edeSdjm { 107435fb0677Sjsing if (s == NULL) 107535fb0677Sjsing return (0); 10766f7f653bSjsing s->tls_session_ticket_ext_cb = cb; 10776f7f653bSjsing s->tls_session_ticket_ext_cb_arg = arg; 10780a5d6edeSdjm return (1); 10790a5d6edeSdjm } 108071e04849Sbeck LSSL_ALIAS(SSL_set_session_ticket_ext_cb); 10810a5d6edeSdjm 108235fb0677Sjsing int 108335fb0677Sjsing SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) 10840a5d6edeSdjm { 108535fb0677Sjsing if (s->version >= TLS1_VERSION) { 10866f7f653bSjsing free(s->tlsext_session_ticket); 10876f7f653bSjsing s->tlsext_session_ticket = 10889c1df9efSjsing malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); 10896f7f653bSjsing if (!s->tlsext_session_ticket) { 1090c9d7abb7Sbeck SSLerror(s, ERR_R_MALLOC_FAILURE); 10910a5d6edeSdjm return 0; 10920a5d6edeSdjm } 10930a5d6edeSdjm 109435fb0677Sjsing if (ext_data) { 10956f7f653bSjsing s->tlsext_session_ticket->length = ext_len; 10966f7f653bSjsing s->tlsext_session_ticket->data = 10976f7f653bSjsing s->tlsext_session_ticket + 1; 10986f7f653bSjsing memcpy(s->tlsext_session_ticket->data, 10999c1df9efSjsing ext_data, ext_len); 110035fb0677Sjsing } else { 11016f7f653bSjsing s->tlsext_session_ticket->length = 0; 11026f7f653bSjsing s->tlsext_session_ticket->data = NULL; 11030a5d6edeSdjm } 11040a5d6edeSdjm 11050a5d6edeSdjm return 1; 11060a5d6edeSdjm } 11070a5d6edeSdjm 11080a5d6edeSdjm return 0; 11090a5d6edeSdjm } 111071e04849Sbeck LSSL_ALIAS(SSL_set_session_ticket_ext); 11110a5d6edeSdjm 111235fb0677Sjsing typedef struct timeout_param_st { 11135b37fcf3Sryker SSL_CTX *ctx; 11145b37fcf3Sryker long time; 11151bbccf41Sjsing struct lhash_st_SSL_SESSION *cache; 11165b37fcf3Sryker } TIMEOUT_PARAM; 11175b37fcf3Sryker 111835fb0677Sjsing static void 111935fb0677Sjsing timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) 11205b37fcf3Sryker { 11219c1df9efSjsing if ((p->time == 0) || (p->time > (s->time + s->timeout))) { 11229c1df9efSjsing /* timeout */ 11235b37fcf3Sryker /* The reason we don't call SSL_CTX_remove_session() is to 11245b37fcf3Sryker * save on locking overhead */ 11250a5d6edeSdjm (void)lh_SSL_SESSION_delete(p->cache, s); 11265b37fcf3Sryker SSL_SESSION_list_remove(p->ctx, s); 11277e086035Sjsing s->not_resumable = 1; 11286f7f653bSjsing if (p->ctx->remove_session_cb != NULL) 11296f7f653bSjsing p->ctx->remove_session_cb(p->ctx, s); 11305b37fcf3Sryker SSL_SESSION_free(s); 11315b37fcf3Sryker } 11325b37fcf3Sryker } 11335b37fcf3Sryker 11341bbccf41Sjsing static void 11351bbccf41Sjsing timeout_LHASH_DOALL_ARG(void *arg1, void *arg2) 11361bbccf41Sjsing { 11371bbccf41Sjsing SSL_SESSION *a = arg1; 11381bbccf41Sjsing TIMEOUT_PARAM *b = arg2; 11391bbccf41Sjsing 11401bbccf41Sjsing timeout_doall_arg(a, b); 11411bbccf41Sjsing } 1142da347917Sbeck 1143aa8444d1Sguenther /* XXX 2038 */ 114435fb0677Sjsing void 114535fb0677Sjsing SSL_CTX_flush_sessions(SSL_CTX *s, long t) 11465b37fcf3Sryker { 11475b37fcf3Sryker TIMEOUT_PARAM tp; 11485b37fcf3Sryker 11495b37fcf3Sryker tp.ctx = s; 11506f7f653bSjsing tp.cache = s->sessions; 115135fb0677Sjsing if (tp.cache == NULL) 115235fb0677Sjsing return; 11535b37fcf3Sryker tp.time = t; 115420273a99Sjsing 11555b37fcf3Sryker CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 11561bbccf41Sjsing lh_SSL_SESSION_doall_arg(tp.cache, timeout_LHASH_DOALL_ARG, 11570a5d6edeSdjm TIMEOUT_PARAM, &tp); 11585b37fcf3Sryker CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 11595b37fcf3Sryker } 116071e04849Sbeck LSSL_ALIAS(SSL_CTX_flush_sessions); 11615b37fcf3Sryker 116235fb0677Sjsing int 116335fb0677Sjsing ssl_clear_bad_session(SSL *s) 11645b37fcf3Sryker { 11656f7f653bSjsing if ((s->session != NULL) && !(s->shutdown & SSL_SENT_SHUTDOWN) && 116635fb0677Sjsing !(SSL_in_init(s) || SSL_in_before(s))) { 11675b37fcf3Sryker SSL_CTX_remove_session(s->ctx, s->session); 11685b37fcf3Sryker return (1); 116935fb0677Sjsing } else 11705b37fcf3Sryker return (0); 11715b37fcf3Sryker } 11725b37fcf3Sryker 11735b37fcf3Sryker /* locked by SSL_CTX in the calling function */ 117435fb0677Sjsing static void 117535fb0677Sjsing SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) 11765b37fcf3Sryker { 11777e086035Sjsing if (s->next == NULL || s->prev == NULL) 11789c1df9efSjsing return; 11795b37fcf3Sryker 11806f7f653bSjsing if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { 11819c1df9efSjsing /* last element in list */ 11826f7f653bSjsing if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { 11839c1df9efSjsing /* only one element in list */ 11846f7f653bSjsing ctx->session_cache_head = NULL; 11856f7f653bSjsing ctx->session_cache_tail = NULL; 118635fb0677Sjsing } else { 11876f7f653bSjsing ctx->session_cache_tail = s->prev; 11887e086035Sjsing s->prev->next = 11896f7f653bSjsing (SSL_SESSION *)&(ctx->session_cache_tail); 11905b37fcf3Sryker } 119135fb0677Sjsing } else { 11926f7f653bSjsing if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { 11939c1df9efSjsing /* first element in list */ 11946f7f653bSjsing ctx->session_cache_head = s->next; 11957e086035Sjsing s->next->prev = 11966f7f653bSjsing (SSL_SESSION *)&(ctx->session_cache_head); 11979c1df9efSjsing } else { 11989c1df9efSjsing /* middle of list */ 11997e086035Sjsing s->next->prev = s->prev; 12007e086035Sjsing s->prev->next = s->next; 12015b37fcf3Sryker } 12025b37fcf3Sryker } 12037e086035Sjsing s->prev = s->next = NULL; 12045b37fcf3Sryker } 12055b37fcf3Sryker 120635fb0677Sjsing static void 120735fb0677Sjsing SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) 12085b37fcf3Sryker { 12097e086035Sjsing if (s->next != NULL && s->prev != NULL) 12105b37fcf3Sryker SSL_SESSION_list_remove(ctx, s); 12115b37fcf3Sryker 12126f7f653bSjsing if (ctx->session_cache_head == NULL) { 12136f7f653bSjsing ctx->session_cache_head = s; 12146f7f653bSjsing ctx->session_cache_tail = s; 12156f7f653bSjsing s->prev = (SSL_SESSION *)&(ctx->session_cache_head); 12166f7f653bSjsing s->next = (SSL_SESSION *)&(ctx->session_cache_tail); 121735fb0677Sjsing } else { 12186f7f653bSjsing s->next = ctx->session_cache_head; 12197e086035Sjsing s->next->prev = s; 12206f7f653bSjsing s->prev = (SSL_SESSION *)&(ctx->session_cache_head); 12216f7f653bSjsing ctx->session_cache_head = s; 12225b37fcf3Sryker } 12235b37fcf3Sryker } 12245b37fcf3Sryker 122535fb0677Sjsing void 122635fb0677Sjsing SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, 122735fb0677Sjsing int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) { 12286f7f653bSjsing ctx->new_session_cb = cb; 12294fcf65c5Sdjm } 123071e04849Sbeck LSSL_ALIAS(SSL_CTX_sess_set_new_cb); 12314fcf65c5Sdjm 12329c1df9efSjsing int 12339c1df9efSjsing (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) 12344fcf65c5Sdjm { 12356f7f653bSjsing return ctx->new_session_cb; 12364fcf65c5Sdjm } 123771e04849Sbeck LSSL_ALIAS(SSL_CTX_sess_get_new_cb); 12384fcf65c5Sdjm 123935fb0677Sjsing void 124035fb0677Sjsing SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, 12414fcf65c5Sdjm void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) 12424fcf65c5Sdjm { 12436f7f653bSjsing ctx->remove_session_cb = cb; 12444fcf65c5Sdjm } 124571e04849Sbeck LSSL_ALIAS(SSL_CTX_sess_set_remove_cb); 12464fcf65c5Sdjm 12479c1df9efSjsing void 12489c1df9efSjsing (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx, SSL_SESSION *sess) 12494fcf65c5Sdjm { 12506f7f653bSjsing return ctx->remove_session_cb; 12514fcf65c5Sdjm } 125271e04849Sbeck LSSL_ALIAS(SSL_CTX_sess_get_remove_cb); 12534fcf65c5Sdjm 125435fb0677Sjsing void 12559c1df9efSjsing SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*cb)(struct ssl_st *ssl, 12560a4fabb9Stb const unsigned char *data, int len, int *copy)) 12574fcf65c5Sdjm { 12586f7f653bSjsing ctx->get_session_cb = cb; 12594fcf65c5Sdjm } 126071e04849Sbeck LSSL_ALIAS(SSL_CTX_sess_set_get_cb); 12614fcf65c5Sdjm 12629c1df9efSjsing SSL_SESSION * 12630a4fabb9Stb (*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, const unsigned char *data, 12649c1df9efSjsing int len, int *copy) 12654fcf65c5Sdjm { 12666f7f653bSjsing return ctx->get_session_cb; 12674fcf65c5Sdjm } 126871e04849Sbeck LSSL_ALIAS(SSL_CTX_sess_get_get_cb); 12694fcf65c5Sdjm 127035fb0677Sjsing void 127135fb0677Sjsing SSL_CTX_set_info_callback(SSL_CTX *ctx, 12724fcf65c5Sdjm void (*cb)(const SSL *ssl, int type, int val)) 12734fcf65c5Sdjm { 12746f7f653bSjsing ctx->info_callback = cb; 12754fcf65c5Sdjm } 127671e04849Sbeck LSSL_ALIAS(SSL_CTX_set_info_callback); 12774fcf65c5Sdjm 12789c1df9efSjsing void 12799c1df9efSjsing (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, int val) 12804fcf65c5Sdjm { 12816f7f653bSjsing return ctx->info_callback; 12824fcf65c5Sdjm } 128371e04849Sbeck LSSL_ALIAS(SSL_CTX_get_info_callback); 12844fcf65c5Sdjm 128535fb0677Sjsing void 128635fb0677Sjsing SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, 12874fcf65c5Sdjm int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)) 12884fcf65c5Sdjm { 12896f7f653bSjsing ctx->client_cert_cb = cb; 12904fcf65c5Sdjm } 129171e04849Sbeck LSSL_ALIAS(SSL_CTX_set_client_cert_cb); 12924fcf65c5Sdjm 12939c1df9efSjsing int 12949c1df9efSjsing (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509, 12959c1df9efSjsing EVP_PKEY **pkey) 12964fcf65c5Sdjm { 12976f7f653bSjsing return ctx->client_cert_cb; 12984fcf65c5Sdjm } 129971e04849Sbeck LSSL_ALIAS(SSL_CTX_get_client_cert_cb); 13004fcf65c5Sdjm 130135fb0677Sjsing void 130235fb0677Sjsing SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, 13034fcf65c5Sdjm int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)) 13044fcf65c5Sdjm { 13056f7f653bSjsing ctx->app_gen_cookie_cb = cb; 13064fcf65c5Sdjm } 130771e04849Sbeck LSSL_ALIAS(SSL_CTX_set_cookie_generate_cb); 13084fcf65c5Sdjm 130935fb0677Sjsing void 131035fb0677Sjsing SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, 13110a4fabb9Stb int (*cb)(SSL *ssl, const unsigned char *cookie, unsigned int cookie_len)) 13124fcf65c5Sdjm { 13136f7f653bSjsing ctx->app_verify_cookie_cb = cb; 13144fcf65c5Sdjm } 131571e04849Sbeck LSSL_ALIAS(SSL_CTX_set_cookie_verify_cb); 13164fcf65c5Sdjm 1317d820b776Sjsing int 1318d820b776Sjsing PEM_write_SSL_SESSION(FILE *fp, SSL_SESSION *x) 131907781822Sjsing { 13207c5b2634Sjsing return PEM_ASN1_write((i2d_of_void *)i2d_SSL_SESSION, 13217c5b2634Sjsing PEM_STRING_SSL_SESSION, fp, x, NULL, NULL, 0, NULL, NULL); 132207781822Sjsing } 132371e04849Sbeck LSSL_ALIAS(PEM_write_SSL_SESSION); 132407781822Sjsing 132507781822Sjsing SSL_SESSION * 132607781822Sjsing PEM_read_SSL_SESSION(FILE *fp, SSL_SESSION **x, pem_password_cb *cb, void *u) 132707781822Sjsing { 13287c5b2634Sjsing return PEM_ASN1_read((d2i_of_void *)d2i_SSL_SESSION, 13297c5b2634Sjsing PEM_STRING_SSL_SESSION, fp, (void **)x, cb, u); 133007781822Sjsing } 133171e04849Sbeck LSSL_ALIAS(PEM_read_SSL_SESSION); 133207781822Sjsing 1333d820b776Sjsing SSL_SESSION * 1334d820b776Sjsing PEM_read_bio_SSL_SESSION(BIO *bp, SSL_SESSION **x, pem_password_cb *cb, void *u) 1335d820b776Sjsing { 13367c5b2634Sjsing return PEM_ASN1_read_bio((d2i_of_void *)d2i_SSL_SESSION, 13377c5b2634Sjsing PEM_STRING_SSL_SESSION, bp, (void **)x, cb, u); 1338d820b776Sjsing } 133971e04849Sbeck LSSL_ALIAS(PEM_read_bio_SSL_SESSION); 1340d820b776Sjsing 134107781822Sjsing int 134207781822Sjsing PEM_write_bio_SSL_SESSION(BIO *bp, SSL_SESSION *x) 134307781822Sjsing { 13447c5b2634Sjsing return PEM_ASN1_write_bio((i2d_of_void *)i2d_SSL_SESSION, 13457c5b2634Sjsing PEM_STRING_SSL_SESSION, bp, x, NULL, NULL, 0, NULL, NULL); 134607781822Sjsing } 134771e04849Sbeck LSSL_ALIAS(PEM_write_bio_SSL_SESSION); 1348