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; | 
