summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_sess.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libssl/ssl_sess.c
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libssl/ssl_sess.c')
-rw-r--r--src/lib/libssl/ssl_sess.c582
1 files changed, 582 insertions, 0 deletions
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
new file mode 100644
index 0000000000..8212600e40
--- /dev/null
+++ b/src/lib/libssl/ssl_sess.c
@@ -0,0 +1,582 @@
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 "lhash.h"
61#include "rand.h"
62#include "ssl_locl.h"
63
64#ifndef NOPROTO
65static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
66static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
67#else
68static void SSL_SESSION_list_remove();
69static void SSL_SESSION_list_add();
70#endif
71
72static ssl_session_num=0;
73static STACK *ssl_session_meth=NULL;
74
75SSL_SESSION *SSL_get_session(ssl)
76SSL *ssl;
77 {
78 return(ssl->session);
79 }
80
81int SSL_SESSION_get_ex_new_index(argl,argp,new_func,dup_func,free_func)
82long argl;
83char *argp;
84int (*new_func)();
85int (*dup_func)();
86void (*free_func)();
87 {
88 ssl_session_num++;
89 return(CRYPTO_get_ex_new_index(ssl_session_num-1,
90 &ssl_session_meth,
91 argl,argp,new_func,dup_func,free_func));
92 }
93
94int SSL_SESSION_set_ex_data(s,idx,arg)
95SSL_SESSION *s;
96int idx;
97char *arg;
98 {
99 return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
100 }
101
102char *SSL_SESSION_get_ex_data(s,idx)
103SSL_SESSION *s;
104int idx;
105 {
106 return(CRYPTO_get_ex_data(&s->ex_data,idx));
107 }
108
109SSL_SESSION *SSL_SESSION_new()
110 {
111 SSL_SESSION *ss;
112
113 ss=(SSL_SESSION *)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->references=1;
122 ss->timeout=60*5+4; /* 5 minute timeout by default */
123 ss->time=time(NULL);
124 ss->prev=NULL;
125 ss->next=NULL;
126 CRYPTO_new_ex_data(ssl_session_meth,(char *)ss,&ss->ex_data);
127 return(ss);
128 }
129
130int ssl_get_new_session(s, session)
131SSL *s;
132int session;
133 {
134 SSL_SESSION *ss=NULL;
135
136 if ((ss=SSL_SESSION_new()) == NULL) return(0);
137
138 /* If the context has a default timeout, use it */
139 if (s->ctx->session_timeout != 0)
140 ss->timeout=SSL_get_default_timeout(s);
141
142 if (s->session != NULL)
143 {
144 SSL_SESSION_free(s->session);
145 s->session=NULL;
146 }
147
148 if (session)
149 {
150 if (s->version == SSL2_CLIENT_VERSION)
151 {
152 ss->ssl_version=SSL2_VERSION;
153 ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
154 }
155 else if (s->version == SSL3_VERSION)
156 {
157 ss->ssl_version=SSL3_VERSION;
158 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
159 }
160 else if (s->version == TLS1_VERSION)
161 {
162 ss->ssl_version=TLS1_VERSION;
163 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
164 }
165 else
166 {
167 SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
168 SSL_SESSION_free(ss);
169 return(0);
170 }
171
172 for (;;)
173 {
174 SSL_SESSION *r;
175
176 RAND_bytes(ss->session_id,ss->session_id_length);
177 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
178 r=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,
179 (char *)ss);
180 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
181 if (r == NULL) break;
182 /* else - woops a session_id match */
183 }
184 }
185 else
186 {
187 ss->session_id_length=0;
188 }
189
190 s->session=ss;
191 ss->ssl_version=s->version;
192
193 return(1);
194 }
195
196int ssl_get_prev_session(s,session_id,len)
197SSL *s;
198unsigned char *session_id;
199int len;
200 {
201 SSL_SESSION *ret=NULL,data;
202
203 /* conn_init();*/
204 data.ssl_version=s->version;
205 data.session_id_length=len;
206 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
207 return(0);
208 memcpy(data.session_id,session_id,len);;
209
210 if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
211 {
212 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
213 ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,(char *)&data);
214 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
215 }
216
217 if (ret == NULL)
218 {
219 int copy=1;
220
221 s->ctx->sess_miss++;
222 ret=NULL;
223 if ((s->ctx->get_session_cb != NULL) &&
224 ((ret=s->ctx->get_session_cb(s,session_id,len,&copy))
225 != NULL))
226 {
227 s->ctx->sess_cb_hit++;
228
229 /* The following should not return 1, otherwise,
230 * things are very strange */
231 SSL_CTX_add_session(s->ctx,ret);
232 /* auto free it */
233 if (!copy)
234 SSL_SESSION_free(ret);
235 }
236 if (ret == NULL) return(0);
237 }
238
239 if (ret->cipher == NULL)
240 {
241 char buf[5],*p;
242 unsigned long l;
243
244 p=buf;
245 l=ret->cipher_id;
246 l2n(l,p);
247 if ((ret->ssl_version>>8) == SSL3_VERSION_MAJOR)
248 ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
249 else
250 ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
251 if (ret->cipher == NULL)
252 return(0);
253 }
254
255 /* If a thread got the session, then 'swaped', and another got
256 * it and then due to a time-out decided to 'Free' it we could
257 * be in trouble. So I'll increment it now, then double decrement
258 * later - am I speaking rubbish?. */
259 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
260
261 if ((long)(ret->time+ret->timeout) < (long)time(NULL)) /* timeout */
262 {
263 s->ctx->sess_timeout++;
264 /* remove it from the cache */
265 SSL_CTX_remove_session(s->ctx,ret);
266 SSL_SESSION_free(ret); /* again to actually Free it */
267 return(0);
268 }
269
270 s->ctx->sess_hit++;
271
272 /* ret->time=time(NULL); */ /* rezero timeout? */
273 /* again, just leave the session
274 * if it is the same session, we have just incremented and
275 * then decremented the reference count :-) */
276 if (s->session != NULL)
277 SSL_SESSION_free(s->session);
278 s->session=ret;
279 return(1);
280 }
281
282int SSL_CTX_add_session(ctx,c)
283SSL_CTX *ctx;
284SSL_SESSION *c;
285 {
286 int ret=0;
287 SSL_SESSION *s;
288
289 /* conn_init(); */
290 CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
291
292 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
293 s=(SSL_SESSION *)lh_insert(ctx->sessions,(char *)c);
294
295 /* Put on the end of the queue unless it is already in the cache */
296 if (s == NULL)
297 SSL_SESSION_list_add(ctx,c);
298
299 /* If the same session if is being 're-added', Free the old
300 * one when the last person stops using it.
301 * This will also work if it is alread in the cache.
302 * The references will go up and then down :-) */
303 if (s != NULL)
304 {
305 SSL_SESSION_free(s);
306 ret=0;
307 }
308 else
309 {
310 ret=1;
311
312 if (SSL_CTX_sess_get_cache_size(ctx) > 0)
313 {
314 while (SSL_CTX_sess_number(ctx) >
315 SSL_CTX_sess_get_cache_size(ctx))
316 {
317 if (!SSL_CTX_remove_session(ctx,
318 ctx->session_cache_tail))
319 break;
320 else
321 ctx->sess_cache_full++;
322 }
323 }
324 }
325 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
326 return(ret);
327 }
328
329int SSL_CTX_remove_session(ctx,c)
330SSL_CTX *ctx;
331SSL_SESSION *c;
332 {
333 SSL_SESSION *r;
334 int ret=0;
335
336 if ((c != NULL) && (c->session_id_length != 0))
337 {
338 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
339 r=(SSL_SESSION *)lh_delete(ctx->sessions,(char *)c);
340 if (r != NULL)
341 {
342 ret=1;
343 SSL_SESSION_list_remove(ctx,c);
344 }
345
346 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
347
348 if (ret)
349 {
350 r->not_resumable=1;
351 if (ctx->remove_session_cb != NULL)
352 ctx->remove_session_cb(ctx,r);
353 SSL_SESSION_free(r);
354 }
355 }
356 else
357 ret=0;
358 return(ret);
359 }
360
361void SSL_SESSION_free(ss)
362SSL_SESSION *ss;
363 {
364 int i;
365
366 i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION);
367#ifdef REF_PRINT
368 REF_PRINT("SSL_SESSION",ss);
369#endif
370 if (i > 0) return;
371#ifdef REF_CHECK
372 if (i < 0)
373 {
374 fprintf(stderr,"SSL_SESSION_free, bad reference count\n");
375 abort(); /* ok */
376 }
377#endif
378
379 CRYPTO_free_ex_data(ssl_session_meth,(char *)ss,&ss->ex_data);
380
381 memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH);
382 memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH);
383 memset(ss->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH);
384 if (ss->cert != NULL) ssl_cert_free(ss->cert);
385 if (ss->peer != NULL) X509_free(ss->peer);
386 if (ss->ciphers != NULL) sk_free(ss->ciphers);
387 memset(ss,0,sizeof(*ss));
388 Free(ss);
389 }
390
391int SSL_set_session(s, session)
392SSL *s;
393SSL_SESSION *session;
394 {
395 int ret=0;
396 SSL_METHOD *meth;
397
398 if (session != NULL)
399 {
400 meth=s->ctx->method->get_ssl_method(session->ssl_version);
401 if (meth == NULL)
402 meth=s->method->get_ssl_method(session->ssl_version);
403 if (meth == NULL)
404 {
405 SSLerr(SSL_F_SSL_SET_SESSION,SSL_R_UNABLE_TO_FIND_SSL_METHOD);
406 return(0);
407 }
408
409 if (meth != s->method)
410 {
411 if (!SSL_set_ssl_method(s,meth))
412 return(0);
413 session->timeout=SSL_get_default_timeout(s);
414 }
415
416 /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/
417 CRYPTO_add(&session->references,1,CRYPTO_LOCK_SSL_SESSION);
418 if (s->session != NULL)
419 SSL_SESSION_free(s->session);
420 s->session=session;
421 /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/
422 ret=1;
423 }
424 else
425 {
426 if (s->session != NULL)
427 {
428 SSL_SESSION_free(s->session);
429 s->session=NULL;
430 }
431 }
432 return(ret);
433 }
434
435long SSL_SESSION_set_timeout(s,t)
436SSL_SESSION *s;
437long t;
438 {
439 if (s == NULL) return(0);
440 s->timeout=t;
441 return(1);
442 }
443
444long SSL_SESSION_get_timeout(s)
445SSL_SESSION *s;
446 {
447 if (s == NULL) return(0);
448 return(s->timeout);
449 }
450
451long SSL_SESSION_get_time(s)
452SSL_SESSION *s;
453 {
454 if (s == NULL) return(0);
455 return(s->time);
456 }
457
458long SSL_SESSION_set_time(s,t)
459SSL_SESSION *s;
460long t;
461 {
462 if (s == NULL) return(0);
463 s->time=t;
464 return(t);
465 }
466
467typedef struct timeout_param_st
468 {
469 SSL_CTX *ctx;
470 long time;
471 LHASH *cache;
472 } TIMEOUT_PARAM;
473
474static void timeout(s,p)
475SSL_SESSION *s;
476TIMEOUT_PARAM *p;
477 {
478 if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
479 {
480 /* The reason we don't call SSL_CTX_remove_session() is to
481 * save on locking overhead */
482 lh_delete(p->cache,(char *)s);
483 SSL_SESSION_list_remove(p->ctx,s);
484 s->not_resumable=1;
485 if (p->ctx->remove_session_cb != NULL)
486 p->ctx->remove_session_cb(p->ctx,s);
487 SSL_SESSION_free(s);
488 }
489 }
490
491void SSL_CTX_flush_sessions(s,t)
492SSL_CTX *s;
493long t;
494 {
495 unsigned long i;
496 TIMEOUT_PARAM tp;
497
498 tp.ctx=s;
499 tp.cache=SSL_CTX_sessions(s);
500 if (tp.cache == NULL) return;
501 tp.time=t;
502 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
503 i=tp.cache->down_load;
504 tp.cache->down_load=0;
505 lh_doall_arg(tp.cache,(void (*)())timeout,(char *)&tp);
506 tp.cache->down_load=i;
507 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
508 }
509
510int ssl_clear_bad_session(s)
511SSL *s;
512 {
513 if ( (s->session != NULL) &&
514 !(s->shutdown & SSL_SENT_SHUTDOWN) &&
515 !(SSL_in_init(s) || SSL_in_before(s)))
516 {
517 SSL_CTX_remove_session(s->ctx,s->session);
518 return(1);
519 }
520 else
521 return(0);
522 }
523
524/* locked by SSL_CTX in the calling function */
525static void SSL_SESSION_list_remove(ctx,s)
526SSL_CTX *ctx;
527SSL_SESSION *s;
528 {
529 if ((s->next == NULL) || (s->prev == NULL)) return;
530
531 if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail))
532 { /* last element in list */
533 if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
534 { /* only one element in list */
535 ctx->session_cache_head=NULL;
536 ctx->session_cache_tail=NULL;
537 }
538 else
539 {
540 ctx->session_cache_tail=s->prev;
541 s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail);
542 }
543 }
544 else
545 {
546 if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head))
547 { /* first element in list */
548 ctx->session_cache_head=s->next;
549 s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head);
550 }
551 else
552 { /* middle of list */
553 s->next->prev=s->prev;
554 s->prev->next=s->next;
555 }
556 }
557 s->prev=s->next=NULL;
558 }
559
560static void SSL_SESSION_list_add(ctx,s)
561SSL_CTX *ctx;
562SSL_SESSION *s;
563 {
564 if ((s->next != NULL) && (s->prev != NULL))
565 SSL_SESSION_list_remove(ctx,s);
566
567 if (ctx->session_cache_head == NULL)
568 {
569 ctx->session_cache_head=s;
570 ctx->session_cache_tail=s;
571 s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
572 s->next=(SSL_SESSION *)&(ctx->session_cache_tail);
573 }
574 else
575 {
576 s->next=ctx->session_cache_head;
577 s->next->prev=s;
578 s->prev=(SSL_SESSION *)&(ctx->session_cache_head);
579 ctx->session_cache_head=s;
580 }
581 }
582