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; 160*6f9291ceSJung-uk Kim /* 161*6f9291ceSJung-uk Kim * Need to lock this all up rather than just use CRYPTO_add so that 162*6f9291ceSJung-uk Kim * somebody doesn't free ssl->session between when we check it's non-null 163*6f9291ceSJung-uk Kim * and when we up the reference count. 164*6f9291ceSJung-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 173*6f9291ceSJung-uk Kim int SSL_SESSION_get_ex_new_index(long argl, void *argp, 174*6f9291ceSJung-uk Kim CRYPTO_EX_new *new_func, 175*6f9291ceSJung-uk Kim CRYPTO_EX_dup *dup_func, 176*6f9291ceSJung-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)); 197*6f9291ceSJung-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 230*6f9291ceSJung-uk Kim const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, 231*6f9291ceSJung-uk Kim unsigned int *len) 2323b4e3dcbSSimon L. B. Nielsen { 2333b4e3dcbSSimon L. B. Nielsen if (len) 2343b4e3dcbSSimon L. B. Nielsen *len = s->session_id_length; 2353b4e3dcbSSimon L. B. Nielsen return s->session_id; 2363b4e3dcbSSimon L. B. Nielsen } 2373b4e3dcbSSimon L. B. Nielsen 2381f13597dSJung-uk Kim unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) 2391f13597dSJung-uk Kim { 2401f13597dSJung-uk Kim return s->compress_meth; 2411f13597dSJung-uk Kim } 2421f13597dSJung-uk Kim 243*6f9291ceSJung-uk Kim /* 244*6f9291ceSJung-uk Kim * Even with SSLv2, we have 16 bytes (128 bits) of session ID space. 245*6f9291ceSJung-uk Kim * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random 246*6f9291ceSJung-uk Kim * gunk repeatedly until we have no conflict is going to complete in one 247*6f9291ceSJung-uk Kim * iteration pretty much "most" of the time (btw: understatement). So, if it 248*6f9291ceSJung-uk Kim * takes us 10 iterations and we still can't avoid a conflict - well that's a 249*6f9291ceSJung-uk Kim * reasonable point to call it quits. Either the RAND code is broken or 250*6f9291ceSJung-uk Kim * someone is trying to open roughly very close to 2^128 (or 2^256) SSL 251*6f9291ceSJung-uk Kim * sessions to our server. How you might store that many sessions is perhaps 252*6f9291ceSJung-uk Kim * a more interesting question ... 253*6f9291ceSJung-uk Kim */ 2545c87c606SMark Murray 2555c87c606SMark Murray #define MAX_SESS_ID_ATTEMPTS 10 2565c87c606SMark Murray static int def_generate_session_id(const SSL *ssl, unsigned char *id, 2575c87c606SMark Murray unsigned int *id_len) 2585c87c606SMark Murray { 2595c87c606SMark Murray unsigned int retry = 0; 2605c87c606SMark Murray do 2616be8ae07SJacques Vidrine if (RAND_pseudo_bytes(id, *id_len) <= 0) 2626be8ae07SJacques Vidrine return 0; 2635c87c606SMark Murray while (SSL_has_matching_session_id(ssl, id, *id_len) && 2645c87c606SMark Murray (++retry < MAX_SESS_ID_ATTEMPTS)) ; 2655c87c606SMark Murray if (retry < MAX_SESS_ID_ATTEMPTS) 2665c87c606SMark Murray return 1; 2675c87c606SMark Murray /* else - woops a session_id match */ 268*6f9291ceSJung-uk Kim /* 269*6f9291ceSJung-uk Kim * XXX We should also check the external cache -- but the probability of 270*6f9291ceSJung-uk Kim * a collision is negligible, and we could not prevent the concurrent 271*6f9291ceSJung-uk Kim * creation of sessions with identical IDs since we currently don't have 272*6f9291ceSJung-uk Kim * means to atomically check whether a session ID already exists and make 273*6f9291ceSJung-uk Kim * a reservation for it if it does not (this problem applies to the 274*6f9291ceSJung-uk Kim * internal cache as well). 2755c87c606SMark Murray */ 2765c87c606SMark Murray return 0; 2775c87c606SMark Murray } 2785c87c606SMark Murray 27974664626SKris Kennaway int ssl_get_new_session(SSL *s, int session) 28074664626SKris Kennaway { 28174664626SKris Kennaway /* This gets used by clients and servers. */ 28274664626SKris Kennaway 2835c87c606SMark Murray unsigned int tmp; 28474664626SKris Kennaway SSL_SESSION *ss = NULL; 2855c87c606SMark Murray GEN_SESSION_CB cb = def_generate_session_id; 28674664626SKris Kennaway 287*6f9291ceSJung-uk Kim if ((ss = SSL_SESSION_new()) == NULL) 288*6f9291ceSJung-uk Kim return (0); 28974664626SKris Kennaway 29074664626SKris Kennaway /* If the context has a default timeout, use it */ 2911f13597dSJung-uk Kim if (s->session_ctx->session_timeout == 0) 29274664626SKris Kennaway ss->timeout = SSL_get_default_timeout(s); 29374664626SKris Kennaway else 2941f13597dSJung-uk Kim ss->timeout = s->session_ctx->session_timeout; 29574664626SKris Kennaway 296*6f9291ceSJung-uk Kim if (s->session != NULL) { 29774664626SKris Kennaway SSL_SESSION_free(s->session); 29874664626SKris Kennaway s->session = NULL; 29974664626SKris Kennaway } 30074664626SKris Kennaway 301*6f9291ceSJung-uk Kim if (session) { 302*6f9291ceSJung-uk Kim if (s->version == SSL2_VERSION) { 30374664626SKris Kennaway ss->ssl_version = SSL2_VERSION; 30474664626SKris Kennaway ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; 305*6f9291ceSJung-uk Kim } else if (s->version == SSL3_VERSION) { 30674664626SKris Kennaway ss->ssl_version = SSL3_VERSION; 30774664626SKris Kennaway ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 308*6f9291ceSJung-uk Kim } else if (s->version == TLS1_VERSION) { 30974664626SKris Kennaway ss->ssl_version = TLS1_VERSION; 31074664626SKris Kennaway ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 311*6f9291ceSJung-uk Kim } else if (s->version == TLS1_1_VERSION) { 3121f13597dSJung-uk Kim ss->ssl_version = TLS1_1_VERSION; 3131f13597dSJung-uk Kim ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 314*6f9291ceSJung-uk Kim } else if (s->version == TLS1_2_VERSION) { 3151f13597dSJung-uk Kim ss->ssl_version = TLS1_2_VERSION; 3161f13597dSJung-uk Kim ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 317*6f9291ceSJung-uk Kim } else if (s->version == DTLS1_BAD_VER) { 3186a599222SSimon L. B. Nielsen ss->ssl_version = DTLS1_BAD_VER; 3196a599222SSimon L. B. Nielsen ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 320*6f9291ceSJung-uk Kim } else if (s->version == DTLS1_VERSION) { 3213b4e3dcbSSimon L. B. Nielsen ss->ssl_version = DTLS1_VERSION; 3223b4e3dcbSSimon L. B. Nielsen ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 323*6f9291ceSJung-uk Kim } else { 32474664626SKris Kennaway SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); 32574664626SKris Kennaway SSL_SESSION_free(ss); 32674664626SKris Kennaway return (0); 32774664626SKris Kennaway } 328db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 329*6f9291ceSJung-uk Kim /*- 330751d2991SJung-uk Kim * If RFC5077 ticket, use empty session ID (as server). 331751d2991SJung-uk Kim * Note that: 332751d2991SJung-uk Kim * (a) ssl_get_prev_session() does lookahead into the 333751d2991SJung-uk Kim * ClientHello extensions to find the session ticket. 334751d2991SJung-uk Kim * When ssl_get_prev_session() fails, s3_srvr.c calls 335751d2991SJung-uk Kim * ssl_get_new_session() in ssl3_get_client_hello(). 336751d2991SJung-uk Kim * At that point, it has not yet parsed the extensions, 337751d2991SJung-uk Kim * however, because of the lookahead, it already knows 338751d2991SJung-uk Kim * whether a ticket is expected or not. 339751d2991SJung-uk Kim * 340751d2991SJung-uk Kim * (b) s3_clnt.c calls ssl_get_new_session() before parsing 341751d2991SJung-uk Kim * ServerHello extensions, and before recording the session 342751d2991SJung-uk Kim * ID received from the server, so this block is a noop. 343751d2991SJung-uk Kim */ 344*6f9291ceSJung-uk Kim if (s->tlsext_ticket_expected) { 345db522d3aSSimon L. B. Nielsen ss->session_id_length = 0; 346db522d3aSSimon L. B. Nielsen goto sess_id_done; 347db522d3aSSimon L. B. Nielsen } 348db522d3aSSimon L. B. Nielsen #endif 3495c87c606SMark Murray /* Choose which callback will set the session ID */ 35074664626SKris Kennaway CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 3515c87c606SMark Murray if (s->generate_session_id) 3525c87c606SMark Murray cb = s->generate_session_id; 3531f13597dSJung-uk Kim else if (s->session_ctx->generate_session_id) 3541f13597dSJung-uk Kim cb = s->session_ctx->generate_session_id; 35574664626SKris Kennaway CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 3565c87c606SMark Murray /* Choose a session ID */ 3575c87c606SMark Murray tmp = ss->session_id_length; 358*6f9291ceSJung-uk Kim if (!cb(s, ss->session_id, &tmp)) { 3595c87c606SMark Murray /* The callback failed */ 3605c87c606SMark Murray SSLerr(SSL_F_SSL_GET_NEW_SESSION, 3615c87c606SMark Murray SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); 3625c87c606SMark Murray SSL_SESSION_free(ss); 3635c87c606SMark Murray return (0); 3645c87c606SMark Murray } 365*6f9291ceSJung-uk Kim /* 366*6f9291ceSJung-uk Kim * Don't allow the callback to set the session length to zero. nor 367*6f9291ceSJung-uk Kim * set it higher than it was. 368*6f9291ceSJung-uk Kim */ 369*6f9291ceSJung-uk Kim if (!tmp || (tmp > ss->session_id_length)) { 3705c87c606SMark Murray /* The callback set an illegal length */ 3715c87c606SMark Murray SSLerr(SSL_F_SSL_GET_NEW_SESSION, 3725c87c606SMark Murray SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); 3735c87c606SMark Murray SSL_SESSION_free(ss); 3745c87c606SMark Murray return (0); 3755c87c606SMark Murray } 3765c87c606SMark Murray /* If the session length was shrunk and we're SSLv2, pad it */ 3775c87c606SMark Murray if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION)) 3785c87c606SMark Murray memset(ss->session_id + tmp, 0, ss->session_id_length - tmp); 3795c87c606SMark Murray else 3805c87c606SMark Murray ss->session_id_length = tmp; 3815c87c606SMark Murray /* Finally, check for a conflict */ 3825c87c606SMark Murray if (SSL_has_matching_session_id(s, ss->session_id, 383*6f9291ceSJung-uk Kim ss->session_id_length)) { 384*6f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); 3855c87c606SMark Murray SSL_SESSION_free(ss); 3865c87c606SMark Murray return (0); 38774664626SKris Kennaway } 388db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 389db522d3aSSimon L. B. Nielsen sess_id_done: 390db522d3aSSimon L. B. Nielsen if (s->tlsext_hostname) { 391db522d3aSSimon L. B. Nielsen ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); 392db522d3aSSimon L. B. Nielsen if (ss->tlsext_hostname == NULL) { 393db522d3aSSimon L. B. Nielsen SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); 394db522d3aSSimon L. B. Nielsen SSL_SESSION_free(ss); 395db522d3aSSimon L. B. Nielsen return 0; 396db522d3aSSimon L. B. Nielsen } 397db522d3aSSimon L. B. Nielsen } 3981f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 399*6f9291ceSJung-uk Kim if (s->tlsext_ecpointformatlist) { 400*6f9291ceSJung-uk Kim if (ss->tlsext_ecpointformatlist != NULL) 401*6f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_ecpointformatlist); 402*6f9291ceSJung-uk Kim if ((ss->tlsext_ecpointformatlist = 403*6f9291ceSJung-uk Kim OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) == 404*6f9291ceSJung-uk Kim NULL) { 4051f13597dSJung-uk Kim SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); 4061f13597dSJung-uk Kim SSL_SESSION_free(ss); 4071f13597dSJung-uk Kim return 0; 4081f13597dSJung-uk Kim } 409*6f9291ceSJung-uk Kim ss->tlsext_ecpointformatlist_length = 410*6f9291ceSJung-uk Kim s->tlsext_ecpointformatlist_length; 411*6f9291ceSJung-uk Kim memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, 412*6f9291ceSJung-uk Kim s->tlsext_ecpointformatlist_length); 4131f13597dSJung-uk Kim } 414*6f9291ceSJung-uk Kim if (s->tlsext_ellipticcurvelist) { 415*6f9291ceSJung-uk Kim if (ss->tlsext_ellipticcurvelist != NULL) 416*6f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_ellipticcurvelist); 417*6f9291ceSJung-uk Kim if ((ss->tlsext_ellipticcurvelist = 418*6f9291ceSJung-uk Kim OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == 419*6f9291ceSJung-uk Kim NULL) { 4201f13597dSJung-uk Kim SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); 4211f13597dSJung-uk Kim SSL_SESSION_free(ss); 4221f13597dSJung-uk Kim return 0; 4231f13597dSJung-uk Kim } 424*6f9291ceSJung-uk Kim ss->tlsext_ellipticcurvelist_length = 425*6f9291ceSJung-uk Kim s->tlsext_ellipticcurvelist_length; 426*6f9291ceSJung-uk Kim memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, 427*6f9291ceSJung-uk Kim s->tlsext_ellipticcurvelist_length); 4281f13597dSJung-uk Kim } 4291f13597dSJung-uk Kim # endif 430db522d3aSSimon L. B. Nielsen #endif 431*6f9291ceSJung-uk Kim } else { 43274664626SKris Kennaway ss->session_id_length = 0; 43374664626SKris Kennaway } 43474664626SKris Kennaway 435*6f9291ceSJung-uk Kim if (s->sid_ctx_length > sizeof ss->sid_ctx) { 4365c87c606SMark Murray SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); 43748454956SJacques Vidrine SSL_SESSION_free(ss); 43848454956SJacques Vidrine return 0; 43948454956SJacques Vidrine } 44074664626SKris Kennaway memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); 44174664626SKris Kennaway ss->sid_ctx_length = s->sid_ctx_length; 44274664626SKris Kennaway s->session = ss; 44374664626SKris Kennaway ss->ssl_version = s->version; 444f579bf8eSKris Kennaway ss->verify_result = X509_V_OK; 44574664626SKris Kennaway 44674664626SKris Kennaway return (1); 44774664626SKris Kennaway } 44874664626SKris Kennaway 449*6f9291ceSJung-uk Kim /*- 450*6f9291ceSJung-uk Kim * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this 4511f13597dSJung-uk Kim * connection. It is only called by servers. 4521f13597dSJung-uk Kim * 4531f13597dSJung-uk Kim * session_id: points at the session ID in the ClientHello. This code will 4541f13597dSJung-uk Kim * read past the end of this in order to parse out the session ticket 4551f13597dSJung-uk Kim * extension, if any. 4561f13597dSJung-uk Kim * len: the length of the session ID. 4571f13597dSJung-uk Kim * limit: a pointer to the first byte after the ClientHello. 4581f13597dSJung-uk Kim * 4591f13597dSJung-uk Kim * Returns: 4601f13597dSJung-uk Kim * -1: error 4611f13597dSJung-uk Kim * 0: a session may have been found. 4621f13597dSJung-uk Kim * 4631f13597dSJung-uk Kim * Side effects: 4641f13597dSJung-uk Kim * - If a session is found then s->session is pointed at it (after freeing an 4651f13597dSJung-uk Kim * existing session if need be) and s->verify_result is set from the session. 4661f13597dSJung-uk Kim * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1 4671f13597dSJung-uk Kim * if the server should issue a new session ticket (to 0 otherwise). 4681f13597dSJung-uk Kim */ 469db522d3aSSimon L. B. Nielsen int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, 470db522d3aSSimon L. B. Nielsen const unsigned char *limit) 47174664626SKris Kennaway { 47274664626SKris Kennaway /* This is used only by servers. */ 47374664626SKris Kennaway 474db522d3aSSimon L. B. Nielsen SSL_SESSION *ret = NULL; 47574664626SKris Kennaway int fatal = 0; 4761f13597dSJung-uk Kim int try_session_cache = 1; 477db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 478db522d3aSSimon L. B. Nielsen int r; 479db522d3aSSimon L. B. Nielsen #endif 48074664626SKris Kennaway 48174664626SKris Kennaway if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) 48274664626SKris Kennaway goto err; 4831f13597dSJung-uk Kim 4841f13597dSJung-uk Kim if (len == 0) 4851f13597dSJung-uk Kim try_session_cache = 0; 4861f13597dSJung-uk Kim 487db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 488*6f9291ceSJung-uk Kim /* sets s->tlsext_ticket_expected */ 489*6f9291ceSJung-uk Kim r = tls1_process_ticket(s, session_id, len, limit, &ret); 490*6f9291ceSJung-uk Kim switch (r) { 4911f13597dSJung-uk Kim case -1: /* Error during processing */ 492db522d3aSSimon L. B. Nielsen fatal = 1; 493db522d3aSSimon L. B. Nielsen goto err; 4941f13597dSJung-uk Kim case 0: /* No ticket found */ 4951f13597dSJung-uk Kim case 1: /* Zero length ticket found */ 4961f13597dSJung-uk Kim break; /* Ok to carry on processing session id. */ 4971f13597dSJung-uk Kim case 2: /* Ticket found but not decrypted. */ 4981f13597dSJung-uk Kim case 3: /* Ticket decrypted, *ret has been set. */ 4991f13597dSJung-uk Kim try_session_cache = 0; 5001f13597dSJung-uk Kim break; 5011f13597dSJung-uk Kim default: 5021f13597dSJung-uk Kim abort(); 503db522d3aSSimon L. B. Nielsen } 504db522d3aSSimon L. B. Nielsen #endif 5051f13597dSJung-uk Kim 5061f13597dSJung-uk Kim if (try_session_cache && 5071f13597dSJung-uk Kim ret == NULL && 508*6f9291ceSJung-uk Kim !(s->session_ctx->session_cache_mode & 509*6f9291ceSJung-uk Kim SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { 510db522d3aSSimon L. B. Nielsen SSL_SESSION data; 511db522d3aSSimon L. B. Nielsen data.ssl_version = s->version; 512db522d3aSSimon L. B. Nielsen data.session_id_length = len; 513db522d3aSSimon L. B. Nielsen if (len == 0) 514db522d3aSSimon L. B. Nielsen return 0; 515db522d3aSSimon L. B. Nielsen memcpy(data.session_id, session_id, len); 51674664626SKris Kennaway CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 5171f13597dSJung-uk Kim ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); 518*6f9291ceSJung-uk Kim if (ret != NULL) { 51974664626SKris Kennaway /* don't allow other threads to steal it: */ 52074664626SKris Kennaway CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); 5211f13597dSJung-uk Kim } 52274664626SKris Kennaway CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 5231f13597dSJung-uk Kim if (ret == NULL) 5241f13597dSJung-uk Kim s->session_ctx->stats.sess_miss++; 52574664626SKris Kennaway } 52674664626SKris Kennaway 5271f13597dSJung-uk Kim if (try_session_cache && 528*6f9291ceSJung-uk Kim ret == NULL && s->session_ctx->get_session_cb != NULL) { 52974664626SKris Kennaway int copy = 1; 53074664626SKris Kennaway 531*6f9291ceSJung-uk Kim if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) { 5321f13597dSJung-uk Kim s->session_ctx->stats.sess_cb_hit++; 53374664626SKris Kennaway 534*6f9291ceSJung-uk Kim /* 535*6f9291ceSJung-uk Kim * Increment reference count now if the session callback asks us 536*6f9291ceSJung-uk Kim * to do so (note that if the session structures returned by the 537*6f9291ceSJung-uk Kim * callback are shared between threads, it must handle the 538*6f9291ceSJung-uk Kim * reference count itself [i.e. copy == 0], or things won't be 539*6f9291ceSJung-uk Kim * thread-safe). 540*6f9291ceSJung-uk Kim */ 54174664626SKris Kennaway if (copy) 54274664626SKris Kennaway CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); 54374664626SKris Kennaway 544*6f9291ceSJung-uk Kim /* 545*6f9291ceSJung-uk Kim * Add the externally cached session to the internal cache as 546*6f9291ceSJung-uk Kim * well if and only if we are supposed to. 547*6f9291ceSJung-uk Kim */ 548*6f9291ceSJung-uk Kim if (! 549*6f9291ceSJung-uk Kim (s->session_ctx->session_cache_mode & 550*6f9291ceSJung-uk Kim SSL_SESS_CACHE_NO_INTERNAL_STORE)) 551*6f9291ceSJung-uk Kim /* 552*6f9291ceSJung-uk Kim * The following should not return 1, otherwise, things are 553*6f9291ceSJung-uk Kim * very strange 554*6f9291ceSJung-uk Kim */ 5551f13597dSJung-uk Kim SSL_CTX_add_session(s->session_ctx, ret); 55674664626SKris Kennaway } 55774664626SKris Kennaway } 55874664626SKris Kennaway 5591f13597dSJung-uk Kim if (ret == NULL) 5601f13597dSJung-uk Kim goto err; 5611f13597dSJung-uk Kim 5621f13597dSJung-uk Kim /* Now ret is non-NULL and we own one of its reference counts. */ 56374664626SKris Kennaway 564db522d3aSSimon L. B. Nielsen if (ret->sid_ctx_length != s->sid_ctx_length 565*6f9291ceSJung-uk Kim || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { 566*6f9291ceSJung-uk Kim /* 567*6f9291ceSJung-uk Kim * We have the session requested by the client, but we don't want to 568*6f9291ceSJung-uk Kim * use it in this context. 569*6f9291ceSJung-uk Kim */ 57074664626SKris Kennaway goto err; /* treat like cache miss */ 57174664626SKris Kennaway } 572db522d3aSSimon L. B. Nielsen 573*6f9291ceSJung-uk Kim if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { 574*6f9291ceSJung-uk Kim /* 575*6f9291ceSJung-uk Kim * We can't be sure if this session is being used out of context, 576*6f9291ceSJung-uk Kim * which is especially important for SSL_VERIFY_PEER. The application 577*6f9291ceSJung-uk Kim * should have used SSL[_CTX]_set_session_id_context. For this error 578*6f9291ceSJung-uk Kim * case, we generate an error instead of treating the event like a 579*6f9291ceSJung-uk Kim * cache miss (otherwise it would be easy for applications to 580*6f9291ceSJung-uk Kim * effectively disable the session cache by accident without anyone 581*6f9291ceSJung-uk Kim * noticing). 582db522d3aSSimon L. B. Nielsen */ 583db522d3aSSimon L. B. Nielsen 584*6f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_GET_PREV_SESSION, 585*6f9291ceSJung-uk Kim SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); 586db522d3aSSimon L. B. Nielsen fatal = 1; 587db522d3aSSimon L. B. Nielsen goto err; 58874664626SKris Kennaway } 58974664626SKris Kennaway 590*6f9291ceSJung-uk Kim if (ret->cipher == NULL) { 59174664626SKris Kennaway unsigned char buf[5], *p; 59274664626SKris Kennaway unsigned long l; 59374664626SKris Kennaway 59474664626SKris Kennaway p = buf; 59574664626SKris Kennaway l = ret->cipher_id; 59674664626SKris Kennaway l2n(l, p); 5976a599222SSimon L. B. Nielsen if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR) 59874664626SKris Kennaway ret->cipher = ssl_get_cipher_by_char(s, &(buf[2])); 59974664626SKris Kennaway else 60074664626SKris Kennaway ret->cipher = ssl_get_cipher_by_char(s, &(buf[1])); 60174664626SKris Kennaway if (ret->cipher == NULL) 60274664626SKris Kennaway goto err; 60374664626SKris Kennaway } 60474664626SKris Kennaway 605*6f9291ceSJung-uk Kim if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ 6061f13597dSJung-uk Kim s->session_ctx->stats.sess_timeout++; 607*6f9291ceSJung-uk Kim if (try_session_cache) { 6081f13597dSJung-uk Kim /* session was from the cache, so remove it */ 6091f13597dSJung-uk Kim SSL_CTX_remove_session(s->session_ctx, ret); 6101f13597dSJung-uk Kim } 61174664626SKris Kennaway goto err; 61274664626SKris Kennaway } 61374664626SKris Kennaway 6141f13597dSJung-uk Kim s->session_ctx->stats.sess_hit++; 61574664626SKris Kennaway 61674664626SKris Kennaway if (s->session != NULL) 61774664626SKris Kennaway SSL_SESSION_free(s->session); 61874664626SKris Kennaway s->session = ret; 619f579bf8eSKris Kennaway s->verify_result = s->session->verify_result; 6201f13597dSJung-uk Kim return 1; 62174664626SKris Kennaway 62274664626SKris Kennaway err: 623*6f9291ceSJung-uk Kim if (ret != NULL) { 62474664626SKris Kennaway SSL_SESSION_free(ret); 6251f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 626*6f9291ceSJung-uk Kim if (!try_session_cache) { 627*6f9291ceSJung-uk Kim /* 628*6f9291ceSJung-uk Kim * The session was from a ticket, so we should issue a ticket for 629*6f9291ceSJung-uk Kim * the new session 630*6f9291ceSJung-uk Kim */ 6311f13597dSJung-uk Kim s->tlsext_ticket_expected = 1; 6321f13597dSJung-uk Kim } 6331f13597dSJung-uk Kim #endif 6341f13597dSJung-uk Kim } 63574664626SKris Kennaway if (fatal) 63674664626SKris Kennaway return -1; 63774664626SKris Kennaway else 63874664626SKris Kennaway return 0; 63974664626SKris Kennaway } 64074664626SKris Kennaway 64174664626SKris Kennaway int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) 64274664626SKris Kennaway { 64374664626SKris Kennaway int ret = 0; 64474664626SKris Kennaway SSL_SESSION *s; 64574664626SKris Kennaway 646*6f9291ceSJung-uk Kim /* 647*6f9291ceSJung-uk Kim * add just 1 reference count for the SSL_CTX's session cache even though 648*6f9291ceSJung-uk Kim * it has two ways of access: each session is in a doubly linked list and 649*6f9291ceSJung-uk Kim * an lhash 650*6f9291ceSJung-uk Kim */ 65174664626SKris Kennaway CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); 652*6f9291ceSJung-uk Kim /* 653*6f9291ceSJung-uk Kim * if session c is in already in cache, we take back the increment later 654*6f9291ceSJung-uk Kim */ 65574664626SKris Kennaway 65674664626SKris Kennaway CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 6571f13597dSJung-uk Kim s = lh_SSL_SESSION_insert(ctx->sessions, c); 65874664626SKris Kennaway 659*6f9291ceSJung-uk Kim /* 660*6f9291ceSJung-uk Kim * s != NULL iff we already had a session with the given PID. In this 661*6f9291ceSJung-uk Kim * case, s == c should hold (then we did not really modify 662*6f9291ceSJung-uk Kim * ctx->sessions), or we're in trouble. 663*6f9291ceSJung-uk Kim */ 664*6f9291ceSJung-uk Kim if (s != NULL && s != c) { 665f579bf8eSKris Kennaway /* We *are* in trouble ... */ 666f579bf8eSKris Kennaway SSL_SESSION_list_remove(ctx, s); 667f579bf8eSKris Kennaway SSL_SESSION_free(s); 668*6f9291ceSJung-uk Kim /* 669*6f9291ceSJung-uk Kim * ... so pretend the other session did not exist in cache (we cannot 670*6f9291ceSJung-uk Kim * handle two SSL_SESSION structures with identical session ID in the 671*6f9291ceSJung-uk Kim * same cache, which could happen e.g. when two threads concurrently 672*6f9291ceSJung-uk Kim * obtain the same session from an external cache) 673*6f9291ceSJung-uk Kim */ 674f579bf8eSKris Kennaway s = NULL; 675f579bf8eSKris Kennaway } 676f579bf8eSKris Kennaway 677f579bf8eSKris Kennaway /* Put at the head of the queue unless it is already in the cache */ 67874664626SKris Kennaway if (s == NULL) 67974664626SKris Kennaway SSL_SESSION_list_add(ctx, c); 68074664626SKris Kennaway 681*6f9291ceSJung-uk Kim if (s != NULL) { 682*6f9291ceSJung-uk Kim /* 683*6f9291ceSJung-uk Kim * existing cache entry -- decrement previously incremented reference 684*6f9291ceSJung-uk Kim * count because it already takes into account the cache 685*6f9291ceSJung-uk Kim */ 686f579bf8eSKris Kennaway 687f579bf8eSKris Kennaway SSL_SESSION_free(s); /* s == c */ 68874664626SKris Kennaway ret = 0; 689*6f9291ceSJung-uk Kim } else { 690*6f9291ceSJung-uk Kim /* 691*6f9291ceSJung-uk Kim * new cache entry -- remove old ones if cache has become too large 692*6f9291ceSJung-uk Kim */ 693f579bf8eSKris Kennaway 69474664626SKris Kennaway ret = 1; 69574664626SKris Kennaway 696*6f9291ceSJung-uk Kim if (SSL_CTX_sess_get_cache_size(ctx) > 0) { 69774664626SKris Kennaway while (SSL_CTX_sess_number(ctx) > 698*6f9291ceSJung-uk Kim SSL_CTX_sess_get_cache_size(ctx)) { 699*6f9291ceSJung-uk Kim if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) 70074664626SKris Kennaway break; 70174664626SKris Kennaway else 70274664626SKris Kennaway ctx->stats.sess_cache_full++; 70374664626SKris Kennaway } 70474664626SKris Kennaway } 70574664626SKris Kennaway } 70674664626SKris Kennaway CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 70774664626SKris Kennaway return (ret); 70874664626SKris Kennaway } 70974664626SKris Kennaway 71074664626SKris Kennaway int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) 71174664626SKris Kennaway { 71274664626SKris Kennaway return remove_session_lock(ctx, c, 1); 71374664626SKris Kennaway } 71474664626SKris Kennaway 71574664626SKris Kennaway static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) 71674664626SKris Kennaway { 71774664626SKris Kennaway SSL_SESSION *r; 71874664626SKris Kennaway int ret = 0; 71974664626SKris Kennaway 720*6f9291ceSJung-uk Kim if ((c != NULL) && (c->session_id_length != 0)) { 721*6f9291ceSJung-uk Kim if (lck) 722*6f9291ceSJung-uk Kim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 723*6f9291ceSJung-uk Kim if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { 72474664626SKris Kennaway ret = 1; 7251f13597dSJung-uk Kim r = lh_SSL_SESSION_delete(ctx->sessions, c); 72674664626SKris Kennaway SSL_SESSION_list_remove(ctx, c); 72774664626SKris Kennaway } 72874664626SKris Kennaway 729*6f9291ceSJung-uk Kim if (lck) 730*6f9291ceSJung-uk Kim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 73174664626SKris Kennaway 732*6f9291ceSJung-uk Kim if (ret) { 73374664626SKris Kennaway r->not_resumable = 1; 73474664626SKris Kennaway if (ctx->remove_session_cb != NULL) 73574664626SKris Kennaway ctx->remove_session_cb(ctx, r); 73674664626SKris Kennaway SSL_SESSION_free(r); 73774664626SKris Kennaway } 738*6f9291ceSJung-uk Kim } else 73974664626SKris Kennaway ret = 0; 74074664626SKris Kennaway return (ret); 74174664626SKris Kennaway } 74274664626SKris Kennaway 74374664626SKris Kennaway void SSL_SESSION_free(SSL_SESSION *ss) 74474664626SKris Kennaway { 74574664626SKris Kennaway int i; 74674664626SKris Kennaway 74774664626SKris Kennaway if (ss == NULL) 74874664626SKris Kennaway return; 74974664626SKris Kennaway 75074664626SKris Kennaway i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); 75174664626SKris Kennaway #ifdef REF_PRINT 75274664626SKris Kennaway REF_PRINT("SSL_SESSION", ss); 75374664626SKris Kennaway #endif 754*6f9291ceSJung-uk Kim if (i > 0) 755*6f9291ceSJung-uk Kim return; 75674664626SKris Kennaway #ifdef REF_CHECK 757*6f9291ceSJung-uk Kim if (i < 0) { 75874664626SKris Kennaway fprintf(stderr, "SSL_SESSION_free, bad reference count\n"); 75974664626SKris Kennaway abort(); /* ok */ 76074664626SKris Kennaway } 76174664626SKris Kennaway #endif 76274664626SKris Kennaway 7635c87c606SMark Murray CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); 76474664626SKris Kennaway 7655c87c606SMark Murray OPENSSL_cleanse(ss->key_arg, sizeof ss->key_arg); 7665c87c606SMark Murray OPENSSL_cleanse(ss->master_key, sizeof ss->master_key); 7675c87c606SMark Murray OPENSSL_cleanse(ss->session_id, sizeof ss->session_id); 768*6f9291ceSJung-uk Kim if (ss->sess_cert != NULL) 769*6f9291ceSJung-uk Kim ssl_sess_cert_free(ss->sess_cert); 770*6f9291ceSJung-uk Kim if (ss->peer != NULL) 771*6f9291ceSJung-uk Kim X509_free(ss->peer); 772*6f9291ceSJung-uk Kim if (ss->ciphers != NULL) 773*6f9291ceSJung-uk Kim sk_SSL_CIPHER_free(ss->ciphers); 774db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT 775*6f9291ceSJung-uk Kim if (ss->tlsext_hostname != NULL) 776*6f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_hostname); 777*6f9291ceSJung-uk Kim if (ss->tlsext_tick != NULL) 778*6f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_tick); 7791f13597dSJung-uk Kim # ifndef OPENSSL_NO_EC 7801f13597dSJung-uk Kim ss->tlsext_ecpointformatlist_length = 0; 781*6f9291ceSJung-uk Kim if (ss->tlsext_ecpointformatlist != NULL) 782*6f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_ecpointformatlist); 7831f13597dSJung-uk Kim ss->tlsext_ellipticcurvelist_length = 0; 784*6f9291ceSJung-uk Kim if (ss->tlsext_ellipticcurvelist != NULL) 785*6f9291ceSJung-uk Kim OPENSSL_free(ss->tlsext_ellipticcurvelist); 7861f13597dSJung-uk Kim # endif /* OPENSSL_NO_EC */ 7871f13597dSJung-uk Kim #endif 7881f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 7891f13597dSJung-uk Kim if (ss->psk_identity_hint != NULL) 7901f13597dSJung-uk Kim OPENSSL_free(ss->psk_identity_hint); 7911f13597dSJung-uk Kim if (ss->psk_identity != NULL) 7921f13597dSJung-uk Kim OPENSSL_free(ss->psk_identity); 7931f13597dSJung-uk Kim #endif 7941f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 7951f13597dSJung-uk Kim if (ss->srp_username != NULL) 7961f13597dSJung-uk Kim OPENSSL_free(ss->srp_username); 797db522d3aSSimon L. B. Nielsen #endif 7985c87c606SMark Murray OPENSSL_cleanse(ss, sizeof(*ss)); 799ddd58736SKris Kennaway OPENSSL_free(ss); 80074664626SKris Kennaway } 80174664626SKris Kennaway 80274664626SKris Kennaway int SSL_set_session(SSL *s, SSL_SESSION *session) 80374664626SKris Kennaway { 80474664626SKris Kennaway int ret = 0; 8051f13597dSJung-uk Kim const SSL_METHOD *meth; 80674664626SKris Kennaway 807*6f9291ceSJung-uk Kim if (session != NULL) { 80874664626SKris Kennaway meth = s->ctx->method->get_ssl_method(session->ssl_version); 80974664626SKris Kennaway if (meth == NULL) 81074664626SKris Kennaway meth = s->method->get_ssl_method(session->ssl_version); 811*6f9291ceSJung-uk Kim if (meth == NULL) { 81274664626SKris Kennaway SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD); 81374664626SKris Kennaway return (0); 81474664626SKris Kennaway } 81574664626SKris Kennaway 816*6f9291ceSJung-uk Kim if (meth != s->method) { 81774664626SKris Kennaway if (!SSL_set_ssl_method(s, meth)) 81874664626SKris Kennaway return (0); 81974664626SKris Kennaway } 8205c87c606SMark Murray #ifndef OPENSSL_NO_KRB5 8215c87c606SMark Murray if (s->kssl_ctx && !s->kssl_ctx->client_princ && 822*6f9291ceSJung-uk Kim session->krb5_client_princ_len > 0) { 823*6f9291ceSJung-uk Kim s->kssl_ctx->client_princ = 824*6f9291ceSJung-uk Kim (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); 8255c87c606SMark Murray memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, 8265c87c606SMark Murray session->krb5_client_princ_len); 8275c87c606SMark Murray s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; 8285c87c606SMark Murray } 8295c87c606SMark Murray #endif /* OPENSSL_NO_KRB5 */ 8305c87c606SMark Murray 83174664626SKris Kennaway /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ 83274664626SKris Kennaway CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); 83374664626SKris Kennaway if (s->session != NULL) 83474664626SKris Kennaway SSL_SESSION_free(s->session); 83574664626SKris Kennaway s->session = session; 836de7cdddaSKris Kennaway s->verify_result = s->session->verify_result; 83774664626SKris Kennaway /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ 83874664626SKris Kennaway ret = 1; 839*6f9291ceSJung-uk Kim } else { 840*6f9291ceSJung-uk Kim if (s->session != NULL) { 84174664626SKris Kennaway SSL_SESSION_free(s->session); 84274664626SKris Kennaway s->session = NULL; 84374664626SKris Kennaway } 84474664626SKris Kennaway 84574664626SKris Kennaway meth = s->ctx->method; 846*6f9291ceSJung-uk Kim if (meth != s->method) { 84774664626SKris Kennaway if (!SSL_set_ssl_method(s, meth)) 84874664626SKris Kennaway return (0); 84974664626SKris Kennaway } 85074664626SKris Kennaway ret = 1; 85174664626SKris Kennaway } 85274664626SKris Kennaway return (ret); 85374664626SKris Kennaway } 85474664626SKris Kennaway 85574664626SKris Kennaway long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) 85674664626SKris Kennaway { 857*6f9291ceSJung-uk Kim if (s == NULL) 858*6f9291ceSJung-uk Kim return (0); 85974664626SKris Kennaway s->timeout = t; 86074664626SKris Kennaway return (1); 86174664626SKris Kennaway } 86274664626SKris Kennaway 8633b4e3dcbSSimon L. B. Nielsen long SSL_SESSION_get_timeout(const SSL_SESSION *s) 86474664626SKris Kennaway { 865*6f9291ceSJung-uk Kim if (s == NULL) 866*6f9291ceSJung-uk Kim return (0); 86774664626SKris Kennaway return (s->timeout); 86874664626SKris Kennaway } 86974664626SKris Kennaway 8703b4e3dcbSSimon L. B. Nielsen long SSL_SESSION_get_time(const SSL_SESSION *s) 87174664626SKris Kennaway { 872*6f9291ceSJung-uk Kim if (s == NULL) 873*6f9291ceSJung-uk Kim return (0); 87474664626SKris Kennaway return (s->time); 87574664626SKris Kennaway } 87674664626SKris Kennaway 87774664626SKris Kennaway long SSL_SESSION_set_time(SSL_SESSION *s, long t) 87874664626SKris Kennaway { 879*6f9291ceSJung-uk Kim if (s == NULL) 880*6f9291ceSJung-uk Kim return (0); 88174664626SKris Kennaway s->time = t; 88274664626SKris Kennaway return (t); 88374664626SKris Kennaway } 88474664626SKris Kennaway 8851f13597dSJung-uk Kim X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) 8861f13597dSJung-uk Kim { 8871f13597dSJung-uk Kim return s->peer; 8881f13597dSJung-uk Kim } 8891f13597dSJung-uk Kim 8901f13597dSJung-uk Kim int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, 8911f13597dSJung-uk Kim unsigned int sid_ctx_len) 8921f13597dSJung-uk Kim { 893*6f9291ceSJung-uk Kim if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { 894*6f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, 895*6f9291ceSJung-uk Kim SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); 8961f13597dSJung-uk Kim return 0; 8971f13597dSJung-uk Kim } 8981f13597dSJung-uk Kim s->sid_ctx_length = sid_ctx_len; 8991f13597dSJung-uk Kim memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); 9001f13597dSJung-uk Kim 9011f13597dSJung-uk Kim return 1; 9021f13597dSJung-uk Kim } 9031f13597dSJung-uk Kim 90474664626SKris Kennaway long SSL_CTX_set_timeout(SSL_CTX *s, long t) 90574664626SKris Kennaway { 90674664626SKris Kennaway long l; 907*6f9291ceSJung-uk Kim if (s == NULL) 908*6f9291ceSJung-uk Kim return (0); 90974664626SKris Kennaway l = s->session_timeout; 91074664626SKris Kennaway s->session_timeout = t; 91174664626SKris Kennaway return (l); 91274664626SKris Kennaway } 91374664626SKris Kennaway 9143b4e3dcbSSimon L. B. Nielsen long SSL_CTX_get_timeout(const SSL_CTX *s) 91574664626SKris Kennaway { 916*6f9291ceSJung-uk Kim if (s == NULL) 917*6f9291ceSJung-uk Kim return (0); 91874664626SKris Kennaway return (s->session_timeout); 91974664626SKris Kennaway } 92074664626SKris Kennaway 9211f13597dSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT 922*6f9291ceSJung-uk Kim int SSL_set_session_secret_cb(SSL *s, 923*6f9291ceSJung-uk Kim int (*tls_session_secret_cb) (SSL *s, 924*6f9291ceSJung-uk Kim void *secret, 925*6f9291ceSJung-uk Kim int *secret_len, 926*6f9291ceSJung-uk Kim STACK_OF(SSL_CIPHER) 927*6f9291ceSJung-uk Kim *peer_ciphers, 928*6f9291ceSJung-uk Kim SSL_CIPHER 929*6f9291ceSJung-uk Kim **cipher, 930*6f9291ceSJung-uk Kim void *arg), 931*6f9291ceSJung-uk Kim void *arg) 9321f13597dSJung-uk Kim { 933*6f9291ceSJung-uk Kim if (s == NULL) 934*6f9291ceSJung-uk Kim return (0); 9351f13597dSJung-uk Kim s->tls_session_secret_cb = tls_session_secret_cb; 9361f13597dSJung-uk Kim s->tls_session_secret_cb_arg = arg; 9371f13597dSJung-uk Kim return (1); 9381f13597dSJung-uk Kim } 9391f13597dSJung-uk Kim 9401f13597dSJung-uk Kim int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, 9411f13597dSJung-uk Kim void *arg) 9421f13597dSJung-uk Kim { 943*6f9291ceSJung-uk Kim if (s == NULL) 944*6f9291ceSJung-uk Kim return (0); 9451f13597dSJung-uk Kim s->tls_session_ticket_ext_cb = cb; 9461f13597dSJung-uk Kim s->tls_session_ticket_ext_cb_arg = arg; 9471f13597dSJung-uk Kim return (1); 9481f13597dSJung-uk Kim } 9491f13597dSJung-uk Kim 9501f13597dSJung-uk Kim int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) 9511f13597dSJung-uk Kim { 952*6f9291ceSJung-uk Kim if (s->version >= TLS1_VERSION) { 953*6f9291ceSJung-uk Kim if (s->tlsext_session_ticket) { 9541f13597dSJung-uk Kim OPENSSL_free(s->tlsext_session_ticket); 9551f13597dSJung-uk Kim s->tlsext_session_ticket = NULL; 9561f13597dSJung-uk Kim } 9571f13597dSJung-uk Kim 958*6f9291ceSJung-uk Kim s->tlsext_session_ticket = 959*6f9291ceSJung-uk Kim OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); 960*6f9291ceSJung-uk Kim if (!s->tlsext_session_ticket) { 9611f13597dSJung-uk Kim SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); 9621f13597dSJung-uk Kim return 0; 9631f13597dSJung-uk Kim } 9641f13597dSJung-uk Kim 965*6f9291ceSJung-uk Kim if (ext_data) { 9661f13597dSJung-uk Kim s->tlsext_session_ticket->length = ext_len; 9671f13597dSJung-uk Kim s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; 9681f13597dSJung-uk Kim memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); 969*6f9291ceSJung-uk Kim } else { 9701f13597dSJung-uk Kim s->tlsext_session_ticket->length = 0; 9711f13597dSJung-uk Kim s->tlsext_session_ticket->data = NULL; 9721f13597dSJung-uk Kim } 9731f13597dSJung-uk Kim 9741f13597dSJung-uk Kim return 1; 9751f13597dSJung-uk Kim } 9761f13597dSJung-uk Kim 9771f13597dSJung-uk Kim return 0; 9781f13597dSJung-uk Kim } 9791f13597dSJung-uk Kim #endif /* OPENSSL_NO_TLSEXT */ 9801f13597dSJung-uk Kim 981*6f9291ceSJung-uk Kim typedef struct timeout_param_st { 98274664626SKris Kennaway SSL_CTX *ctx; 98374664626SKris Kennaway long time; 9841f13597dSJung-uk Kim LHASH_OF(SSL_SESSION) *cache; 98574664626SKris Kennaway } TIMEOUT_PARAM; 98674664626SKris Kennaway 9871f13597dSJung-uk Kim static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) 98874664626SKris Kennaway { 989*6f9291ceSJung-uk Kim if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ 990*6f9291ceSJung-uk Kim /* 991*6f9291ceSJung-uk Kim * The reason we don't call SSL_CTX_remove_session() is to save on 992*6f9291ceSJung-uk Kim * locking overhead 993*6f9291ceSJung-uk Kim */ 9941f13597dSJung-uk Kim (void)lh_SSL_SESSION_delete(p->cache, s); 99574664626SKris Kennaway SSL_SESSION_list_remove(p->ctx, s); 99674664626SKris Kennaway s->not_resumable = 1; 99774664626SKris Kennaway if (p->ctx->remove_session_cb != NULL) 99874664626SKris Kennaway p->ctx->remove_session_cb(p->ctx, s); 99974664626SKris Kennaway SSL_SESSION_free(s); 100074664626SKris Kennaway } 100174664626SKris Kennaway } 100274664626SKris Kennaway 10031f13597dSJung-uk Kim static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) 10045c87c606SMark Murray 100574664626SKris Kennaway void SSL_CTX_flush_sessions(SSL_CTX *s, long t) 100674664626SKris Kennaway { 100774664626SKris Kennaway unsigned long i; 100874664626SKris Kennaway TIMEOUT_PARAM tp; 100974664626SKris Kennaway 101074664626SKris Kennaway tp.ctx = s; 101174664626SKris Kennaway tp.cache = s->sessions; 1012*6f9291ceSJung-uk Kim if (tp.cache == NULL) 1013*6f9291ceSJung-uk Kim return; 101474664626SKris Kennaway tp.time = t; 101574664626SKris Kennaway CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 10161f13597dSJung-uk Kim i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; 10171f13597dSJung-uk Kim CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; 10181f13597dSJung-uk Kim lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), 10191f13597dSJung-uk Kim TIMEOUT_PARAM, &tp); 10201f13597dSJung-uk Kim CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; 102174664626SKris Kennaway CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 102274664626SKris Kennaway } 102374664626SKris Kennaway 102474664626SKris Kennaway int ssl_clear_bad_session(SSL *s) 102574664626SKris Kennaway { 102674664626SKris Kennaway if ((s->session != NULL) && 102774664626SKris Kennaway !(s->shutdown & SSL_SENT_SHUTDOWN) && 1028*6f9291ceSJung-uk Kim !(SSL_in_init(s) || SSL_in_before(s))) { 102974664626SKris Kennaway SSL_CTX_remove_session(s->ctx, s->session); 103074664626SKris Kennaway return (1); 1031*6f9291ceSJung-uk Kim } else 103274664626SKris Kennaway return (0); 103374664626SKris Kennaway } 103474664626SKris Kennaway 103574664626SKris Kennaway /* locked by SSL_CTX in the calling function */ 103674664626SKris Kennaway static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) 103774664626SKris Kennaway { 1038*6f9291ceSJung-uk Kim if ((s->next == NULL) || (s->prev == NULL)) 1039*6f9291ceSJung-uk Kim return; 104074664626SKris Kennaway 1041*6f9291ceSJung-uk Kim if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { 1042*6f9291ceSJung-uk Kim /* last element in list */ 1043*6f9291ceSJung-uk Kim if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { 1044*6f9291ceSJung-uk Kim /* only one element in list */ 104574664626SKris Kennaway ctx->session_cache_head = NULL; 104674664626SKris Kennaway ctx->session_cache_tail = NULL; 1047*6f9291ceSJung-uk Kim } else { 104874664626SKris Kennaway ctx->session_cache_tail = s->prev; 104974664626SKris Kennaway s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); 105074664626SKris Kennaway } 1051*6f9291ceSJung-uk Kim } else { 1052*6f9291ceSJung-uk Kim if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { 1053*6f9291ceSJung-uk Kim /* first element in list */ 105474664626SKris Kennaway ctx->session_cache_head = s->next; 105574664626SKris Kennaway s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); 1056*6f9291ceSJung-uk Kim } else { 1057*6f9291ceSJung-uk Kim /* middle of list */ 105874664626SKris Kennaway s->next->prev = s->prev; 105974664626SKris Kennaway s->prev->next = s->next; 106074664626SKris Kennaway } 106174664626SKris Kennaway } 106274664626SKris Kennaway s->prev = s->next = NULL; 106374664626SKris Kennaway } 106474664626SKris Kennaway 106574664626SKris Kennaway static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) 106674664626SKris Kennaway { 106774664626SKris Kennaway if ((s->next != NULL) && (s->prev != NULL)) 106874664626SKris Kennaway SSL_SESSION_list_remove(ctx, s); 106974664626SKris Kennaway 1070*6f9291ceSJung-uk Kim if (ctx->session_cache_head == NULL) { 107174664626SKris Kennaway ctx->session_cache_head = s; 107274664626SKris Kennaway ctx->session_cache_tail = s; 107374664626SKris Kennaway s->prev = (SSL_SESSION *)&(ctx->session_cache_head); 107474664626SKris Kennaway s->next = (SSL_SESSION *)&(ctx->session_cache_tail); 1075*6f9291ceSJung-uk Kim } else { 107674664626SKris Kennaway s->next = ctx->session_cache_head; 107774664626SKris Kennaway s->next->prev = s; 107874664626SKris Kennaway s->prev = (SSL_SESSION *)&(ctx->session_cache_head); 107974664626SKris Kennaway ctx->session_cache_head = s; 108074664626SKris Kennaway } 108174664626SKris Kennaway } 108274664626SKris Kennaway 10835471f83eSSimon L. B. Nielsen void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, 1084*6f9291ceSJung-uk Kim int (*cb) (struct ssl_st *ssl, 1085*6f9291ceSJung-uk Kim SSL_SESSION *sess)) 10865471f83eSSimon L. B. Nielsen { 10875471f83eSSimon L. B. Nielsen ctx->new_session_cb = cb; 10885471f83eSSimon L. B. Nielsen } 10895471f83eSSimon L. B. Nielsen 1090*6f9291ceSJung-uk Kim int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { 10915471f83eSSimon L. B. Nielsen return ctx->new_session_cb; 10925471f83eSSimon L. B. Nielsen } 10935471f83eSSimon L. B. Nielsen 10945471f83eSSimon L. B. Nielsen void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, 10955471f83eSSimon L. B. Nielsen void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess)) 10965471f83eSSimon L. B. Nielsen { 10975471f83eSSimon L. B. Nielsen ctx->remove_session_cb = cb; 10985471f83eSSimon L. B. Nielsen } 10995471f83eSSimon L. B. Nielsen 1100*6f9291ceSJung-uk Kim void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, 1101*6f9291ceSJung-uk Kim SSL_SESSION *sess) { 11025471f83eSSimon L. B. Nielsen return ctx->remove_session_cb; 11035471f83eSSimon L. B. Nielsen } 11045471f83eSSimon L. B. Nielsen 11055471f83eSSimon L. B. Nielsen void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, 11065471f83eSSimon L. B. Nielsen SSL_SESSION *(*cb) (struct ssl_st *ssl, 1107*6f9291ceSJung-uk Kim unsigned char *data, int len, 1108*6f9291ceSJung-uk Kim int *copy)) 11095471f83eSSimon L. B. Nielsen { 11105471f83eSSimon L. B. Nielsen ctx->get_session_cb = cb; 11115471f83eSSimon L. B. Nielsen } 11125471f83eSSimon L. B. Nielsen 11135471f83eSSimon L. B. Nielsen SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl, 1114*6f9291ceSJung-uk Kim unsigned char *data, 1115*6f9291ceSJung-uk Kim int len, int *copy) { 11165471f83eSSimon L. B. Nielsen return ctx->get_session_cb; 11175471f83eSSimon L. B. Nielsen } 11185471f83eSSimon L. B. Nielsen 11195471f83eSSimon L. B. Nielsen void SSL_CTX_set_info_callback(SSL_CTX *ctx, 11205471f83eSSimon L. B. Nielsen void (*cb) (const SSL *ssl, int type, int val)) 11215471f83eSSimon L. B. Nielsen { 11225471f83eSSimon L. B. Nielsen ctx->info_callback = cb; 11235471f83eSSimon L. B. Nielsen } 11245471f83eSSimon L. B. Nielsen 1125*6f9291ceSJung-uk Kim void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, 1126*6f9291ceSJung-uk Kim int val) { 11275471f83eSSimon L. B. Nielsen return ctx->info_callback; 11285471f83eSSimon L. B. Nielsen } 11295471f83eSSimon L. B. Nielsen 11305471f83eSSimon L. B. Nielsen void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, 1131*6f9291ceSJung-uk Kim int (*cb) (SSL *ssl, X509 **x509, 1132*6f9291ceSJung-uk Kim EVP_PKEY **pkey)) 11335471f83eSSimon L. B. Nielsen { 11345471f83eSSimon L. B. Nielsen ctx->client_cert_cb = cb; 11355471f83eSSimon L. B. Nielsen } 11365471f83eSSimon L. B. Nielsen 1137*6f9291ceSJung-uk Kim int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, 1138*6f9291ceSJung-uk Kim EVP_PKEY **pkey) { 11395471f83eSSimon L. B. Nielsen return ctx->client_cert_cb; 11405471f83eSSimon L. B. Nielsen } 11415471f83eSSimon L. B. Nielsen 1142db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_ENGINE 1143db522d3aSSimon L. B. Nielsen int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) 1144db522d3aSSimon L. B. Nielsen { 1145*6f9291ceSJung-uk Kim if (!ENGINE_init(e)) { 1146db522d3aSSimon L. B. Nielsen SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); 1147db522d3aSSimon L. B. Nielsen return 0; 1148db522d3aSSimon L. B. Nielsen } 1149*6f9291ceSJung-uk Kim if (!ENGINE_get_ssl_client_cert_function(e)) { 1150*6f9291ceSJung-uk Kim SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, 1151*6f9291ceSJung-uk Kim SSL_R_NO_CLIENT_CERT_METHOD); 1152db522d3aSSimon L. B. Nielsen ENGINE_finish(e); 1153db522d3aSSimon L. B. Nielsen return 0; 1154db522d3aSSimon L. B. Nielsen } 1155db522d3aSSimon L. B. Nielsen ctx->client_cert_engine = e; 1156db522d3aSSimon L. B. Nielsen return 1; 1157db522d3aSSimon L. B. Nielsen } 1158db522d3aSSimon L. B. Nielsen #endif 1159db522d3aSSimon L. B. Nielsen 11605471f83eSSimon L. B. Nielsen void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, 1161*6f9291ceSJung-uk Kim int (*cb) (SSL *ssl, 1162*6f9291ceSJung-uk Kim unsigned char *cookie, 1163*6f9291ceSJung-uk Kim unsigned int *cookie_len)) 11645471f83eSSimon L. B. Nielsen { 11655471f83eSSimon L. B. Nielsen ctx->app_gen_cookie_cb = cb; 11665471f83eSSimon L. B. Nielsen } 11675471f83eSSimon L. B. Nielsen 11685471f83eSSimon L. B. Nielsen void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, 1169*6f9291ceSJung-uk Kim int (*cb) (SSL *ssl, unsigned char *cookie, 1170*6f9291ceSJung-uk Kim unsigned int cookie_len)) 11715471f83eSSimon L. B. Nielsen { 11725471f83eSSimon L. B. Nielsen ctx->app_verify_cookie_cb = cb; 11735471f83eSSimon L. B. Nielsen } 11745471f83eSSimon L. B. Nielsen 1175*6f9291ceSJung-uk Kim IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, 1176*6f9291ceSJung-uk Kim SSL_SESSION) 1177