diff options
Diffstat (limited to 'src/lib/libssl/ssl_sess.c')
-rw-r--r-- | src/lib/libssl/ssl_sess.c | 160 |
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 | ||
234 | unsigned 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 | */ | ||
463 | int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, | 426 | int 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,©))) | 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,©)) | ||
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 | ||
872 | X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) | ||
873 | { | ||
874 | return s->peer; | ||
875 | } | ||
876 | |||
877 | int 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 | |||
891 | long SSL_CTX_set_timeout(SSL_CTX *s, long t) | 827 | long SSL_CTX_set_timeout(SSL_CTX *s, long t) |
892 | { | 828 | { |
893 | long l; | 829 | long l; |