X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fssl_sess.c;h=b7638780d0428f4d817164c95c8f680e9e0e81df;hb=2813852d7111ad0a49a963bdc49d944d453e52e7;hp=f78c9cde5f43e2275fc9fdff6783652df4599ace;hpb=df0fed9aab239e2e9a269d06637a6442051dee3b;p=oweals%2Fopenssl.git diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index f78c9cde5f..b7638780d0 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the OpenSSL license (the "License"). You may not use @@ -12,6 +12,7 @@ #include #include #include "internal/refcount.h" +#include "internal/cryptlib.h" #include "ssl_locl.h" #include "statem/statem_locl.h" @@ -124,7 +125,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) dest->ext.hostname = NULL; #ifndef OPENSSL_NO_EC dest->ext.ecpointformats = NULL; - dest->ext.supportedgroups = NULL; #endif dest->ext.tick = NULL; dest->ext.alpn_selected = NULL; @@ -133,7 +133,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) #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)); @@ -201,13 +200,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) if (dest->ext.ecpointformats == NULL) goto err; } - if (src->ext.supportedgroups) { - dest->ext.supportedgroups = - OPENSSL_memdup(src->ext.supportedgroups, - src->ext.supportedgroups_len); - if (dest->ext.supportedgroups == NULL) - goto err; - } #endif if (ticket != 0 && src->ext.tick != NULL) { @@ -220,19 +212,10 @@ 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) { - 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; } @@ -295,7 +278,7 @@ static int def_generate_session_id(SSL *ssl, unsigned char *id, { unsigned int retry = 0; do - if (ssl_randbytes(ssl, id, *id_len) <= 0) + if (RAND_bytes(id, *id_len) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; @@ -417,21 +400,18 @@ int ssl_get_new_session(SSL *s, int session) s->session = NULL; if (session) { - if (!ssl_generate_session_id(s, ss)) { + if (SSL_IS_TLS13(s)) { + /* + * We generate the session id while constructing the + * NewSessionTicket in TLSv1.3. + */ + ss->session_id_length = 0; + } else if (!ssl_generate_session_id(s, ss)) { /* SSLfatal() already called */ SSL_SESSION_free(ss); 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; } @@ -455,6 +435,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. @@ -477,11 +521,16 @@ 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_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) @@ -502,8 +551,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: @@ -512,67 +564,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; @@ -609,8 +600,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); @@ -638,8 +628,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; @@ -666,7 +655,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; /* @@ -733,8 +722,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); } } } @@ -755,21 +743,21 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) if ((c != NULL) && (c->session_id_length != 0)) { if (lck) CRYPTO_THREAD_write_lock(ctx->lock); - if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { + if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) { ret = 1; - r = lh_SSL_SESSION_delete(ctx->sessions, c); - SSL_SESSION_list_remove(ctx, c); + r = lh_SSL_SESSION_delete(ctx->sessions, r); + SSL_SESSION_list_remove(ctx, r); } c->not_resumable = 1; 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; @@ -781,7 +769,6 @@ void SSL_SESSION_free(SSL_SESSION *ss) if (ss == NULL) return; - CRYPTO_DOWN_REF(&ss->references, &i, ss->lock); REF_PRINT_COUNT("SSL_SESSION", ss); if (i > 0) @@ -801,9 +788,6 @@ void SSL_SESSION_free(SSL_SESSION *ss) OPENSSL_free(ss->ext.ecpointformats); ss->ext.ecpointformats = NULL; ss->ext.ecpointformats_len = 0; - OPENSSL_free(ss->ext.supportedgroups); - ss->ext.supportedgroups = NULL; - ss->ext.supportedgroups_len = 0; #endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_PSK OPENSSL_free(ss->psk_identity_hint); @@ -813,7 +797,6 @@ void SSL_SESSION_free(SSL_SESSION *ss) 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)); @@ -1301,4 +1284,22 @@ int SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len) return 1; } +void SSL_CTX_set_stateless_cookie_generate_cb( + SSL_CTX *ctx, + int (*cb) (SSL *ssl, + unsigned char *cookie, + size_t *cookie_len)) +{ + ctx->gen_stateless_cookie_cb = cb; +} + +void SSL_CTX_set_stateless_cookie_verify_cb( + SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char *cookie, + size_t cookie_len)) +{ + ctx->verify_stateless_cookie_cb = cb; +} + IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)