summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_sess.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/ssl_sess.c')
-rw-r--r--src/lib/libssl/ssl_sess.c160
1 files changed, 48 insertions, 112 deletions
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
index ad40fadd02..8e5d8a0972 100644
--- a/src/lib/libssl/ssl_sess.c
+++ b/src/lib/libssl/ssl_sess.c
@@ -218,9 +218,6 @@ SSL_SESSION *SSL_SESSION_new(void)
218 ss->psk_identity_hint=NULL; 218 ss->psk_identity_hint=NULL;
219 ss->psk_identity=NULL; 219 ss->psk_identity=NULL;
220#endif 220#endif
221#ifndef OPENSSL_NO_SRP
222 ss->srp_username=NULL;
223#endif
224 return(ss); 221 return(ss);
225 } 222 }
226 223
@@ -231,11 +228,6 @@ const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
231 return s->session_id; 228 return s->session_id;
232 } 229 }
233 230
234unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
235 {
236 return s->compress_meth;
237 }
238
239/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1 231/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
240 * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly 232 * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
241 * until we have no conflict is going to complete in one iteration pretty much 233 * until we have no conflict is going to complete in one iteration pretty much
@@ -308,16 +300,6 @@ int ssl_get_new_session(SSL *s, int session)
308 ss->ssl_version=TLS1_VERSION; 300 ss->ssl_version=TLS1_VERSION;
309 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH; 301 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
310 } 302 }
311 else if (s->version == TLS1_1_VERSION)
312 {
313 ss->ssl_version=TLS1_1_VERSION;
314 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
315 }
316 else if (s->version == TLS1_2_VERSION)
317 {
318 ss->ssl_version=TLS1_2_VERSION;
319 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
320 }
321 else if (s->version == DTLS1_BAD_VER) 303 else if (s->version == DTLS1_BAD_VER)
322 { 304 {
323 ss->ssl_version=DTLS1_BAD_VER; 305 ss->ssl_version=DTLS1_BAD_VER;
@@ -441,25 +423,6 @@ int ssl_get_new_session(SSL *s, int session)
441 return(1); 423 return(1);
442 } 424 }
443 425
444/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
445 * connection. It is only called by servers.
446 *
447 * session_id: points at the session ID in the ClientHello. This code will
448 * read past the end of this in order to parse out the session ticket
449 * extension, if any.
450 * len: the length of the session ID.
451 * limit: a pointer to the first byte after the ClientHello.
452 *
453 * Returns:
454 * -1: error
455 * 0: a session may have been found.
456 *
457 * Side effects:
458 * - If a session is found then s->session is pointed at it (after freeing an
459 * existing session if need be) and s->verify_result is set from the session.
460 * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
461 * if the server should issue a new session ticket (to 0 otherwise).
462 */
463int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, 426int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
464 const unsigned char *limit) 427 const unsigned char *limit)
465 { 428 {
@@ -467,39 +430,27 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
467 430
468 SSL_SESSION *ret=NULL; 431 SSL_SESSION *ret=NULL;
469 int fatal = 0; 432 int fatal = 0;
470 int try_session_cache = 1;
471#ifndef OPENSSL_NO_TLSEXT 433#ifndef OPENSSL_NO_TLSEXT
472 int r; 434 int r;
473#endif 435#endif
474 436
475 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) 437 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
476 goto err; 438 goto err;
477
478 if (len == 0)
479 try_session_cache = 0;
480
481#ifndef OPENSSL_NO_TLSEXT 439#ifndef OPENSSL_NO_TLSEXT
482 r = tls1_process_ticket(s, session_id, len, limit, &ret); /* sets s->tlsext_ticket_expected */ 440 r = tls1_process_ticket(s, session_id, len, limit, &ret);
483 switch (r) 441 if (r == -1)
484 { 442 {
485 case -1: /* Error during processing */
486 fatal = 1; 443 fatal = 1;
487 goto err; 444 goto err;
488 case 0: /* No ticket found */
489 case 1: /* Zero length ticket found */
490 break; /* Ok to carry on processing session id. */
491 case 2: /* Ticket found but not decrypted. */
492 case 3: /* Ticket decrypted, *ret has been set. */
493 try_session_cache = 0;
494 break;
495 default:
496 abort();
497 } 445 }
446 else if (r == 0 || (!ret && !len))
447 goto err;
448 else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
449#else
450 if (len == 0)
451 goto err;
452 if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
498#endif 453#endif
499
500 if (try_session_cache &&
501 ret == NULL &&
502 !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
503 { 454 {
504 SSL_SESSION data; 455 SSL_SESSION data;
505 data.ssl_version=s->version; 456 data.ssl_version=s->version;
@@ -510,22 +461,20 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
510 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 461 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
511 ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data); 462 ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
512 if (ret != NULL) 463 if (ret != NULL)
513 { 464 /* don't allow other threads to steal it: */
514 /* don't allow other threads to steal it: */ 465 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
515 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
516 }
517 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 466 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
518 if (ret == NULL)
519 s->session_ctx->stats.sess_miss++;
520 } 467 }
521 468
522 if (try_session_cache && 469 if (ret == NULL)
523 ret == NULL &&
524 s->session_ctx->get_session_cb != NULL)
525 { 470 {
526 int copy=1; 471 int copy=1;
527 472
528 if ((ret=s->session_ctx->get_session_cb(s,session_id,len,&copy))) 473 s->session_ctx->stats.sess_miss++;
474 ret=NULL;
475 if (s->session_ctx->get_session_cb != NULL
476 && (ret=s->session_ctx->get_session_cb(s,session_id,len,&copy))
477 != NULL)
529 { 478 {
530 s->session_ctx->stats.sess_cb_hit++; 479 s->session_ctx->stats.sess_cb_hit++;
531 480
@@ -544,18 +493,23 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
544 * things are very strange */ 493 * things are very strange */
545 SSL_CTX_add_session(s->session_ctx,ret); 494 SSL_CTX_add_session(s->session_ctx,ret);
546 } 495 }
496 if (ret == NULL)
497 goto err;
547 } 498 }
548 499
549 if (ret == NULL) 500 /* Now ret is non-NULL, and we own one of its reference counts. */
550 goto err;
551
552 /* Now ret is non-NULL and we own one of its reference counts. */
553 501
554 if (ret->sid_ctx_length != s->sid_ctx_length 502 if (ret->sid_ctx_length != s->sid_ctx_length
555 || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)) 503 || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
556 { 504 {
557 /* We have the session requested by the client, but we don't 505 /* We've found the session named by the client, but we don't
558 * want to use it in this context. */ 506 * want to use it in this context. */
507
508#if 0 /* The client cannot always know when a session is not appropriate,
509 * so we shouldn't generate an error message. */
510
511 SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
512#endif
559 goto err; /* treat like cache miss */ 513 goto err; /* treat like cache miss */
560 } 514 }
561 515
@@ -592,38 +546,39 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
592 goto err; 546 goto err;
593 } 547 }
594 548
549
550#if 0 /* This is way too late. */
551
552 /* If a thread got the session, then 'swaped', and another got
553 * it and then due to a time-out decided to 'OPENSSL_free' it we could
554 * be in trouble. So I'll increment it now, then double decrement
555 * later - am I speaking rubbish?. */
556 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
557#endif
558
595 if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */ 559 if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
596 { 560 {
597 s->session_ctx->stats.sess_timeout++; 561 s->session_ctx->stats.sess_timeout++;
598 if (try_session_cache) 562 /* remove it from the cache */
599 { 563 SSL_CTX_remove_session(s->session_ctx,ret);
600 /* session was from the cache, so remove it */
601 SSL_CTX_remove_session(s->session_ctx,ret);
602 }
603 goto err; 564 goto err;
604 } 565 }
605 566
606 s->session_ctx->stats.sess_hit++; 567 s->session_ctx->stats.sess_hit++;
607 568
569 /* ret->time=time(NULL); */ /* rezero timeout? */
570 /* again, just leave the session
571 * if it is the same session, we have just incremented and
572 * then decremented the reference count :-) */
608 if (s->session != NULL) 573 if (s->session != NULL)
609 SSL_SESSION_free(s->session); 574 SSL_SESSION_free(s->session);
610 s->session=ret; 575 s->session=ret;
611 s->verify_result = s->session->verify_result; 576 s->verify_result = s->session->verify_result;
612 return 1; 577 return(1);
613 578
614 err: 579 err:
615 if (ret != NULL) 580 if (ret != NULL)
616 {
617 SSL_SESSION_free(ret); 581 SSL_SESSION_free(ret);
618#ifndef OPENSSL_NO_TLSEXT
619 if (!try_session_cache)
620 {
621 /* The session was from a ticket, so we should
622 * issue a ticket for the new session */
623 s->tlsext_ticket_expected = 1;
624 }
625#endif
626 }
627 if (fatal) 582 if (fatal)
628 return -1; 583 return -1;
629 else 584 else
@@ -774,10 +729,6 @@ void SSL_SESSION_free(SSL_SESSION *ss)
774 if (ss->psk_identity != NULL) 729 if (ss->psk_identity != NULL)
775 OPENSSL_free(ss->psk_identity); 730 OPENSSL_free(ss->psk_identity);
776#endif 731#endif
777#ifndef OPENSSL_NO_SRP
778 if (ss->srp_username != NULL)
779 OPENSSL_free(ss->srp_username);
780#endif
781 OPENSSL_cleanse(ss,sizeof(*ss)); 732 OPENSSL_cleanse(ss,sizeof(*ss));
782 OPENSSL_free(ss); 733 OPENSSL_free(ss);
783 } 734 }
@@ -802,6 +753,10 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
802 { 753 {
803 if (!SSL_set_ssl_method(s,meth)) 754 if (!SSL_set_ssl_method(s,meth))
804 return(0); 755 return(0);
756 if (s->ctx->session_timeout == 0)
757 session->timeout=SSL_get_default_timeout(s);
758 else
759 session->timeout=s->ctx->session_timeout;
805 } 760 }
806 761
807#ifndef OPENSSL_NO_KRB5 762#ifndef OPENSSL_NO_KRB5
@@ -869,25 +824,6 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t)
869 return(t); 824 return(t);
870 } 825 }
871 826
872X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
873 {
874 return s->peer;
875 }
876
877int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
878 unsigned int sid_ctx_len)
879 {
880 if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH)
881 {
882 SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
883 return 0;
884 }
885 s->sid_ctx_length=sid_ctx_len;
886 memcpy(s->sid_ctx,sid_ctx,sid_ctx_len);
887
888 return 1;
889 }
890
891long SSL_CTX_set_timeout(SSL_CTX *s, long t) 827long SSL_CTX_set_timeout(SSL_CTX *s, long t)
892 { 828 {
893 long l; 829 long l;