]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Do not provide a shim for SSL_SESSION_is_resumable()
authorArtem Boldariev <artem@boldariev.com>
Mon, 23 May 2022 10:41:06 +0000 (13:41 +0300)
committerArtem Boldariev <artem@boldariev.com>
Mon, 23 May 2022 15:25:18 +0000 (18:25 +0300)
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.

lib/isc/openssl_shim.c
lib/isc/openssl_shim.h
lib/isc/tls.c

index 040fc68fbb3f98da71ad3d60588f09576cb212e1..c39ba8c68270b46202c5342788c262dbc21d52e6 100644 (file)
@@ -196,11 +196,3 @@ SSL_CTX_up_ref(SSL_CTX *ctx) {
        return (CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX) > 0);
 }
 #endif /* !HAVE_SSL_CTX_UP_REF */
-
-#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 */
index 6b3a30b28851cb947dd0da1174d37414f611c8a2..b2916e20a903325b3369c8b32c72de29e919c228 100644 (file)
@@ -135,8 +135,3 @@ SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store);
 int
 SSL_CTX_up_ref(SSL_CTX *store);
 #endif /* !HAVE_SSL_CTX_UP_REF */
-
-#if !HAVE_SSL_SESSION_IS_RESUMABLE
-int
-SSL_SESSION_is_resumable(const SSL_SESSION *s);
-#endif /* HAVE_SSL_SESSION_IS_RESUMABLE */
index 84b3330e7b1ea802a09698d9ffa6e0a000698fca..29cd063246c5d7455a994632aa9800d83ccc1bcd 100644 (file)
@@ -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;
        }