/src/openssl32/ssl/ssl_sess.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.  | 
3  |  |  * Copyright 2005 Nokia. All rights reserved.  | 
4  |  |  *  | 
5  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use  | 
6  |  |  * this file except in compliance with the License.  You can obtain a copy  | 
7  |  |  * in the file LICENSE in the source distribution or at  | 
8  |  |  * https://www.openssl.org/source/license.html  | 
9  |  |  */  | 
10  |  |  | 
11  |  | #if defined(__TANDEM) && defined(_SPT_MODEL_)  | 
12  |  | # include <spthread.h>  | 
13  |  | # include <spt_extensions.h> /* timeval */  | 
14  |  | #endif  | 
15  |  | #include <stdio.h>  | 
16  |  | #include <openssl/rand.h>  | 
17  |  | #include <openssl/engine.h>  | 
18  |  | #include "internal/refcount.h"  | 
19  |  | #include "internal/cryptlib.h"  | 
20  |  | #include "ssl_local.h"  | 
21  |  | #include "statem/statem_local.h"  | 
22  |  |  | 
23  |  | static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);  | 
24  |  | static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);  | 
25  |  | static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);  | 
26  |  |  | 
27  |  | DEFINE_STACK_OF(SSL_SESSION)  | 
28  |  |  | 
29  |  | __owur static ossl_inline int sess_timedout(OSSL_TIME t, SSL_SESSION *ss)  | 
30  | 107  | { | 
31  | 107  |     return ossl_time_compare(t, ss->calc_timeout) > 0;  | 
32  | 107  | }  | 
33  |  |  | 
34  |  | /*  | 
35  |  |  * Returns -1/0/+1 as other XXXcmp-type functions  | 
36  |  |  * Takes calculated timeout into consideration  | 
37  |  |  */  | 
38  |  | __owur static ossl_inline int timeoutcmp(SSL_SESSION *a, SSL_SESSION *b)  | 
39  | 0  | { | 
40  | 0  |     return ossl_time_compare(a->calc_timeout, b->calc_timeout);  | 
41  | 0  | }  | 
42  |  |  | 
43  |  | /*  | 
44  |  |  * Calculates effective timeout  | 
45  |  |  * Locking must be done by the caller of this function  | 
46  |  |  */  | 
47  |  | void ssl_session_calculate_timeout(SSL_SESSION *ss)  | 
48  | 110k  | { | 
49  | 110k  |     ss->calc_timeout = ossl_time_add(ss->time, ss->timeout);  | 
50  | 110k  | }  | 
51  |  |  | 
52  |  | /*  | 
53  |  |  * SSL_get_session() and SSL_get1_session() are problematic in TLS1.3 because,  | 
54  |  |  * unlike in earlier protocol versions, the session ticket may not have been  | 
55  |  |  * sent yet even though a handshake has finished. The session ticket data could  | 
56  |  |  * come in sometime later...or even change if multiple session ticket messages  | 
57  |  |  * are sent from the server. The preferred way for applications to obtain  | 
58  |  |  * a resumable session is to use SSL_CTX_sess_set_new_cb().  | 
59  |  |  */  | 
60  |  |  | 
61  |  | SSL_SESSION *SSL_get_session(const SSL *ssl)  | 
62  |  | /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */  | 
63  | 1  | { | 
64  | 1  |     const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);  | 
65  |  |  | 
66  | 1  |     if (sc == NULL)  | 
67  | 0  |         return NULL;  | 
68  |  |  | 
69  | 1  |     return sc->session;  | 
70  | 1  | }  | 
71  |  |  | 
72  |  | SSL_SESSION *SSL_get1_session(SSL *ssl)  | 
73  |  | /* variant of SSL_get_session: caller really gets something */  | 
74  | 0  | { | 
75  | 0  |     SSL_SESSION *sess;  | 
76  |  |  | 
77  |  |     /*  | 
78  |  |      * Need to lock this all up rather than just use CRYPTO_add so that  | 
79  |  |      * somebody doesn't free ssl->session between when we check it's non-null  | 
80  |  |      * and when we up the reference count.  | 
81  |  |      */  | 
82  | 0  |     if (!CRYPTO_THREAD_read_lock(ssl->lock))  | 
83  | 0  |         return NULL;  | 
84  | 0  |     sess = SSL_get_session(ssl);  | 
85  | 0  |     if (sess != NULL)  | 
86  | 0  |         SSL_SESSION_up_ref(sess);  | 
87  | 0  |     CRYPTO_THREAD_unlock(ssl->lock);  | 
88  | 0  |     return sess;  | 
89  | 0  | }  | 
90  |  |  | 
91  |  | int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)  | 
92  | 0  | { | 
93  | 0  |     return CRYPTO_set_ex_data(&s->ex_data, idx, arg);  | 
94  | 0  | }  | 
95  |  |  | 
96  |  | void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)  | 
97  | 0  | { | 
98  | 0  |     return CRYPTO_get_ex_data(&s->ex_data, idx);  | 
99  | 0  | }  | 
100  |  |  | 
101  |  | SSL_SESSION *SSL_SESSION_new(void)  | 
102  | 54.5k  | { | 
103  | 54.5k  |     SSL_SESSION *ss;  | 
104  |  |  | 
105  | 54.5k  |     if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))  | 
106  | 0  |         return NULL;  | 
107  |  |  | 
108  | 54.5k  |     ss = OPENSSL_zalloc(sizeof(*ss));  | 
109  | 54.5k  |     if (ss == NULL)  | 
110  | 0  |         return NULL;  | 
111  |  |  | 
112  | 54.5k  |     ss->ext.max_fragment_len_mode = TLSEXT_max_fragment_length_UNSPECIFIED;  | 
113  | 54.5k  |     ss->verify_result = 1;      /* avoid 0 (= X509_V_OK) just in case */  | 
114  |  |    /* 5 minute timeout by default */  | 
115  | 54.5k  |     ss->timeout = ossl_seconds2time(60 * 5 + 4);  | 
116  | 54.5k  |     ss->time = ossl_time_now();  | 
117  | 54.5k  |     ssl_session_calculate_timeout(ss);  | 
118  | 54.5k  |     if (!CRYPTO_NEW_REF(&ss->references, 1)) { | 
119  | 0  |         OPENSSL_free(ss);  | 
120  | 0  |         return NULL;  | 
121  | 0  |     }  | 
122  |  |  | 
123  | 54.5k  |     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data)) { | 
124  | 0  |         CRYPTO_FREE_REF(&ss->references);  | 
125  | 0  |         OPENSSL_free(ss);  | 
126  | 0  |         return NULL;  | 
127  | 0  |     }  | 
128  | 54.5k  |     return ss;  | 
129  | 54.5k  | }  | 
130  |  |  | 
131  |  | /*  | 
132  |  |  * Create a new SSL_SESSION and duplicate the contents of |src| into it. If  | 
133  |  |  * ticket == 0 then no ticket information is duplicated, otherwise it is.  | 
134  |  |  */  | 
135  |  | static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)  | 
136  | 1.12k  | { | 
137  | 1.12k  |     SSL_SESSION *dest;  | 
138  |  |  | 
139  | 1.12k  |     dest = OPENSSL_malloc(sizeof(*dest));  | 
140  | 1.12k  |     if (dest == NULL)  | 
141  | 0  |         return NULL;  | 
142  |  |  | 
143  |  |     /*  | 
144  |  |      * src is logically read-only but the prev/next pointers are not, they are  | 
145  |  |      * part of the session cache and can be modified concurrently.  | 
146  |  |      */  | 
147  | 1.12k  |     memcpy(dest, src, offsetof(SSL_SESSION, prev));  | 
148  |  |  | 
149  |  |     /*  | 
150  |  |      * Set the various pointers to NULL so that we can call SSL_SESSION_free in  | 
151  |  |      * the case of an error whilst halfway through constructing dest  | 
152  |  |      */  | 
153  | 1.12k  | #ifndef OPENSSL_NO_PSK  | 
154  | 1.12k  |     dest->psk_identity_hint = NULL;  | 
155  | 1.12k  |     dest->psk_identity = NULL;  | 
156  | 1.12k  | #endif  | 
157  | 1.12k  |     dest->ext.hostname = NULL;  | 
158  | 1.12k  |     dest->ext.tick = NULL;  | 
159  | 1.12k  |     dest->ext.alpn_selected = NULL;  | 
160  | 1.12k  | #ifndef OPENSSL_NO_SRP  | 
161  | 1.12k  |     dest->srp_username = NULL;  | 
162  | 1.12k  | #endif  | 
163  | 1.12k  |     dest->peer_chain = NULL;  | 
164  | 1.12k  |     dest->peer = NULL;  | 
165  | 1.12k  |     dest->peer_rpk = NULL;  | 
166  | 1.12k  |     dest->ticket_appdata = NULL;  | 
167  | 1.12k  |     memset(&dest->ex_data, 0, sizeof(dest->ex_data));  | 
168  |  |  | 
169  |  |     /* As the copy is not in the cache, we remove the associated pointers */  | 
170  | 1.12k  |     dest->prev = NULL;  | 
171  | 1.12k  |     dest->next = NULL;  | 
172  | 1.12k  |     dest->owner = NULL;  | 
173  |  |  | 
174  | 1.12k  |     if (!CRYPTO_NEW_REF(&dest->references, 1)) { | 
175  | 0  |         OPENSSL_free(dest);  | 
176  | 0  |         return NULL;  | 
177  | 0  |     }  | 
178  |  |  | 
179  | 1.12k  |     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) { | 
180  | 0  |         ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);  | 
181  | 0  |         goto err;  | 
182  | 0  |     }  | 
183  |  |  | 
184  | 1.12k  |     if (src->peer != NULL) { | 
185  | 1.12k  |         if (!X509_up_ref(src->peer)) { | 
186  | 0  |             ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB);  | 
187  | 0  |             goto err;  | 
188  | 0  |         }  | 
189  | 1.12k  |         dest->peer = src->peer;  | 
190  | 1.12k  |     }  | 
191  |  |  | 
192  | 1.12k  |     if (src->peer_chain != NULL) { | 
193  | 1.12k  |         dest->peer_chain = X509_chain_up_ref(src->peer_chain);  | 
194  | 1.12k  |         if (dest->peer_chain == NULL) { | 
195  | 0  |             ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB);  | 
196  | 0  |             goto err;  | 
197  | 0  |         }  | 
198  | 1.12k  |     }  | 
199  |  |  | 
200  | 1.12k  |     if (src->peer_rpk != NULL) { | 
201  | 0  |         if (!EVP_PKEY_up_ref(src->peer_rpk))  | 
202  | 0  |             goto err;  | 
203  | 0  |         dest->peer_rpk = src->peer_rpk;  | 
204  | 0  |     }  | 
205  |  |  | 
206  | 1.12k  | #ifndef OPENSSL_NO_PSK  | 
207  | 1.12k  |     if (src->psk_identity_hint) { | 
208  | 0  |         dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint);  | 
209  | 0  |         if (dest->psk_identity_hint == NULL)  | 
210  | 0  |             goto err;  | 
211  | 0  |     }  | 
212  | 1.12k  |     if (src->psk_identity) { | 
213  | 0  |         dest->psk_identity = OPENSSL_strdup(src->psk_identity);  | 
214  | 0  |         if (dest->psk_identity == NULL)  | 
215  | 0  |             goto err;  | 
216  | 0  |     }  | 
217  | 1.12k  | #endif  | 
218  |  |  | 
219  | 1.12k  |     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,  | 
220  | 1.12k  |                             &dest->ex_data, &src->ex_data)) { | 
221  | 0  |         ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);  | 
222  | 0  |         goto err;  | 
223  | 0  |     }  | 
224  |  |  | 
225  | 1.12k  |     if (src->ext.hostname) { | 
226  | 2  |         dest->ext.hostname = OPENSSL_strdup(src->ext.hostname);  | 
227  | 2  |         if (dest->ext.hostname == NULL)  | 
228  | 0  |             goto err;  | 
229  | 2  |     }  | 
230  |  |  | 
231  | 1.12k  |     if (ticket != 0 && src->ext.tick != NULL) { | 
232  | 0  |         dest->ext.tick =  | 
233  | 0  |             OPENSSL_memdup(src->ext.tick, src->ext.ticklen);  | 
234  | 0  |         if (dest->ext.tick == NULL)  | 
235  | 0  |             goto err;  | 
236  | 1.12k  |     } else { | 
237  | 1.12k  |         dest->ext.tick_lifetime_hint = 0;  | 
238  | 1.12k  |         dest->ext.ticklen = 0;  | 
239  | 1.12k  |     }  | 
240  |  |  | 
241  | 1.12k  |     if (src->ext.alpn_selected != NULL) { | 
242  | 1.12k  |         dest->ext.alpn_selected = OPENSSL_memdup(src->ext.alpn_selected,  | 
243  | 1.12k  |                                                  src->ext.alpn_selected_len);  | 
244  | 1.12k  |         if (dest->ext.alpn_selected == NULL)  | 
245  | 0  |             goto err;  | 
246  | 1.12k  |     }  | 
247  |  |  | 
248  | 1.12k  | #ifndef OPENSSL_NO_SRP  | 
249  | 1.12k  |     if (src->srp_username) { | 
250  | 0  |         dest->srp_username = OPENSSL_strdup(src->srp_username);  | 
251  | 0  |         if (dest->srp_username == NULL)  | 
252  | 0  |             goto err;  | 
253  | 0  |     }  | 
254  | 1.12k  | #endif  | 
255  |  |  | 
256  | 1.12k  |     if (src->ticket_appdata != NULL) { | 
257  | 0  |         dest->ticket_appdata =  | 
258  | 0  |             OPENSSL_memdup(src->ticket_appdata, src->ticket_appdata_len);  | 
259  | 0  |         if (dest->ticket_appdata == NULL)  | 
260  | 0  |             goto err;  | 
261  | 0  |     }  | 
262  |  |  | 
263  | 1.12k  |     return dest;  | 
264  | 0  |  err:  | 
265  | 0  |     SSL_SESSION_free(dest);  | 
266  | 0  |     return NULL;  | 
267  | 1.12k  | }  | 
268  |  |  | 
269  |  | SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)  | 
270  | 0  | { | 
271  | 0  |     return ssl_session_dup_intern(src, 1);  | 
272  | 0  | }  | 
273  |  |  | 
274  |  | /*  | 
275  |  |  * Used internally when duplicating a session which might be already shared.  | 
276  |  |  * We will have resumed the original session. Subsequently we might have marked  | 
277  |  |  * it as non-resumable (e.g. in another thread) - but this copy should be ok to  | 
278  |  |  * resume from.  | 
279  |  |  */  | 
280  |  | SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)  | 
281  | 1.13k  | { | 
282  | 1.13k  |     SSL_SESSION *sess = ssl_session_dup_intern(src, ticket);  | 
283  |  |  | 
284  | 1.13k  |     if (sess != NULL)  | 
285  | 1.13k  |         sess->not_resumable = 0;  | 
286  |  |  | 
287  | 1.13k  |     return sess;  | 
288  | 1.13k  | }  | 
289  |  |  | 
290  |  | const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)  | 
291  | 0  | { | 
292  | 0  |     if (len)  | 
293  | 0  |         *len = (unsigned int)s->session_id_length;  | 
294  | 0  |     return s->session_id;  | 
295  | 0  | }  | 
296  |  | const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s,  | 
297  |  |                                                 unsigned int *len)  | 
298  | 0  | { | 
299  | 0  |     if (len != NULL)  | 
300  | 0  |         *len = (unsigned int)s->sid_ctx_length;  | 
301  | 0  |     return s->sid_ctx;  | 
302  | 0  | }  | 
303  |  |  | 
304  |  | unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)  | 
305  | 0  | { | 
306  | 0  |     return s->compress_meth;  | 
307  | 0  | }  | 
308  |  |  | 
309  |  | /*  | 
310  |  |  * SSLv3/TLSv1 has 32 bytes (256 bits) of session ID space. As such, filling  | 
311  |  |  * the ID with random junk repeatedly until we have no conflict is going to  | 
312  |  |  * complete in one iteration pretty much "most" of the time (btw:  | 
313  |  |  * understatement). So, if it takes us 10 iterations and we still can't avoid  | 
314  |  |  * a conflict - well that's a reasonable point to call it quits. Either the  | 
315  |  |  * RAND code is broken or someone is trying to open roughly very close to  | 
316  |  |  * 2^256 SSL sessions to our server. How you might store that many sessions  | 
317  |  |  * is perhaps a more interesting question ...  | 
318  |  |  */  | 
319  |  |  | 
320  | 9.83k  | #define MAX_SESS_ID_ATTEMPTS 10  | 
321  |  | static int def_generate_session_id(SSL *ssl, unsigned char *id,  | 
322  |  |                                    unsigned int *id_len)  | 
323  | 9.83k  | { | 
324  | 9.83k  |     unsigned int retry = 0;  | 
325  | 9.83k  |     do { | 
326  | 9.83k  |         if (RAND_bytes_ex(ssl->ctx->libctx, id, *id_len, 0) <= 0)  | 
327  | 0  |             return 0;  | 
328  | 9.83k  | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION  | 
329  | 9.83k  |         if (retry > 0) { | 
330  | 0  |             id[0]++;  | 
331  | 0  |         }  | 
332  | 9.83k  | #endif  | 
333  | 9.83k  |     } while (SSL_has_matching_session_id(ssl, id, *id_len) &&  | 
334  | 9.83k  |            (++retry < MAX_SESS_ID_ATTEMPTS)) ;  | 
335  | 9.83k  |     if (retry < MAX_SESS_ID_ATTEMPTS)  | 
336  | 9.83k  |         return 1;  | 
337  |  |     /* else - woops a session_id match */  | 
338  |  |     /*  | 
339  |  |      * XXX We should also check the external cache -- but the probability of  | 
340  |  |      * a collision is negligible, and we could not prevent the concurrent  | 
341  |  |      * creation of sessions with identical IDs since we currently don't have  | 
342  |  |      * means to atomically check whether a session ID already exists and make  | 
343  |  |      * a reservation for it if it does not (this problem applies to the  | 
344  |  |      * internal cache as well).  | 
345  |  |      */  | 
346  | 0  |     return 0;  | 
347  | 9.83k  | }  | 
348  |  |  | 
349  |  | int ssl_generate_session_id(SSL_CONNECTION *s, SSL_SESSION *ss)  | 
350  | 17.3k  | { | 
351  | 17.3k  |     unsigned int tmp;  | 
352  | 17.3k  |     GEN_SESSION_CB cb = def_generate_session_id;  | 
353  | 17.3k  |     SSL *ssl = SSL_CONNECTION_GET_SSL(s);  | 
354  |  |  | 
355  | 17.3k  |     switch (s->version) { | 
356  | 2.98k  |     case SSL3_VERSION:  | 
357  | 3.56k  |     case TLS1_VERSION:  | 
358  | 4.46k  |     case TLS1_1_VERSION:  | 
359  | 13.9k  |     case TLS1_2_VERSION:  | 
360  | 13.9k  |     case TLS1_3_VERSION:  | 
361  | 13.9k  |     case DTLS1_BAD_VER:  | 
362  | 14.8k  |     case DTLS1_VERSION:  | 
363  | 17.3k  |     case DTLS1_2_VERSION:  | 
364  | 17.3k  |         ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;  | 
365  | 17.3k  |         break;  | 
366  | 0  |     default:  | 
367  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNSUPPORTED_SSL_VERSION);  | 
368  | 0  |         return 0;  | 
369  | 17.3k  |     }  | 
370  |  |  | 
371  |  |     /*-  | 
372  |  |      * If RFC5077 ticket, use empty session ID (as server).  | 
373  |  |      * Note that:  | 
374  |  |      * (a) ssl_get_prev_session() does lookahead into the  | 
375  |  |      *     ClientHello extensions to find the session ticket.  | 
376  |  |      *     When ssl_get_prev_session() fails, statem_srvr.c calls  | 
377  |  |      *     ssl_get_new_session() in tls_process_client_hello().  | 
378  |  |      *     At that point, it has not yet parsed the extensions,  | 
379  |  |      *     however, because of the lookahead, it already knows  | 
380  |  |      *     whether a ticket is expected or not.  | 
381  |  |      *  | 
382  |  |      * (b) statem_clnt.c calls ssl_get_new_session() before parsing  | 
383  |  |      *     ServerHello extensions, and before recording the session  | 
384  |  |      *     ID received from the server, so this block is a noop.  | 
385  |  |      */  | 
386  | 17.3k  |     if (s->ext.ticket_expected) { | 
387  | 1.41k  |         ss->session_id_length = 0;  | 
388  | 1.41k  |         return 1;  | 
389  | 1.41k  |     }  | 
390  |  |  | 
391  |  |     /* Choose which callback will set the session ID */  | 
392  | 15.9k  |     if (!CRYPTO_THREAD_read_lock(SSL_CONNECTION_GET_SSL(s)->lock))  | 
393  | 0  |         return 0;  | 
394  | 15.9k  |     if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) { | 
395  | 0  |         CRYPTO_THREAD_unlock(ssl->lock);  | 
396  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR,  | 
397  | 0  |                  SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);  | 
398  | 0  |         return 0;  | 
399  | 0  |     }  | 
400  | 15.9k  |     if (s->generate_session_id)  | 
401  | 0  |         cb = s->generate_session_id;  | 
402  | 15.9k  |     else if (s->session_ctx->generate_session_id)  | 
403  | 0  |         cb = s->session_ctx->generate_session_id;  | 
404  | 15.9k  |     CRYPTO_THREAD_unlock(s->session_ctx->lock);  | 
405  | 15.9k  |     CRYPTO_THREAD_unlock(ssl->lock);  | 
406  |  |     /* Choose a session ID */  | 
407  | 15.9k  |     memset(ss->session_id, 0, ss->session_id_length);  | 
408  | 15.9k  |     tmp = (int)ss->session_id_length;  | 
409  | 15.9k  |     if (!cb(ssl, ss->session_id, &tmp)) { | 
410  |  |         /* The callback failed */  | 
411  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR,  | 
412  | 0  |                  SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);  | 
413  | 0  |         return 0;  | 
414  | 0  |     }  | 
415  |  |     /*  | 
416  |  |      * Don't allow the callback to set the session length to zero. nor  | 
417  |  |      * set it higher than it was.  | 
418  |  |      */  | 
419  | 15.9k  |     if (tmp == 0 || tmp > ss->session_id_length) { | 
420  |  |         /* The callback set an illegal length */  | 
421  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR,  | 
422  | 0  |                  SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);  | 
423  | 0  |         return 0;  | 
424  | 0  |     }  | 
425  | 15.9k  |     ss->session_id_length = tmp;  | 
426  |  |     /* Finally, check for a conflict */  | 
427  | 15.9k  |     if (SSL_has_matching_session_id(ssl, ss->session_id,  | 
428  | 15.9k  |                                     (unsigned int)ss->session_id_length)) { | 
429  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_CONFLICT);  | 
430  | 0  |         return 0;  | 
431  | 0  |     }  | 
432  |  |  | 
433  | 15.9k  |     return 1;  | 
434  | 15.9k  | }  | 
435  |  |  | 
436  |  | int ssl_get_new_session(SSL_CONNECTION *s, int session)  | 
437  | 53.1k  | { | 
438  |  |     /* This gets used by clients and servers. */  | 
439  |  |  | 
440  | 53.1k  |     SSL_SESSION *ss = NULL;  | 
441  |  |  | 
442  | 53.1k  |     if ((ss = SSL_SESSION_new()) == NULL) { | 
443  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB);  | 
444  | 0  |         return 0;  | 
445  | 0  |     }  | 
446  |  |  | 
447  |  |     /* If the context has a default timeout, use it */  | 
448  | 53.1k  |     if (ossl_time_is_zero(s->session_ctx->session_timeout))  | 
449  | 0  |         ss->timeout = SSL_CONNECTION_GET_SSL(s)->method->get_timeout();  | 
450  | 53.1k  |     else  | 
451  | 53.1k  |         ss->timeout = s->session_ctx->session_timeout;  | 
452  | 53.1k  |     ssl_session_calculate_timeout(ss);  | 
453  |  |  | 
454  | 53.1k  |     SSL_SESSION_free(s->session);  | 
455  | 53.1k  |     s->session = NULL;  | 
456  |  |  | 
457  | 53.1k  |     if (session) { | 
458  | 12.4k  |         if (SSL_CONNECTION_IS_TLS13(s)) { | 
459  |  |             /*  | 
460  |  |              * We generate the session id while constructing the  | 
461  |  |              * NewSessionTicket in TLSv1.3.  | 
462  |  |              */  | 
463  | 1.78k  |             ss->session_id_length = 0;  | 
464  | 10.7k  |         } else if (!ssl_generate_session_id(s, ss)) { | 
465  |  |             /* SSLfatal() already called */  | 
466  | 0  |             SSL_SESSION_free(ss);  | 
467  | 0  |             return 0;  | 
468  | 0  |         }  | 
469  |  |  | 
470  | 40.6k  |     } else { | 
471  | 40.6k  |         ss->session_id_length = 0;  | 
472  | 40.6k  |     }  | 
473  |  |  | 
474  | 53.1k  |     if (s->sid_ctx_length > sizeof(ss->sid_ctx)) { | 
475  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);  | 
476  | 0  |         SSL_SESSION_free(ss);  | 
477  | 0  |         return 0;  | 
478  | 0  |     }  | 
479  | 53.1k  |     memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);  | 
480  | 53.1k  |     ss->sid_ctx_length = s->sid_ctx_length;  | 
481  | 53.1k  |     s->session = ss;  | 
482  | 53.1k  |     ss->ssl_version = s->version;  | 
483  | 53.1k  |     ss->verify_result = X509_V_OK;  | 
484  |  |  | 
485  |  |     /* If client supports extended master secret set it in session */  | 
486  | 53.1k  |     if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS)  | 
487  | 1.02k  |         ss->flags |= SSL_SESS_FLAG_EXTMS;  | 
488  |  |  | 
489  | 53.1k  |     return 1;  | 
490  | 53.1k  | }  | 
491  |  |  | 
492  |  | SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s,  | 
493  |  |                                   const unsigned char *sess_id,  | 
494  |  |                                   size_t sess_id_len)  | 
495  | 163  | { | 
496  | 163  |     SSL_SESSION *ret = NULL;  | 
497  |  |  | 
498  | 163  |     if ((s->session_ctx->session_cache_mode  | 
499  | 163  |          & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) { | 
500  | 163  |         SSL_SESSION data;  | 
501  |  |  | 
502  | 163  |         data.ssl_version = s->version;  | 
503  | 163  |         if (!ossl_assert(sess_id_len <= SSL_MAX_SSL_SESSION_ID_LENGTH))  | 
504  | 0  |             return NULL;  | 
505  |  |  | 
506  | 163  |         memcpy(data.session_id, sess_id, sess_id_len);  | 
507  | 163  |         data.session_id_length = sess_id_len;  | 
508  |  |  | 
509  | 163  |         if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock))  | 
510  | 0  |             return NULL;  | 
511  | 163  |         ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data);  | 
512  | 163  |         if (ret != NULL) { | 
513  |  |             /* don't allow other threads to steal it: */  | 
514  | 0  |             SSL_SESSION_up_ref(ret);  | 
515  | 0  |         }  | 
516  | 163  |         CRYPTO_THREAD_unlock(s->session_ctx->lock);  | 
517  | 163  |         if (ret == NULL)  | 
518  | 163  |             ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_miss);  | 
519  | 163  |     }  | 
520  |  |  | 
521  | 163  |     if (ret == NULL && s->session_ctx->get_session_cb != NULL) { | 
522  | 0  |         int copy = 1;  | 
523  |  | 
  | 
524  | 0  |         ret = s->session_ctx->get_session_cb(SSL_CONNECTION_GET_USER_SSL(s),  | 
525  | 0  |                                              sess_id, sess_id_len, ©);  | 
526  |  | 
  | 
527  | 0  |         if (ret != NULL) { | 
528  | 0  |             if (ret->not_resumable) { | 
529  |  |                 /* If its not resumable then ignore this session */  | 
530  | 0  |                 if (!copy)  | 
531  | 0  |                     SSL_SESSION_free(ret);  | 
532  | 0  |                 return NULL;  | 
533  | 0  |             }  | 
534  | 0  |             ssl_tsan_counter(s->session_ctx,  | 
535  | 0  |                              &s->session_ctx->stats.sess_cb_hit);  | 
536  |  |  | 
537  |  |             /*  | 
538  |  |              * Increment reference count now if the session callback asks us  | 
539  |  |              * to do so (note that if the session structures returned by the  | 
540  |  |              * callback are shared between threads, it must handle the  | 
541  |  |              * reference count itself [i.e. copy == 0], or things won't be  | 
542  |  |              * thread-safe).  | 
543  |  |              */  | 
544  | 0  |             if (copy)  | 
545  | 0  |                 SSL_SESSION_up_ref(ret);  | 
546  |  |  | 
547  |  |             /*  | 
548  |  |              * Add the externally cached session to the internal cache as  | 
549  |  |              * well if and only if we are supposed to.  | 
550  |  |              */  | 
551  | 0  |             if ((s->session_ctx->session_cache_mode &  | 
552  | 0  |                  SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0) { | 
553  |  |                 /*  | 
554  |  |                  * Either return value of SSL_CTX_add_session should not  | 
555  |  |                  * interrupt the session resumption process. The return  | 
556  |  |                  * value is intentionally ignored.  | 
557  |  |                  */  | 
558  | 0  |                 (void)SSL_CTX_add_session(s->session_ctx, ret);  | 
559  | 0  |             }  | 
560  | 0  |         }  | 
561  | 0  |     }  | 
562  |  |  | 
563  | 163  |     return ret;  | 
564  | 163  | }  | 
565  |  |  | 
566  |  | /*-  | 
567  |  |  * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this  | 
568  |  |  * connection. It is only called by servers.  | 
569  |  |  *  | 
570  |  |  *   hello: The parsed ClientHello data  | 
571  |  |  *  | 
572  |  |  * Returns:  | 
573  |  |  *   -1: fatal error  | 
574  |  |  *    0: no session found  | 
575  |  |  *    1: a session may have been found.  | 
576  |  |  *  | 
577  |  |  * Side effects:  | 
578  |  |  *   - If a session is found then s->session is pointed at it (after freeing an  | 
579  |  |  *     existing session if need be) and s->verify_result is set from the session.  | 
580  |  |  *   - Both for new and resumed sessions, s->ext.ticket_expected is set to 1  | 
581  |  |  *     if the server should issue a new session ticket (to 0 otherwise).  | 
582  |  |  */  | 
583  |  | int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello)  | 
584  | 15.8k  | { | 
585  |  |     /* This is used only by servers. */  | 
586  |  |  | 
587  | 15.8k  |     SSL_SESSION *ret = NULL;  | 
588  | 15.8k  |     int fatal = 0;  | 
589  | 15.8k  |     int try_session_cache = 0;  | 
590  | 15.8k  |     SSL_TICKET_STATUS r;  | 
591  |  |  | 
592  | 15.8k  |     if (SSL_CONNECTION_IS_TLS13(s)) { | 
593  | 3.75k  |         SSL_SESSION_free(s->session);  | 
594  | 3.75k  |         s->session = NULL;  | 
595  |  |         /*  | 
596  |  |          * By default we will send a new ticket. This can be overridden in the  | 
597  |  |          * ticket processing.  | 
598  |  |          */  | 
599  | 3.75k  |         s->ext.ticket_expected = 1;  | 
600  | 3.75k  |         if (!tls_parse_extension(s, TLSEXT_IDX_psk_kex_modes,  | 
601  | 3.75k  |                                  SSL_EXT_CLIENT_HELLO, hello->pre_proc_exts,  | 
602  | 3.75k  |                                  NULL, 0)  | 
603  | 3.75k  |                 || !tls_parse_extension(s, TLSEXT_IDX_psk, SSL_EXT_CLIENT_HELLO,  | 
604  | 3.71k  |                                         hello->pre_proc_exts, NULL, 0))  | 
605  | 378  |             return -1;  | 
606  |  |  | 
607  |  |         /* If we resumed, s->session will now be set */  | 
608  | 3.38k  |         ret = s->session;  | 
609  | 12.0k  |     } else { | 
610  |  |         /* sets s->ext.ticket_expected */  | 
611  | 12.0k  |         r = tls_get_ticket_from_client(s, hello, &ret);  | 
612  | 12.0k  |         switch (r) { | 
613  | 0  |         case SSL_TICKET_FATAL_ERR_MALLOC:  | 
614  | 0  |         case SSL_TICKET_FATAL_ERR_OTHER:  | 
615  | 0  |             fatal = 1;  | 
616  | 0  |             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);  | 
617  | 0  |             goto err;  | 
618  | 10.4k  |         case SSL_TICKET_NONE:  | 
619  | 11.1k  |         case SSL_TICKET_EMPTY:  | 
620  | 11.1k  |             if (hello->session_id_len > 0) { | 
621  | 598  |                 try_session_cache = 1;  | 
622  | 598  |                 ret = lookup_sess_in_cache(s, hello->session_id,  | 
623  | 598  |                                            hello->session_id_len);  | 
624  | 598  |             }  | 
625  | 11.1k  |             break;  | 
626  | 717  |         case SSL_TICKET_NO_DECRYPT:  | 
627  | 936  |         case SSL_TICKET_SUCCESS:  | 
628  | 936  |         case SSL_TICKET_SUCCESS_RENEW:  | 
629  | 936  |             break;  | 
630  | 12.0k  |         }  | 
631  | 12.0k  |     }  | 
632  |  |  | 
633  | 15.4k  |     if (ret == NULL)  | 
634  | 15.2k  |         goto err;  | 
635  |  |  | 
636  |  |     /* Now ret is non-NULL and we own one of its reference counts. */  | 
637  |  |  | 
638  |  |     /* Check TLS version consistency */  | 
639  | 226  |     if (ret->ssl_version != s->version)  | 
640  | 7  |         goto err;  | 
641  |  |  | 
642  | 219  |     if (ret->sid_ctx_length != s->sid_ctx_length  | 
643  | 219  |         || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { | 
644  |  |         /*  | 
645  |  |          * We have the session requested by the client, but we don't want to  | 
646  |  |          * use it in this context.  | 
647  |  |          */  | 
648  | 5  |         goto err;               /* treat like cache miss */  | 
649  | 5  |     }  | 
650  |  |  | 
651  | 214  |     if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { | 
652  |  |         /*  | 
653  |  |          * We can't be sure if this session is being used out of context,  | 
654  |  |          * which is especially important for SSL_VERIFY_PEER. The application  | 
655  |  |          * should have used SSL[_CTX]_set_session_id_context. For this error  | 
656  |  |          * case, we generate an error instead of treating the event like a  | 
657  |  |          * cache miss (otherwise it would be easy for applications to  | 
658  |  |          * effectively disable the session cache by accident without anyone  | 
659  |  |          * noticing).  | 
660  |  |          */  | 
661  |  | 
  | 
662  | 0  |         SSLfatal(s, SSL_AD_INTERNAL_ERROR,  | 
663  | 0  |                  SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);  | 
664  | 0  |         fatal = 1;  | 
665  | 0  |         goto err;  | 
666  | 0  |     }  | 
667  |  |  | 
668  | 214  |     if (sess_timedout(ossl_time_now(), ret)) { | 
669  | 6  |         ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_timeout);  | 
670  | 6  |         if (try_session_cache) { | 
671  |  |             /* session was from the cache, so remove it */  | 
672  | 0  |             SSL_CTX_remove_session(s->session_ctx, ret);  | 
673  | 0  |         }  | 
674  | 6  |         goto err;  | 
675  | 6  |     }  | 
676  |  |  | 
677  |  |     /* Check extended master secret extension consistency */  | 
678  | 208  |     if (ret->flags & SSL_SESS_FLAG_EXTMS) { | 
679  |  |         /* If old session includes extms, but new does not: abort handshake */  | 
680  | 178  |         if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS)) { | 
681  | 12  |             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INCONSISTENT_EXTMS);  | 
682  | 12  |             fatal = 1;  | 
683  | 12  |             goto err;  | 
684  | 12  |         }  | 
685  | 178  |     } else if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) { | 
686  |  |         /* If new session includes extms, but old does not: do not resume */  | 
687  | 14  |         goto err;  | 
688  | 14  |     }  | 
689  |  |  | 
690  | 182  |     if (!SSL_CONNECTION_IS_TLS13(s)) { | 
691  |  |         /* We already did this for TLS1.3 */  | 
692  | 180  |         SSL_SESSION_free(s->session);  | 
693  | 180  |         s->session = ret;  | 
694  | 180  |     }  | 
695  |  |  | 
696  | 182  |     ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_hit);  | 
697  | 182  |     s->verify_result = s->session->verify_result;  | 
698  | 182  |     return 1;  | 
699  |  |  | 
700  | 15.2k  |  err:  | 
701  | 15.2k  |     if (ret != NULL) { | 
702  | 44  |         SSL_SESSION_free(ret);  | 
703  |  |         /* In TLSv1.3 s->session was already set to ret, so we NULL it out */  | 
704  | 44  |         if (SSL_CONNECTION_IS_TLS13(s))  | 
705  | 5  |             s->session = NULL;  | 
706  |  |  | 
707  | 44  |         if (!try_session_cache) { | 
708  |  |             /*  | 
709  |  |              * The session was from a ticket, so we should issue a ticket for  | 
710  |  |              * the new session  | 
711  |  |              */  | 
712  | 44  |             s->ext.ticket_expected = 1;  | 
713  | 44  |         }  | 
714  | 44  |     }  | 
715  | 15.2k  |     if (fatal)  | 
716  | 12  |         return -1;  | 
717  |  |  | 
718  | 15.2k  |     return 0;  | 
719  | 15.2k  | }  | 
720  |  |  | 
721  |  | int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)  | 
722  | 361  | { | 
723  | 361  |     int ret = 0;  | 
724  | 361  |     SSL_SESSION *s;  | 
725  |  |  | 
726  |  |     /*  | 
727  |  |      * add just 1 reference count for the SSL_CTX's session cache even though  | 
728  |  |      * it has two ways of access: each session is in a doubly linked list and  | 
729  |  |      * an lhash  | 
730  |  |      */  | 
731  | 361  |     SSL_SESSION_up_ref(c);  | 
732  |  |     /*  | 
733  |  |      * if session c is in already in cache, we take back the increment later  | 
734  |  |      */  | 
735  |  |  | 
736  | 361  |     if (!CRYPTO_THREAD_write_lock(ctx->lock)) { | 
737  | 0  |         SSL_SESSION_free(c);  | 
738  | 0  |         return 0;  | 
739  | 0  |     }  | 
740  | 361  |     s = lh_SSL_SESSION_insert(ctx->sessions, c);  | 
741  |  |  | 
742  |  |     /*  | 
743  |  |      * s != NULL iff we already had a session with the given PID. In this  | 
744  |  |      * case, s == c should hold (then we did not really modify  | 
745  |  |      * ctx->sessions), or we're in trouble.  | 
746  |  |      */  | 
747  | 361  |     if (s != NULL && s != c) { | 
748  |  |         /* We *are* in trouble ... */  | 
749  | 0  |         SSL_SESSION_list_remove(ctx, s);  | 
750  | 0  |         SSL_SESSION_free(s);  | 
751  |  |         /*  | 
752  |  |          * ... so pretend the other session did not exist in cache (we cannot  | 
753  |  |          * handle two SSL_SESSION structures with identical session ID in the  | 
754  |  |          * same cache, which could happen e.g. when two threads concurrently  | 
755  |  |          * obtain the same session from an external cache)  | 
756  |  |          */  | 
757  | 0  |         s = NULL;  | 
758  | 361  |     } else if (s == NULL &&  | 
759  | 361  |                lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) { | 
760  |  |         /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */  | 
761  |  |  | 
762  |  |         /*  | 
763  |  |          * ... so take back the extra reference and also don't add  | 
764  |  |          * the session to the SSL_SESSION_list at this time  | 
765  |  |          */  | 
766  | 0  |         s = c;  | 
767  | 0  |     }  | 
768  |  |  | 
769  |  |     /* Adjust last used time, and add back into the cache at the appropriate spot */  | 
770  | 361  |     if (ctx->session_cache_mode & SSL_SESS_CACHE_UPDATE_TIME) { | 
771  | 0  |         c->time = ossl_time_now();  | 
772  | 0  |         ssl_session_calculate_timeout(c);  | 
773  | 0  |     }  | 
774  |  |  | 
775  | 361  |     if (s == NULL) { | 
776  |  |         /*  | 
777  |  |          * new cache entry -- remove old ones if cache has become too large  | 
778  |  |          * delete cache entry *before* add, so we don't remove the one we're adding!  | 
779  |  |          */  | 
780  |  |  | 
781  | 361  |         ret = 1;  | 
782  |  |  | 
783  | 361  |         if (SSL_CTX_sess_get_cache_size(ctx) > 0) { | 
784  | 361  |             while (SSL_CTX_sess_number(ctx) >= SSL_CTX_sess_get_cache_size(ctx)) { | 
785  | 0  |                 if (!remove_session_lock(ctx, ctx->session_cache_tail, 0))  | 
786  | 0  |                     break;  | 
787  | 0  |                 else  | 
788  | 0  |                     ssl_tsan_counter(ctx, &ctx->stats.sess_cache_full);  | 
789  | 0  |             }  | 
790  | 361  |         }  | 
791  | 361  |     }  | 
792  |  |  | 
793  | 361  |     SSL_SESSION_list_add(ctx, c);  | 
794  |  |  | 
795  | 361  |     if (s != NULL) { | 
796  |  |         /*  | 
797  |  |          * existing cache entry -- decrement previously incremented reference  | 
798  |  |          * count because it already takes into account the cache  | 
799  |  |          */  | 
800  |  | 
  | 
801  | 0  |         SSL_SESSION_free(s);    /* s == c */  | 
802  | 0  |         ret = 0;  | 
803  | 0  |     }  | 
804  | 361  |     CRYPTO_THREAD_unlock(ctx->lock);  | 
805  | 361  |     return ret;  | 
806  | 361  | }  | 
807  |  |  | 
808  |  | int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)  | 
809  | 45.2k  | { | 
810  | 45.2k  |     return remove_session_lock(ctx, c, 1);  | 
811  | 45.2k  | }  | 
812  |  |  | 
813  |  | static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)  | 
814  | 45.2k  | { | 
815  | 45.2k  |     SSL_SESSION *r;  | 
816  | 45.2k  |     int ret = 0;  | 
817  |  |  | 
818  | 45.2k  |     if ((c != NULL) && (c->session_id_length != 0)) { | 
819  | 15.0k  |         if (lck) { | 
820  | 15.0k  |             if (!CRYPTO_THREAD_write_lock(ctx->lock))  | 
821  | 0  |                 return 0;  | 
822  | 15.0k  |         }  | 
823  | 15.0k  |         if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) { | 
824  | 704  |             ret = 1;  | 
825  | 704  |             r = lh_SSL_SESSION_delete(ctx->sessions, r);  | 
826  | 704  |             SSL_SESSION_list_remove(ctx, r);  | 
827  | 704  |         }  | 
828  | 15.0k  |         c->not_resumable = 1;  | 
829  |  |  | 
830  | 15.0k  |         if (lck)  | 
831  | 15.0k  |             CRYPTO_THREAD_unlock(ctx->lock);  | 
832  |  |  | 
833  | 15.0k  |         if (ctx->remove_session_cb != NULL)  | 
834  | 0  |             ctx->remove_session_cb(ctx, c);  | 
835  |  |  | 
836  | 15.0k  |         if (ret)  | 
837  | 704  |             SSL_SESSION_free(r);  | 
838  | 15.0k  |     }  | 
839  | 45.2k  |     return ret;  | 
840  | 45.2k  | }  | 
841  |  |  | 
842  |  | void SSL_SESSION_free(SSL_SESSION *ss)  | 
843  | 498k  | { | 
844  | 498k  |     int i;  | 
845  |  |  | 
846  | 498k  |     if (ss == NULL)  | 
847  | 417k  |         return;  | 
848  | 80.3k  |     CRYPTO_DOWN_REF(&ss->references, &i);  | 
849  | 80.3k  |     REF_PRINT_COUNT("SSL_SESSION", i, ss); | 
850  | 80.3k  |     if (i > 0)  | 
851  | 833  |         return;  | 
852  | 79.5k  |     REF_ASSERT_ISNT(i < 0);  | 
853  |  |  | 
854  | 79.5k  |     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);  | 
855  |  |  | 
856  | 79.5k  |     OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key));  | 
857  | 79.5k  |     OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id));  | 
858  | 79.5k  |     X509_free(ss->peer);  | 
859  | 79.5k  |     EVP_PKEY_free(ss->peer_rpk);  | 
860  | 79.5k  |     OSSL_STACK_OF_X509_free(ss->peer_chain);  | 
861  | 79.5k  |     OPENSSL_free(ss->ext.hostname);  | 
862  | 79.5k  |     OPENSSL_free(ss->ext.tick);  | 
863  | 79.5k  | #ifndef OPENSSL_NO_PSK  | 
864  | 79.5k  |     OPENSSL_free(ss->psk_identity_hint);  | 
865  | 79.5k  |     OPENSSL_free(ss->psk_identity);  | 
866  | 79.5k  | #endif  | 
867  | 79.5k  | #ifndef OPENSSL_NO_SRP  | 
868  | 79.5k  |     OPENSSL_free(ss->srp_username);  | 
869  | 79.5k  | #endif  | 
870  | 79.5k  |     OPENSSL_free(ss->ext.alpn_selected);  | 
871  | 79.5k  |     OPENSSL_free(ss->ticket_appdata);  | 
872  | 79.5k  |     CRYPTO_FREE_REF(&ss->references);  | 
873  | 79.5k  |     OPENSSL_clear_free(ss, sizeof(*ss));  | 
874  | 79.5k  | }  | 
875  |  |  | 
876  |  | int SSL_SESSION_up_ref(SSL_SESSION *ss)  | 
877  | 833  | { | 
878  | 833  |     int i;  | 
879  |  |  | 
880  | 833  |     if (CRYPTO_UP_REF(&ss->references, &i) <= 0)  | 
881  | 0  |         return 0;  | 
882  |  |  | 
883  | 833  |     REF_PRINT_COUNT("SSL_SESSION", i, ss); | 
884  | 833  |     REF_ASSERT_ISNT(i < 2);  | 
885  | 833  |     return ((i > 1) ? 1 : 0);  | 
886  | 833  | }  | 
887  |  |  | 
888  |  | int SSL_set_session(SSL *s, SSL_SESSION *session)  | 
889  | 0  | { | 
890  | 0  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);  | 
891  |  | 
  | 
892  | 0  |     if (sc == NULL)  | 
893  | 0  |         return 0;  | 
894  |  |  | 
895  | 0  |     ssl_clear_bad_session(sc);  | 
896  | 0  |     if (s->defltmeth != s->method) { | 
897  | 0  |         if (!SSL_set_ssl_method(s, s->defltmeth))  | 
898  | 0  |             return 0;  | 
899  | 0  |     }  | 
900  |  |  | 
901  | 0  |     if (session != NULL) { | 
902  | 0  |         SSL_SESSION_up_ref(session);  | 
903  | 0  |         sc->verify_result = session->verify_result;  | 
904  | 0  |     }  | 
905  | 0  |     SSL_SESSION_free(sc->session);  | 
906  | 0  |     sc->session = session;  | 
907  |  | 
  | 
908  | 0  |     return 1;  | 
909  | 0  | }  | 
910  |  |  | 
911  |  | int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,  | 
912  |  |                         unsigned int sid_len)  | 
913  | 0  | { | 
914  | 0  |     if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { | 
915  | 0  |       ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_TOO_LONG);  | 
916  | 0  |       return 0;  | 
917  | 0  |     }  | 
918  | 0  |     s->session_id_length = sid_len;  | 
919  | 0  |     if (sid != s->session_id && sid_len > 0)  | 
920  | 0  |         memcpy(s->session_id, sid, sid_len);  | 
921  |  | 
  | 
922  | 0  |     return 1;  | 
923  | 0  | }  | 
924  |  |  | 
925  |  | long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)  | 
926  | 0  | { | 
927  | 0  |     OSSL_TIME new_timeout = ossl_seconds2time(t);  | 
928  |  | 
  | 
929  | 0  |     if (s == NULL || t < 0)  | 
930  | 0  |         return 0;  | 
931  | 0  |     if (s->owner != NULL) { | 
932  | 0  |         if (!CRYPTO_THREAD_write_lock(s->owner->lock))  | 
933  | 0  |             return 0;  | 
934  | 0  |         s->timeout = new_timeout;  | 
935  | 0  |         ssl_session_calculate_timeout(s);  | 
936  | 0  |         SSL_SESSION_list_add(s->owner, s);  | 
937  | 0  |         CRYPTO_THREAD_unlock(s->owner->lock);  | 
938  | 0  |     } else { | 
939  | 0  |         s->timeout = new_timeout;  | 
940  | 0  |         ssl_session_calculate_timeout(s);  | 
941  | 0  |     }  | 
942  | 0  |     return 1;  | 
943  | 0  | }  | 
944  |  |  | 
945  |  | long SSL_SESSION_get_timeout(const SSL_SESSION *s)  | 
946  | 0  | { | 
947  | 0  |     if (s == NULL)  | 
948  | 0  |         return 0;  | 
949  | 0  |     return (long)ossl_time_to_time_t(s->timeout);  | 
950  | 0  | }  | 
951  |  |  | 
952  |  | long SSL_SESSION_get_time(const SSL_SESSION *s)  | 
953  | 0  | { | 
954  | 0  |     if (s == NULL)  | 
955  | 0  |         return 0;  | 
956  | 0  |     return (long)ossl_time_to_time_t(s->time);  | 
957  | 0  | }  | 
958  |  |  | 
959  |  | long SSL_SESSION_set_time(SSL_SESSION *s, long t)  | 
960  | 0  | { | 
961  | 0  |     OSSL_TIME new_time = ossl_time_from_time_t((time_t)t);  | 
962  |  | 
  | 
963  | 0  |     if (s == NULL)  | 
964  | 0  |         return 0;  | 
965  | 0  |     if (s->owner != NULL) { | 
966  | 0  |         if (!CRYPTO_THREAD_write_lock(s->owner->lock))  | 
967  | 0  |             return 0;  | 
968  | 0  |         s->time = new_time;  | 
969  | 0  |         ssl_session_calculate_timeout(s);  | 
970  | 0  |         SSL_SESSION_list_add(s->owner, s);  | 
971  | 0  |         CRYPTO_THREAD_unlock(s->owner->lock);  | 
972  | 0  |     } else { | 
973  | 0  |         s->time = new_time;  | 
974  | 0  |         ssl_session_calculate_timeout(s);  | 
975  | 0  |     }  | 
976  | 0  |     return t;  | 
977  | 0  | }  | 
978  |  |  | 
979  |  | int SSL_SESSION_get_protocol_version(const SSL_SESSION *s)  | 
980  | 0  | { | 
981  | 0  |     return s->ssl_version;  | 
982  | 0  | }  | 
983  |  |  | 
984  |  | int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version)  | 
985  | 0  | { | 
986  | 0  |     s->ssl_version = version;  | 
987  | 0  |     return 1;  | 
988  | 0  | }  | 
989  |  |  | 
990  |  | const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s)  | 
991  | 0  | { | 
992  | 0  |     return s->cipher;  | 
993  | 0  | }  | 
994  |  |  | 
995  |  | int SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher)  | 
996  | 0  | { | 
997  | 0  |     s->cipher = cipher;  | 
998  | 0  |     return 1;  | 
999  | 0  | }  | 
1000  |  |  | 
1001  |  | const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s)  | 
1002  | 0  | { | 
1003  | 0  |     return s->ext.hostname;  | 
1004  | 0  | }  | 
1005  |  |  | 
1006  |  | int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname)  | 
1007  | 0  | { | 
1008  | 0  |     OPENSSL_free(s->ext.hostname);  | 
1009  | 0  |     if (hostname == NULL) { | 
1010  | 0  |         s->ext.hostname = NULL;  | 
1011  | 0  |         return 1;  | 
1012  | 0  |     }  | 
1013  | 0  |     s->ext.hostname = OPENSSL_strdup(hostname);  | 
1014  |  | 
  | 
1015  | 0  |     return s->ext.hostname != NULL;  | 
1016  | 0  | }  | 
1017  |  |  | 
1018  |  | int SSL_SESSION_has_ticket(const SSL_SESSION *s)  | 
1019  | 0  | { | 
1020  | 0  |     return (s->ext.ticklen > 0) ? 1 : 0;  | 
1021  | 0  | }  | 
1022  |  |  | 
1023  |  | unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s)  | 
1024  | 0  | { | 
1025  | 0  |     return s->ext.tick_lifetime_hint;  | 
1026  | 0  | }  | 
1027  |  |  | 
1028  |  | void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick,  | 
1029  |  |                              size_t *len)  | 
1030  | 0  | { | 
1031  | 0  |     *len = s->ext.ticklen;  | 
1032  | 0  |     if (tick != NULL)  | 
1033  | 0  |         *tick = s->ext.tick;  | 
1034  | 0  | }  | 
1035  |  |  | 
1036  |  | uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s)  | 
1037  | 0  | { | 
1038  | 0  |     return s->ext.max_early_data;  | 
1039  | 0  | }  | 
1040  |  |  | 
1041  |  | int SSL_SESSION_set_max_early_data(SSL_SESSION *s, uint32_t max_early_data)  | 
1042  | 0  | { | 
1043  | 0  |     s->ext.max_early_data = max_early_data;  | 
1044  |  | 
  | 
1045  | 0  |     return 1;  | 
1046  | 0  | }  | 
1047  |  |  | 
1048  |  | void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s,  | 
1049  |  |                                     const unsigned char **alpn,  | 
1050  |  |                                     size_t *len)  | 
1051  | 0  | { | 
1052  | 0  |     *alpn = s->ext.alpn_selected;  | 
1053  | 0  |     *len = s->ext.alpn_selected_len;  | 
1054  | 0  | }  | 
1055  |  |  | 
1056  |  | int SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, const unsigned char *alpn,  | 
1057  |  |                                    size_t len)  | 
1058  | 0  | { | 
1059  | 0  |     OPENSSL_free(s->ext.alpn_selected);  | 
1060  | 0  |     if (alpn == NULL || len == 0) { | 
1061  | 0  |         s->ext.alpn_selected = NULL;  | 
1062  | 0  |         s->ext.alpn_selected_len = 0;  | 
1063  | 0  |         return 1;  | 
1064  | 0  |     }  | 
1065  | 0  |     s->ext.alpn_selected = OPENSSL_memdup(alpn, len);  | 
1066  | 0  |     if (s->ext.alpn_selected == NULL) { | 
1067  | 0  |         s->ext.alpn_selected_len = 0;  | 
1068  | 0  |         return 0;  | 
1069  | 0  |     }  | 
1070  | 0  |     s->ext.alpn_selected_len = len;  | 
1071  |  | 
  | 
1072  | 0  |     return 1;  | 
1073  | 0  | }  | 
1074  |  |  | 
1075  |  | X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)  | 
1076  | 0  | { | 
1077  | 0  |     return s->peer;  | 
1078  | 0  | }  | 
1079  |  |  | 
1080  |  | EVP_PKEY *SSL_SESSION_get0_peer_rpk(SSL_SESSION *s)  | 
1081  | 0  | { | 
1082  | 0  |     return s->peer_rpk;  | 
1083  | 0  | }  | 
1084  |  |  | 
1085  |  | int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,  | 
1086  |  |                                 unsigned int sid_ctx_len)  | 
1087  | 0  | { | 
1088  | 0  |     if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { | 
1089  | 0  |         ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);  | 
1090  | 0  |         return 0;  | 
1091  | 0  |     }  | 
1092  | 0  |     s->sid_ctx_length = sid_ctx_len;  | 
1093  | 0  |     if (sid_ctx != s->sid_ctx)  | 
1094  | 0  |         memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);  | 
1095  |  | 
  | 
1096  | 0  |     return 1;  | 
1097  | 0  | }  | 
1098  |  |  | 
1099  |  | int SSL_SESSION_is_resumable(const SSL_SESSION *s)  | 
1100  | 1.79k  | { | 
1101  |  |     /*  | 
1102  |  |      * In the case of EAP-FAST, we can have a pre-shared "ticket" without a  | 
1103  |  |      * session ID.  | 
1104  |  |      */  | 
1105  | 1.79k  |     return !s->not_resumable  | 
1106  | 1.79k  |            && (s->session_id_length > 0 || s->ext.ticklen > 0);  | 
1107  | 1.79k  | }  | 
1108  |  |  | 
1109  |  | long SSL_CTX_set_timeout(SSL_CTX *s, long t)  | 
1110  | 0  | { | 
1111  | 0  |     long l;  | 
1112  |  | 
  | 
1113  | 0  |     if (s == NULL)  | 
1114  | 0  |         return 0;  | 
1115  | 0  |     l = (long)ossl_time2seconds(s->session_timeout);  | 
1116  | 0  |     s->session_timeout = ossl_seconds2time(t);  | 
1117  | 0  |     return l;  | 
1118  | 0  | }  | 
1119  |  |  | 
1120  |  | long SSL_CTX_get_timeout(const SSL_CTX *s)  | 
1121  | 0  | { | 
1122  | 0  |     if (s == NULL)  | 
1123  | 0  |         return 0;  | 
1124  | 0  |     return (long)ossl_time2seconds(s->session_timeout);  | 
1125  | 0  | }  | 
1126  |  |  | 
1127  |  | int SSL_set_session_secret_cb(SSL *s,  | 
1128  |  |                               tls_session_secret_cb_fn tls_session_secret_cb,  | 
1129  |  |                               void *arg)  | 
1130  | 0  | { | 
1131  | 0  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);  | 
1132  |  | 
  | 
1133  | 0  |     if (sc == NULL)  | 
1134  | 0  |         return 0;  | 
1135  |  |  | 
1136  | 0  |     sc->ext.session_secret_cb = tls_session_secret_cb;  | 
1137  | 0  |     sc->ext.session_secret_cb_arg = arg;  | 
1138  | 0  |     return 1;  | 
1139  | 0  | }  | 
1140  |  |  | 
1141  |  | int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,  | 
1142  |  |                                   void *arg)  | 
1143  | 0  | { | 
1144  | 0  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);  | 
1145  |  | 
  | 
1146  | 0  |     if (sc == NULL)  | 
1147  | 0  |         return 0;  | 
1148  |  |  | 
1149  | 0  |     sc->ext.session_ticket_cb = cb;  | 
1150  | 0  |     sc->ext.session_ticket_cb_arg = arg;  | 
1151  | 0  |     return 1;  | 
1152  | 0  | }  | 
1153  |  |  | 
1154  |  | int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)  | 
1155  | 0  | { | 
1156  | 0  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);  | 
1157  |  | 
  | 
1158  | 0  |     if (sc == NULL)  | 
1159  | 0  |         return 0;  | 
1160  |  |  | 
1161  | 0  |     if (sc->version >= TLS1_VERSION) { | 
1162  | 0  |         OPENSSL_free(sc->ext.session_ticket);  | 
1163  | 0  |         sc->ext.session_ticket = NULL;  | 
1164  | 0  |         sc->ext.session_ticket =  | 
1165  | 0  |             OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);  | 
1166  | 0  |         if (sc->ext.session_ticket == NULL)  | 
1167  | 0  |             return 0;  | 
1168  |  |  | 
1169  | 0  |         if (ext_data != NULL) { | 
1170  | 0  |             sc->ext.session_ticket->length = ext_len;  | 
1171  | 0  |             sc->ext.session_ticket->data = sc->ext.session_ticket + 1;  | 
1172  | 0  |             memcpy(sc->ext.session_ticket->data, ext_data, ext_len);  | 
1173  | 0  |         } else { | 
1174  | 0  |             sc->ext.session_ticket->length = 0;  | 
1175  | 0  |             sc->ext.session_ticket->data = NULL;  | 
1176  | 0  |         }  | 
1177  |  | 
  | 
1178  | 0  |         return 1;  | 
1179  | 0  |     }  | 
1180  |  |  | 
1181  | 0  |     return 0;  | 
1182  | 0  | }  | 
1183  |  |  | 
1184  |  | void SSL_CTX_flush_sessions(SSL_CTX *s, long t)  | 
1185  | 48.2k  | { | 
1186  | 48.2k  |     STACK_OF(SSL_SESSION) *sk;  | 
1187  | 48.2k  |     SSL_SESSION *current;  | 
1188  | 48.2k  |     unsigned long i;  | 
1189  | 48.2k  |     const OSSL_TIME timeout = ossl_time_from_time_t(t);  | 
1190  |  |  | 
1191  | 48.2k  |     if (!CRYPTO_THREAD_write_lock(s->lock))  | 
1192  | 0  |         return;  | 
1193  |  |  | 
1194  | 48.2k  |     sk = sk_SSL_SESSION_new_null();  | 
1195  | 48.2k  |     i = lh_SSL_SESSION_get_down_load(s->sessions);  | 
1196  | 48.2k  |     lh_SSL_SESSION_set_down_load(s->sessions, 0);  | 
1197  |  |  | 
1198  |  |     /*  | 
1199  |  |      * Iterate over the list from the back (oldest), and stop  | 
1200  |  |      * when a session can no longer be removed.  | 
1201  |  |      * Add the session to a temporary list to be freed outside  | 
1202  |  |      * the SSL_CTX lock.  | 
1203  |  |      * But still do the remove_session_cb() within the lock.  | 
1204  |  |      */  | 
1205  | 48.3k  |     while (s->session_cache_tail != NULL) { | 
1206  | 60  |         current = s->session_cache_tail;  | 
1207  | 60  |         if (t == 0 || sess_timedout(timeout, current)) { | 
1208  | 60  |             lh_SSL_SESSION_delete(s->sessions, current);  | 
1209  | 60  |             SSL_SESSION_list_remove(s, current);  | 
1210  | 60  |             current->not_resumable = 1;  | 
1211  | 60  |             if (s->remove_session_cb != NULL)  | 
1212  | 0  |                 s->remove_session_cb(s, current);  | 
1213  |  |             /*  | 
1214  |  |              * Throw the session on a stack, it's entirely plausible  | 
1215  |  |              * that while freeing outside the critical section, the  | 
1216  |  |              * session could be re-added, so avoid using the next/prev  | 
1217  |  |              * pointers. If the stack failed to create, or the session  | 
1218  |  |              * couldn't be put on the stack, just free it here  | 
1219  |  |              */  | 
1220  | 60  |             if (sk == NULL || !sk_SSL_SESSION_push(sk, current))  | 
1221  | 0  |                 SSL_SESSION_free(current);  | 
1222  | 60  |         } else { | 
1223  | 0  |             break;  | 
1224  | 0  |         }  | 
1225  | 60  |     }  | 
1226  |  |  | 
1227  | 48.2k  |     lh_SSL_SESSION_set_down_load(s->sessions, i);  | 
1228  | 48.2k  |     CRYPTO_THREAD_unlock(s->lock);  | 
1229  |  |  | 
1230  | 48.2k  |     sk_SSL_SESSION_pop_free(sk, SSL_SESSION_free);  | 
1231  | 48.2k  | }  | 
1232  |  |  | 
1233  |  | int ssl_clear_bad_session(SSL_CONNECTION *s)  | 
1234  | 232k  | { | 
1235  | 232k  |     if ((s->session != NULL) &&  | 
1236  | 232k  |         !(s->shutdown & SSL_SENT_SHUTDOWN) &&  | 
1237  | 232k  |         !(SSL_in_init(SSL_CONNECTION_GET_SSL(s))  | 
1238  | 74.2k  |           || SSL_in_before(SSL_CONNECTION_GET_SSL(s)))) { | 
1239  | 4.38k  |         SSL_CTX_remove_session(s->session_ctx, s->session);  | 
1240  | 4.38k  |         return 1;  | 
1241  | 4.38k  |     } else  | 
1242  | 228k  |         return 0;  | 
1243  | 232k  | }  | 
1244  |  |  | 
1245  |  | /* locked by SSL_CTX in the calling function */  | 
1246  |  | static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)  | 
1247  | 833  | { | 
1248  | 833  |     if ((s->next == NULL) || (s->prev == NULL))  | 
1249  | 0  |         return;  | 
1250  |  |  | 
1251  | 833  |     if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { | 
1252  |  |         /* last element in list */  | 
1253  | 833  |         if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { | 
1254  |  |             /* only one element in list */  | 
1255  | 833  |             ctx->session_cache_head = NULL;  | 
1256  | 833  |             ctx->session_cache_tail = NULL;  | 
1257  | 833  |         } else { | 
1258  | 0  |             ctx->session_cache_tail = s->prev;  | 
1259  | 0  |             s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);  | 
1260  | 0  |         }  | 
1261  | 833  |     } else { | 
1262  | 0  |         if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { | 
1263  |  |             /* first element in list */  | 
1264  | 0  |             ctx->session_cache_head = s->next;  | 
1265  | 0  |             s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);  | 
1266  | 0  |         } else { | 
1267  |  |             /* middle of list */  | 
1268  | 0  |             s->next->prev = s->prev;  | 
1269  | 0  |             s->prev->next = s->next;  | 
1270  | 0  |         }  | 
1271  | 0  |     }  | 
1272  | 833  |     s->prev = s->next = NULL;  | 
1273  | 833  |     s->owner = NULL;  | 
1274  | 833  | }  | 
1275  |  |  | 
1276  |  | static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)  | 
1277  | 833  | { | 
1278  | 833  |     SSL_SESSION *next;  | 
1279  |  |  | 
1280  | 833  |     if ((s->next != NULL) && (s->prev != NULL))  | 
1281  | 0  |         SSL_SESSION_list_remove(ctx, s);  | 
1282  |  |  | 
1283  | 833  |     if (ctx->session_cache_head == NULL) { | 
1284  | 833  |         ctx->session_cache_head = s;  | 
1285  | 833  |         ctx->session_cache_tail = s;  | 
1286  | 833  |         s->prev = (SSL_SESSION *)&(ctx->session_cache_head);  | 
1287  | 833  |         s->next = (SSL_SESSION *)&(ctx->session_cache_tail);  | 
1288  | 833  |     } else { | 
1289  | 0  |         if (timeoutcmp(s, ctx->session_cache_head) >= 0) { | 
1290  |  |             /*  | 
1291  |  |              * if we timeout after (or the same time as) the first  | 
1292  |  |              * session, put us first - usual case  | 
1293  |  |              */  | 
1294  | 0  |             s->next = ctx->session_cache_head;  | 
1295  | 0  |             s->next->prev = s;  | 
1296  | 0  |             s->prev = (SSL_SESSION *)&(ctx->session_cache_head);  | 
1297  | 0  |             ctx->session_cache_head = s;  | 
1298  | 0  |         } else if (timeoutcmp(s, ctx->session_cache_tail) < 0) { | 
1299  |  |             /* if we timeout before the last session, put us last */  | 
1300  | 0  |             s->prev = ctx->session_cache_tail;  | 
1301  | 0  |             s->prev->next = s;  | 
1302  | 0  |             s->next = (SSL_SESSION *)&(ctx->session_cache_tail);  | 
1303  | 0  |             ctx->session_cache_tail = s;  | 
1304  | 0  |         } else { | 
1305  |  |             /*  | 
1306  |  |              * we timeout somewhere in-between - if there is only  | 
1307  |  |              * one session in the cache it will be caught above  | 
1308  |  |              */  | 
1309  | 0  |             next = ctx->session_cache_head->next;  | 
1310  | 0  |             while (next != (SSL_SESSION*)&(ctx->session_cache_tail)) { | 
1311  | 0  |                 if (timeoutcmp(s, next) >= 0) { | 
1312  | 0  |                     s->next = next;  | 
1313  | 0  |                     s->prev = next->prev;  | 
1314  | 0  |                     next->prev->next = s;  | 
1315  | 0  |                     next->prev = s;  | 
1316  | 0  |                     break;  | 
1317  | 0  |                 }  | 
1318  | 0  |                 next = next->next;  | 
1319  | 0  |             }  | 
1320  | 0  |         }  | 
1321  | 0  |     }  | 
1322  | 833  |     s->owner = ctx;  | 
1323  | 833  | }  | 
1324  |  |  | 
1325  |  | void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,  | 
1326  |  |                              int (*cb) (struct ssl_st *ssl, SSL_SESSION *sess))  | 
1327  | 0  | { | 
1328  | 0  |     ctx->new_session_cb = cb;  | 
1329  | 0  | }  | 
1330  |  |  | 
1331  | 0  | int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { | 
1332  | 0  |     return ctx->new_session_cb;  | 
1333  | 0  | }  | 
1334  |  |  | 
1335  |  | void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,  | 
1336  |  |                                 void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess))  | 
1337  | 0  | { | 
1338  | 0  |     ctx->remove_session_cb = cb;  | 
1339  | 0  | }  | 
1340  |  |  | 
1341  |  | void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx,  | 
1342  | 0  |                                                   SSL_SESSION *sess) { | 
1343  | 0  |     return ctx->remove_session_cb;  | 
1344  | 0  | }  | 
1345  |  |  | 
1346  |  | void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,  | 
1347  |  |                              SSL_SESSION *(*cb) (SSL *ssl,  | 
1348  |  |                                                  const unsigned char *data,  | 
1349  |  |                                                  int len, int *copy))  | 
1350  | 0  | { | 
1351  | 0  |     ctx->get_session_cb = cb;  | 
1352  | 0  | }  | 
1353  |  |  | 
1354  |  | SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl,  | 
1355  |  |                                                        const unsigned char  | 
1356  |  |                                                        *data, int len,  | 
1357  | 0  |                                                        int *copy) { | 
1358  | 0  |     return ctx->get_session_cb;  | 
1359  | 0  | }  | 
1360  |  |  | 
1361  |  | void SSL_CTX_set_info_callback(SSL_CTX *ctx,  | 
1362  |  |                                void (*cb) (const SSL *ssl, int type, int val))  | 
1363  | 0  | { | 
1364  | 0  |     ctx->info_callback = cb;  | 
1365  | 0  | }  | 
1366  |  |  | 
1367  |  | void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,  | 
1368  | 0  |                                                  int val) { | 
1369  | 0  |     return ctx->info_callback;  | 
1370  | 0  | }  | 
1371  |  |  | 
1372  |  | void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,  | 
1373  |  |                                 int (*cb) (SSL *ssl, X509 **x509,  | 
1374  |  |                                            EVP_PKEY **pkey))  | 
1375  | 0  | { | 
1376  | 0  |     ctx->client_cert_cb = cb;  | 
1377  | 0  | }  | 
1378  |  |  | 
1379  |  | int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,  | 
1380  | 0  |                                                  EVP_PKEY **pkey) { | 
1381  | 0  |     return ctx->client_cert_cb;  | 
1382  | 0  | }  | 
1383  |  |  | 
1384  |  | void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,  | 
1385  |  |                                     int (*cb) (SSL *ssl,  | 
1386  |  |                                                unsigned char *cookie,  | 
1387  |  |                                                unsigned int *cookie_len))  | 
1388  | 0  | { | 
1389  | 0  |     ctx->app_gen_cookie_cb = cb;  | 
1390  | 0  | }  | 
1391  |  |  | 
1392  |  | void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,  | 
1393  |  |                                   int (*cb) (SSL *ssl,  | 
1394  |  |                                              const unsigned char *cookie,  | 
1395  |  |                                              unsigned int cookie_len))  | 
1396  | 0  | { | 
1397  | 0  |     ctx->app_verify_cookie_cb = cb;  | 
1398  | 0  | }  | 
1399  |  |  | 
1400  |  | int SSL_SESSION_set1_ticket_appdata(SSL_SESSION *ss, const void *data, size_t len)  | 
1401  | 0  | { | 
1402  | 0  |     OPENSSL_free(ss->ticket_appdata);  | 
1403  | 0  |     ss->ticket_appdata_len = 0;  | 
1404  | 0  |     if (data == NULL || len == 0) { | 
1405  | 0  |         ss->ticket_appdata = NULL;  | 
1406  | 0  |         return 1;  | 
1407  | 0  |     }  | 
1408  | 0  |     ss->ticket_appdata = OPENSSL_memdup(data, len);  | 
1409  | 0  |     if (ss->ticket_appdata != NULL) { | 
1410  | 0  |         ss->ticket_appdata_len = len;  | 
1411  | 0  |         return 1;  | 
1412  | 0  |     }  | 
1413  | 0  |     return 0;  | 
1414  | 0  | }  | 
1415  |  |  | 
1416  |  | int SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len)  | 
1417  | 0  | { | 
1418  | 0  |     *data = ss->ticket_appdata;  | 
1419  | 0  |     *len = ss->ticket_appdata_len;  | 
1420  | 0  |     return 1;  | 
1421  | 0  | }  | 
1422  |  |  | 
1423  |  | void SSL_CTX_set_stateless_cookie_generate_cb(  | 
1424  |  |     SSL_CTX *ctx,  | 
1425  |  |     int (*cb) (SSL *ssl,  | 
1426  |  |                unsigned char *cookie,  | 
1427  |  |                size_t *cookie_len))  | 
1428  | 0  | { | 
1429  | 0  |     ctx->gen_stateless_cookie_cb = cb;  | 
1430  | 0  | }  | 
1431  |  |  | 
1432  |  | void SSL_CTX_set_stateless_cookie_verify_cb(  | 
1433  |  |     SSL_CTX *ctx,  | 
1434  |  |     int (*cb) (SSL *ssl,  | 
1435  |  |                const unsigned char *cookie,  | 
1436  |  |                size_t cookie_len))  | 
1437  | 0  | { | 
1438  | 0  |     ctx->verify_stateless_cookie_cb = cb;  | 
1439  | 0  | }  | 
1440  |  |  | 
1441  |  | IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)  |