summaryrefslogtreecommitdiff
path: root/ssl/ssl_sess.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2018-06-13 15:57:39 +0100
committerMatt Caswell <matt@openssl.org>2018-06-26 18:09:46 +0100
commit6cc0b3c2171e26379e898574cb6d42b8d8dcc113 (patch)
treeabc151eedbe6c46563085d8f690b7b008b3c1c8e /ssl/ssl_sess.c
parent6a11d5c5ededa1543c2eeb2f9edcbe39bc58bb70 (diff)
downloadopenssl-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.c134
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, &copy);
+
+ 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,
- &copy);
-
- 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;