174664626SKris Kennaway /* ssl/ssl_sess.c */ 274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 374664626SKris Kennaway * All rights reserved. 474664626SKris Kennaway * 574664626SKris Kennaway * This package is an SSL implementation written 674664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 774664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 874664626SKris Kennaway * 974664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1074664626SKris Kennaway * the following conditions are aheared to. The following conditions 1174664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1274664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1374664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1474664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1574664626SKris Kennaway * 1674664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1774664626SKris Kennaway * the code are not to be removed. 1874664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 1974664626SKris Kennaway * as the author of the parts of the library used. 2074664626SKris Kennaway * This can be in the form of a textual message at program startup or 2174664626SKris Kennaway * in documentation (online or textual) provided with the package. 2274664626SKris Kennaway * 2374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2474664626SKris Kennaway * modification, are permitted provided that the following conditions 2574664626SKris Kennaway * are met: 2674664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2774664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 2874664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3074664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3174664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3274664626SKris Kennaway * must display the following acknowledgement: 3374664626SKris Kennaway * "This product includes cryptographic software written by 3474664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3574664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3674664626SKris Kennaway * being used are not cryptographic related :-). 3774664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 3874664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 3974664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4074664626SKris Kennaway * 4174664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4274664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4374664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4474664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4574664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4674664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4774664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4874664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4974664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5074664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5174664626SKris Kennaway * SUCH DAMAGE. 5274664626SKris Kennaway * 5374664626SKris Kennaway * The licence and distribution terms for any publically available version or 5474664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5574664626SKris Kennaway * copied and put under another distribution licence 5674664626SKris Kennaway * [including the GNU Public Licence.] 5774664626SKris Kennaway */ 581f13597dSJung-uk Kim /* ==================================================================== 591f13597dSJung-uk Kim * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 601f13597dSJung-uk Kim * 611f13597dSJung-uk Kim * Redistribution and use in source and binary forms, with or without 621f13597dSJung-uk Kim * modification, are permitted provided that the following conditions 631f13597dSJung-uk Kim * are met: 641f13597dSJung-uk Kim * 651f13597dSJung-uk Kim * 1. Redistributions of source code must retain the above copyright 661f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer. 671f13597dSJung-uk Kim * 681f13597dSJung-uk Kim * 2. Redistributions in binary form must reproduce the above copyright 691f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer in 701f13597dSJung-uk Kim * the documentation and/or other materials provided with the 711f13597dSJung-uk Kim * distribution. 721f13597dSJung-uk Kim * 731f13597dSJung-uk Kim * 3. All advertising materials mentioning features or use of this 741f13597dSJung-uk Kim * software must display the following acknowledgment: 751f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 761f13597dSJung-uk Kim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 771f13597dSJung-uk Kim * 781f13597dSJung-uk Kim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 791f13597dSJung-uk Kim * endorse or promote products derived from this software without 801f13597dSJung-uk Kim * prior written permission. For written permission, please contact 811f13597dSJung-uk Kim * openssl-core@openssl.org. 821f13597dSJung-uk Kim * 831f13597dSJung-uk Kim * 5. Products derived from this software may not be called "OpenSSL" 841f13597dSJung-uk Kim * nor may "OpenSSL" appear in their names without prior written 851f13597dSJung-uk Kim * permission of the OpenSSL Project. 861f13597dSJung-uk Kim * 871f13597dSJung-uk Kim * 6. Redistributions of any form whatsoever must retain the following 881f13597dSJung-uk Kim * acknowledgment: 891f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 901f13597dSJung-uk Kim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 911f13597dSJung-uk Kim * 921f13597dSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 931f13597dSJung-uk Kim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 941f13597dSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 951f13597dSJung-uk Kim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 961f13597dSJung-uk Kim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 971f13597dSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 981f13597dSJung-uk Kim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 991f13597dSJung-uk Kim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1001f13597dSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1011f13597dSJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1021f13597dSJung-uk Kim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1031f13597dSJung-uk Kim * OF THE POSSIBILITY OF SUCH DAMAGE. 1041f13597dSJung-uk Kim * ==================================================================== 1051f13597dSJung-uk Kim * 1061f13597dSJung-uk Kim * This product includes cryptographic software written by Eric Young 1071f13597dSJung-uk Kim * (eay@cryptsoft.com). This product includes software written by Tim 1081f13597dSJung-uk Kim * Hudson (tjh@cryptsoft.com). 1091f13597dSJung-uk Kim * 1101f13597dSJung-uk Kim */ 1111f13597dSJung-uk Kim /* ==================================================================== 1121f13597dSJung-uk Kim * Copyright 2005 Nokia. All rights reserved. 1131f13597dSJung-uk Kim * 1141f13597dSJung-uk Kim * The portions of the attached software ("Contribution") is developed by 1151f13597dSJung-uk Kim * Nokia Corporation and is licensed pursuant to the OpenSSL open source 1161f13597dSJung-uk Kim * license. 1171f13597dSJung-uk Kim * 1181f13597dSJung-uk Kim * The Contribution, originally written by Mika Kousa and Pasi Eronen of 1191f13597dSJung-uk Kim * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 1201f13597dSJung-uk Kim * support (see RFC 4279) to OpenSSL. 1211f13597dSJung-uk Kim * 1221f13597dSJung-uk Kim * No patent licenses or other rights except those expressly stated in 1231f13597dSJung-uk Kim * the OpenSSL open source license shall be deemed granted or received 1241f13597dSJung-uk Kim * expressly, by implication, estoppel, or otherwise. 1251f13597dSJung-uk Kim * 1261f13597dSJung-uk Kim * No assurances are provided by Nokia that the Contribution does not 1271f13597dSJung-uk Kim * infringe the patent or other intellectual property rights of any third 1281f13597dSJung-uk Kim * party or that the license provides you with all the necessary rights 1291f13597dSJung-uk Kim * to make use of the Contribution. 1301f13597dSJung-uk Kim * 1311f13597dSJung-uk Kim * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 1321f13597dSJung-uk Kim * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 1331f13597dSJung-uk Kim * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 1341f13597dSJung-uk Kim * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 1351f13597dSJung-uk Kim * OTHERWISE. 1361f13597dSJung-uk Kim */ 13774664626SKris Kennaway 13874664626SKris Kennaway #include <stdio.h> 13974664626SKris Kennaway #include <openssl/lhash.h> 14074664626SKris Kennaway #include <openssl/rand.h> 141db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_ENGINE 142db522d3aSSimon L. B. Nielsen # include <openssl/engine.h> 143db522d3aSSimon L. B. Nielsen #endif 14474664626SKris Kennaway #include "ssl_locl.h" 14574664626SKris Kennaway 14674664626SKris Kennaway static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); 14774664626SKris Kennaway static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); 14874664626SKris Kennaway static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); 14974664626SKris Kennaway 1503b4e3dcbSSimon L. B. Nielsen SSL_SESSION *SSL_get_session(const SSL *ssl) 151f579bf8eSKris Kennaway /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ 15274664626SKris Kennaway { 15374664626SKris Kennaway return (ssl->session); 15474664626SKris Kennaway } 15574664626SKris Kennaway 156f579bf8eSKris Kennaway SSL_SESSION *SSL_get1_session(SSL *ssl) 157f579bf8eSKris Kennaway /* variant of SSL_get_session: caller really gets something */ 158f579bf8eSKris Kennaway { 159f579bf8eSKris Kennaway SSL_SESSION *sess; 1606f9291ceSJung-uk Kim /* 1616f9291ceSJung-uk Kim * Need to lock this all up rather than just use CRYPTO_add so that 1626f9291ceSJung-uk Kim * somebody doesn't free ssl->session between when we check it's non-null 1636f9291ceSJung-uk Kim * and when we up the reference count. 1646f9291ceSJung-uk Kim */ 16550ef0093SJacques Vidrine CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); 166f579bf8eSKris Kennaway sess = ssl->session; 167f579bf8eSKris Kennaway if (sess) 168f579bf8eSKris Kennaway sess->references++; 16950ef0093SJacques Vidrine CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); 170f579bf8eSKris Kennaway return (sess); 171f579bf8eSKris Kennaway } 172f579bf8eSKris Kennaway 1736f9291ceSJung-uk Kim int SSL_SESSION_get_ex_new_index(long argl, void *argp, 1746f9291ceSJung-uk Kim CRYPTO_EX_new *new_func, 1756f9291ceSJung-uk Kim CRYPTO_EX_dup *dup_func, 1766f9291ceSJung-uk Kim CRYPTO_EX_free *free_func) 17774664626SKris Kennaway { 1785c87c606SMark Murray return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp, 1795c87c606SMark Murray new_func, dup_func, free_func); 18074664626SKris Kennaway } 18174664626SKris Kennaway 18274664626SKris Kennaway int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) 18374664626SKris Kennaway { 18474664626SKris Kennaway return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); 18574664626SKris Kennaway } 18674664626SKris Kennaway 1873b4e3dcbSSimon L. B. Nielsen void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) 18874664626SKris Kennaway { 18974664626SKris Kennaway return (CRYPTO_get_ex_data(&s->ex_data, idx)); 19074664626SKris Kennaway } 19174664626SKris Kennaway 19274664626SKris Kennaway SSL_SESSION *SSL_SESSION_new(void) 19374664626SKris Kennaway { 19474664626SKris Kennaway SSL_SESSION *ss; 19574664626SKris Kennaway 196ddd58736SKris Kennaway ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION)); 1976f9291ceSJung-uk Kim if (ss == NULL) { 19874664626SKris Kennaway SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); 19974664626SKris Kennaway return (0); 20074664626SKris Kennaway } 20174664626SKris Kennaway memset(ss, 0, sizeof(SSL_SESSION)); 20274664626SKris Kennaway 203f579bf8eSKris Kennaway ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ 20474664626SKris Kennaway ss->references = 1; 20574664626SKris Kennaway ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ 2063b4e3dcbSSimon L. B. Nielsen ss->time = (unsigned long)time(NULL); 20774664626SKris Kennaway ss->prev = NULL; 20874664626SKris Kennaway ss->next = NULL; 20974664626SKris Kennaway ss->compress_meth = 0; 210db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 211db522d3aSSimon L. B. Nielsen ss->tlsext_hostname = NULL; 2121f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 2131f13597dSJung-uk Kim ss->tlsext_ecpointformatlist_length = 0; 2141f13597dSJung-uk Kim ss->tlsext_ecpointformatlist = NULL; 2151f13597dSJung-uk Kim ss->tlsext_ellipticcurvelist_length = 0; 2161f13597dSJung-uk Kim ss->tlsext_ellipticcurvelist = NULL; 2171f13597dSJung-uk Kim # endif 218db522d3aSSimon L. B. Nielsen #endif 2195c87c606SMark Murray CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); 2201f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 2211f13597dSJung-uk Kim ss->psk_identity_hint = NULL; 2221f13597dSJung-uk Kim ss->psk_identity = NULL; 2231f13597dSJung-uk Kim #endif 2241f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 2251f13597dSJung-uk Kim ss->srp_username = NULL; 2261f13597dSJung-uk Kim #endif 22774664626SKris Kennaway return (ss); 22874664626SKris Kennaway } 22974664626SKris Kennaway 230ed6b93beSJung-uk Kim /* 231ed6b93beSJung-uk Kim * Create a new SSL_SESSION and duplicate the contents of |src| into it. If 232ed6b93beSJung-uk Kim * ticket == 0 then no ticket information is duplicated, otherwise it is. 233ed6b93beSJung-uk Kim */ 234ed6b93beSJung-uk Kim SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) 235ed6b93beSJung-uk Kim { 236ed6b93beSJung-uk Kim SSL_SESSION *dest; 237ed6b93beSJung-uk Kim 238ed6b93beSJung-uk Kim dest = OPENSSL_malloc(sizeof(*src)); 239ed6b93beSJung-uk Kim if (dest == NULL) { 240ed6b93beSJung-uk Kim goto err; 241ed6b93beSJung-uk Kim } 242ed6b93beSJung-uk Kim memcpy(dest, src, sizeof(*dest)); 243ed6b93beSJung-uk Kim 244ed6b93beSJung-uk Kim /* 245ed6b93beSJung-uk Kim * Set the various pointers to NULL so that we can call SSL_SESSION_free in 246ed6b93beSJung-uk Kim * the case of an error whilst halfway through constructing dest 247ed6b93beSJung-uk Kim */ 248ed6b93beSJung-uk Kim #ifndef OPENSSL_NO_PSK 249ed6b93beSJung-uk Kim dest->psk_identity_hint = NULL; 250ed6b93beSJung-uk Kim dest->psk_identity = NULL; 251ed6b93beSJung-uk Kim #endif 252ed6b93beSJung-uk Kim dest->ciphers = NULL; 253ed6b93beSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 254ed6b93beSJung-uk Kim dest->tlsext_hostname = NULL; 255ed6b93beSJung-uk Kim # ifndef OPENSSL_NO_EC 256ed6b93beSJung-uk Kim dest->tlsext_ecpointformatlist = NULL; 257ed6b93beSJung-uk Kim dest->tlsext_ellipticcurvelist = NULL; 258ed6b93beSJung-uk Kim # endif 259ed6b93beSJung-uk Kim dest->tlsext_tick = NULL; 26080815a77SJung-uk Kim #endif 261ed6b93beSJung-uk Kim #ifndef OPENSSL_NO_SRP 262ed6b93beSJung-uk Kim dest->srp_username = NULL; 263ed6b93beSJung-uk Kim #endif 264ed6b93beSJung-uk Kim 265ed6b93beSJung-uk Kim /* We deliberately don't copy the prev and next pointers */ 266ed6b93beSJung-uk Kim dest->prev = NULL; 267ed6b93beSJung-uk Kim dest->next = NULL; 268ed6b93beSJung-uk Kim 269ed6b93beSJung-uk Kim dest->references = 1; 270ed6b93beSJung-uk Kim 271ed6b93beSJung-uk Kim if (src->sess_cert != NULL) 272ed6b93beSJung-uk Kim CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); 273ed6b93beSJung-uk Kim 274ed6b93beSJung-uk Kim if (src->peer != NULL) 275ed6b93beSJung-uk Kim CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); 276ed6b93beSJung-uk Kim 27747902a71SJung-uk Kim if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) 27847902a71SJung-uk Kim goto err; 27947902a71SJung-uk Kim 280ed6b93beSJung-uk Kim #ifndef OPENSSL_NO_PSK 281ed6b93beSJung-uk Kim if (src->psk_identity_hint) { 282ed6b93beSJung-uk Kim dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); 283ed6b93beSJung-uk Kim if (dest->psk_identity_hint == NULL) { 284ed6b93beSJung-uk Kim goto err; 285ed6b93beSJung-uk Kim } 286ed6b93beSJung-uk Kim } 287ed6b93beSJung-uk Kim if (src->psk_identity) { 288ed6b93beSJung-uk Kim dest->psk_identity = BUF_strdup(src->psk_identity); 289ed6b93beSJung-uk Kim if (dest->psk_identity == NULL) { 290ed6b93beSJung-uk Kim goto err; 291ed6b93beSJung-uk Kim } 292ed6b93beSJung-uk Kim } 293ed6b93beSJung-uk Kim #endif 294ed6b93beSJung-uk Kim 295ed6b93beSJung-uk Kim if(src->ciphers != NULL) { 296ed6b93beSJung-uk Kim dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); 297ed6b93beSJung-uk Kim if (dest->ciphers == NULL) 298ed6b93beSJung-uk Kim goto err; 299ed6b93beSJung-uk Kim } 300ed6b93beSJung-uk Kim 301ed6b93beSJung-uk Kim if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, 302ed6b93beSJung-uk Kim &dest->ex_data, &src->ex_data)) { 303ed6b93beSJung-uk Kim goto err; 304ed6b93beSJung-uk Kim } 305ed6b93beSJung-uk Kim 306ed6b93beSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 307ed6b93beSJung-uk Kim if (src->tlsext_hostname) { 308ed6b93beSJung-uk Kim dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); 309ed6b93beSJung-uk Kim if (dest->tlsext_hostname == NULL) { 310ed6b93beSJung-uk Kim goto err; 311ed6b93beSJung-uk Kim } 312ed6b93beSJung-uk Kim } 313ed6b93beSJung-uk Kim # ifndef OPENSSL_NO_EC 314ed6b93beSJung-uk Kim if (src->tlsext_ecpointformatlist) { 315ed6b93beSJung-uk Kim dest->tlsext_ecpointformatlist = 316ed6b93beSJung-uk Kim BUF_memdup(src->tlsext_ecpointformatlist, 317ed6b93beSJung-uk Kim src->tlsext_ecpointformatlist_length); 318ed6b93beSJung-uk Kim if (dest->tlsext_ecpointformatlist == NULL) 319ed6b93beSJung-uk Kim goto err; 320ed6b93beSJung-uk Kim } 321ed6b93beSJung-uk Kim if (src->tlsext_ellipticcurvelist) { 322ed6b93beSJung-uk Kim dest->tlsext_ellipticcurvelist = 323ed6b93beSJung-uk Kim BUF_memdup(src->tlsext_ellipticcurvelist, 324ed6b93beSJung-uk Kim src->tlsext_ellipticcurvelist_length); 325ed6b93beSJung-uk Kim if (dest->tlsext_ellipticcurvelist == NULL) 326ed6b93beSJung-uk Kim goto err; 327ed6b93beSJung-uk Kim } 328ed6b93beSJung-uk Kim # endif 329ed6b93beSJung-uk Kim 33047902a71SJung-uk Kim if (ticket != 0 && src->tlsext_tick != NULL) { 331ed6b93beSJung-uk Kim dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); 332ed6b93beSJung-uk Kim if(dest->tlsext_tick == NULL) 333ed6b93beSJung-uk Kim goto err; 334ed6b93beSJung-uk Kim } else { 335ed6b93beSJung-uk Kim dest->tlsext_tick_lifetime_hint = 0; 336ed6b93beSJung-uk Kim dest->tlsext_ticklen = 0; 337ed6b93beSJung-uk Kim } 33880815a77SJung-uk Kim #endif 339ed6b93beSJung-uk Kim 340ed6b93beSJung-uk Kim #ifndef OPENSSL_NO_SRP 341ed6b93beSJung-uk Kim if (src->srp_username) { 342ed6b93beSJung-uk Kim dest->srp_username = BUF_strdup(src->srp_username); 343ed6b93beSJung-uk Kim if (dest->srp_username == NULL) { 344ed6b93beSJung-uk Kim goto err; 345ed6b93beSJung-uk Kim } 346ed6b93beSJung-uk Kim } 347ed6b93beSJung-uk Kim #endif 348ed6b93beSJung-uk Kim 349ed6b93beSJung-uk Kim return dest; 350ed6b93beSJung-uk Kim err: 351ed6b93beSJung-uk Kim SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); 352ed6b93beSJung-uk Kim SSL_SESSION_free(dest); 353ed6b93beSJung-uk Kim return NULL; 354ed6b93beSJung-uk Kim } 355ed6b93beSJung-uk Kim 3566f9291ceSJung-uk Kim const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, 3576f9291ceSJung-uk Kim unsigned int *len) 3583b4e3dcbSSimon L. B. Nielsen { 3593b4e3dcbSSimon L. B. Nielsen if (len) 3603b4e3dcbSSimon L. B. Nielsen *len = s->session_id_length; 3613b4e3dcbSSimon L. B. Nielsen return s->session_id; 3623b4e3dcbSSimon L. B. Nielsen } 3633b4e3dcbSSimon L. B. Nielsen 3641f13597dSJung-uk Kim unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) 3651f13597dSJung-uk Kim { 3661f13597dSJung-uk Kim return s->compress_meth; 3671f13597dSJung-uk Kim } 3681f13597dSJung-uk Kim 3696f9291ceSJung-uk Kim /* 3706f9291ceSJung-uk Kim * Even with SSLv2, we have 16 bytes (128 bits) of session ID space. 3716f9291ceSJung-uk Kim * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random 3726f9291ceSJung-uk Kim * gunk repeatedly until we have no conflict is going to complete in one 3736f9291ceSJung-uk Kim * iteration pretty much "most" of the time (btw: understatement). So, if it 3746f9291ceSJung-uk Kim * takes us 10 iterations and we still can't avoid a conflict - well that's a 3756f9291ceSJung-uk Kim * reasonable point to call it quits. Either the RAND code is broken or 3766f9291ceSJung-uk Kim * someone is trying to open roughly very close to 2^128 (or 2^256) SSL 3776f9291ceSJung-uk Kim * sessions to our server. How you might store that many sessions is perhaps 3786f9291ceSJung-uk Kim * a more interesting question ... 3796f9291ceSJung-uk Kim */ 3805c87c606SMark Murray 3815c87c606SMark Murray #define MAX_SESS_ID_ATTEMPTS 10 3825c87c606SMark Murray static int def_generate_session_id(const SSL *ssl, unsigned char *id, 3835c87c606SMark Murray unsigned int *id_len) 3845c87c606SMark Murray { 3855c87c606SMark Murray unsigned int retry = 0; 3865c87c606SMark Murray do 387aeb5019cSJung-uk Kim if (RAND_bytes(id, *id_len) <= 0) 3886be8ae07SJacques Vidrine return 0; 3895c87c606SMark Murray while (SSL_has_matching_session_id(ssl, id, *id_len) && 3905c87c606SMark Murray (++retry < MAX_SESS_ID_ATTEMPTS)) ; 3915c87c606SMark Murray if (retry < MAX_SESS_ID_ATTEMPTS) 3925c87c606SMark Murray return 1; 3935c87c606SMark Murray /* else - woops a session_id match */ 3946f9291ceSJung-uk Kim /* 3956f9291ceSJung-uk Kim * XXX We should also check the external cache -- but the probability of 3966f9291ceSJung-uk Kim * a collision is negligible, and we could not prevent the concurrent 3976f9291ceSJung-uk Kim * creation of sessions with identical IDs since we currently don't have 3986f9291ceSJung-uk Kim * means to atomically check whether a session ID already exists and make 3996f9291ceSJung-uk Kim * a reservation for it if it does not (this problem applies to the 4006f9291ceSJung-uk Kim * internal cache as well). 4015c87c606SMark Murray */ 4025c87c606SMark Murray return 0; 4035c87c606SMark Murray } 4045c87c606SMark Murray 40574664626SKris Kennaway int ssl_get_new_session(SSL *s, int session) 40674664626SKris Kennaway { 40774664626SKris Kennaway /* This gets used by clients and servers. */ 40874664626SKris Kennaway 4095c87c606SMark Murray unsigned int tmp; 41074664626SKris Kennaway SSL_SESSION *ss = NULL; 4115c87c606SMark Murray GEN_SESSION_CB cb = def_generate_session_id; 41274664626SKris Kennaway 4136f9291ceSJung-uk Kim if ((ss = SSL_SESSION_new()) == NULL) 4146f9291ceSJung-uk Kim return (0); 41574664626SKris Kennaway 41674664626SKris Kennaway /* If the context has a default timeout, use it */ 4171f13597dSJung-uk Kim if (s->session_ctx->session_timeout == 0) 41874664626SKris Kennaway ss->timeout = SSL_get_default_timeout(s); 41974664626SKris Kennaway else 4201f13597dSJung-uk Kim ss->timeout = s->session_ctx->session_timeout; 42174664626SKris Kennaway 4226f9291ceSJung-uk Kim if (s->session != NULL) { 42374664626SKris Kennaway SSL_SESSION_free(s->session); 42474664626SKris Kennaway s->session = NULL; 42574664626SKris Kennaway } 42674664626SKris Kennaway 4276f9291ceSJung-uk Kim if (session) { 4286f9291ceSJung-uk Kim if (s->version == SSL2_VERSION) { 42974664626SKris Kennaway ss->ssl_version = SSL2_VERSION; 43074664626SKris Kennaway ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; 4316f9291ceSJung-uk Kim } else if (s->version == SSL3_VERSION) { 43274664626SKris Kennaway ss->ssl_version = SSL3_VERSION; 43374664626SKris Kennaway ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4346f9291ceSJung-uk Kim } else if (s->version == TLS1_VERSION) { 43574664626SKris Kennaway ss->ssl_version = TLS1_VERSION; 43674664626SKris Kennaway ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4376f9291ceSJung-uk Kim } else if (s->version == TLS1_1_VERSION) { 4381f13597dSJung-uk Kim ss->ssl_version = TLS1_1_VERSION; 4391f13597dSJung-uk Kim ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4406f9291ceSJung-uk Kim } else if (s->version == TLS1_2_VERSION) { 4411f13597dSJung-uk Kim ss->ssl_version = TLS1_2_VERSION; 4421f13597dSJung-uk Kim ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4436f9291ceSJung-uk Kim } else if (s->version == DTLS1_BAD_VER) { 4446a599222SSimon L. B. Nielsen ss->ssl_version = DTLS1_BAD_VER; 4456a599222SSimon L. B. Nielsen ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4466f9291ceSJung-uk Kim } else if (s->version == DTLS1_VERSION) { 4473b4e3dcbSSimon L. B. Nielsen ss->ssl_version = DTLS1_VERSION; 4483b4e3dcbSSimon L. B. Nielsen ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4497bded2dbSJung-uk Kim } else if (s->version == DTLS1_2_VERSION) { 4507bded2dbSJung-uk Kim ss->ssl_version = DTLS1_2_VERSION; 4517bded2dbSJung-uk Kim ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 4526f9291ceSJung-uk Kim } else { 45374664626SKris Kennaway SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); 45474664626SKris Kennaway SSL_SESSION_free(ss); 45574664626SKris Kennaway return (0); 45674664626SKris Kennaway } 457db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 4586f9291ceSJung-uk Kim /*- 459751d2991SJung-uk Kim * If RFC5077 ticket, use empty session ID (as server). 460751d2991SJung-uk Kim * Note that: 461751d2991SJung-uk Kim * (a) ssl_get_prev_session() does lookahead into the 462751d2991SJung-uk Kim * ClientHello extensions to find the session ticket. 463751d2991SJung-uk Kim * When ssl_get_prev_session() fails, s3_srvr.c calls 464751d2991SJung-uk Kim * ssl_get_new_session() in ssl3_get_client_hello(). 465751d2991SJung-uk Kim * At that point, it has not yet parsed the extensions, 466751d2991SJung-uk Kim * however, because of the lookahead, it already knows 467751d2991SJung-uk Kim * whether a ticket is expected or not. 468751d2991SJung-uk Kim * 469751d2991SJung-uk Kim * (b) s3_clnt.c calls ssl_get_new_session() before parsing 470751d2991SJung-uk Kim * ServerHello extensions, and before recording the session 471751d2991SJung-uk Kim * ID received from the server, so this block is a noop. 472751d2991SJung-uk Kim */ 4736f9291ceSJung-uk Kim if (s->tlsext_ticket_expected) { 474db522d3aSSimon L. B. Nielsen ss->session_id_length = 0; 475db522d3aSSimon L. B. Nielsen goto sess_id_done; 476db522d3aSSimon L. B. Nielsen } 477db522d3aSSimon L. B. Nielsen #endif 4785c87c606SMark Murray /* Choose which callback will set the session ID */ 47974664626SKris Kennaway CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 4805c87c606SMark Murray if (s->generate_session_id) 4815c87c606SMark Murray cb = s->generate_session_id; 4821f13597dSJung-uk Kim else if (s->session_ctx->generate_session_id) 4831f13597dSJung-uk Kim cb = s->session_ctx->generate_session_id; 48474664626SKris Kennaway CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 4855c87c606SMark Murray /* Choose a session ID */ 4865c87c606SMark Murray tmp = ss->session_id_length; 4876f9291ceSJung-uk Kim if (!cb(s, ss->session_id, &tmp)) { 4885c87c606SMark Murray /* The callback failed */ 4895c87c606SMark Murray SSLerr(SSL_F_SSL_GET_NEW_SESSION, 4905c87c606SMark Murray SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); 4915c87c606SMark Murray SSL_SESSION_free(ss); 4925c87c606SMark Murray return (0); 4935c87c606SMark Murray } 4946f9291ceSJung-uk Kim /* 4956f9291ceSJung-uk Kim * Don't allow the callback to set the session length to zero. nor 4966f9291ceSJung-uk Kim * set it higher than it was. 4976f9291ceSJung-uk Kim */ 4986f9291ceSJung-uk Kim if (!tmp || (tmp > ss->session_id_length)) { 4995c87c606SMark Murray /* The callback set an illegal length */ 5005c87c606SMark Murray SSLerr(SSL_F_SSL_GET_NEW_SESSION, 5015c87c606SMark Murray SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); 5025c87c606SMark Murray SSL_SESSION_free(ss); 5035c87c606SMark Murray return (0); 5045c87c606SMark Murray } 5055c87c606SMark Murray /* If the session length was shrunk and we're SSLv2, pad it */ 5065c87c606SMark Murray if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION)) 5075c87c606SMark Murray memset(ss->session_id + tmp, 0, ss->session_id_length - tmp); 5085c87c606SMark Murray else 5095c87c606SMark Murray ss->session_id_length = tmp; 5105c87c606SMark Murray /* Finally, check for a conflict */ 5115c87c606SMark Murray if (SSL_has_matching_session_id(s, ss->session_id, 5126f9291ceSJung-uk Kim ss->session_id_length)) { 5136f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); 5145c87c606SMark Murray SSL_SESSION_free(ss); 5155c87c606SMark Murray return (0); 51674664626SKris Kennaway } 517db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 518db522d3aSSimon L. B. Nielsen sess_id_done: 519db522d3aSSimon L. B. Nielsen if (s->tlsext_hostname) { 520db522d3aSSimon L. B. Nielsen ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); 521db522d3aSSimon L. B. Nielsen if (ss->tlsext_hostname == NULL) { 522db522d3aSSimon L. B. Nielsen SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); 523db522d3aSSimon L. B. Nielsen SSL_SESSION_free(ss); 524db522d3aSSimon L. B. Nielsen return 0; 525db522d3aSSimon L. B. Nielsen } 526db522d3aSSimon L. B. Nielsen } 527db522d3aSSimon L. B. Nielsen #endif 5286f9291ceSJung-uk Kim } else { 52974664626SKris Kennaway ss->session_id_length = 0; 53074664626SKris Kennaway } 53174664626SKris Kennaway 532*dee36b4fSJung-uk Kim if (s->sid_ctx_length > sizeof(ss->sid_ctx)) { 5335c87c606SMark Murray SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); 53448454956SJacques Vidrine SSL_SESSION_free(ss); 53548454956SJacques Vidrine return 0; 53648454956SJacques Vidrine } 53774664626SKris Kennaway memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); 53874664626SKris Kennaway ss->sid_ctx_length = s->sid_ctx_length; 53974664626SKris Kennaway s->session = ss; 54074664626SKris Kennaway ss->ssl_version = s->version; 541f579bf8eSKris Kennaway ss->verify_result = X509_V_OK; 54274664626SKris Kennaway 54374664626SKris Kennaway return (1); 54474664626SKris Kennaway } 54574664626SKris Kennaway 5466f9291ceSJung-uk Kim /*- 5476f9291ceSJung-uk Kim * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this 5481f13597dSJung-uk Kim * connection. It is only called by servers. 5491f13597dSJung-uk Kim * 5501f13597dSJung-uk Kim * session_id: points at the session ID in the ClientHello. This code will 5511f13597dSJung-uk Kim * read past the end of this in order to parse out the session ticket 5521f13597dSJung-uk Kim * extension, if any. 5531f13597dSJung-uk Kim * len: the length of the session ID. 5541f13597dSJung-uk Kim * limit: a pointer to the first byte after the ClientHello. 5551f13597dSJung-uk Kim * 5561f13597dSJung-uk Kim * Returns: 5571f13597dSJung-uk Kim * -1: error 5581f13597dSJung-uk Kim * 0: a session may have been found. 5591f13597dSJung-uk Kim * 5601f13597dSJung-uk Kim * Side effects: 5611f13597dSJung-uk Kim * - If a session is found then s->session is pointed at it (after freeing an 5621f13597dSJung-uk Kim * existing session if need be) and s->verify_result is set from the session. 5631f13597dSJung-uk Kim * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1 5641f13597dSJung-uk Kim * if the server should issue a new session ticket (to 0 otherwise). 5651f13597dSJung-uk Kim */ 566db522d3aSSimon L. B. Nielsen int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, 567db522d3aSSimon L. B. Nielsen const unsigned char *limit) 56874664626SKris Kennaway { 56974664626SKris Kennaway /* This is used only by servers. */ 57074664626SKris Kennaway 571db522d3aSSimon L. B. Nielsen SSL_SESSION *ret = NULL; 57274664626SKris Kennaway int fatal = 0; 5731f13597dSJung-uk Kim int try_session_cache = 1; 574db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 575db522d3aSSimon L. B. Nielsen int r; 576db522d3aSSimon L. B. Nielsen #endif 57774664626SKris Kennaway 578aeb5019cSJung-uk Kim if (limit - session_id < len) { 579ed6b93beSJung-uk Kim fatal = 1; 580ed6b93beSJung-uk Kim goto err; 581ed6b93beSJung-uk Kim } 582ed6b93beSJung-uk Kim 5831f13597dSJung-uk Kim if (len == 0) 5841f13597dSJung-uk Kim try_session_cache = 0; 5851f13597dSJung-uk Kim 586db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 5876f9291ceSJung-uk Kim /* sets s->tlsext_ticket_expected */ 5886f9291ceSJung-uk Kim r = tls1_process_ticket(s, session_id, len, limit, &ret); 5896f9291ceSJung-uk Kim switch (r) { 5901f13597dSJung-uk Kim case -1: /* Error during processing */ 591db522d3aSSimon L. B. Nielsen fatal = 1; 592db522d3aSSimon L. B. Nielsen goto err; 5931f13597dSJung-uk Kim case 0: /* No ticket found */ 5941f13597dSJung-uk Kim case 1: /* Zero length ticket found */ 5951f13597dSJung-uk Kim break; /* Ok to carry on processing session id. */ 5961f13597dSJung-uk Kim case 2: /* Ticket found but not decrypted. */ 5971f13597dSJung-uk Kim case 3: /* Ticket decrypted, *ret has been set. */ 5981f13597dSJung-uk Kim try_session_cache = 0; 5991f13597dSJung-uk Kim break; 6001f13597dSJung-uk Kim default: 6011f13597dSJung-uk Kim abort(); 602db522d3aSSimon L. B. Nielsen } 603db522d3aSSimon L. B. Nielsen #endif 6041f13597dSJung-uk Kim 6051f13597dSJung-uk Kim if (try_session_cache && 6061f13597dSJung-uk Kim ret == NULL && 6076f9291ceSJung-uk Kim !(s->session_ctx->session_cache_mode & 6086f9291ceSJung-uk Kim SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { 609db522d3aSSimon L. B. Nielsen SSL_SESSION data; 610db522d3aSSimon L. B. Nielsen data.ssl_version = s->version; 611db522d3aSSimon L. B. Nielsen data.session_id_length = len; 612db522d3aSSimon L. B. Nielsen if (len == 0) 613db522d3aSSimon L. B. Nielsen return 0; 614db522d3aSSimon L. B. Nielsen memcpy(data.session_id, session_id, len); 61574664626SKris Kennaway CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 6161f13597dSJung-uk Kim ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); 6176f9291ceSJung-uk Kim if (ret != NULL) { 61874664626SKris Kennaway /* don't allow other threads to steal it: */ 61974664626SKris Kennaway CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); 6201f13597dSJung-uk Kim } 62174664626SKris Kennaway CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 6221f13597dSJung-uk Kim if (ret == NULL) 6231f13597dSJung-uk Kim s->session_ctx->stats.sess_miss++; 62474664626SKris Kennaway } 62574664626SKris Kennaway 6261f13597dSJung-uk Kim if (try_session_cache && 6276f9291ceSJung-uk Kim ret == NULL && s->session_ctx->get_session_cb != NULL) { 62874664626SKris Kennaway int copy = 1; 62974664626SKris Kennaway 6306f9291ceSJung-uk Kim if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) { 6311f13597dSJung-uk Kim s->session_ctx->stats.sess_cb_hit++; 63274664626SKris Kennaway 6336f9291ceSJung-uk Kim /* 6346f9291ceSJung-uk Kim * Increment reference count now if the session callback asks us 6356f9291ceSJung-uk Kim * to do so (note that if the session structures returned by the 6366f9291ceSJung-uk Kim * callback are shared between threads, it must handle the 6376f9291ceSJung-uk Kim * reference count itself [i.e. copy == 0], or things won't be 6386f9291ceSJung-uk Kim * thread-safe). 6396f9291ceSJung-uk Kim */ 64074664626SKris Kennaway if (copy) 64174664626SKris Kennaway CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); 64274664626SKris Kennaway 6436f9291ceSJung-uk Kim /* 6446f9291ceSJung-uk Kim * Add the externally cached session to the internal cache as 6456f9291ceSJung-uk Kim * well if and only if we are supposed to. 6466f9291ceSJung-uk Kim */ 6476f9291ceSJung-uk Kim if (! 6486f9291ceSJung-uk Kim (s->session_ctx->session_cache_mode & 6496f9291ceSJung-uk Kim SSL_SESS_CACHE_NO_INTERNAL_STORE)) 6506f9291ceSJung-uk Kim /* 6516f9291ceSJung-uk Kim * The following should not return 1, otherwise, things are 6526f9291ceSJung-uk Kim * very strange 6536f9291ceSJung-uk Kim */ 6541f13597dSJung-uk Kim SSL_CTX_add_session(s->session_ctx, ret); 65574664626SKris Kennaway } 65674664626SKris Kennaway } 65774664626SKris Kennaway 6581f13597dSJung-uk Kim if (ret == NULL) 6591f13597dSJung-uk Kim goto err; 6601f13597dSJung-uk Kim 6611f13597dSJung-uk Kim /* Now ret is non-NULL and we own one of its reference counts. */ 66274664626SKris Kennaway 663db522d3aSSimon L. B. Nielsen if (ret->sid_ctx_length != s->sid_ctx_length 6646f9291ceSJung-uk Kim || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { 6656f9291ceSJung-uk Kim /* 6666f9291ceSJung-uk Kim * We have the session requested by the client, but we don't want to 6676f9291ceSJung-uk Kim * use it in this context. 6686f9291ceSJung-uk Kim */ 66974664626SKris Kennaway goto err; /* treat like cache miss */ 67074664626SKris Kennaway } 671db522d3aSSimon L. B. Nielsen 6726f9291ceSJung-uk Kim if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { 6736f9291ceSJung-uk Kim /* 6746f9291ceSJung-uk Kim * We can't be sure if this session is being used out of context, 6756f9291ceSJung-uk Kim * which is especially important for SSL_VERIFY_PEER. The application 6766f9291ceSJung-uk Kim * should have used SSL[_CTX]_set_session_id_context. For this error 6776f9291ceSJung-uk Kim * case, we generate an error instead of treating the event like a 6786f9291ceSJung-uk Kim * cache miss (otherwise it would be easy for applications to 6796f9291ceSJung-uk Kim * effectively disable the session cache by accident without anyone 6806f9291ceSJung-uk Kim * noticing). 681db522d3aSSimon L. B. Nielsen */ 682db522d3aSSimon L. B. Nielsen 6836f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_GET_PREV_SESSION, 6846f9291ceSJung-uk Kim SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); 685db522d3aSSimon L. B. Nielsen fatal = 1; 686db522d3aSSimon L. B. Nielsen goto err; 68774664626SKris Kennaway } 68874664626SKris Kennaway 6896f9291ceSJung-uk Kim if (ret->cipher == NULL) { 69074664626SKris Kennaway unsigned char buf[5], *p; 69174664626SKris Kennaway unsigned long l; 69274664626SKris Kennaway 69374664626SKris Kennaway p = buf; 69474664626SKris Kennaway l = ret->cipher_id; 69574664626SKris Kennaway l2n(l, p); 6966a599222SSimon L. B. Nielsen if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR) 69774664626SKris Kennaway ret->cipher = ssl_get_cipher_by_char(s, &(buf[2])); 69874664626SKris Kennaway else 69974664626SKris Kennaway ret->cipher = ssl_get_cipher_by_char(s, &(buf[1])); 70074664626SKris Kennaway if (ret->cipher == NULL) 70174664626SKris Kennaway goto err; 70274664626SKris Kennaway } 70374664626SKris Kennaway 7046f9291ceSJung-uk Kim if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ 7051f13597dSJung-uk Kim s->session_ctx->stats.sess_timeout++; 7066f9291ceSJung-uk Kim if (try_session_cache) { 7071f13597dSJung-uk Kim /* session was from the cache, so remove it */ 7081f13597dSJung-uk Kim SSL_CTX_remove_session(s->session_ctx, ret); 7091f13597dSJung-uk Kim } 71074664626SKris Kennaway goto err; 71174664626SKris Kennaway } 71274664626SKris Kennaway 7131f13597dSJung-uk Kim s->session_ctx->stats.sess_hit++; 71474664626SKris Kennaway 71574664626SKris Kennaway if (s->session != NULL) 71674664626SKris Kennaway SSL_SESSION_free(s->session); 71774664626SKris Kennaway s->session = ret; 718f579bf8eSKris Kennaway s->verify_result = s->session->verify_result; 7191f13597dSJung-uk Kim return 1; 72074664626SKris Kennaway 72174664626SKris Kennaway err: 7226f9291ceSJung-uk Kim if (ret != NULL) { 72374664626SKris Kennaway SSL_SESSION_free(ret); 7241f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 7256f9291ceSJung-uk Kim if (!try_session_cache) { 7266f9291ceSJung-uk Kim /* 7276f9291ceSJung-uk Kim * The session was from a ticket, so we should issue a ticket for 7286f9291ceSJung-uk Kim * the new session 7296f9291ceSJung-uk Kim */ 7301f13597dSJung-uk Kim s->tlsext_ticket_expected = 1; 7311f13597dSJung-uk Kim } 7321f13597dSJung-uk Kim #endif 7331f13597dSJung-uk Kim } 73474664626SKris Kennaway if (fatal) 73574664626SKris Kennaway return -1; 73674664626SKris Kennaway else 73774664626SKris Kennaway return 0; 73874664626SKris Kennaway } 73974664626SKris Kennaway 74074664626SKris Kennaway int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) 74174664626SKris Kennaway { 74274664626SKris Kennaway int ret = 0; 74374664626SKris Kennaway SSL_SESSION *s; 74474664626SKris Kennaway 7456f9291ceSJung-uk Kim /* 7466f9291ceSJung-uk Kim * add just 1 reference count for the SSL_CTX's session cache even though 7476f9291ceSJung-uk Kim * it has two ways of access: each session is in a doubly linked list and 7486f9291ceSJung-uk Kim * an lhash 7496f9291ceSJung-uk Kim */ 75074664626SKris Kennaway CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); 7516f9291ceSJung-uk Kim /* 7526f9291ceSJung-uk Kim * if session c is in already in cache, we take back the increment later 7536f9291ceSJung-uk Kim */ 75474664626SKris Kennaway 75574664626SKris Kennaway CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 7561f13597dSJung-uk Kim s = lh_SSL_SESSION_insert(ctx->sessions, c); 75774664626SKris Kennaway 7586f9291ceSJung-uk Kim /* 7596f9291ceSJung-uk Kim * s != NULL iff we already had a session with the given PID. In this 7606f9291ceSJung-uk Kim * case, s == c should hold (then we did not really modify 7616f9291ceSJung-uk Kim * ctx->sessions), or we're in trouble. 7626f9291ceSJung-uk Kim */ 7636f9291ceSJung-uk Kim if (s != NULL && s != c) { 764f579bf8eSKris Kennaway /* We *are* in trouble ... */ 765f579bf8eSKris Kennaway SSL_SESSION_list_remove(ctx, s); 766f579bf8eSKris Kennaway SSL_SESSION_free(s); 7676f9291ceSJung-uk Kim /* 7686f9291ceSJung-uk Kim * ... so pretend the other session did not exist in cache (we cannot 7696f9291ceSJung-uk Kim * handle two SSL_SESSION structures with identical session ID in the 7706f9291ceSJung-uk Kim * same cache, which could happen e.g. when two threads concurrently 7716f9291ceSJung-uk Kim * obtain the same session from an external cache) 7726f9291ceSJung-uk Kim */ 773f579bf8eSKris Kennaway s = NULL; 7746cf8931aSJung-uk Kim } else if (s == NULL && 7756cf8931aSJung-uk Kim lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) { 7766cf8931aSJung-uk Kim /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */ 7776cf8931aSJung-uk Kim 7786cf8931aSJung-uk Kim /* 7796cf8931aSJung-uk Kim * ... so take back the extra reference and also don't add 7806cf8931aSJung-uk Kim * the session to the SSL_SESSION_list at this time 7816cf8931aSJung-uk Kim */ 7826cf8931aSJung-uk Kim s = c; 783f579bf8eSKris Kennaway } 784f579bf8eSKris Kennaway 785f579bf8eSKris Kennaway /* Put at the head of the queue unless it is already in the cache */ 78674664626SKris Kennaway if (s == NULL) 78774664626SKris Kennaway SSL_SESSION_list_add(ctx, c); 78874664626SKris Kennaway 7896f9291ceSJung-uk Kim if (s != NULL) { 7906f9291ceSJung-uk Kim /* 7916f9291ceSJung-uk Kim * existing cache entry -- decrement previously incremented reference 7926f9291ceSJung-uk Kim * count because it already takes into account the cache 7936f9291ceSJung-uk Kim */ 794f579bf8eSKris Kennaway 795f579bf8eSKris Kennaway SSL_SESSION_free(s); /* s == c */ 79674664626SKris Kennaway ret = 0; 7976f9291ceSJung-uk Kim } else { 7986f9291ceSJung-uk Kim /* 7996f9291ceSJung-uk Kim * new cache entry -- remove old ones if cache has become too large 8006f9291ceSJung-uk Kim */ 801f579bf8eSKris Kennaway 80274664626SKris Kennaway ret = 1; 80374664626SKris Kennaway 8046f9291ceSJung-uk Kim if (SSL_CTX_sess_get_cache_size(ctx) > 0) { 80574664626SKris Kennaway while (SSL_CTX_sess_number(ctx) > 8066f9291ceSJung-uk Kim SSL_CTX_sess_get_cache_size(ctx)) { 8076f9291ceSJung-uk Kim if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) 80874664626SKris Kennaway break; 80974664626SKris Kennaway else 81074664626SKris Kennaway ctx->stats.sess_cache_full++; 81174664626SKris Kennaway } 81274664626SKris Kennaway } 81374664626SKris Kennaway } 81474664626SKris Kennaway CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 81574664626SKris Kennaway return (ret); 81674664626SKris Kennaway } 81774664626SKris Kennaway 81874664626SKris Kennaway int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) 81974664626SKris Kennaway { 82074664626SKris Kennaway return remove_session_lock(ctx, c, 1); 82174664626SKris Kennaway } 82274664626SKris Kennaway 82374664626SKris Kennaway static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) 82474664626SKris Kennaway { 82574664626SKris Kennaway SSL_SESSION *r; 82674664626SKris Kennaway int ret = 0; 82774664626SKris Kennaway 8286f9291ceSJung-uk Kim if ((c != NULL) && (c->session_id_length != 0)) { 8296f9291ceSJung-uk Kim if (lck) 8306f9291ceSJung-uk Kim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 8316f9291ceSJung-uk Kim if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { 83274664626SKris Kennaway ret = 1; 8331f13597dSJung-uk Kim r = lh_SSL_SESSION_delete(ctx->sessions, c); 83474664626SKris Kennaway SSL_SESSION_list_remove(ctx, c); 83574664626SKris Kennaway } 83674664626SKris Kennaway 8376f9291ceSJung-uk Kim if (lck) 8386f9291ceSJung-uk Kim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 83974664626SKris Kennaway 8406f9291ceSJung-uk Kim if (ret) { 84174664626SKris Kennaway r->not_resumable = 1; 84274664626SKris Kennaway if (ctx->remove_session_cb != NULL) 84374664626SKris Kennaway ctx->remove_session_cb(ctx, r); 84474664626SKris Kennaway SSL_SESSION_free(r); 84574664626SKris Kennaway } 8466f9291ceSJung-uk Kim } else 84774664626SKris Kennaway ret = 0; 84874664626SKris Kennaway return (ret); 84974664626SKris Kennaway } 85074664626SKris Kennaway 85174664626SKris Kennaway void SSL_SESSION_free(SSL_SESSION *ss) 85274664626SKris Kennaway { 85374664626SKris Kennaway int i; 85474664626SKris Kennaway 85574664626SKris Kennaway if (ss == NULL) 85674664626SKris Kennaway return; 85774664626SKris Kennaway 85874664626SKris Kennaway i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); 85974664626SKris Kennaway #ifdef REF_PRINT 86074664626SKris Kennaway REF_PRINT("SSL_SESSION", ss); 86174664626SKris Kennaway #endif 8626f9291ceSJung-uk Kim if (i > 0) 8636f9291ceSJung-uk Kim return; 86474664626SKris Kennaway #ifdef REF_CHECK 8656f9291ceSJung-uk Kim if (i < 0) { 86674664626SKris Kennaway fprintf(stderr, "SSL_SESSION_free, bad reference count\n"); 86774664626SKris Kennaway abort(); /* ok */ 86874664626SKris Kennaway } 86974664626SKris Kennaway #endif 87074664626SKris Kennaway 8715c87c606SMark Murray CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); 87274664626SKris Kennaway 873*dee36b4fSJung-uk Kim OPENSSL_cleanse(ss->key_arg, sizeof(ss->key_arg)); 874*dee36b4fSJung-uk Kim OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key)); 875*dee36b4fSJung-uk Kim OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id)); 8766f9291ceSJung-uk Kim if (ss->sess_cert != NULL) 8776f9291ceSJung-uk Kim ssl_sess_cert_free(ss->sess_cert); 8786f9291ceSJung-uk Kim if (ss->peer != NULL) 8796f9291ceSJung-uk Kim X509_free(ss->peer); 8806f9291ceSJung-uk Kim if (ss->ciphers != NULL) 8816f9291ceSJung-uk Kim sk_SSL_CIPHER_free(ss->ciphers); 882db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 8836f9291ceSJung-uk Kim if (ss->tlsext_hostname != NULL) 8846f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_hostname); 8856f9291ceSJung-uk Kim if (ss->tlsext_tick != NULL) 8866f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_tick); 8871f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 8881f13597dSJung-uk Kim ss->tlsext_ecpointformatlist_length = 0; 8896f9291ceSJung-uk Kim if (ss->tlsext_ecpointformatlist != NULL) 8906f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_ecpointformatlist); 8911f13597dSJung-uk Kim ss->tlsext_ellipticcurvelist_length = 0; 8926f9291ceSJung-uk Kim if (ss->tlsext_ellipticcurvelist != NULL) 8936f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_ellipticcurvelist); 8941f13597dSJung-uk Kim # endif /* OPENSSL_NO_EC */ 8951f13597dSJung-uk Kim #endif 8961f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 8971f13597dSJung-uk Kim if (ss->psk_identity_hint != NULL) 8981f13597dSJung-uk Kim OPENSSL_free(ss->psk_identity_hint); 8991f13597dSJung-uk Kim if (ss->psk_identity != NULL) 9001f13597dSJung-uk Kim OPENSSL_free(ss->psk_identity); 9011f13597dSJung-uk Kim #endif 9021f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 9031f13597dSJung-uk Kim if (ss->srp_username != NULL) 9041f13597dSJung-uk Kim OPENSSL_free(ss->srp_username); 905db522d3aSSimon L. B. Nielsen #endif 9065c87c606SMark Murray OPENSSL_cleanse(ss, sizeof(*ss)); 907ddd58736SKris Kennaway OPENSSL_free(ss); 90874664626SKris Kennaway } 90974664626SKris Kennaway 91074664626SKris Kennaway int SSL_set_session(SSL *s, SSL_SESSION *session) 91174664626SKris Kennaway { 91274664626SKris Kennaway int ret = 0; 9131f13597dSJung-uk Kim const SSL_METHOD *meth; 91474664626SKris Kennaway 9156f9291ceSJung-uk Kim if (session != NULL) { 91674664626SKris Kennaway meth = s->ctx->method->get_ssl_method(session->ssl_version); 91774664626SKris Kennaway if (meth == NULL) 91874664626SKris Kennaway meth = s->method->get_ssl_method(session->ssl_version); 9196f9291ceSJung-uk Kim if (meth == NULL) { 92074664626SKris Kennaway SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD); 92174664626SKris Kennaway return (0); 92274664626SKris Kennaway } 92374664626SKris Kennaway 9246f9291ceSJung-uk Kim if (meth != s->method) { 92574664626SKris Kennaway if (!SSL_set_ssl_method(s, meth)) 92674664626SKris Kennaway return (0); 92774664626SKris Kennaway } 9285c87c606SMark Murray #ifndef OPENSSL_NO_KRB5 9295c87c606SMark Murray if (s->kssl_ctx && !s->kssl_ctx->client_princ && 9306f9291ceSJung-uk Kim session->krb5_client_princ_len > 0) { 9316f9291ceSJung-uk Kim s->kssl_ctx->client_princ = 9326f9291ceSJung-uk Kim (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); 933aeb5019cSJung-uk Kim if (s->kssl_ctx->client_princ == NULL) { 934aeb5019cSJung-uk Kim SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE); 935aeb5019cSJung-uk Kim return 0; 936aeb5019cSJung-uk Kim } 9375c87c606SMark Murray memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, 9385c87c606SMark Murray session->krb5_client_princ_len); 9395c87c606SMark Murray s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; 9405c87c606SMark Murray } 9415c87c606SMark Murray #endif /* OPENSSL_NO_KRB5 */ 9425c87c606SMark Murray 94374664626SKris Kennaway /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ 94474664626SKris Kennaway CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); 94574664626SKris Kennaway if (s->session != NULL) 94674664626SKris Kennaway SSL_SESSION_free(s->session); 94774664626SKris Kennaway s->session = session; 948de7cdddaSKris Kennaway s->verify_result = s->session->verify_result; 94974664626SKris Kennaway /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ 95074664626SKris Kennaway ret = 1; 9516f9291ceSJung-uk Kim } else { 9526f9291ceSJung-uk Kim if (s->session != NULL) { 95374664626SKris Kennaway SSL_SESSION_free(s->session); 95474664626SKris Kennaway s->session = NULL; 95574664626SKris Kennaway } 95674664626SKris Kennaway 95774664626SKris Kennaway meth = s->ctx->method; 9586f9291ceSJung-uk Kim if (meth != s->method) { 95974664626SKris Kennaway if (!SSL_set_ssl_method(s, meth)) 96074664626SKris Kennaway return (0); 96174664626SKris Kennaway } 96274664626SKris Kennaway ret = 1; 96374664626SKris Kennaway } 96474664626SKris Kennaway return (ret); 96574664626SKris Kennaway } 96674664626SKris Kennaway 96774664626SKris Kennaway long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) 96874664626SKris Kennaway { 9696f9291ceSJung-uk Kim if (s == NULL) 9706f9291ceSJung-uk Kim return (0); 97174664626SKris Kennaway s->timeout = t; 97274664626SKris Kennaway return (1); 97374664626SKris Kennaway } 97474664626SKris Kennaway 9753b4e3dcbSSimon L. B. Nielsen long SSL_SESSION_get_timeout(const SSL_SESSION *s) 97674664626SKris Kennaway { 9776f9291ceSJung-uk Kim if (s == NULL) 9786f9291ceSJung-uk Kim return (0); 97974664626SKris Kennaway return (s->timeout); 98074664626SKris Kennaway } 98174664626SKris Kennaway 9823b4e3dcbSSimon L. B. Nielsen long SSL_SESSION_get_time(const SSL_SESSION *s) 98374664626SKris Kennaway { 9846f9291ceSJung-uk Kim if (s == NULL) 9856f9291ceSJung-uk Kim return (0); 98674664626SKris Kennaway return (s->time); 98774664626SKris Kennaway } 98874664626SKris Kennaway 98974664626SKris Kennaway long SSL_SESSION_set_time(SSL_SESSION *s, long t) 99074664626SKris Kennaway { 9916f9291ceSJung-uk Kim if (s == NULL) 9926f9291ceSJung-uk Kim return (0); 99374664626SKris Kennaway s->time = t; 99474664626SKris Kennaway return (t); 99574664626SKris Kennaway } 99674664626SKris Kennaway 9971f13597dSJung-uk Kim X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) 9981f13597dSJung-uk Kim { 9991f13597dSJung-uk Kim return s->peer; 10001f13597dSJung-uk Kim } 10011f13597dSJung-uk Kim 10021f13597dSJung-uk Kim int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, 10031f13597dSJung-uk Kim unsigned int sid_ctx_len) 10041f13597dSJung-uk Kim { 10056f9291ceSJung-uk Kim if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { 10066f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, 10076f9291ceSJung-uk Kim SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); 10081f13597dSJung-uk Kim return 0; 10091f13597dSJung-uk Kim } 10101f13597dSJung-uk Kim s->sid_ctx_length = sid_ctx_len; 1011ed7112f0SJung-uk Kim if (s->sid_ctx != sid_ctx) 10121f13597dSJung-uk Kim memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); 10131f13597dSJung-uk Kim 10141f13597dSJung-uk Kim return 1; 10151f13597dSJung-uk Kim } 10161f13597dSJung-uk Kim 101774664626SKris Kennaway long SSL_CTX_set_timeout(SSL_CTX *s, long t) 101874664626SKris Kennaway { 101974664626SKris Kennaway long l; 10206f9291ceSJung-uk Kim if (s == NULL) 10216f9291ceSJung-uk Kim return (0); 102274664626SKris Kennaway l = s->session_timeout; 102374664626SKris Kennaway s->session_timeout = t; 102474664626SKris Kennaway return (l); 102574664626SKris Kennaway } 102674664626SKris Kennaway 10273b4e3dcbSSimon L. B. Nielsen long SSL_CTX_get_timeout(const SSL_CTX *s) 102874664626SKris Kennaway { 10296f9291ceSJung-uk Kim if (s == NULL) 10306f9291ceSJung-uk Kim return (0); 103174664626SKris Kennaway return (s->session_timeout); 103274664626SKris Kennaway } 103374664626SKris Kennaway 10341f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 10356f9291ceSJung-uk Kim int SSL_set_session_secret_cb(SSL *s, 10366f9291ceSJung-uk Kim int (*tls_session_secret_cb) (SSL *s, 10376f9291ceSJung-uk Kim void *secret, 10386f9291ceSJung-uk Kim int *secret_len, 10396f9291ceSJung-uk Kim STACK_OF(SSL_CIPHER) 10406f9291ceSJung-uk Kim *peer_ciphers, 10416f9291ceSJung-uk Kim SSL_CIPHER 10426f9291ceSJung-uk Kim **cipher, 10436f9291ceSJung-uk Kim void *arg), 10446f9291ceSJung-uk Kim void *arg) 10451f13597dSJung-uk Kim { 10466f9291ceSJung-uk Kim if (s == NULL) 10476f9291ceSJung-uk Kim return (0); 10481f13597dSJung-uk Kim s->tls_session_secret_cb = tls_session_secret_cb; 10491f13597dSJung-uk Kim s->tls_session_secret_cb_arg = arg; 10501f13597dSJung-uk Kim return (1); 10511f13597dSJung-uk Kim } 10521f13597dSJung-uk Kim 10531f13597dSJung-uk Kim int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, 10541f13597dSJung-uk Kim void *arg) 10551f13597dSJung-uk Kim { 10566f9291ceSJung-uk Kim if (s == NULL) 10576f9291ceSJung-uk Kim return (0); 10581f13597dSJung-uk Kim s->tls_session_ticket_ext_cb = cb; 10591f13597dSJung-uk Kim s->tls_session_ticket_ext_cb_arg = arg; 10601f13597dSJung-uk Kim return (1); 10611f13597dSJung-uk Kim } 10621f13597dSJung-uk Kim 10631f13597dSJung-uk Kim int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) 10641f13597dSJung-uk Kim { 10656f9291ceSJung-uk Kim if (s->version >= TLS1_VERSION) { 10666f9291ceSJung-uk Kim if (s->tlsext_session_ticket) { 10671f13597dSJung-uk Kim OPENSSL_free(s->tlsext_session_ticket); 10681f13597dSJung-uk Kim s->tlsext_session_ticket = NULL; 10691f13597dSJung-uk Kim } 10701f13597dSJung-uk Kim 10716f9291ceSJung-uk Kim s->tlsext_session_ticket = 10726f9291ceSJung-uk Kim OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); 10736f9291ceSJung-uk Kim if (!s->tlsext_session_ticket) { 10741f13597dSJung-uk Kim SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); 10751f13597dSJung-uk Kim return 0; 10761f13597dSJung-uk Kim } 10771f13597dSJung-uk Kim 10786f9291ceSJung-uk Kim if (ext_data) { 10791f13597dSJung-uk Kim s->tlsext_session_ticket->length = ext_len; 10801f13597dSJung-uk Kim s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; 10811f13597dSJung-uk Kim memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); 10826f9291ceSJung-uk Kim } else { 10831f13597dSJung-uk Kim s->tlsext_session_ticket->length = 0; 10841f13597dSJung-uk Kim s->tlsext_session_ticket->data = NULL; 10851f13597dSJung-uk Kim } 10861f13597dSJung-uk Kim 10871f13597dSJung-uk Kim return 1; 10881f13597dSJung-uk Kim } 10891f13597dSJung-uk Kim 10901f13597dSJung-uk Kim return 0; 10911f13597dSJung-uk Kim } 10921f13597dSJung-uk Kim #endif /* OPENSSL_NO_TLSEXT */ 10931f13597dSJung-uk Kim 10946f9291ceSJung-uk Kim typedef struct timeout_param_st { 109574664626SKris Kennaway SSL_CTX *ctx; 109674664626SKris Kennaway long time; 10971f13597dSJung-uk Kim LHASH_OF(SSL_SESSION) *cache; 109874664626SKris Kennaway } TIMEOUT_PARAM; 109974664626SKris Kennaway 11001f13597dSJung-uk Kim static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) 110174664626SKris Kennaway { 11026f9291ceSJung-uk Kim if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ 11036f9291ceSJung-uk Kim /* 11046f9291ceSJung-uk Kim * The reason we don't call SSL_CTX_remove_session() is to save on 11056f9291ceSJung-uk Kim * locking overhead 11066f9291ceSJung-uk Kim */ 11071f13597dSJung-uk Kim (void)lh_SSL_SESSION_delete(p->cache, s); 110874664626SKris Kennaway SSL_SESSION_list_remove(p->ctx, s); 110974664626SKris Kennaway s->not_resumable = 1; 111074664626SKris Kennaway if (p->ctx->remove_session_cb != NULL) 111174664626SKris Kennaway p->ctx->remove_session_cb(p->ctx, s); 111274664626SKris Kennaway SSL_SESSION_free(s); 111374664626SKris Kennaway } 111474664626SKris Kennaway } 111574664626SKris Kennaway 11161f13597dSJung-uk Kim static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) 11175c87c606SMark Murray 111874664626SKris Kennaway void SSL_CTX_flush_sessions(SSL_CTX *s, long t) 111974664626SKris Kennaway { 112074664626SKris Kennaway unsigned long i; 112174664626SKris Kennaway TIMEOUT_PARAM tp; 112274664626SKris Kennaway 112374664626SKris Kennaway tp.ctx = s; 112474664626SKris Kennaway tp.cache = s->sessions; 11256f9291ceSJung-uk Kim if (tp.cache == NULL) 11266f9291ceSJung-uk Kim return; 112774664626SKris Kennaway tp.time = t; 112874664626SKris Kennaway CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 11291f13597dSJung-uk Kim i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; 11301f13597dSJung-uk Kim CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; 11311f13597dSJung-uk Kim lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), 11321f13597dSJung-uk Kim TIMEOUT_PARAM, &tp); 11331f13597dSJung-uk Kim CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; 113474664626SKris Kennaway CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 113574664626SKris Kennaway } 113674664626SKris Kennaway 113774664626SKris Kennaway int ssl_clear_bad_session(SSL *s) 113874664626SKris Kennaway { 113974664626SKris Kennaway if ((s->session != NULL) && 114074664626SKris Kennaway !(s->shutdown & SSL_SENT_SHUTDOWN) && 11416f9291ceSJung-uk Kim !(SSL_in_init(s) || SSL_in_before(s))) { 1142aeb5019cSJung-uk Kim SSL_CTX_remove_session(s->session_ctx, s->session); 114374664626SKris Kennaway return (1); 11446f9291ceSJung-uk Kim } else 114574664626SKris Kennaway return (0); 114674664626SKris Kennaway } 114774664626SKris Kennaway 114874664626SKris Kennaway /* locked by SSL_CTX in the calling function */ 114974664626SKris Kennaway static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) 115074664626SKris Kennaway { 11516f9291ceSJung-uk Kim if ((s->next == NULL) || (s->prev == NULL)) 11526f9291ceSJung-uk Kim return; 115374664626SKris Kennaway 11546f9291ceSJung-uk Kim if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { 11556f9291ceSJung-uk Kim /* last element in list */ 11566f9291ceSJung-uk Kim if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { 11576f9291ceSJung-uk Kim /* only one element in list */ 115874664626SKris Kennaway ctx->session_cache_head = NULL; 115974664626SKris Kennaway ctx->session_cache_tail = NULL; 11606f9291ceSJung-uk Kim } else { 116174664626SKris Kennaway ctx->session_cache_tail = s->prev; 116274664626SKris Kennaway s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); 116374664626SKris Kennaway } 11646f9291ceSJung-uk Kim } else { 11656f9291ceSJung-uk Kim if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { 11666f9291ceSJung-uk Kim /* first element in list */ 116774664626SKris Kennaway ctx->session_cache_head = s->next; 116874664626SKris Kennaway s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); 11696f9291ceSJung-uk Kim } else { 11706f9291ceSJung-uk Kim /* middle of list */ 117174664626SKris Kennaway s->next->prev = s->prev; 117274664626SKris Kennaway s->prev->next = s->next; 117374664626SKris Kennaway } 117474664626SKris Kennaway } 117574664626SKris Kennaway s->prev = s->next = NULL; 117674664626SKris Kennaway } 117774664626SKris Kennaway 117874664626SKris Kennaway static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) 117974664626SKris Kennaway { 118074664626SKris Kennaway if ((s->next != NULL) && (s->prev != NULL)) 118174664626SKris Kennaway SSL_SESSION_list_remove(ctx, s); 118274664626SKris Kennaway 11836f9291ceSJung-uk Kim if (ctx->session_cache_head == NULL) { 118474664626SKris Kennaway ctx->session_cache_head = s; 118574664626SKris Kennaway ctx->session_cache_tail = s; 118674664626SKris Kennaway s->prev = (SSL_SESSION *)&(ctx->session_cache_head); 118774664626SKris Kennaway s->next = (SSL_SESSION *)&(ctx->session_cache_tail); 11886f9291ceSJung-uk Kim } else { 118974664626SKris Kennaway s->next = ctx->session_cache_head; 119074664626SKris Kennaway s->next->prev = s; 119174664626SKris Kennaway s->prev = (SSL_SESSION *)&(ctx->session_cache_head); 119274664626SKris Kennaway ctx->session_cache_head = s; 119374664626SKris Kennaway } 119474664626SKris Kennaway } 119574664626SKris Kennaway 11965471f83eSSimon L. B. Nielsen void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, 11976f9291ceSJung-uk Kim int (*cb) (struct ssl_st *ssl, 11986f9291ceSJung-uk Kim SSL_SESSION *sess)) 11995471f83eSSimon L. B. Nielsen { 12005471f83eSSimon L. B. Nielsen ctx->new_session_cb = cb; 12015471f83eSSimon L. B. Nielsen } 12025471f83eSSimon L. B. Nielsen 12036f9291ceSJung-uk Kim int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { 12045471f83eSSimon L. B. Nielsen return ctx->new_session_cb; 12055471f83eSSimon L. B. Nielsen } 12065471f83eSSimon L. B. Nielsen 12075471f83eSSimon L. B. Nielsen void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, 12085471f83eSSimon L. B. Nielsen void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess)) 12095471f83eSSimon L. B. Nielsen { 12105471f83eSSimon L. B. Nielsen ctx->remove_session_cb = cb; 12115471f83eSSimon L. B. Nielsen } 12125471f83eSSimon L. B. Nielsen 12136f9291ceSJung-uk Kim void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, 12146f9291ceSJung-uk Kim SSL_SESSION *sess) { 12155471f83eSSimon L. B. Nielsen return ctx->remove_session_cb; 12165471f83eSSimon L. B. Nielsen } 12175471f83eSSimon L. B. Nielsen 12185471f83eSSimon L. B. Nielsen void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, 12195471f83eSSimon L. B. Nielsen SSL_SESSION *(*cb) (struct ssl_st *ssl, 12206f9291ceSJung-uk Kim unsigned char *data, int len, 12216f9291ceSJung-uk Kim int *copy)) 12225471f83eSSimon L. B. Nielsen { 12235471f83eSSimon L. B. Nielsen ctx->get_session_cb = cb; 12245471f83eSSimon L. B. Nielsen } 12255471f83eSSimon L. B. Nielsen 12265471f83eSSimon L. B. Nielsen SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl, 12276f9291ceSJung-uk Kim unsigned char *data, 12286f9291ceSJung-uk Kim int len, int *copy) { 12295471f83eSSimon L. B. Nielsen return ctx->get_session_cb; 12305471f83eSSimon L. B. Nielsen } 12315471f83eSSimon L. B. Nielsen 12325471f83eSSimon L. B. Nielsen void SSL_CTX_set_info_callback(SSL_CTX *ctx, 12335471f83eSSimon L. B. Nielsen void (*cb) (const SSL *ssl, int type, int val)) 12345471f83eSSimon L. B. Nielsen { 12355471f83eSSimon L. B. Nielsen ctx->info_callback = cb; 12365471f83eSSimon L. B. Nielsen } 12375471f83eSSimon L. B. Nielsen 12386f9291ceSJung-uk Kim void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, 12396f9291ceSJung-uk Kim int val) { 12405471f83eSSimon L. B. Nielsen return ctx->info_callback; 12415471f83eSSimon L. B. Nielsen } 12425471f83eSSimon L. B. Nielsen 12435471f83eSSimon L. B. Nielsen void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, 12446f9291ceSJung-uk Kim int (*cb) (SSL *ssl, X509 **x509, 12456f9291ceSJung-uk Kim EVP_PKEY **pkey)) 12465471f83eSSimon L. B. Nielsen { 12475471f83eSSimon L. B. Nielsen ctx->client_cert_cb = cb; 12485471f83eSSimon L. B. Nielsen } 12495471f83eSSimon L. B. Nielsen 12506f9291ceSJung-uk Kim int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, 12516f9291ceSJung-uk Kim EVP_PKEY **pkey) { 12525471f83eSSimon L. B. Nielsen return ctx->client_cert_cb; 12535471f83eSSimon L. B. Nielsen } 12545471f83eSSimon L. B. Nielsen 1255db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_ENGINE 1256db522d3aSSimon L. B. Nielsen int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) 1257db522d3aSSimon L. B. Nielsen { 12586f9291ceSJung-uk Kim if (!ENGINE_init(e)) { 1259db522d3aSSimon L. B. Nielsen SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); 1260db522d3aSSimon L. B. Nielsen return 0; 1261db522d3aSSimon L. B. Nielsen } 12626f9291ceSJung-uk Kim if (!ENGINE_get_ssl_client_cert_function(e)) { 12636f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, 12646f9291ceSJung-uk Kim SSL_R_NO_CLIENT_CERT_METHOD); 1265db522d3aSSimon L. B. Nielsen ENGINE_finish(e); 1266db522d3aSSimon L. B. Nielsen return 0; 1267db522d3aSSimon L. B. Nielsen } 1268db522d3aSSimon L. B. Nielsen ctx->client_cert_engine = e; 1269db522d3aSSimon L. B. Nielsen return 1; 1270db522d3aSSimon L. B. Nielsen } 1271db522d3aSSimon L. B. Nielsen #endif 1272db522d3aSSimon L. B. Nielsen 12735471f83eSSimon L. B. Nielsen void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, 12746f9291ceSJung-uk Kim int (*cb) (SSL *ssl, 12756f9291ceSJung-uk Kim unsigned char *cookie, 12766f9291ceSJung-uk Kim unsigned int *cookie_len)) 12775471f83eSSimon L. B. Nielsen { 12785471f83eSSimon L. B. Nielsen ctx->app_gen_cookie_cb = cb; 12795471f83eSSimon L. B. Nielsen } 12805471f83eSSimon L. B. Nielsen 12815471f83eSSimon L. B. Nielsen void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, 12826f9291ceSJung-uk Kim int (*cb) (SSL *ssl, unsigned char *cookie, 12836f9291ceSJung-uk Kim unsigned int cookie_len)) 12845471f83eSSimon L. B. Nielsen { 12855471f83eSSimon L. B. Nielsen ctx->app_verify_cookie_cb = cb; 12865471f83eSSimon L. B. Nielsen } 12875471f83eSSimon L. B. Nielsen 12886f9291ceSJung-uk Kim IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, 12896f9291ceSJung-uk Kim SSL_SESSION) 1290