1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59: #include <stdio.h>
60: #include <openssl/lhash.h>
61: #include <openssl/rand.h>
62: #include "ssl_locl.h"
63:
64: static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
65: static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
66: static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
67:
68: SSL_SESSION *SSL_get_session(const SSL *ssl)
69:
70: {
71: return(ssl->session);
72: }
73:
74: SSL_SESSION *SSL_get1_session(SSL *ssl)
75:
76: {
77: SSL_SESSION *sess;
78:
79:
80:
81: CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION);
82: sess = ssl->session;
83: if(sess)
84: sess->references++;
85: CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION);
86: return(sess);
87: }
88:
89: int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
90: CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
91: {
92: return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
93: new_func, dup_func, free_func);
94: }
95:
96: int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
97: {
98: return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
99: }
100:
101: void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
102: {
103: return(CRYPTO_get_ex_data(&s->ex_data,idx));
104: }
105:
106: SSL_SESSION *SSL_SESSION_new(void)
107: {
108: SSL_SESSION *ss;
109:
110: ss=(SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
111: if (ss == NULL)
112: {
113: SSLerr(SSL_F_SSL_SESSION_NEW,ERR_R_MALLOC_FAILURE);
114: return(0);
115: }
116: memset(ss,0,sizeof(SSL_SESSION));
117:
118: ss->verify_result = 1;
119: ss->references=1;
120: ss->timeout=60*5+4;
121: ss->time=(unsigned long)time(NULL);
122: ss->prev=NULL;
123: ss->next=NULL;
124: ss->compress_meth=0;
125: #ifndef OPENSSL_NO_TLSEXT
126: ss->tlsext_hostname = NULL;
127: #endif
128: CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
129: return(ss);
130: }
131:
132: const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
133: {
134: if(len)
135: *len = s->session_id_length;
136: return s->session_id;
137: }
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148: #define MAX_SESS_ID_ATTEMPTS 10
149: static int def_generate_session_id(const SSL *ssl, unsigned char *id,
150: unsigned int *id_len)
151: {
152: unsigned int retry = 0;
153: do
154: if (RAND_pseudo_bytes(id, *id_len) <= 0)
155: return 0;
156: while(SSL_has_matching_session_id(ssl, id, *id_len) &&
157: (++retry < MAX_SESS_ID_ATTEMPTS));
158: if(retry < MAX_SESS_ID_ATTEMPTS)
159: return 1;
160:
161:
162:
163:
164:
165:
166:
167:
168:
169: return 0;
170: }
171:
172: int ssl_get_new_session(SSL *s, int session)
173: {
174:
175:
176: unsigned int tmp;
177: SSL_SESSION *ss=NULL;
178: GEN_SESSION_CB cb = def_generate_session_id;
179:
180: if ((ss=SSL_SESSION_new()) == NULL) return(0);
181:
182:
183: if (s->ctx->session_timeout == 0)
184: ss->timeout=SSL_get_default_timeout(s);
185: else
186: ss->timeout=s->ctx->session_timeout;
187:
188: if (s->session != NULL)
189: {
190: SSL_SESSION_free(s->session);
191: s->session=NULL;
192: }
193:
194: if (session)
195: {
196: if (s->version == SSL2_VERSION)
197: {
198: ss->ssl_version=SSL2_VERSION;
199: ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
200: }
201: else if (s->version == SSL3_VERSION)
202: {
203: ss->ssl_version=SSL3_VERSION;
204: ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
205: }
206: else if (s->version == TLS1_VERSION)
207: {
208: ss->ssl_version=TLS1_VERSION;
209: ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
210: }
211: else if (s->version == DTLS1_VERSION)
212: {
213: ss->ssl_version=DTLS1_VERSION;
214: ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
215: }
216: else
217: {
218: SSLerr(SSL_F_SSL_GET_NEW_SESSION,SSL_R_UNSUPPORTED_SSL_VERSION);
219: SSL_SESSION_free(ss);
220: return(0);
221: }
222: #ifndef OPENSSL_NO_TLSEXT
223:
224: if (s->tlsext_ticket_expected)
225: {
226: ss->session_id_length = 0;
227: goto sess_id_done;
228: }
229: #endif
230:
231: CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
232: if(s->generate_session_id)
233: cb = s->generate_session_id;
234: else if(s->ctx->generate_session_id)
235: cb = s->ctx->generate_session_id;
236: CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
237:
238: tmp = ss->session_id_length;
239: if(!cb(s, ss->session_id, &tmp))
240: {
241:
242: SSLerr(SSL_F_SSL_GET_NEW_SESSION,
243: SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
244: SSL_SESSION_free(ss);
245: return(0);
246: }
247:
248:
249: if(!tmp || (tmp > ss->session_id_length))
250: {
251:
252: SSLerr(SSL_F_SSL_GET_NEW_SESSION,
253: SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
254: SSL_SESSION_free(ss);
255: return(0);
256: }
257:
258: if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
259: memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
260: else
261: ss->session_id_length = tmp;
262:
263: if(SSL_has_matching_session_id(s, ss->session_id,
264: ss->session_id_length))
265: {
266: SSLerr(SSL_F_SSL_GET_NEW_SESSION,
267: SSL_R_SSL_SESSION_ID_CONFLICT);
268: SSL_SESSION_free(ss);
269: return(0);
270: }
271: #ifndef OPENSSL_NO_TLSEXT
272: sess_id_done:
273: if (s->tlsext_hostname) {
274: ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
275: if (ss->tlsext_hostname == NULL) {
276: SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
277: SSL_SESSION_free(ss);
278: return 0;
279: }
280: }
281: #endif
282: }
283: else
284: {
285: ss->session_id_length=0;
286: }
287:
288: if (s->sid_ctx_length > sizeof ss->sid_ctx)
289: {
290: SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
291: SSL_SESSION_free(ss);
292: return 0;
293: }
294: memcpy(ss->sid_ctx,s->sid_ctx,s->sid_ctx_length);
295: ss->sid_ctx_length=s->sid_ctx_length;
296: s->session=ss;
297: ss->ssl_version=s->version;
298: ss->verify_result = X509_V_OK;
299:
300: return(1);
301: }
302:
303: int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
304: const unsigned char *limit)
305: {
306:
307:
308: SSL_SESSION *ret=NULL;
309: int fatal = 0;
310: #ifndef OPENSSL_NO_TLSEXT
311: int r;
312: #endif
313:
314: if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
315: goto err;
316: #ifndef OPENSSL_NO_TLSEXT
317: r = tls1_process_ticket(s, session_id, len, limit, &ret);
318: if (r == -1)
319: {
320: fatal = 1;
321: goto err;
322: }
323: else if (r == 0 || (!ret && !len))
324: goto err;
325: else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
326: #else
327: if (len == 0)
328: goto err;
329: if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
330: #endif
331: {
332: SSL_SESSION data;
333: data.ssl_version=s->version;
334: data.session_id_length=len;
335: if (len == 0)
336: return 0;
337: memcpy(data.session_id,session_id,len);
338: CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
339: ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
340: if (ret != NULL)
341:
342: CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
343: CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
344: }
345:
346: if (ret == NULL)
347: {
348: int copy=1;
349:
350: s->ctx->stats.sess_miss++;
351: ret=NULL;
352: if (s->ctx->get_session_cb != NULL
353: && (ret=s->ctx->get_session_cb(s,session_id,len,©))
354: != NULL)
355: {
356: s->ctx->stats.sess_cb_hit++;
357:
358:
359:
360:
361:
362:
363: if (copy)
364: CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
365:
366:
367:
368: if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
369:
370:
371: SSL_CTX_add_session(s->ctx,ret);
372: }
373: if (ret == NULL)
374: goto err;
375: }
376:
377:
378:
379: if (ret->sid_ctx_length != s->sid_ctx_length
380: || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
381: {
382:
383:
384:
385: #if 0
386:
387:
388: SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
389: #endif
390: goto err;
391: }
392:
393: if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
394: {
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405: SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
406: fatal = 1;
407: goto err;
408: }
409:
410: if (ret->cipher == NULL)
411: {
412: unsigned char buf[5],*p;
413: unsigned long l;
414:
415: p=buf;
416: l=ret->cipher_id;
417: l2n(l,p);
418: if ((ret->ssl_version>>8) == SSL3_VERSION_MAJOR)
419: ret->cipher=ssl_get_cipher_by_char(s,&(buf[2]));
420: else
421: ret->cipher=ssl_get_cipher_by_char(s,&(buf[1]));
422: if (ret->cipher == NULL)
423: goto err;
424: }
425:
426:
427: #if 0
428:
429:
430:
431:
432:
433: CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
434: #endif
435:
436: if (ret->timeout < (long)(time(NULL) - ret->time))
437: {
438: s->ctx->stats.sess_timeout++;
439:
440: SSL_CTX_remove_session(s->ctx,ret);
441: goto err;
442: }
443:
444: s->ctx->stats.sess_hit++;
445:
446:
447:
448:
449:
450: if (s->session != NULL)
451: SSL_SESSION_free(s->session);
452: s->session=ret;
453: s->verify_result = s->session->verify_result;
454: return(1);
455:
456: err:
457: if (ret != NULL)
458: SSL_SESSION_free(ret);
459: if (fatal)
460: return -1;
461: else
462: return 0;
463: }
464:
465: int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
466: {
467: int ret=0;
468: SSL_SESSION *s;
469:
470:
471:
472:
473: CRYPTO_add(&c->references,1,CRYPTO_LOCK_SSL_SESSION);
474:
475:
476: CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
477: s=(SSL_SESSION *)lh_insert(ctx->sessions,c);
478:
479:
480:
481:
482: if (s != NULL && s != c)
483: {
484:
485: SSL_SESSION_list_remove(ctx,s);
486: SSL_SESSION_free(s);
487:
488:
489:
490:
491:
492: s = NULL;
493: }
494:
495:
496: if (s == NULL)
497: SSL_SESSION_list_add(ctx,c);
498:
499: if (s != NULL)
500: {
501:
502:
503:
504: SSL_SESSION_free(s);
505: ret=0;
506: }
507: else
508: {
509:
510:
511: ret=1;
512:
513: if (SSL_CTX_sess_get_cache_size(ctx) > 0)
514: {
515: while (SSL_CTX_sess_number(ctx) >
516: SSL_CTX_sess_get_cache_size(ctx))
517: {
518: if (!remove_session_lock(ctx,
519: ctx->session_cache_tail, 0))
520: break;
521: else
522: ctx->stats.sess_cache_full++;
523: }
524: }
525: }
526: CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
527: return(ret);
528: }
529:
530: int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
531: {
532: return remove_session_lock(ctx, c, 1);
533: }
534:
535: static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
536: {
537: SSL_SESSION *r;
538: int ret=0;
539:
540: if ((c != NULL) && (c->session_id_length != 0))
541: {
542: if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
543: if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c)
544: {
545: ret=1;
546: r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
547: SSL_SESSION_list_remove(ctx,c);
548: }
549:
550: if(lck) CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
551:
552: if (ret)
553: {
554: r->not_resumable=1;
555: if (ctx->remove_session_cb != NULL)
556: ctx->remove_session_cb(ctx,r);
557: SSL_SESSION_free(r);
558: }