1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved.
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com).
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL.
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to.  The following conditions
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA,
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed.
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used.
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package.
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in the
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    documentation and/or other materials provided with the distribution.
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    must display the following acknowledgement:
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes cryptographic software written by
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *     Eric Young (eay@cryptsoft.com)"
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    The word 'cryptographic' can be left out if the rouines from the library
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    being used are not cryptographic related :-).
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the apps directory (application code) you must include an acknowledgement:
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE.
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed.  i.e. this code cannot simply be
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.]
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the documentation and/or other materials provided with the
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    distribution.
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    software must display the following acknowledgment:
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    endorse or promote products derived from this software without
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    prior written permission. For written permission, please contact
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    openssl-core@openssl.org.
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL"
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    nor may "OpenSSL" appear in their names without prior written
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    permission of the OpenSSL Project.
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    acknowledgment:
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ====================================================================
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com).
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright 2005 Nokia. All rights reserved.
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The portions of the attached software ("Contribution") is developed by
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Nokia Corporation and is licensed pursuant to the OpenSSL open source
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * license.
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The Contribution, originally written by Mika Kousa and Pasi Eronen of
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * support (see RFC 4279) to OpenSSL.
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * No patent licenses or other rights except those expressly stated in
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the OpenSSL open source license shall be deemed granted or received
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * expressly, by implication, estoppel, or otherwise.
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * No assurances are provided by Nokia that the Contribution does not
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * infringe the patent or other intellectual property rights of any third
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * party or that the license provides you with all the necessary rights
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to make use of the Contribution.
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OTHERWISE. */
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdio.h>
137e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string.h>
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h>
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/lhash.h>
141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h>
142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/rand.h>
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
144e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "internal.h"
145e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../crypto/internal.h"
146e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* The address of this is a magic value, a pointer to which is returned by
149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SSL_magic_pending_session_ptr(). It allows a session callback to indicate
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * that it needs to asynchronously fetch session information. */
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char g_pending_session_magic = 0;
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
153e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
154e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
156e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
159d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_SESSION *SSL_magic_pending_session_ptr(void) {
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return (SSL_SESSION *)&g_pending_session_magic;
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
163d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_SESSION *SSL_get_session(const SSL *ssl)
164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ssl->session;
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
169d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_SESSION *SSL_get1_session(SSL *ssl) {
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* variant of SSL_get_session: caller really gets something */
171e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return SSL_SESSION_up_ref(ssl->session);
172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
174d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                 CRYPTO_EX_dup *dup_func,
176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                 CRYPTO_EX_free *free_func) {
177e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  int index;
178e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
179e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                               dup_func, free_func)) {
180e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return -1;
181e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
182e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return index;
183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) {
186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
189d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) {
190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return CRYPTO_get_ex_data(&s->ex_data, idx);
191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
193d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_SESSION *SSL_SESSION_new(void) {
194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *ss;
195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ss == NULL) {
198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(SSL, SSL_SESSION_new, ERR_R_MALLOC_FAILURE);
199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memset(ss, 0, sizeof(SSL_SESSION));
202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->references = 1;
205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->time = (unsigned long)time(NULL);
207e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  CRYPTO_new_ex_data(&g_ex_data_class, ss, &ss->ex_data);
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ss;
209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
211d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) {
212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (len) {
213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    *len = s->session_id_length;
214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return s->session_id;
216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space.
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * gunk repeatedly until we have no conflict is going to complete in one
221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * iteration pretty much "most" of the time (btw: understatement). So, if it
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * takes us 10 iterations and we still can't avoid a conflict - well that's a
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * reasonable point to call it quits. Either the RAND code is broken or someone
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * is trying to open roughly very close to 2^128 (or 2^256) SSL sessions to our
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * server. How you might store that many sessions is perhaps a more interesting
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * question ... */
227d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int def_generate_session_id(const SSL *ssl, uint8_t *id,
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                   unsigned int *id_len) {
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  static const unsigned kMaxAttempts = 10;
230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  unsigned int retry = 0;
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  do {
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!RAND_bytes(id, *id_len)) {
233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } while (SSL_has_matching_session_id(ssl, id, *id_len) &&
236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley           (++retry < kMaxAttempts));
237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (retry < kMaxAttempts) {
239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* else - woops a session_id match */
243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* XXX We should also check the external cache -- but the probability of a
244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * collision is negligible, and we could not prevent the concurrent creation
245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * of sessions with identical IDs since we currently don't have means to
246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * atomically check whether a session ID already exists and make a
247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * reservation for it if it does not (this problem applies to the internal
248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * cache as well). */
249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
252d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ssl_get_new_session(SSL *s, int session) {
253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* This gets used by clients and servers. */
254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  unsigned int tmp;
256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *ss = NULL;
257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  GEN_SESSION_CB cb = def_generate_session_id;
258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->mode & SSL_MODE_NO_SESSION_CREATION) {
260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                      SSL_R_SESSION_MAY_NOT_BE_CREATED);
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
265d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss = SSL_SESSION_new();
266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ss == NULL) {
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If the context has a default timeout, use it over the default. */
271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->initial_ctx->session_timeout != 0) {
272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ss->timeout = s->initial_ctx->session_timeout;
273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
275e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  SSL_SESSION_free(s->session);
276e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  s->session = NULL;
277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (session) {
279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (s->version == SSL3_VERSION || s->version == TLS1_VERSION ||
280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        s->version == TLS1_1_VERSION || s->version == TLS1_2_VERSION ||
281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        s->version == DTLS1_VERSION || s->version == DTLS1_2_VERSION) {
282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ss->ssl_version = s->version;
283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else {
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        SSL_R_UNSUPPORTED_SSL_VERSION);
287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_SESSION_free(ss);
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* If RFC4507 ticket use empty session ID */
292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (s->tlsext_ticket_expected) {
293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ss->session_id_length = 0;
294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto sess_id_done;
295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
296d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Choose which callback will set the session ID */
298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (s->generate_session_id) {
299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      cb = s->generate_session_id;
300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else if (s->initial_ctx->generate_session_id) {
301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      cb = s->initial_ctx->generate_session_id;
302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Choose a session ID */
305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    tmp = ss->session_id_length;
306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!cb(s, ss->session_id, &tmp)) {
307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* The callback failed */
308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_SESSION_free(ss);
311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Don't allow the callback to set the session length to zero. nor set it
315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * higher than it was. */
316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!tmp || tmp > ss->session_id_length) {
317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* The callback set an illegal length */
318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_SESSION_free(ss);
321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ss->session_id_length = tmp;
325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Finally, check for a conflict */
326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (SSL_has_matching_session_id(s, ss->session_id, ss->session_id_length)) {
327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        SSL_R_SSL_SESSION_ID_CONFLICT);
329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_SESSION_free(ss);
330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  sess_id_done:
334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (s->tlsext_hostname) {
335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (ss->tlsext_hostname == NULL) {
337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        SSL_SESSION_free(ss);
339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        return 0;
340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ss->session_id_length = 0;
344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->sid_ctx_length > sizeof(ss->sid_ctx)) {
347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
348d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_free(ss);
349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->sid_ctx_length = s->sid_ctx_length;
354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->session = ss;
355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->ssl_version = s->version;
356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ss->verify_result = X509_V_OK;
357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * connection. It is only called by servers.
363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *   ctx: contains the early callback context, which is the result of a
365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *       shallow parse of the ClientHello.
366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Returns:
368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *   -1: error
369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    0: a session may have been found.
370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Side effects:
372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *   - If a session is found then s->session is pointed at it (after freeing an
373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *     existing session if need be) and s->verify_result is set from the session.
374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *   - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *     if the server should issue a new session ticket (to 0 otherwise). */
376d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx) {
377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* This is used only by servers. */
378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *ret = NULL;
379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int fatal = 0;
380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int try_session_cache = 1;
381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int r;
382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->session_id_len == 0) {
388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    try_session_cache = 0;
389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  r = tls1_process_ticket(s, ctx, &ret); /* sets s->tlsext_ticket_expected */
392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  switch (r) {
393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case -1: /* Error during processing */
394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      fatal = 1;
395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case 0:  /* No ticket found */
398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case 1:  /* Zero length ticket found */
399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      break; /* Ok to carry on processing session id. */
400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case 2:  /* Ticket found but not decrypted. */
402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case 3:  /* Ticket decrypted, *ret has been set. */
403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      try_session_cache = 0;
404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      break;
405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    default:
407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      abort();
408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (try_session_cache && ret == NULL &&
411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !(s->initial_ctx->session_cache_mode &
412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION data;
414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    data.ssl_version = s->version;
415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    data.session_id_length = ctx->session_id_len;
416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (ctx->session_id_len == 0) {
417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    memcpy(data.session_id, ctx->session_id, ctx->session_id_len);
42053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley
42153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    CRYPTO_MUTEX_lock_read(&s->initial_ctx->lock);
42253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    ret = lh_SSL_SESSION_retrieve(s->initial_ctx->sessions, &data);
42353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    CRYPTO_MUTEX_unlock(&s->initial_ctx->lock);
42453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley
42553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    if (ret != NULL) {
42653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley      SSL_SESSION_up_ref(ret);
42753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    }
428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (try_session_cache && ret == NULL &&
431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      s->initial_ctx->get_session_cb != NULL) {
432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    int copy = 1;
433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ret = s->initial_ctx->get_session_cb(s, (uint8_t *)ctx->session_id,
435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                         ctx->session_id_len, &copy);
436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (ret != NULL) {
437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (ret == SSL_magic_pending_session_ptr()) {
438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        /* This is a magic value which indicates that the callback needs to
439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley         * unwind the stack and figure out the session asynchronously. */
440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        return PENDING_SESSION;
441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* Increment reference count now if the session callback asks us to do so
444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * (note that if the session structures returned by the callback are
445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * shared between threads, it must handle the reference count itself
446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * [i.e. copy == 0], or things won't be thread-safe). */
447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (copy) {
448e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley        SSL_SESSION_up_ref(ret);
449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* Add the externally cached session to the internal cache as well if and
452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * only if we are supposed to. */
453d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (!(s->initial_ctx->session_cache_mode &
454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley            SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        /* The following should not return 1, otherwise, things are very
456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley         * strange */
457d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        SSL_CTX_add_session(s->initial_ctx, ret);
458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ret == NULL) {
463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Now ret is non-NULL and we own one of its reference counts. */
467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ret->sid_ctx_length != s->sid_ctx_length ||
469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* We have the session requested by the client, but we don't want to use it
471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * in this context. */
472d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err; /* treat like cache miss */
473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
475d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* We can't be sure if this session is being used out of context, which is
477d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * especially important for SSL_VERIFY_PEER. The application should have
478d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * used SSL[_CTX]_set_session_id_context.
479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     *
480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * For this error case, we generate an error instead of treating the event
481d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * like a cache miss (otherwise it would be easy for applications to
482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * effectively disable the session cache by accident without anyone
483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * noticing). */
484d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(SSL, ssl_get_prev_session,
485d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                      SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
486d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fatal = 1;
487d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
488d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
489d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
490d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ret->timeout < (long)(time(NULL) - ret->time)) {
491d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* timeout */
492d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (try_session_cache) {
493d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* session was from the cache, so remove it */
494d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_CTX_remove_session(s->initial_ctx, ret);
495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
497d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
498d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
499e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  SSL_SESSION_free(s->session);
500d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->session = ret;
501d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->verify_result = s->session->verify_result;
502d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
503d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
504d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
505d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ret != NULL) {
506d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_free(ret);
507d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!try_session_cache) {
508d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* The session was from a ticket, so we should
509d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * issue a ticket for the new session */
510d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      s->tlsext_ticket_expected = 1;
511d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
512d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
513d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (fatal) {
514d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return -1;
515d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
516d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
517d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
518d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
519d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
520d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = 0;
521d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *s;
522d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
523d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* add just 1 reference count for the SSL_CTX's session cache even though it
524d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * has two ways of access: each session is in a doubly linked list and an
525d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * lhash */
526e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  SSL_SESSION_up_ref(c);
527d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* if session c is in already in cache, we take back the increment later */
528d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
52953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  CRYPTO_MUTEX_lock_write(&ctx->lock);
530d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
53153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    CRYPTO_MUTEX_unlock(&ctx->lock);
532d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
533d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
534d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
535d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* s != NULL iff we already had a session with the given PID. In this case, s
536d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * == c should hold (then we did not really modify ctx->sessions), or we're
537d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * in trouble. */
538d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s != NULL && s != c) {
539d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* We *are* in trouble ... */
540d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_list_remove(ctx, s);
541d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_free(s);
542d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* ... so pretend the other session did not exist in cache (we cannot
543d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * handle two SSL_SESSION structures with identical session ID in the same
544d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * cache, which could happen e.g. when two threads concurrently obtain the
545d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * same session from an external cache) */
546d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s = NULL;
547d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
548d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
549d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Put at the head of the queue unless it is already in the cache */
550d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
551d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_list_add(ctx, c);
552d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
553d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
554d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s != NULL) {
555d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* existing cache entry -- decrement previously incremented reference count
556d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * because it already takes into account the cache */
557d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_free(s); /* s == c */
558d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ret = 0;
559d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
560d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* new cache entry -- remove old ones if cache has become too large */
561d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ret = 1;
562d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
563d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
564d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
565d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
566d9e397b599b13d642138480a28c14db7a136bf0Adam Langley          break;
567d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        }
568d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
569d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
570d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
571d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
57253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  CRYPTO_MUTEX_unlock(&ctx->lock);
573d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
574d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
575d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
576d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) {
577d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return remove_session_lock(ctx, c, 1);
578d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
579d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
580d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
581d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *r;
582d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = 0;
583d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
584d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (c != NULL && c->session_id_length != 0) {
585d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (lock) {
58653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley      CRYPTO_MUTEX_lock_write(&ctx->lock);
587d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
588d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    r = lh_SSL_SESSION_retrieve(ctx->sessions, c);
589d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (r == c) {
590d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ret = 1;
591d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      r = lh_SSL_SESSION_delete(ctx->sessions, c);
592d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_SESSION_list_remove(ctx, c);
593d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
594d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
595d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (lock) {
59653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley      CRYPTO_MUTEX_unlock(&ctx->lock);
597d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
598d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
599d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (ret) {
600d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      r->not_resumable = 1;
601d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (ctx->remove_session_cb != NULL) {
602d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        ctx->remove_session_cb(ctx, r);
603d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
604d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      SSL_SESSION_free(r);
605d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
606d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
607d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
608d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
609d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
610d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
611e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam LangleySSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
612e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (session) {
61353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    CRYPTO_refcount_inc(&session->references);
614d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
615e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return session;
616e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
617d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
618e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_SESSION_free(SSL_SESSION *session) {
619e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (session == NULL ||
62053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley      !CRYPTO_refcount_dec_and_test_zero(&session->references)) {
621d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
622d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
623d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
624e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data);
625d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
626e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
627e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
628e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl_sess_cert_free(session->sess_cert);
629e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  X509_free(session->peer);
630e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(session->tlsext_hostname);
631e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(session->tlsext_tick);
632e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(session->tlsext_signed_cert_timestamp_list);
633e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(session->ocsp_response);
634e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(session->psk_identity);
635e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_cleanse(session, sizeof(*session));
636e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(session);
637d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
638d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
639d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_set_session(SSL *s, SSL_SESSION *session) {
640d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->session == session) {
641d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
642d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
643d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
644e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  SSL_SESSION_free(s->session);
645d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->session = session;
646d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (session != NULL) {
647e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    SSL_SESSION_up_ref(session);
648d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s->verify_result = session->verify_result;
649d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
650d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
651d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
652d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
653d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
654d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_SESSION_set_timeout(SSL_SESSION *s, long t) {
655d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
656d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
657d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
658d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
659d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->timeout = t;
660d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
661d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
662d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
663d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_SESSION_get_timeout(const SSL_SESSION *s) {
664d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
665d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
666d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
667d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
668d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return s->timeout;
669d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
670d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
671d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_SESSION_get_time(const SSL_SESSION *s) {
672d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
673d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
674d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
675d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
676d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return s->time;
677d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
678d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
679d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_SESSION_set_time(SSL_SESSION *s, long t) {
680d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
681d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
682d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
683d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
684d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->time = t;
685d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return t;
686d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
687d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
688d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyX509 *SSL_SESSION_get0_peer(SSL_SESSION *s) { return s->peer; }
689d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
690d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_SESSION_set1_id_context(SSL_SESSION *s, const uint8_t *sid_ctx,
691d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                unsigned int sid_ctx_len) {
692d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
693d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_PUT_ERROR(SSL, SSL_SESSION_set1_id_context,
694d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                      SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
695d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
696d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
697d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
698d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->sid_ctx_length = sid_ctx_len;
699d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
700d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
701d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
702d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
703d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
704d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_CTX_set_timeout(SSL_CTX *s, long t) {
705d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  long l;
706d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
707d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
708d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
709d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
710d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  l = s->session_timeout;
711d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->session_timeout = t;
712d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return l;
713d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
714d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
715d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_CTX_get_timeout(const SSL_CTX *s) {
716d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s == NULL) {
717d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
718d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
719d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
720d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return s->session_timeout;
721d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
722d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
723d9e397b599b13d642138480a28c14db7a136bf0Adam Langleytypedef struct timeout_param_st {
724d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_CTX *ctx;
725d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  long time;
726e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  LHASH_OF(SSL_SESSION) *cache;
727d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} TIMEOUT_PARAM;
728d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
729d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void timeout_doall_arg(SSL_SESSION *sess, void *void_param) {
730d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  TIMEOUT_PARAM *param = void_param;
731d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
732d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (param->time == 0 ||
733d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      param->time > (sess->time + sess->timeout)) {
734d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* timeout */
735d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* The reason we don't call SSL_CTX_remove_session() is to
736d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     * save on locking overhead */
737d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    (void) lh_SSL_SESSION_delete(param->cache, sess);
738d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_list_remove(param->ctx, sess);
739d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    sess->not_resumable = 1;
740d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (param->ctx->remove_session_cb != NULL) {
741d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      param->ctx->remove_session_cb(param->ctx, sess);
742d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
743d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_free(sess);
744d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
745d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
746d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
74753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langleyvoid SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
748d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  TIMEOUT_PARAM tp;
749d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
75053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  tp.ctx = ctx;
75153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  tp.cache = ctx->sessions;
752d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (tp.cache == NULL) {
753d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
754d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
755d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  tp.time = t;
75653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  CRYPTO_MUTEX_lock_write(&ctx->lock);
757d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
75853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  CRYPTO_MUTEX_unlock(&ctx->lock);
759d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
760d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
761d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ssl_clear_bad_session(SSL *s) {
762d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->session != NULL && !(s->shutdown & SSL_SENT_SHUTDOWN) &&
763d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !SSL_in_init(s)) {
764d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_CTX_remove_session(s->ctx, s->session);
765d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
766d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
767d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
768d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
769d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
770d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
771d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* locked by SSL_CTX in the calling function */
772d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) {
773d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->next == NULL || s->prev == NULL) {
774d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
775d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
776d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
777d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->next == (SSL_SESSION *)&ctx->session_cache_tail) {
778d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* last element in list */
779d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
780d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* only one element in list */
781d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ctx->session_cache_head = NULL;
782d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ctx->session_cache_tail = NULL;
783d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else {
784d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ctx->session_cache_tail = s->prev;
785d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
786d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
787d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
788d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
789d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* first element in list */
790d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ctx->session_cache_head = s->next;
791d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
792d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else { /* middle of list */
793d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      s->next->prev = s->prev;
794d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      s->prev->next = s->next;
795d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
796d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
797d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s->prev = s->next = NULL;
798d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
799d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
800d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) {
801d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (s->next != NULL && s->prev != NULL) {
802d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_SESSION_list_remove(ctx, s);
803d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
804d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
805d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->session_cache_head == NULL) {
806d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx->session_cache_head = s;
807d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx->session_cache_tail = s;
808d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
809d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
810d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
811d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s->next = ctx->session_cache_head;
812d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s->next->prev = s;
813d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
814d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx->session_cache_head = s;
815d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
816d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
817d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
818d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
819d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                             int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) {
820d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->new_session_cb = cb;
821d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
822d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
823d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) {
824d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->new_session_cb;
825d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
826d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
827d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
828d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) {
829d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->remove_session_cb = cb;
830d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
831d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
832d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
833d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                 SSL_SESSION *sess) {
834d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->remove_session_cb;
835d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
836d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
837d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
838d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                             SSL_SESSION *(*cb)(struct ssl_st *ssl,
839d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                uint8_t *data, int len,
840d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                int *copy)) {
841d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->get_session_cb = cb;
842d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
843d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
844d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, uint8_t *data,
845d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                      int len, int *copy) {
846d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->get_session_cb;
847d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
848d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
849d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_info_callback(SSL_CTX *ctx,
850d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                               void (*cb)(const SSL *ssl, int type, int val)) {
851d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->info_callback = cb;
852d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
853d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
854d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type,
855d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                int val) {
856d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->info_callback;
857d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
858d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
859d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509,
860d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                        EVP_PKEY **pkey)) {
861d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->client_cert_cb = cb;
862d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
863d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
864d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509,
865d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                EVP_PKEY **pkey) {
866d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->client_cert_cb;
867d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
868d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
869d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
870d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                               void (*cb)(SSL *ssl, EVP_PKEY **pkey)) {
871d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->channel_id_cb = cb;
872d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
873d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
874d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) {
875d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->channel_id_cb;
876d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
877d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
878d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyIMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
879