httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r1670397 - in /httpd/httpd/trunk/modules/ssl: mod_ssl.c mod_ssl.h ssl_engine_config.c ssl_engine_io.c ssl_private.h
Date Tue, 31 Mar 2015 17:12:52 GMT
Author: jim
Date: Tue Mar 31 17:12:51 2015
New Revision: 1670397

URL: http://svn.apache.org/r1670397
Log:
ALPN support, based on mod_spdy/mod_h2 patch set

Modified:
    httpd/httpd/trunk/modules/ssl/mod_ssl.c
    httpd/httpd/trunk/modules/ssl/mod_ssl.h
    httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
    httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
    httpd/httpd/trunk/modules/ssl/ssl_private.h

Modified: httpd/httpd/trunk/modules/ssl/mod_ssl.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/mod_ssl.c?rev=1670397&r1=1670396&r2=1670397&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/mod_ssl.c (original)
+++ httpd/httpd/trunk/modules/ssl/mod_ssl.c Tue Mar 31 17:12:51 2015
@@ -283,6 +283,12 @@ static const command_rec ssl_config_cmds
                 "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."),
@@ -473,6 +479,37 @@ static int modssl_register_npn(conn_rec
 #endif
 }
 
+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;
@@ -642,6 +679,7 @@ static void ssl_register_hooks(apr_pool_
     APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
     APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
     APR_REGISTER_OPTIONAL_FN(modssl_register_npn);
+    APR_REGISTER_OPTIONAL_FN(modssl_register_alpn);
 
     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
                               AUTHZ_PROVIDER_VERSION,

Modified: httpd/httpd/trunk/modules/ssl/mod_ssl.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/mod_ssl.h?rev=1670397&r1=1670396&r2=1670397&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/mod_ssl.h (original)
+++ httpd/httpd/trunk/modules/ssl/mod_ssl.h Tue Mar 31 17:12:51 2015
@@ -128,5 +128,46 @@ APR_DECLARE_OPTIONAL_FN(int, modssl_regi
                                                    ssl_npn_advertise_protos advertisefn,
                                                    ssl_npn_proto_negotiated negotiatedfn));
 
+/** 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__ */
 /** @} */

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_config.c?rev=1670397&r1=1670396&r2=1670397&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_config.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_config.c Tue Mar 31 17:12:51 2015
@@ -160,6 +160,9 @@ static void modssl_ctx_init(modssl_ctx_t
     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,
@@ -304,6 +307,9 @@ static void modssl_ctx_cfg_merge(apr_poo
 #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,
@@ -1856,6 +1862,16 @@ const char *ssl_cmd_SSLOpenSSLConfCmd(cm
     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
 

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_io.c?rev=1670397&r1=1670396&r2=1670397&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_io.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_io.c Tue Mar 31 17:12:51 2015
@@ -316,6 +316,7 @@ typedef struct {
     char buffer[AP_IOBUFSIZE];
     ssl_filter_ctx_t *filter_ctx;
     int npn_finished;  /* 1 if NPN has finished, 0 otherwise */
+    int alpn_finished;  /* 1 if ALPN has finished, 0 otherwise */
 } bio_filter_in_ctx_t;
 
 /*
@@ -1483,6 +1484,37 @@ static apr_status_t ssl_io_filter_input(
         APR_BRIGADE_INSERT_TAIL(bb, bucket);
     }
 
+#ifdef HAVE_TLS_ALPN
+    /* 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) {
+            SSL_get0_alpn_selected(inctx->ssl, &next_proto, &next_proto_len);
+            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c,
+                          APLOGNO() "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
+
 #ifdef HAVE_TLS_NPN
     /* By this point, Next Protocol Negotiation (NPN) should be completed (if
      * our version of OpenSSL supports it).  If we haven't already, find out
@@ -1995,6 +2027,7 @@ static void ssl_io_input_add_filter(ssl_
     inctx->pool = c->pool;
     inctx->filter_ctx = filter_ctx;
     inctx->npn_finished = 0;
+    inctx->alpn_finished = 0;
 }
 
 /* The request_rec pointer is passed in here only to ensure that the

Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=1670397&r1=1670396&r2=1670397&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Tue Mar 31 17:12:51 2015
@@ -181,6 +181,16 @@
 #define HAVE_TLS_NPN
 #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
@@ -444,6 +454,12 @@ typedef struct {
     apr_array_header_t *npn_negofns; /* list of ssl_npn_proto_negotiated callbacks. */
 #endif
 
+#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;
 
@@ -624,6 +640,10 @@ typedef struct {
     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 {
@@ -750,6 +770,10 @@ const char *ssl_cmd_SSLOCSPEnable(cmd_pa
 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);
@@ -799,6 +823,15 @@ int         ssl_callback_SessionTicket(S
 #endif
 int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len,
void *arg);
 
+#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);
+#endif
+#if 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);



Mime
View raw message