Blob Blame History Raw

Support building against OpenSSL 1.0.1 but using ALPN support from
OpenSSL 1.0.2 if possible, using the dynamic loader to look up
symbols at run-time.

--- httpd-2.4.26/modules/ssl/config.m4.sslalpnthunks
+++ httpd-2.4.26/modules/ssl/config.m4
@@ -49,6 +49,15 @@
     fi
 ])
 
+AC_ARG_ENABLE(tls-alpn-thunks,
+APACHE_HELP_STRING(--enable-tls-alpn-thunks,Enable support for ALPN thunks in mod_ssl),[
+  if test "$enableval" = "yes"; then
+    AC_DEFINE(HAVE_TLS_ALPN_THUNKS, 1, [Define if support for ALPN thunks is enabled])
+    AC_MSG_NOTICE([Enabled support for  ALPN thunks in mod_ssl])
+  fi
+])
+
+
 # Ensure that other modules can pick up mod_ssl.h
 APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
 
diff -uap httpd-2.4.26/modules/ssl/mod_ssl.c.sslalpnthunks httpd-2.4.26/modules/ssl/mod_ssl.c
--- httpd-2.4.26/modules/ssl/mod_ssl.c.sslalpnthunks
+++ httpd-2.4.26/modules/ssl/mod_ssl.c
@@ -725,6 +725,9 @@
                               &ssl_authz_provider_verify_client,
                               AP_AUTH_INTERNAL_PER_CONF);
 
+#ifdef HAVE_TLS_ALPN_THUNKS
+    modssl_init_alpn_thunks();
+#endif    
 }
 
 module AP_MODULE_DECLARE_DATA ssl_module = {
diff -uap httpd-2.4.26/modules/ssl/ssl_engine_init.c.sslalpnthunks httpd-2.4.26/modules/ssl/ssl_engine_init.c
--- httpd-2.4.26/modules/ssl/ssl_engine_init.c.sslalpnthunks
+++ httpd-2.4.26/modules/ssl/ssl_engine_init.c
@@ -47,6 +47,50 @@
 #define KEYTYPES "RSA or DSA"
 #endif
 
+#ifdef HAVE_TLS_ALPN_THUNKS
+#include <dlfcn.h>
+
+/* During initialization, fetch pointers to OpenSSL functions if
+ * available from the dynamic loader, and store these for later
+ * use. */
+typedef int (ssl_alpn_callback_fn)(SSL *ssl, const unsigned char **out,
+                                   unsigned char *outlen, const unsigned char *in,
+                                   unsigned int inlen, void *arg);
+static void SSL_CTX_set_alpn_select_cb(SSL_CTX *, ssl_alpn_callback_fn *, void *);
+int modssl_SSL_set_alpn_protos(SSL *, unsigned char *, unsigned);
+
+static typeof(SSL_CTX_set_alpn_select_cb) *thunk_set_alpn_select_cb;
+static typeof(modssl_SSL_set_alpn_protos) *thunk_set_alpn_protos;
+
+void modssl_init_alpn_thunks(void)
+{
+    thunk_set_alpn_select_cb = dlsym(RTLD_NEXT, "SSL_CTX_set_alpn_select_cb");
+    thunk_set_alpn_protos = dlsym(RTLD_NEXT, "SSL_set_alpn_protos");
+
+    if (!thunk_set_alpn_select_cb || !thunk_set_alpn_protos) {
+        /* All or nothing... */
+        thunk_set_alpn_select_cb = NULL;
+        thunk_set_alpn_protos = NULL;
+    }
+}
+
+static void SSL_CTX_set_alpn_select_cb(SSL_CTX *ssl, ssl_alpn_callback_fn *cb, void *ud)
+{
+    if (thunk_set_alpn_select_cb)
+        thunk_set_alpn_select_cb(ssl, cb, ud);
+}
+
+int modssl_SSL_set_alpn_protos(SSL *ssl, unsigned char *ps, unsigned plen)
+{
+    if (thunk_set_alpn_protos)
+        return thunk_set_alpn_protos(ssl, ps, plen);
+    else
+        /* Succeed silently; less harmless than failing and logging
+         * warnings. */
+        return 0;           
+}
+#endif /* HAVE_TLS_ALPN_THUNKS */
+
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 /* OpenSSL Pre-1.1.0 compatibility */
 /* Taken from OpenSSL 1.1.0 snapshot 20160410 */
diff -uap httpd-2.4.26/modules/ssl/ssl_private.h.sslalpnthunks httpd-2.4.26/modules/ssl/ssl_private.h
--- httpd-2.4.26/modules/ssl/ssl_private.h.sslalpnthunks
+++ httpd-2.4.26/modules/ssl/ssl_private.h
@@ -199,6 +199,24 @@
 #include <openssl/srp.h>
 #endif
 
+#ifdef HAVE_TLS_ALPN_THUNKS
+
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
+#error Cannot enable TLS ALPN thunks if OpenSSL support is present
+#endif
+
+#define TLSEXT_TYPE_application_layer_protocol_negotiation 16
+
+#define SSL_set_alpn_protos(s, p, l) modssl_SSL_set_alpn_protos(s, p, l)
+
+/* Thunk for SSL_set_alpn_protos(). */
+int modssl_SSL_set_alpn_protos(SSL *, unsigned char *, unsigned);
+
+/* Initialize thunks. */
+void modssl_init_alpn_thunks(void);
+
+#endif
+
 /* ALPN Protocol Negotiation */
 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
 #define HAVE_TLS_ALPN