From 334eeef5a1b2861355c731493e7bbc5152165e49 Mon Sep 17 00:00:00 2001 From: Artem Boldariev Date: Mon, 23 May 2022 13:41:06 +0300 Subject: [PATCH] Do not provide a shim for SSL_SESSION_is_resumable() The recently added TLS client session cache used SSL_SESSION_is_resumable() to avoid polluting the cache with non-resumable sessions. However, it turned out that we cannot provide a shim for this function across the whole range of OpenSSL versions due to the fact that OpenSSL 1.1.0 does uses opaque pointers for SSL_SESSION objects. The commit replaces the shim for SSL_SESSION_is_resumable() with a non public approximation of it on systems shipped with OpenSSL 1.1.0. It is not turned into a proper shim because it does not fully emulate the behaviour of SSL_SESSION_is_resumable(), but in our case it is good enough, as it still helps to protect the cache from pollution. For systems shipped with OpenSSL 1.0.X and derivatives (e.g. older versions of LibreSSL), the provided replacement perfectly mimics the function it is intended to replace. (cherry picked from commit 40be3c926309867ebaeb4b1dcd7e1199473dea4d) --- lib/isc/openssl_shim.c | 8 -------- lib/isc/openssl_shim.h | 5 ----- lib/isc/tls.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/isc/openssl_shim.c b/lib/isc/openssl_shim.c index 1099a4a92f..b8dbfaa71b 100644 --- a/lib/isc/openssl_shim.c +++ b/lib/isc/openssl_shim.c @@ -196,11 +196,3 @@ SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) { } #endif /* !HAVE_SSL_CTX_SET1_CERT_STORE */ - -#if !HAVE_SSL_SESSION_IS_RESUMABLE -int -SSL_SESSION_is_resumable(const SSL_SESSION *sess) { - return (!sess->not_resumable && - (sess->session_id_length > 0 || sess->tlsext_ticklen > 0)); -} -#endif /* HAVE_SSL_SESSION_IS_RESUMABLE */ diff --git a/lib/isc/openssl_shim.h b/lib/isc/openssl_shim.h index 005055c3e8..c0abd14467 100644 --- a/lib/isc/openssl_shim.h +++ b/lib/isc/openssl_shim.h @@ -135,8 +135,3 @@ X509_STORE_up_ref(X509_STORE *v); void SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store); #endif /* !HAVE_SSL_CTX_SET1_CERT_STORE */ - -#if !HAVE_SSL_SESSION_IS_RESUMABLE -int -SSL_SESSION_is_resumable(const SSL_SESSION *s); -#endif /* HAVE_SSL_SESSION_IS_RESUMABLE */ diff --git a/lib/isc/tls.c b/lib/isc/tls.c index 2a6923b73d..a2264a3945 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -1484,6 +1484,33 @@ isc_tlsctx_client_session_cache_detach( isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache)); } +static bool +ssl_session_seems_resumable(const SSL_SESSION *sess) { +#ifdef HAVE_SSL_SESSION_IS_RESUMABLE + /* + * If SSL_SESSION_is_resumable() is available, let's use that. It + * is expected to be available on OpenSSL >= 1.1.1 and its modern + * siblings. + */ + return (SSL_SESSION_is_resumable(sess) != 0); +#elif (OPENSSL_VERSION_NUMBER >= 0x10100000L) + /* + * Taking into consideration that OpenSSL 1.1.0 uses opaque + * pointers for SSL_SESSION, we cannot implement a replacement for + * SSL_SESSION_is_resumable() manually. Let's use a sensible + * approximation for that, then: if there is an associated session + * ticket or session ID, then, most likely, the session is + * resumable. + */ + unsigned int session_id_len = 0; + (void)SSL_SESSION_get_id(sess, &session_id_len); + return (SSL_SESSION_has_ticket(sess) || session_id_len > 0); +#else + return (!sess->not_resumable && + (sess->session_id_length > 0 || sess->tlsext_ticklen > 0)); +#endif +} + void isc_tlsctx_client_session_cache_keep(isc_tlsctx_client_session_cache_t *cache, char *remote_peer_name, isc_tls_t *tls) { @@ -1500,7 +1527,7 @@ isc_tlsctx_client_session_cache_keep(isc_tlsctx_client_session_cache_t *cache, sess = SSL_get1_session(tls); if (sess == NULL) { return; - } else if (SSL_SESSION_is_resumable(sess) == 0) { + } else if (!ssl_session_seems_resumable(sess)) { SSL_SESSION_free(sess); return; }