X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_sess.c;h=5ad2792a1b4c9087f684b4eaa748f8e6cdf0ea52;hp=525edb3289b7d8c7392e12f9192f61f4d33f549c;hb=ed48d2032d29a82c6aebbddf0fbf530ac2d2521d;hpb=6cf2dbd9faffbed52a6bede924fe0a93345b8bfa diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 525edb3289..5ad2792a1b 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -12,6 +12,7 @@ #include #include #include "internal/refcount.h" +#include "internal/cryptlib.h" #include "ssl_locl.h" #include "statem/statem_locl.h" @@ -220,13 +221,11 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) dest->ext.ticklen = 0; } - if (src->ext.alpn_selected) { - dest->ext.alpn_selected = - (unsigned char*)OPENSSL_strndup((char*)src->ext.alpn_selected, - src->ext.alpn_selected_len); - if (dest->ext.alpn_selected == NULL) { + if (src->ext.alpn_selected != NULL) { + dest->ext.alpn_selected = OPENSSL_memdup(src->ext.alpn_selected, + src->ext.alpn_selected_len); + if (dest->ext.alpn_selected == NULL) goto err; - } } #ifndef OPENSSL_NO_SRP @@ -422,15 +421,6 @@ int ssl_get_new_session(SSL *s, int session) return 0; } - if (s->ext.hostname) { - ss->ext.hostname = OPENSSL_strdup(s->ext.hostname); - if (ss->ext.hostname == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_NEW_SESSION, - ERR_R_INTERNAL_ERROR); - SSL_SESSION_free(ss); - return 0; - } - } } else { ss->session_id_length = 0; } @@ -454,6 +444,70 @@ int ssl_get_new_session(SSL *s, int session) return 1; } +SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, + size_t sess_id_len) +{ + SSL_SESSION *ret = NULL; + + if ((s->session_ctx->session_cache_mode + & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) { + SSL_SESSION data; + + data.ssl_version = s->version; + if (!ossl_assert(sess_id_len <= SSL_MAX_SSL_SESSION_ID_LENGTH)) + return NULL; + + memcpy(data.session_id, sess_id, sess_id_len); + data.session_id_length = sess_id_len; + + CRYPTO_THREAD_read_lock(s->session_ctx->lock); + ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); + if (ret != NULL) { + /* don't allow other threads to steal it: */ + SSL_SESSION_up_ref(ret); + } + CRYPTO_THREAD_unlock(s->session_ctx->lock); + if (ret == NULL) + tsan_counter(&s->session_ctx->stats.sess_miss); + } + + if (ret == NULL && s->session_ctx->get_session_cb != NULL) { + int copy = 1; + + ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©); + + if (ret != NULL) { + tsan_counter(&s->session_ctx->stats.sess_cb_hit); + + /* + * Increment reference count now if the session callback asks us + * to do so (note that if the session structures returned by the + * callback are shared between threads, it must handle the + * reference count itself [i.e. copy == 0], or things won't be + * thread-safe). + */ + if (copy) + SSL_SESSION_up_ref(ret); + + /* + * Add the externally cached session to the internal cache as + * well if and only if we are supposed to. + */ + if ((s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0) { + /* + * Either return value of SSL_CTX_add_session should not + * interrupt the session resumption process. The return + * value is intentionally ignored. + */ + (void)SSL_CTX_add_session(s->session_ctx, ret); + } + } + } + + return ret; +} + /*- * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this * connection. It is only called by servers. @@ -476,7 +530,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) /* This is used only by servers. */ SSL_SESSION *ret = NULL; - int fatal = 0, discard; + int fatal = 0; int try_session_cache = 0; SSL_TICKET_STATUS r; @@ -506,8 +560,11 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) goto err; case SSL_TICKET_NONE: case SSL_TICKET_EMPTY: - if (hello->session_id_len > 0) + if (hello->session_id_len > 0) { try_session_cache = 1; + ret = lookup_sess_in_cache(s, hello->session_id, + hello->session_id_len); + } break; case SSL_TICKET_NO_DECRYPT: case SSL_TICKET_SUCCESS: @@ -516,67 +573,6 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) } } - if (try_session_cache && - ret == NULL && - !(s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { - SSL_SESSION data; - - data.ssl_version = s->version; - memcpy(data.session_id, hello->session_id, hello->session_id_len); - data.session_id_length = hello->session_id_len; - - CRYPTO_THREAD_read_lock(s->session_ctx->lock); - ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); - if (ret != NULL) { - /* don't allow other threads to steal it: */ - SSL_SESSION_up_ref(ret); - } - CRYPTO_THREAD_unlock(s->session_ctx->lock); - if (ret == NULL) - CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard, - s->session_ctx->lock); - } - - if (try_session_cache && - ret == NULL && s->session_ctx->get_session_cb != NULL) { - int copy = 1; - - ret = s->session_ctx->get_session_cb(s, hello->session_id, - hello->session_id_len, - ©); - - if (ret != NULL) { - CRYPTO_atomic_add(&s->session_ctx->stats.sess_cb_hit, 1, &discard, - s->session_ctx->lock); - - /* - * Increment reference count now if the session callback asks us - * to do so (note that if the session structures returned by the - * callback are shared between threads, it must handle the - * reference count itself [i.e. copy == 0], or things won't be - * thread-safe). - */ - if (copy) - SSL_SESSION_up_ref(ret); - - /* - * Add the externally cached session to the internal cache as - * well if and only if we are supposed to. - */ - if (! - (s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_STORE)) { - /* - * Either return value of SSL_CTX_add_session should not - * interrupt the session resumption process. The return - * value is intentionally ignored. - */ - SSL_CTX_add_session(s->session_ctx, ret); - } - } - } - if (ret == NULL) goto err; @@ -613,8 +609,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) } if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ - CRYPTO_atomic_add(&s->session_ctx->stats.sess_timeout, 1, &discard, - s->session_ctx->lock); + tsan_counter(&s->session_ctx->stats.sess_timeout); if (try_session_cache) { /* session was from the cache, so remove it */ SSL_CTX_remove_session(s->session_ctx, ret); @@ -642,8 +637,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) s->session = ret; } - CRYPTO_atomic_add(&s->session_ctx->stats.sess_hit, 1, &discard, - s->session_ctx->lock); + tsan_counter(&s->session_ctx->stats.sess_hit); s->verify_result = s->session->verify_result; return 1; @@ -670,7 +664,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) { - int ret = 0, discard; + int ret = 0; SSL_SESSION *s; /* @@ -737,8 +731,7 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) break; else - CRYPTO_atomic_add(&ctx->stats.sess_cache_full, 1, &discard, - ctx->lock); + tsan_counter(&ctx->stats.sess_cache_full); } } } @@ -769,11 +762,11 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) if (lck) CRYPTO_THREAD_unlock(ctx->lock); - if (ret) - SSL_SESSION_free(r); - if (ctx->remove_session_cb != NULL) ctx->remove_session_cb(ctx, c); + + if (ret) + SSL_SESSION_free(r); } else ret = 0; return ret;