]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/ssl/ssl_sess.c
Fix OpenSSL multiple vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / ssl / ssl_sess.c
1 /* ssl/ssl_sess.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include <openssl/lhash.h>
61 #include <openssl/rand.h>
62 #ifndef OPENSSL_NO_ENGINE
63 #include <openssl/engine.h>
64 #endif
65 #include "ssl_locl.h"
66
67 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
68 static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
69 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
70
71 SSL_SESSION *SSL_get_session(const SSL *ssl)
72 /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
73         {
74         return(ssl->session);
75         }
76
77 SSL_SESSION *SSL_get1_session(SSL *ssl)
78 /* variant of SSL_get_session: caller really gets something */
79         {
80         SSL_SESSION *sess;
81         /* Need to lock this all up rather than just use CRYPTO_add so that
82          * somebody doesn't free ssl->session between when we check it's
83          * non-null and when we up the reference count. */
84         CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION);
85         sess = ssl->session;
86         if(sess)
87                 sess->references++;
88         CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION);
89         return(sess);
90         }
91
92 int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
93              CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
94         {
95         return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
96                         new_func, dup_func, free_func);
97         }
98
99 int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
100         {
101         return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
102         }
103
104 void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
105         {
106         return(CRYPTO_get_ex_data(&s->ex_data,idx));
107         }
108
109 SSL_SESSION *SSL_SESSION_new(void)
110         {
111         SSL_SESSION *ss;
112
113         ss=(SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
114         if (ss == NULL)
115                 {
116                 SSLerr(SSL_F_SSL_SESSION_NEW,ERR_R_MALLOC_FAILURE);
117                 return(0);
118                 }
119         memset(ss,0,sizeof(SSL_SESSION));
120
121         ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
122         ss->references=1;
123         ss->timeout=60*5+4; /* 5 minute timeout by default */
124         ss->time=(unsigned long)time(NULL);
125         ss->prev=NULL;
126         ss->next=NULL;
127         ss->compress_meth=0;
128 #ifndef OPENSSL_NO_TLSEXT
129         ss->tlsext_hostname = NULL; 
130 #endif
131         CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
132         return(ss);
133         }
134
135 /*
136  * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
137  * ticket == 0 then no ticket information is duplicated, otherwise it is.
138  */
139 SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
140 {
141     SSL_SESSION *dest;
142
143     dest = OPENSSL_malloc(sizeof(*src));
144     if (dest == NULL) {
145         goto err;
146     }
147     memcpy(dest, src, sizeof(*dest));
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     dest->ciphers = NULL;
154 #ifndef OPENSSL_NO_TLSEXT
155     dest->tlsext_hostname = NULL;
156 #endif
157     dest->tlsext_tick = NULL;
158     memset(&dest->ex_data, 0, sizeof(dest->ex_data));
159
160     /* We deliberately don't copy the prev and next pointers */
161     dest->prev = NULL;
162     dest->next = NULL;
163
164     dest->references = 1;
165
166     if (src->sess_cert != NULL)
167         CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
168
169     if (src->peer != NULL)
170         CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
171
172     if(src->ciphers != NULL) {
173         dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
174         if (dest->ciphers == NULL)
175             goto err;
176     }
177
178     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
179                                             &dest->ex_data, &src->ex_data)) {
180         goto err;
181     }
182
183 #ifndef OPENSSL_NO_TLSEXT
184     if (src->tlsext_hostname) {
185         dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
186         if (dest->tlsext_hostname == NULL) {
187             goto err;
188         }
189     }
190 #endif
191
192     if (ticket != 0) {
193         dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
194         if(dest->tlsext_tick == NULL)
195             goto err;
196     } else {
197         dest->tlsext_tick_lifetime_hint = 0;
198         dest->tlsext_ticklen = 0;
199     }
200
201     return dest;
202 err:
203     SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
204     SSL_SESSION_free(dest);
205     return NULL;
206 }
207
208 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
209         {
210         if(len)
211                 *len = s->session_id_length;
212         return s->session_id;
213         }
214
215 /* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
216  * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
217  * until we have no conflict is going to complete in one iteration pretty much
218  * "most" of the time (btw: understatement). So, if it takes us 10 iterations
219  * and we still can't avoid a conflict - well that's a reasonable point to call
220  * it quits. Either the RAND code is broken or someone is trying to open roughly
221  * very close to 2^128 (or 2^256) SSL sessions to our server. How you might
222  * store that many sessions is perhaps a more interesting question ... */
223
224 #define MAX_SESS_ID_ATTEMPTS 10
225 static int def_generate_session_id(const SSL *ssl, unsigned char *id,
226                                 unsigned int *id_len)
227 {
228         unsigned int retry = 0;
229         do
230                 if (RAND_pseudo_bytes(id, *id_len) <= 0)
231                         return 0;
232         while(SSL_has_matching_session_id(ssl, id, *id_len) &&
233                 (++retry < MAX_SESS_ID_ATTEMPTS));
234         if(retry < MAX_SESS_ID_ATTEMPTS)
235                 return 1;
236         /* else - woops a session_id match */
237         /* XXX We should also check the external cache --
238          * but the probability of a collision is negligible, and
239          * we could not prevent the concurrent creation of sessions
240          * with identical IDs since we currently don't have means
241          * to atomically check whether a session ID already exists
242          * and make a reservation for it if it does not
243          * (this problem applies to the internal cache as well).
244          */
245         return 0;
246 }
247
248 int ssl_get_new_session(SSL *s, int session)
249         {
250         /* This gets used by clients and servers. */
251
252         unsigned int tmp;
253         SSL_SESSION *ss=NULL;
254         GEN_SESSION_CB cb = def_generate_session_id;
255
256         if ((ss=SSL_SESSION_new()) == NULL) return(0);
257
258         /* If the context has a default timeout, use it */
259         if (s->ctx->session_timeout == 0)
260                 ss->timeout=SSL_get_default_timeout(s);
261         else
262                 ss->timeout=s->ctx->session_timeout;
263
264         if (s->session != NULL)
265                 {
266                 SSL_SESSION_free(s->session);
267                 s->session=NULL;
268                 }
269
270         if (session)
271                 {
272                 if (s->version == SSL2_VERSION)
273                         {
274                         ss->ssl_version=SSL2_VERSION;
275                         ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
276                         }
277                 else if (s->version == SSL3_VERSION)
278                         {
279                         ss->ssl_version=SSL3_VERSION;
280                         ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
281                         }
282                 else if (s->version == TLS1_VERSION)
283                         {
284                         ss->ssl_version=TLS1_VERSION;
285                         ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
286                         }
287                 else if (s->version == DTLS1_BAD_VER)
288                         {
289                         ss->ssl_version=DTLS1_BAD_VER;
290                         ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
291                         }
292                 else if (s->version == DTLS1_VERSION)
293                         {
294                         ss->ssl_version=DTLS1_VERSION;
295                         ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
296                         }
297                 else
298                         {
299                         SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
300                         SSL_SESSION_free(ss);
301                         return(0);
302                         }
303 #ifndef OPENSSL_NO_TLSEXT
304                 /* If RFC4507 ticket use empty session ID */
305                 if (s->tlsext_ticket_expected)
306                         {
307                         ss->session_id_length = 0;
308                         goto sess_id_done;
309                         }
310 #endif
311                 /* Choose which callback will set the session ID */
312                 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
313                 if(s->generate_session_id)
314                         cb = s->generate_session_id;
315                 else if(s->ctx->generate_session_id)
316                         cb = s->ctx->generate_session_id;
317                 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
318                 /* Choose a session ID */
319                 tmp = ss->session_id_length;
320                 if(!cb(s, ss->session_id, &tmp))
321                         {
322                         /* The callback failed */
323                         SSLerr(SSL_F_SSL_GET_NEW_SESSION,
324                                 SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
325                         SSL_SESSION_free(ss);
326                         return(0);
327                         }
328                 /* Don't allow the callback to set the session length to zero.
329                  * nor set it higher than it was. */
330                 if(!tmp || (tmp > ss->session_id_length))
331                         {
332                         /* The callback set an illegal length */
333                         SSLerr(SSL_F_SSL_GET_NEW_SESSION,
334                                 SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
335                         SSL_SESSION_free(ss);
336                         return(0);
337                         }
338                 /* If the session length was shrunk and we're SSLv2, pad it */
339                 if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
340                         memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
341                 else
342                         ss->session_id_length = tmp;
343                 /* Finally, check for a conflict */
344                 if(SSL_has_matching_session_id(s, ss->session_id,
345                                                 ss->session_id_length))
346                         {
347                         SSLerr(SSL_F_SSL_GET_NEW_SESSION,
348                                 SSL_R_SSL_SESSION_ID_CONFLICT);
349                         SSL_SESSION_free(ss);
350                         return(0);
351                         }
352 #ifndef OPENSSL_NO_TLSEXT
353                 sess_id_done:
354                 if (s->tlsext_hostname) {
355                         ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
356                         if (ss->tlsext_hostname == NULL) {
357                                 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
358                                 SSL_SESSION_free(ss);
359                                 return 0;
360                                 }
361                         }
362 #endif
363                 }
364         else
365                 {
366                 ss->session_id_length=0;
367                 }
368
369         if (s->sid_ctx_length > sizeof ss->sid_ctx)
370                 {
371                 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
372                 SSL_SESSION_free(ss);
373                 return 0;
374                 }
375         memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length);
376         ss->sid_ctx_length=s->sid_ctx_length;
377         s->session=ss;
378         ss->ssl_version=s->version;
379         ss->verify_result = X509_V_OK;
380
381         return(1);
382         }
383
384 int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
385                         const unsigned char *limit)
386         {
387         /* This is used only by servers. */
388
389         SSL_SESSION *ret=NULL;
390         int fatal = 0;
391 #ifndef OPENSSL_NO_TLSEXT
392         int r;
393 #endif
394   
395         if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
396                 goto err;
397 #ifndef OPENSSL_NO_TLSEXT
398         r = tls1_process_ticket(s, session_id, len, limit, &ret);
399         if (r == -1)
400                 {
401                 fatal = 1;
402                 goto err;
403                 }
404         else if (r == 0 || (!ret && !len))
405                 goto err;
406         else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
407 #else
408         if (len == 0)
409                 goto err;
410         if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
411 #endif
412                 {
413                 SSL_SESSION data;
414                 data.ssl_version=s->version;
415                 data.session_id_length=len;
416                 if (len == 0)
417                         return 0;
418                 memcpy(data.session_id,session_id,len);
419                 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
420                 ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
421                 if (ret != NULL)
422                     /* don't allow other threads to steal it: */
423                     CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
424                 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
425                 }
426
427         if (ret == NULL)
428                 {
429                 int copy=1;
430         
431                 s->ctx->stats.sess_miss++;
432                 ret=NULL;
433                 if (s->ctx->get_session_cb != NULL
434                     && (ret=s->ctx->get_session_cb(s,session_id,len,&copy))
435                        != NULL)
436                         {
437                         s->ctx->stats.sess_cb_hit++;
438
439                         /* Increment reference count now if the session callback
440                          * asks us to do so (note that if the session structures
441                          * returned by the callback are shared between threads,
442                          * it must handle the reference count itself [i.e. copy == 0],
443                          * or things won't be thread-safe). */
444                         if (copy)
445                                 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
446
447                         /* Add the externally cached session to the internal
448                          * cache as well if and only if we are supposed to. */
449                         if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
450                                 /* The following should not return 1, otherwise,
451                                  * things are very strange */
452                                 SSL_CTX_add_session(s->ctx,ret);
453                         }
454                 if (ret == NULL)
455                         goto err;
456                 }
457
458         /* Now ret is non-NULL, and we own one of its reference counts. */
459
460         if (ret->sid_ctx_length != s->sid_ctx_length
461             || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
462                 {
463                 /* We've found the session named by the client, but we don't
464                  * want to use it in this context. */
465
466 #if 0 /* The client cannot always know when a session is not appropriate,
467        * so we shouldn't generate an error message. */
468
469                 SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
470 #endif
471                 goto err; /* treat like cache miss */
472                 }
473         
474         if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
475                 {
476                 /* We can't be sure if this session is being used out of
477                  * context, which is especially important for SSL_VERIFY_PEER.
478                  * The application should have used SSL[_CTX]_set_session_id_context.
479                  *
480                  * For this error case, we generate an error instead of treating
481                  * the event like a cache miss (otherwise it would be easy for
482                  * applications to effectively disable the session cache by
483                  * accident without anyone noticing).
484                  */
485                 
486                 SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
487                 fatal = 1;
488                 goto err;
489                 }
490
491         if (ret->cipher == NULL)
492                 {
493                 unsigned char buf[5],*p;
494                 unsigned long l;
495
496                 p=buf;
497                 l=ret->cipher_id;
498                 l2n(l,p);
499                 if ((ret->ssl_version>>8) >= SSL3_VERSION_MAJOR)
500                         ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
501                 else 
502                         ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
503                 if (ret->cipher == NULL)
504                         goto err;
505                 }
506
507
508 #if 0 /* This is way too late. */
509
510         /* If a thread got the session, then 'swaped', and another got
511          * it and then due to a time-out decided to 'OPENSSL_free' it we could
512          * be in trouble.  So I'll increment it now, then double decrement
513          * later - am I speaking rubbish?. */
514         CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
515 #endif
516
517         if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
518                 {
519                 s->ctx->stats.sess_timeout++;
520                 /* remove it from the cache */
521                 SSL_CTX_remove_session(s->ctx,ret);
522                 goto err;
523                 }
524
525         s->ctx->stats.sess_hit++;
526
527         /* ret->time=time(NULL); */ /* rezero timeout? */
528         /* again, just leave the session 
529          * if it is the same session, we have just incremented and
530          * then decremented the reference count :-) */
531         if (s->session != NULL)
532                 SSL_SESSION_free(s->session);
533         s->session=ret;
534         s->verify_result = s->session->verify_result;
535         return(1);
536
537  err:
538         if (ret != NULL)
539                 SSL_SESSION_free(ret);
540         if (fatal)
541                 return -1;
542         else
543                 return 0;
544         }
545
546 int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
547         {
548         int ret=0;
549         SSL_SESSION *s;
550
551         /* add just 1 reference count for the SSL_CTX's session cache
552          * even though it has two ways of access: each session is in a
553          * doubly linked list and an lhash */
554         CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
555         /* if session c is in already in cache, we take back the increment later */
556
557         CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
558         s=(SSL_SESSION *)lh_insert(ctx->sessions,c);
559         
560         /* s != NULL iff we already had a session with the given PID.
561          * In this case, s == c should hold (then we did not really modify
562          * ctx->sessions), or we're in trouble. */
563         if (s != NULL && s != c)
564                 {
565                 /* We *are* in trouble ... */
566                 SSL_SESSION_list_remove(ctx,s);
567                 SSL_SESSION_free(s);
568                 /* ... so pretend the other session did not exist in cache
569                  * (we cannot handle two SSL_SESSION structures with identical
570                  * session ID in the same cache, which could happen e.g. when
571                  * two threads concurrently obtain the same session from an external
572                  * cache) */
573                 s = NULL;
574                 }
575
576         /* Put at the head of the queue unless it is already in the cache */
577         if (s == NULL)
578                 SSL_SESSION_list_add(ctx,c);
579
580         if (s != NULL)
581                 {
582                 /* existing cache entry -- decrement previously incremented reference
583                  * count because it already takes into account the cache */
584
585                 SSL_SESSION_free(s); /* s == c */
586                 ret=0;
587                 }
588         else
589                 {
590                 /* new cache entry -- remove old ones if cache has become too large */
591                 
592                 ret=1;
593
594                 if (SSL_CTX_sess_get_cache_size(ctx) > 0)
595                         {
596                         while (SSL_CTX_sess_number(ctx) >
597                                 SSL_CTX_sess_get_cache_size(ctx))
598                                 {
599                                 if (!remove_session_lock(ctx,
600                                         ctx->session_cache_tail, 0))
601                                         break;
602                                 else
603                                         ctx->stats.sess_cache_full++;
604                                 }
605                         }
606                 }
607         CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
608         return(ret);
609         }
610
611 int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
612 {
613         return remove_session_lock(ctx, c, 1);
614 }
615
616 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
617         {
618         SSL_SESSION *r;
619         int ret=0;
620
621         if ((c != NULL) && (c->session_id_length != 0))
622                 {
623                 if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
624                 if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c)
625                         {
626                         ret=1;
627                         r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
628                         SSL_SESSION_list_remove(ctx,c);
629                         }
630
631                 if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
632
633                 if (ret)
634                         {
635                         r->not_resumable=1;
636                         if (ctx->remove_session_cb != NULL)
637                                 ctx->remove_session_cb(ctx,r);
638                         SSL_SESSION_free(r);
639                         }
640                 }
641         else
642                 ret=0;
643         return(ret);
644         }
645
646 void SSL_SESSION_free(SSL_SESSION *ss)
647         {
648         int i;
649
650         if(ss == NULL)
651             return;
652
653         i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);
654 #ifdef REF_PRINT
655         REF_PRINT("SSL_SESSION",ss);
656 #endif
657         if (i > 0) return;
658 #ifdef REF_CHECK
659         if (i < 0)
660                 {
661                 fprintf(stderr,"SSL_SESSION_free, bad reference count\n");
662                 abort(); /* ok */
663                 }
664 #endif
665
666         CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
667
668         OPENSSL_cleanse(ss->key_arg,sizeof ss->key_arg);
669         OPENSSL_cleanse(ss->master_key,sizeof ss->master_key);
670         OPENSSL_cleanse(ss->session_id,sizeof ss->session_id);
671         if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
672         if (ss->peer != NULL) X509_free(ss->peer);
673         if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
674 #ifndef OPENSSL_NO_TLSEXT
675         if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
676         if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
677 #endif
678         OPENSSL_cleanse(ss,sizeof(*ss));
679         OPENSSL_free(ss);
680         }
681
682 int SSL_set_session(SSL *s, SSL_SESSION *session)
683         {
684         int ret=0;
685         SSL_METHOD *meth;
686
687         if (session != NULL)
688                 {
689                 meth=s->ctx->method->get_ssl_method(session->ssl_version);
690                 if (meth == NULL)
691                         meth=s->method->get_ssl_method(session->ssl_version);
692                 if (meth == NULL)
693                         {
694                         SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);
695                         return(0);
696                         }
697
698                 if (meth != s->method)
699                         {
700                         if (!SSL_set_ssl_method(s,meth))
701                                 return(0);
702                         if (s->ctx->session_timeout == 0)
703                                 session->timeout=SSL_get_default_timeout(s);
704                         else
705                                 session->timeout=s->ctx->session_timeout;
706                         }
707
708 #ifndef OPENSSL_NO_KRB5
709                 if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
710                     session->krb5_client_princ_len > 0)
711                 {
712                     s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
713                     memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
714                             session->krb5_client_princ_len);
715                     s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
716                 }
717 #endif /* OPENSSL_NO_KRB5 */
718
719                 /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
720                 CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
721                 if (s->session != NULL)
722                         SSL_SESSION_free(s->session);
723                 s->session=session;
724                 s->verify_result = s->session->verify_result;
725                 /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
726                 ret=1;
727                 }
728         else
729                 {
730                 if (s->session != NULL)
731                         {
732                         SSL_SESSION_free(s->session);
733                         s->session=NULL;
734                         }
735
736                 meth=s->ctx->method;
737                 if (meth != s->method)
738                         {
739                         if (!SSL_set_ssl_method(s,meth))
740                                 return(0);
741                         }
742                 ret=1;
743                 }
744         return(ret);
745         }
746
747 long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
748         {
749         if (s == NULL) return(0);
750         s->timeout=t;
751         return(1);
752         }
753
754 long SSL_SESSION_get_timeout(const SSL_SESSION *s)
755         {
756         if (s == NULL) return(0);
757         return(s->timeout);
758         }
759
760 long SSL_SESSION_get_time(const SSL_SESSION *s)
761         {
762         if (s == NULL) return(0);
763         return(s->time);
764         }
765
766 long SSL_SESSION_set_time(SSL_SESSION *s, long t)
767         {
768         if (s == NULL) return(0);
769         s->time=t;
770         return(t);
771         }
772
773 long SSL_CTX_set_timeout(SSL_CTX *s, long t)
774         {
775         long l;
776         if (s == NULL) return(0);
777         l=s->session_timeout;
778         s->session_timeout=t;
779         return(l);
780         }
781
782 long SSL_CTX_get_timeout(const SSL_CTX *s)
783         {
784         if (s == NULL) return(0);
785         return(s->session_timeout);
786         }
787
788 typedef struct timeout_param_st
789         {
790         SSL_CTX *ctx;
791         long time;
792         LHASH *cache;
793         } TIMEOUT_PARAM;
794
795 static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)
796         {
797         if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
798                 {
799                 /* The reason we don't call SSL_CTX_remove_session() is to
800                  * save on locking overhead */
801                 lh_delete(p->cache,s);
802                 SSL_SESSION_list_remove(p->ctx,s);
803                 s->not_resumable=1;
804                 if (p->ctx->remove_session_cb != NULL)
805                         p->ctx->remove_session_cb(p->ctx,s);
806                 SSL_SESSION_free(s);
807                 }
808         }
809
810 static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION *, TIMEOUT_PARAM *)
811
812 void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
813         {
814         unsigned long i;
815         TIMEOUT_PARAM tp;
816
817         tp.ctx=s;
818         tp.cache=s->sessions;
819         if (tp.cache == NULL) return;
820         tp.time=t;
821         CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
822         i=tp.cache->down_load;
823         tp.cache->down_load=0;
824         lh_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), &tp);
825         tp.cache->down_load=i;
826         CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
827         }
828
829 int ssl_clear_bad_session(SSL *s)
830         {
831         if (    (s->session != NULL) &&
832                 !(s->shutdown & SSL_SENT_SHUTDOWN) &&
833                 !(SSL_in_init(s) || SSL_in_before(s)))
834                 {
835                 SSL_CTX_remove_session(s->ctx,s->session);
836                 return(1);
837                 }
838         else
839                 return(0);
840         }
841
842 /* locked by SSL_CTX in the calling function */
843 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
844         {
845         if ((s->next == NULL) || (s->prev == NULL)) return;
846
847         if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))
848                 { /* last element in list */
849                 if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
850                         { /* only one element in list */
851                         ctx->session_cache_head=NULL;
852                         ctx->session_cache_tail=NULL;
853                         }
854                 else
855                         {
856                         ctx->session_cache_tail=s->prev;
857                         s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);
858                         }
859                 }
860         else
861                 {
862                 if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
863                         { /* first element in list */
864                         ctx->session_cache_head=s->next;
865                         s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);
866                         }
867                 else
868                         { /* middle of list */
869                         s->next->prev=s->prev;
870                         s->prev->next=s->next;
871                         }
872                 }
873         s->prev=s->next=NULL;
874         }
875
876 static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
877         {
878         if ((s->next != NULL) && (s->prev != NULL))
879                 SSL_SESSION_list_remove(ctx,s);
880
881         if (ctx->session_cache_head == NULL)
882                 {
883                 ctx->session_cache_head=s;
884                 ctx->session_cache_tail=s;
885                 s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
886                 s->next=(SSL_SESSION *)&(ctx->session_cache_tail);
887                 }
888         else
889                 {
890                 s->next=ctx->session_cache_head;
891                 s->next->prev=s;
892                 s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
893                 ctx->session_cache_head=s;
894                 }
895         }
896
897 void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
898         int (*cb)(struct ssl_st *ssl,SSL_SESSION *sess))
899         {
900         ctx->new_session_cb=cb;
901         }
902
903 int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess)
904         {
905         return ctx->new_session_cb;
906         }
907
908 void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
909         void (*cb)(SSL_CTX *ctx,SSL_SESSION *sess))
910         {
911         ctx->remove_session_cb=cb;
912         }
913
914 void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx,SSL_SESSION *sess)
915         {
916         return ctx->remove_session_cb;
917         }
918
919 void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
920         SSL_SESSION *(*cb)(struct ssl_st *ssl,
921                  unsigned char *data,int len,int *copy))
922         {
923         ctx->get_session_cb=cb;
924         }
925
926 SSL_SESSION * (*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl,
927                  unsigned char *data,int len,int *copy)
928         {
929         return ctx->get_session_cb;
930         }
931
932 void SSL_CTX_set_info_callback(SSL_CTX *ctx, 
933         void (*cb)(const SSL *ssl,int type,int val))
934         {
935         ctx->info_callback=cb;
936         }
937
938 void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val)
939         {
940         return ctx->info_callback;
941         }
942
943 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
944         int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey))
945         {
946         ctx->client_cert_cb=cb;
947         }
948
949 int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PKEY **pkey)
950         {
951         return ctx->client_cert_cb;
952         }
953
954 #ifndef OPENSSL_NO_ENGINE
955 int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
956         {
957         if (!ENGINE_init(e))
958                 {
959                 SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
960                 return 0;
961                 }
962         if(!ENGINE_get_ssl_client_cert_function(e))
963                 {
964                 SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD);
965                 ENGINE_finish(e);
966                 return 0;
967                 }
968         ctx->client_cert_engine = e;
969         return 1;
970         }
971 #endif
972
973 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
974         int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
975         {
976         ctx->app_gen_cookie_cb=cb;
977         }
978
979 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
980         int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len))
981         {
982         ctx->app_verify_cookie_cb=cb;
983         }
984