diff options
author | Matt Caswell <matt@openssl.org> | 2018-06-13 15:57:39 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2018-06-26 18:09:46 +0100 |
commit | 6cc0b3c2171e26379e898574cb6d42b8d8dcc113 (patch) | |
tree | abc151eedbe6c46563085d8f690b7b008b3c1c8e /ssl/ssl_sess.c | |
parent | 6a11d5c5ededa1543c2eeb2f9edcbe39bc58bb70 (diff) | |
download | openssl-new-6cc0b3c2171e26379e898574cb6d42b8d8dcc113.tar.gz |
Respect SSL_OP_NO_TICKET in TLSv1.3
Implement support for stateful TLSv1.3 tickets, and use them if
SSL_OP_NO_TICKET is set.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6563)
Diffstat (limited to 'ssl/ssl_sess.c')
-rw-r--r-- | ssl/ssl_sess.c | 134 |
1 files changed, 72 insertions, 62 deletions
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index fde4187d9c..628b9f060b 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -12,6 +12,7 @@ #include <openssl/rand.h> #include <openssl/engine.h> #include "internal/refcount.h" +#include "internal/cryptlib.h" #include "ssl_locl.h" #include "statem/statem_locl.h" @@ -452,6 +453,73 @@ 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; + int discard; + + 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) + CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard, + s->session_ctx->lock); + } + + 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) { + 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) == 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. @@ -504,8 +572,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: @@ -514,67 +585,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; |