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