#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"
#endif
dest->peer_chain = NULL;
dest->peer = NULL;
- dest->ext.tick_nonce = NULL;
dest->ticket_appdata = NULL;
memset(&dest->ex_data, 0, sizeof(dest->ex_data));
if (src->ext.supportedgroups) {
dest->ext.supportedgroups =
OPENSSL_memdup(src->ext.supportedgroups,
- src->ext.supportedgroups_len);
+ src->ext.supportedgroups_len
+ * sizeof(*src->ext.supportedgroups));
if (dest->ext.supportedgroups == NULL)
goto err;
}
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) {
- goto err;
- }
- }
-
- if (src->ext.tick_nonce != NULL) {
- dest->ext.tick_nonce = OPENSSL_memdup(src->ext.tick_nonce,
- src->ext.tick_nonce_len);
- if (dest->ext.tick_nonce == 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;
}
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;
}
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.
/* This is used only by servers. */
SSL_SESSION *ret = NULL;
- int fatal = 0, discard;
+ int fatal = 0;
int try_session_cache = 0;
- SSL_TICKET_RETURN r;
+ SSL_TICKET_STATUS r;
if (SSL_IS_TLS13(s)) {
+ /*
+ * By default we will send a new ticket. This can be overridden in the
+ * ticket processing.
+ */
+ s->ext.ticket_expected = 1;
if (!tls_parse_extension(s, TLSEXT_IDX_psk_kex_modes,
SSL_EXT_CLIENT_HELLO, hello->pre_proc_exts,
NULL, 0)
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:
}
}
- 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;
}
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);
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;
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
{
- int ret = 0, discard;
+ int ret = 0;
SSL_SESSION *s;
/*
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);
}
}
}
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;
if (ss == NULL)
return;
-
CRYPTO_DOWN_REF(&ss->references, &i, ss->lock);
REF_PRINT_COUNT("SSL_SESSION", ss);
if (i > 0)
OPENSSL_free(ss->srp_username);
#endif
OPENSSL_free(ss->ext.alpn_selected);
- OPENSSL_free(ss->ext.tick_nonce);
OPENSSL_free(ss->ticket_appdata);
CRYPTO_THREAD_lock_free(ss->lock);
OPENSSL_clear_free(ss, sizeof(*ss));