ASF Bugzilla – Attachment 32464 Details for
Bug 52210
Add TLS Next Protocol Negotiation (NPN) support to mod_ssl
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Add ALPN/NPN support to mod_ssl
alpn-2.4.x.unified.diff.patch (text/plain), 21.30 KB, created by
Stefan Eissing
on 2015-02-12 16:02:14 UTC
(
hide
)
Description:
Add ALPN/NPN support to mod_ssl
Filename:
MIME Type:
Creator:
Stefan Eissing
Created:
2015-02-12 16:02:14 UTC
Size:
21.30 KB
patch
obsolete
>diff -ru gen/httpd-2.4.x/modules/ssl/mod_ssl.c modules/ssl/mod_ssl.c >--- gen/httpd-2.4.x/modules/ssl/mod_ssl.c 2015-01-19 16:52:30.000000000 +0100 >+++ modules/ssl/mod_ssl.c 2015-01-19 15:42:53.904000000 +0100 >@@ -273,6 +270,12 @@ > "OpenSSL configuration command") > #endif > >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ SSL_CMD_SRV(AlpnPreference, ITERATE, >+ "Preference in Application-Layer Protocol Negotiation (ALPN), " >+ "protocols are chosed in the specified order") >+#endif >+ > /* Deprecated directives. */ > AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL, > "SSLLog directive is no longer supported - use ErrorLog."), >@@ -423,6 +423,37 @@ > return 1; > } > >+static int modssl_register_alpn(conn_rec *c, >+ ssl_alpn_propose_protos advertisefn, >+ ssl_alpn_proto_negotiated negotiatedfn) >+{ >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ SSLConnRec *sslconn = myConnConfig(c); >+ >+ if (!sslconn) { >+ return DECLINED; >+ } >+ >+ if (!sslconn->alpn_proposefns) { >+ sslconn->alpn_proposefns = >+ apr_array_make(c->pool, 5, sizeof(ssl_alpn_propose_protos)); >+ sslconn->alpn_negofns = >+ apr_array_make(c->pool, 5, sizeof(ssl_alpn_proto_negotiated)); >+ } >+ >+ if (advertisefn) >+ APR_ARRAY_PUSH(sslconn->alpn_proposefns, ssl_alpn_propose_protos) = >+ advertisefn; >+ if (negotiatedfn) >+ APR_ARRAY_PUSH(sslconn->alpn_negofns, ssl_alpn_proto_negotiated) = >+ negotiatedfn; >+ >+ return OK; >+#else >+ return DECLINED; >+#endif >+} >+ > int ssl_init_ssl_connection(conn_rec *c, request_rec *r) > { > SSLSrvConfigRec *sc; >@@ -585,6 +616,7 @@ > > APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); > APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); >+ APR_REGISTER_OPTIONAL_FN(modssl_register_alpn); > > ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl", > AUTHZ_PROVIDER_VERSION, >diff -ru gen/httpd-2.4.x/modules/ssl/mod_ssl.h modules/ssl/mod_ssl.h >--- gen/httpd-2.4.x/modules/ssl/mod_ssl.h 2015-01-07 17:03:34.000000000 +0100 >+++ modules/ssl/mod_ssl.h 2015-01-19 15:42:53.904000000 +0100 >@@ -63,5 +63,46 @@ > > APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); > >+/** The alpn_propose_proto callback allows other modules to propose >+ * the name of the protocol that will be chosen during the >+ * Application-Layer Protocol Negotiation (ALPN) portion of the SSL handshake. >+ * The callback is given the connection and a list of NULL-terminated >+ * protocol strings as supported by the client. If this client_protos is >+ * non-empty, it must pick its preferred protocol from that list. Otherwise >+ * it should add its supported protocols in order of precedence. >+ * The callback should not yet modify the connection or install any filters >+ * as its proposal(s) may be overridden by another callback or server >+ * configuration. >+ * It should return OK or, to prevent further processing of (other modules') >+ * callbacks, return DONE. >+ */ >+typedef int (*ssl_alpn_propose_protos)(conn_rec *connection, >+ apr_array_header_t *client_protos, >+ apr_array_header_t *proposed_protos); >+ >+/** The alpn_proto_negotiated callback allows other modules to discover >+ * the name of the protocol that was chosen during the Application-Layer >+ * Protocol Negotiation (ALPN) portion of the SSL handshake. >+ * The callback is given the connection, a >+ * non-NUL-terminated string containing the protocol name, and the >+ * length of the string; it should do something appropriate >+ * (i.e. insert or remove filters) and return OK. To prevent further >+ * processing of (other modules') callbacks, return DONE. */ >+typedef int (*ssl_alpn_proto_negotiated)(conn_rec *connection, >+ const char *proto_name, >+ apr_size_t proto_name_len); >+ >+/* An optional function which can be used to register a pair of callbacks >+ * for ALPN handling. >+ * This optional function should be invoked from a pre_connection hook >+ * which runs *after* mod_ssl.c's pre_connection hook. The function returns >+ * OK if the callbacks are registered, or DECLINED otherwise (for example if >+ * mod_ssl does not support ALPN). >+ */ >+APR_DECLARE_OPTIONAL_FN(int, modssl_register_alpn, >+ (conn_rec *conn, >+ ssl_alpn_propose_protos proposefn, >+ ssl_alpn_proto_negotiated negotiatedfn)); >+ > #endif /* __MOD_SSL_H__ */ > /** @} */ >diff -ru gen/httpd-2.4.x/modules/ssl/ssl_engine_config.c modules/ssl/ssl_engine_config.c >--- gen/httpd-2.4.x/modules/ssl/ssl_engine_config.c 2015-01-19 16:52:30.000000000 +0100 >+++ modules/ssl/ssl_engine_config.c 2015-01-19 16:34:55.944000000 +0100 >@@ -159,6 +159,9 @@ > SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_CERTIFICATE); > mctx->ssl_ctx_param = apr_array_make(p, 5, sizeof(ssl_ctx_param_t)); > #endif >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ mctx->ssl_alpn_pref = apr_array_make(p, 5, sizeof(const char *)); >+#endif > } > > static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc, >@@ -298,6 +300,9 @@ > #ifdef HAVE_SSL_CONF_CMD > cfgMergeArray(ssl_ctx_param); > #endif >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ cfgMergeArray(ssl_alpn_pref); >+#endif > } > > static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p, >@@ -1868,6 +1861,16 @@ > return NULL; > } > #endif >+ >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+const char *ssl_cmd_SSLAlpnPreference(cmd_parms *cmd, void *dcfg, >+ const char *protocol) >+{ >+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); >+ APR_ARRAY_PUSH(sc->server->ssl_alpn_pref, const char *) = protocol; >+ return NULL; >+} >+#endif > > #ifdef HAVE_SRP > >diff -ru gen/httpd-2.4.x/modules/ssl/ssl_engine_init.c modules/ssl/ssl_engine_init.c >--- gen/httpd-2.4.x/modules/ssl/ssl_engine_init.c 2015-01-19 16:52:30.000000000 +0100 >+++ modules/ssl/ssl_engine_init.c 2015-01-19 15:42:53.908000000 +0100 >@@ -623,6 +613,14 @@ > SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); > > SSL_CTX_set_info_callback(ctx, ssl_callback_Info); >+ >+#if defined(HAVE_TLS_ALPN) >+ SSL_CTX_set_alpn_select_cb( >+ ctx, ssl_callback_alpn_select, NULL); >+#elif defined(HAVE_TLS_NPN) >+ SSL_CTX_set_next_protos_advertised_cb( >+ ctx, ssl_callback_AdvertiseNextProtos, NULL); >+#endif > } > > static apr_status_t ssl_init_ctx_verify(server_rec *s, >diff -ru gen/httpd-2.4.x/modules/ssl/ssl_engine_io.c modules/ssl/ssl_engine_io.c >--- gen/httpd-2.4.x/modules/ssl/ssl_engine_io.c 2015-01-19 16:52:30.000000000 +0100 >+++ modules/ssl/ssl_engine_io.c 2015-01-19 15:42:53.908000000 +0100 >@@ -28,6 +28,7 @@ > core keeps dumping.'' > -- Unknown */ > #include "ssl_private.h" >+#include "mod_ssl.h" > #include "apr_date.h" > > /* _________________________________________________________________ >@@ -297,6 +298,7 @@ > apr_pool_t *pool; > char buffer[AP_IOBUFSIZE]; > ssl_filter_ctx_t *filter_ctx; >+ int alpn_finished; /* 1 if ALPN has finished, 0 otherwise */ > } bio_filter_in_ctx_t; > > /* >@@ -1412,6 +1414,42 @@ > APR_BRIGADE_INSERT_TAIL(bb, bucket); > } > >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ /* By this point, Application-Layer Protocol Negotiation (ALPN) should be >+ * completed (if our version of OpenSSL supports it). If we haven't already, >+ * find out which protocol was decided upon and inform other modules >+ * by calling alpn_proto_negotiated_hook. >+ */ >+ if (!inctx->alpn_finished) { >+ SSLConnRec *sslconn = myConnConfig(f->c); >+ const unsigned char *next_proto = NULL; >+ unsigned next_proto_len = 0; >+ int n; >+ >+ if (sslconn->alpn_negofns) { >+ #ifdef HAVE_TLS_ALPN >+ SSL_get0_alpn_selected(inctx->ssl, &next_proto, &next_proto_len); >+ #else >+ SSL_get0_next_proto_negotiated( >+ inctx->ssl, &next_proto, &next_proto_len); >+ #endif >+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c, >+ APLOGNO(02306) "SSL negotiated protocol: '%s'", >+ (next_proto && next_proto_len)? >+ apr_pstrmemdup(f->c->pool, (const char *)next_proto, >+ next_proto_len) : "(null)"); >+ for (n = 0; n < sslconn->alpn_negofns->nelts; n++) { >+ ssl_alpn_proto_negotiated fn = >+ APR_ARRAY_IDX(sslconn->alpn_negofns, n, ssl_alpn_proto_negotiated); >+ >+ if (fn(f->c, (const char *)next_proto, next_proto_len) == DONE) >+ break; >+ } >+ } >+ inctx->alpn_finished = 1; >+ } >+#endif >+ > return APR_SUCCESS; > } > >@@ -1893,6 +1932,7 @@ > inctx->block = APR_BLOCK_READ; > inctx->pool = c->pool; > inctx->filter_ctx = filter_ctx; >+ inctx->alpn_finished = 0; > } > > /* The request_rec pointer is passed in here only to ensure that the >diff -ru gen/httpd-2.4.x/modules/ssl/ssl_engine_kernel.c modules/ssl/ssl_engine_kernel.c >--- gen/httpd-2.4.x/modules/ssl/ssl_engine_kernel.c 2015-01-19 16:52:30.000000000 +0100 >+++ modules/ssl/ssl_engine_kernel.c 2015-01-19 16:37:09.536000000 +0100 >@@ -29,6 +29,7 @@ > time I was too famous.'' > -- Unknown */ > #include "ssl_private.h" >+#include "mod_ssl.h" > #include "util_md5.h" > > static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); >@@ -2136,6 +2131,270 @@ > } > #endif /* HAVE_TLS_SESSION_TICKETS */ > >+static int ssl_array_index(apr_array_header_t *array, >+ const char *s) >+{ >+ int i; >+ for (i = 0; i < array->nelts; i++) { >+ const char *p = APR_ARRAY_IDX(array, i, const char*); >+ if (!strcmp(p, s)) { >+ return i; >+ } >+ } >+ return -1; >+} >+ >+#ifdef HAVE_TLS_ALPN >+/* >+ * Compare to ALPN protocol proposal. Result is similar to strcmp(): >+ * 0 gives same precedence, >0 means proto1 is prefered. >+ */ >+static int ssl_cmp_alpn_protos(modssl_ctx_t *ctx, >+ const char *proto1, >+ const char *proto2) >+{ >+ /* TODO: we should have a mod_ssl configuration parameter. */ >+ if (ctx && ctx->ssl_alpn_pref) { >+ int index1 = ssl_array_index(ctx->ssl_alpn_pref, proto1); >+ int index2 = ssl_array_index(ctx->ssl_alpn_pref, proto2); >+ if (index2 > index1) { >+ return (index1 >= 0)? 1 : -1; >+ } >+ else if (index1 > index2) { >+ return (index2 >= 0)? -1 : 1; >+ } >+ } >+ /* both have the same index (mabye -1 or no pref configured) and we compare >+ * the names so that spdy3 gets precedence over spdy2. That makes >+ * the outcome at least deterministic. */ >+ return strcmp((const char *)proto1, (const char *)proto2); >+} >+ >+/* >+ * This callback function is executed when the TLS Application Layer >+ * Protocol Negotiate Extension (ALPN, RFC 7301) is triggered by the client >+ * hello, giving a list of desired protocol names (in descending preference) >+ * to the server. >+ * The callback has to select a protocol name or return an error if none of >+ * the clients preferences is supported. >+ * The selected protocol does not have to be on the client list, according >+ * to RFC 7301, so no checks are performed. >+ * The client protocol list is serialized as length byte followed by ascii >+ * characters (not null-terminated), followed by the next protocol name. >+ */ >+int ssl_callback_alpn_select(SSL *ssl, >+ const unsigned char **out, unsigned char *outlen, >+ const unsigned char *in, unsigned int inlen, void *arg) >+{ >+ conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); >+ SSLConnRec *sslconn = myConnConfig(c); >+ server_rec *s = mySrvFromConn(c); >+ SSLSrvConfigRec *sc = mySrvConfig(s); >+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); >+ const char *alpn_http1 = "http/1.1"; >+ apr_array_header_t *client_protos; >+ apr_array_header_t *proposed_protos; >+ int i; >+ >+ /* If the connection object is not available, >+ * then there's nothing for us to do. */ >+ if (c == NULL) { >+ return SSL_TLSEXT_ERR_OK; >+ } >+ >+ if (inlen == 0) { >+ // someone tries to trick us? >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02306) >+ "alpn client protocol list empty"); >+ return SSL_TLSEXT_ERR_ALERT_FATAL; >+ } >+ >+ client_protos = apr_array_make(c->pool, 0, sizeof(char *)); >+ for (i = 0; i < inlen; /**/) { >+ unsigned int plen = in[i++]; >+ if (plen + i > inlen) { >+ // someone tries to trick us? >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02306) >+ "alpn protocol identier too long"); >+ return SSL_TLSEXT_ERR_ALERT_FATAL; >+ } >+ APR_ARRAY_PUSH(client_protos, char*) = >+ apr_pstrndup(c->pool, (const char *)in+i, plen); >+ i += plen; >+ } >+ >+ /* Regardless of installed hooks, the http/1.1 protocol is always >+ * supported by us. Add it to the proposals if the client also >+ * offers it. */ >+ proposed_protos = apr_array_make(c->pool, client_protos->nelts+1, >+ sizeof(char *)); >+ if (ssl_array_index(client_protos, alpn_http1) >= 0) { >+ APR_ARRAY_PUSH(proposed_protos, const char*) = alpn_http1; >+ } >+ >+ if (sslconn->alpn_proposefns != NULL) { >+ /* Invoke our alpn_propos_proto hooks, giving other modules a chance to >+ * propose protocol names for selection. We might have several such >+ * hooks installed and if two make a proposal, we need to give >+ * preference to one. >+ */ >+ for (i = 0; i < sslconn->alpn_proposefns->nelts; i++) { >+ ssl_alpn_propose_protos fn = >+ APR_ARRAY_IDX(sslconn->alpn_proposefns, i, >+ ssl_alpn_propose_protos); >+ >+ if (fn(c, client_protos, proposed_protos) == DONE) >+ break; >+ } >+ } >+ >+ if (proposed_protos->nelts <= 0) { >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02306) >+ "none of the client alpn protocols are supported"); >+ return SSL_TLSEXT_ERR_ALERT_FATAL; >+ } >+ >+ /* Now select the most preferred protocol from the proposals. */ >+ *out = APR_ARRAY_IDX(proposed_protos, 0, const unsigned char *); >+ for (i = 1; i < proposed_protos->nelts; ++i) { >+ const char *proto = APR_ARRAY_IDX(proposed_protos, i, const char*); >+ /* Do we prefer it over existing candidate? */ >+ if (ssl_cmp_alpn_protos(mctx, (const char *)*out, proto) < 0) { >+ *out = (const unsigned char*)proto; >+ } >+ } >+ >+ size_t len = strlen((const char*)*out); >+ if (len > 255) { >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02306) >+ "alpn negotiated protocol name too long"); >+ return SSL_TLSEXT_ERR_ALERT_FATAL; >+ } >+ *outlen = (unsigned char)len; >+ >+ return SSL_TLSEXT_ERR_OK; >+} >+ >+#elif defined(HAVE_TLS_NPN) >+/* >+ * This callback function is executed when SSL needs to decide what protocols >+ * to advertise during Next Protocol Negotiation (NPN). It must produce a >+ * string in wire format -- a sequence of length-prefixed strings -- indicating >+ * the advertised protocols. Refer to SSL_CTX_set_next_protos_advertised_cb >+ * in OpenSSL for reference. >+ */ >+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out, >+ unsigned int *size_out, void *arg) >+{ >+ conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); >+ SSLConnRec *sslconn = myConnConfig(c); >+ server_rec *s = mySrvFromConn(c); >+ SSLSrvConfigRec *sc = mySrvConfig(s); >+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); >+ apr_array_header_t *protos; >+ int num_protos; >+ unsigned int size; >+ int i, j; >+ unsigned char *data; >+ unsigned char *start; >+ const char *http11 = "http/1.1"; >+ >+ *data_out = NULL; >+ *size_out = 0; >+ >+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02306) >+ "advertisingNextProtos"); >+ >+ /* If the connection object is not available, or there are no NPN >+ * hooks registered, then there's nothing for us to do. */ >+ if (c == NULL || sslconn->alpn_proposefns == NULL) { >+ return SSL_TLSEXT_ERR_OK; >+ } >+ >+ /* Invoke our alpn_propose_proto hook, giving other modules a chance to >+ * add alternate protocol names to advertise. */ >+ protos = apr_array_make(c->pool, 0, sizeof(char *)); >+ for (i = 0; i < sslconn->alpn_proposefns->nelts; i++) { >+ ssl_alpn_propose_protos fn = >+ APR_ARRAY_IDX(sslconn->alpn_proposefns, i, ssl_alpn_propose_protos); >+ >+ if (fn(c, NULL, protos) == DONE) >+ break; >+ } >+ if (ssl_array_index(protos, http11) < 0) { >+ APR_ARRAY_PUSH(protos, const char*) = http11; >+ } >+ num_protos = protos->nelts; >+ >+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02306) >+ "alpn protos %d to advertise, %d in pref config", num_protos, mctx->ssl_alpn_pref->nelts ); >+ if (num_protos > 1 && mctx->ssl_alpn_pref && mctx->ssl_alpn_pref->nelts > 0) { >+ /* Sort the protocol names according to our configured preferences. */ >+ int insert_idx = 0; >+ for (i = 0; i < mctx->ssl_alpn_pref->nelts; ++i) { >+ const char *proto = APR_ARRAY_IDX(mctx->ssl_alpn_pref, i, const char*); >+ int idx = ssl_array_index(protos, proto); >+ if (idx > insert_idx) { >+ /* bubble found protocol up */ >+ for (j = idx; j > insert_idx; --j) { >+ ((const char **)protos->elts)[j] = ((const char **)protos->elts)[j-1]; >+ } >+ ((const char **)protos->elts)[insert_idx] = proto; >+ ++insert_idx; >+ } >+ } >+ } >+ >+ /* We now have a list of null-terminated strings; we need to concatenate >+ * them together into a single string, where each protocol name is prefixed >+ * by its length. First, calculate how long that string will be. */ >+ size = 0; >+ for (i = 0; i < num_protos; ++i) { >+ const char *string = APR_ARRAY_IDX(protos, i, const char*); >+ unsigned int length = strlen(string); >+ /* If the protocol name is too long (the length must fit in one byte), >+ * then log an error and skip it. */ >+ if (length > 255) { >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02307) >+ "SSL NPN protocol name too long (length=%u): %s", >+ length, string); >+ continue; >+ } >+ /* Leave room for the length prefix (one byte) plus the protocol name >+ * itself. */ >+ size += 1 + length; >+ } >+ >+ /* If there is nothing to advertise (either because no modules added >+ * anything to the protos array, or because all strings added to the array >+ * were skipped), then we're done. */ >+ if (size == 0) { >+ return SSL_TLSEXT_ERR_OK; >+ } >+ >+ /* Now we can build the string. Copy each protocol name string into the >+ * larger string, prefixed by its length. */ >+ data = apr_palloc(c->pool, size * sizeof(unsigned char)); >+ start = data; >+ for (i = 0; i < num_protos; ++i) { >+ const char *string = APR_ARRAY_IDX(protos, i, const char*); >+ apr_size_t length = strlen(string); >+ if (length > 255) >+ continue; >+ *start = (unsigned char)length; >+ ++start; >+ memcpy(start, string, length * sizeof(unsigned char)); >+ start += length; >+ } >+ >+ /* Success. */ >+ *data_out = data; >+ *size_out = size; >+ return SSL_TLSEXT_ERR_OK; >+} >+ >+#endif /* HAVE_TLS_NPN */ >+ > #ifdef HAVE_SRP > > int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg) >diff -ru gen/httpd-2.4.x/modules/ssl/ssl_private.h modules/ssl/ssl_private.h >--- gen/httpd-2.4.x/modules/ssl/ssl_private.h 2015-01-19 16:52:30.000000000 +0100 >+++ modules/ssl/ssl_private.h 2015-01-19 15:42:53.908000000 +0100 >@@ -176,6 +169,16 @@ > #endif > #endif > >+/* ALPN Protocol Negotiation */ >+#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) >+#define HAVE_TLS_ALPN >+#endif >+ >+/* Next Protocol Negotiation */ >+#if !defined(OPENSSL_NO_NEXTPROTONEG) && !defined(OPENSSL_NO_TLSEXT) && defined(OPENSSL_NPN_NEGOTIATED) >+#define HAVE_TLS_NPN >+#endif >+ > /* Secure Remote Password */ > #if !defined(OPENSSL_NO_SRP) && defined(SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB) > #define HAVE_SRP >@@ -443,6 +446,12 @@ > * connection */ > } reneg_state; > >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ /* Poor man's inter-module optional hooks for NPN. */ >+ apr_array_header_t *alpn_proposefns; /* list of ssl_alpn_propose_protos callbacks */ >+ apr_array_header_t *alpn_negofns; /* list of ssl_alpn_proto_negotiated callbacks. */ >+#endif >+ > server_rec *server; > } SSLConnRec; > >@@ -622,6 +631,10 @@ > SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */ > apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */ > #endif >+ >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+ apr_array_header_t *ssl_alpn_pref; /* protocol names in order of preference */ >+#endif > } modssl_ctx_t; > > struct SSLSrvConfigRec { >@@ -748,6 +759,10 @@ > const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg, const char *arg1, const char *arg2); > #endif > >+#if defined(HAVE_TLS_ALPN) || defined(HAVE_TLS_NPN) >+const char *ssl_cmd_SSLAlpnPreference(cmd_parms *cmd, void *dcfg, const char *protocol); >+#endif >+ > #ifdef HAVE_SRP > const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg); > const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, const char *arg); >@@ -796,6 +811,14 @@ > EVP_CIPHER_CTX *, HMAC_CTX *, int); > #endif > >+#ifdef HAVE_TLS_ALPN >+int ssl_callback_alpn_select(SSL *ssl, const unsigned char **out, >+ unsigned char *outlen, const unsigned char *in, >+ unsigned int inlen, void *arg); >+#elif defined(HAVE_TLS_NPN) >+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg); >+#endif >+ > /** Session Cache Support */ > apr_status_t ssl_scache_init(server_rec *, apr_pool_t *); > void ssl_scache_status_register(apr_pool_t *p);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 52210
:
27969
|
28486
|
28513
|
28588
|
32381
|
32399
|
32452
|
32463
|
32464
|
32521
|
32523