summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_sess.c
diff options
context:
space:
mode:
authordjm <>2012-10-13 21:25:14 +0000
committerdjm <>2012-10-13 21:25:14 +0000
commit93723b50b639d8dc717bc1bf463fd46e1b321239 (patch)
tree281e0a29ae8f87a8c47fbd4deaa1f3d48b8cc5c1 /src/lib/libssl/ssl_sess.c
parent65e72ac55a6405783db7a12d7e35a7561d46005b (diff)
downloadopenbsd-93723b50b639d8dc717bc1bf463fd46e1b321239.tar.gz
openbsd-93723b50b639d8dc717bc1bf463fd46e1b321239.tar.bz2
openbsd-93723b50b639d8dc717bc1bf463fd46e1b321239.zip
resolve conflicts
Diffstat (limited to 'src/lib/libssl/ssl_sess.c')
-rw-r--r--src/lib/libssl/ssl_sess.c160
1 files changed, 112 insertions, 48 deletions
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
index 8e5d8a0972..ad40fadd02 100644
--- a/src/lib/libssl/ssl_sess.c
+++ b/src/lib/libssl/ssl_sess.c
@@ -218,6 +218,9 @@ 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
221 return(ss); 224 return(ss);
222 } 225 }
223 226
@@ -228,6 +231,11 @@ const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
228 return s->session_id; 231 return s->session_id;
229 } 232 }
230 233
234unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
235 {
236 return s->compress_meth;
237 }
238
231/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1 239/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space. SSLv3/TLSv1
232 * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly 240 * has 32 bytes (256 bits). As such, filling the ID with random gunk repeatedly
233 * until we have no conflict is going to complete in one iteration pretty much 241 * until we have no conflict is going to complete in one iteration pretty much
@@ -300,6 +308,16 @@ int ssl_get_new_session(SSL *s, int session)
300 ss->ssl_version=TLS1_VERSION; 308 ss->ssl_version=TLS1_VERSION;
301 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH; 309 ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
302 } 310 }
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 }
303 else if (s->version == DTLS1_BAD_VER) 321 else if (s->version == DTLS1_BAD_VER)
304 { 322 {
305 ss->ssl_version=DTLS1_BAD_VER; 323 ss->ssl_version=DTLS1_BAD_VER;
@@ -423,6 +441,25 @@ int ssl_get_new_session(SSL *s, int session)
423 return(1); 441 return(1);
424 } 442 }
425 443
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 */
426int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, 463int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
427 const unsigned char *limit) 464 const unsigned char *limit)
428 { 465 {
@@ -430,27 +467,39 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
430 467
431 SSL_SESSION *ret=NULL; 468 SSL_SESSION *ret=NULL;
432 int fatal = 0; 469 int fatal = 0;
470 int try_session_cache = 1;
433#ifndef OPENSSL_NO_TLSEXT 471#ifndef OPENSSL_NO_TLSEXT
434 int r; 472 int r;
435#endif 473#endif
436 474
437 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) 475 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
438 goto err; 476 goto err;
477
478 if (len == 0)
479 try_session_cache = 0;
480
439#ifndef OPENSSL_NO_TLSEXT 481#ifndef OPENSSL_NO_TLSEXT
440 r = tls1_process_ticket(s, session_id, len, limit, &ret); 482 r = tls1_process_ticket(s, session_id, len, limit, &ret); /* sets s->tlsext_ticket_expected */
441 if (r == -1) 483 switch (r)
442 { 484 {
485 case -1: /* Error during processing */
443 fatal = 1; 486 fatal = 1;
444 goto err; 487 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();
445 } 497 }
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))
453#endif 498#endif
499
500 if (try_session_cache &&
501 ret == NULL &&
502 !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
454 { 503 {
455 SSL_SESSION data; 504 SSL_SESSION data;
456 data.ssl_version=s->version; 505 data.ssl_version=s->version;
@@ -461,20 +510,22 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
461 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 510 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
462 ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data); 511 ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
463 if (ret != NULL) 512 if (ret != NULL)
464 /* don't allow other threads to steal it: */ 513 {
465 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION); 514 /* don't allow other threads to steal it: */
515 CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
516 }
466 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); 517 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
518 if (ret == NULL)
519 s->session_ctx->stats.sess_miss++;
467 } 520 }
468 521
469 if (ret == NULL) 522 if (try_session_cache &&
523 ret == NULL &&
524 s->session_ctx->get_session_cb != NULL)
470 { 525 {
471 int copy=1; 526 int copy=1;
472 527
473 s->session_ctx->stats.sess_miss++; 528 if ((ret=s->session_ctx->get_session_cb(s,session_id,len,&copy)))
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)
478 { 529 {
479 s->session_ctx->stats.sess_cb_hit++; 530 s->session_ctx->stats.sess_cb_hit++;
480 531
@@ -493,23 +544,18 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
493 * things are very strange */ 544 * things are very strange */
494 SSL_CTX_add_session(s->session_ctx,ret); 545 SSL_CTX_add_session(s->session_ctx,ret);
495 } 546 }
496 if (ret == NULL)
497 goto err;
498 } 547 }
499 548
500 /* Now ret is non-NULL, and we own one of its reference counts. */ 549 if (ret == NULL)
550 goto err;
551
552 /* Now ret is non-NULL and we own one of its reference counts. */
501 553
502 if (ret->sid_ctx_length != s->sid_ctx_length 554 if (ret->sid_ctx_length != s->sid_ctx_length
503 || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)) 555 || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
504 { 556 {
505 /* We've found the session named by the client, but we don't 557 /* We have the session requested by the client, but we don't
506 * want to use it in this context. */ 558 * 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
513 goto err; /* treat like cache miss */ 559 goto err; /* treat like cache miss */
514 } 560 }
515 561
@@ -546,39 +592,38 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
546 goto err; 592 goto err;
547 } 593 }
548 594
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
559 if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */ 595 if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
560 { 596 {
561 s->session_ctx->stats.sess_timeout++; 597 s->session_ctx->stats.sess_timeout++;
562 /* remove it from the cache */ 598 if (try_session_cache)
563 SSL_CTX_remove_session(s->session_ctx,ret); 599 {
600 /* session was from the cache, so remove it */
601 SSL_CTX_remove_session(s->session_ctx,ret);
602 }
564 goto err; 603 goto err;
565 } 604 }
566 605
567 s->session_ctx->stats.sess_hit++; 606 s->session_ctx->stats.sess_hit++;
568 607
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 :-) */
573 if (s->session != NULL) 608 if (s->session != NULL)
574 SSL_SESSION_free(s->session); 609 SSL_SESSION_free(s->session);
575 s->session=ret; 610 s->session=ret;
576 s->verify_result = s->session->verify_result; 611 s->verify_result = s->session->verify_result;
577 return(1); 612 return 1;
578 613
579 err: 614 err:
580 if (ret != NULL) 615 if (ret != NULL)
616 {
581 SSL_SESSION_free(ret); 617 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 }
582 if (fatal) 627 if (fatal)
583 return -1; 628 return -1;
584 else 629 else
@@ -729,6 +774,10 @@ void SSL_SESSION_free(SSL_SESSION *ss)
729 if (ss->psk_identity != NULL) 774 if (ss->psk_identity != NULL)
730 OPENSSL_free(ss->psk_identity); 775 OPENSSL_free(ss->psk_identity);
731#endif 776#endif
777#ifndef OPENSSL_NO_SRP
778 if (ss->srp_username != NULL)
779 OPENSSL_free(ss->srp_username);
780#endif
732 OPENSSL_cleanse(ss,sizeof(*ss)); 781 OPENSSL_cleanse(ss,sizeof(*ss));
733 OPENSSL_free(ss); 782 OPENSSL_free(ss);
734 } 783 }
@@ -753,10 +802,6 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
753 { 802 {
754 if (!SSL_set_ssl_method(s,meth)) 803 if (!SSL_set_ssl_method(s,meth))
755 return(0); 804 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;
760 } 805 }
761 806
762#ifndef OPENSSL_NO_KRB5 807#ifndef OPENSSL_NO_KRB5
@@ -824,6 +869,25 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t)
824 return(t); 869 return(t);
825 } 870 }
826 871
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
827long SSL_CTX_set_timeout(SSL_CTX *s, long t) 891long SSL_CTX_set_timeout(SSL_CTX *s, long t)
828 { 892 {
829 long l; 893 long l;