Return-Path: Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: (qmail 61504 invoked from network); 7 Nov 2009 11:07:01 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 7 Nov 2009 11:07:01 -0000 Received: (qmail 20503 invoked by uid 500); 7 Nov 2009 11:07:00 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 20420 invoked by uid 500); 7 Nov 2009 11:07:00 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 20411 invoked by uid 99); 7 Nov 2009 11:07:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 07 Nov 2009 11:07:00 +0000 X-ASF-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [62.75.148.60] (HELO appendix.velox.ch) (62.75.148.60) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 07 Nov 2009 11:06:56 +0000 Received: from cortex.velox.ch (80-218-64-214.dclient.hispeed.ch [80.218.64.214]) (authenticated bits=0) by appendix.velox.ch (8.14.2/8.14.2/2.0) with ESMTP id nA7B6XCe019877 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 7 Nov 2009 12:06:34 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=velox.ch; s=appendix-177f; t=1257591994; bh=3h3PnNALfS5Ozm0A4HJbqBtQbxdW0X++KgfWngNCp24=; h=Message-ID:Date:From:MIME-Version:To:Subject:References: In-Reply-To:Content-Type; b=KoBxbNBSmjQAY+hGDA8quy0dpQu88vJ2IeXvvz2txyPE4ZVY016VrmTBnCoPllT4K 5tlEgWt7PsKArUesurSuikqVeZL8kp/lY8LxWM251zp6lyhgLYbFPuylDLcNS3iW84 m5ccYhhDH+AWiRuFMdkEeZP9+vCg8g2vyJkEB0mpXejesZDonHeqFN9xjj1rFP3sLm NHr+qXTH3+1NhvLugijjyRJ4kT5w23LCeZt0QCP3ANziMb/j0dn8s96wzE5u21uul5 fy2AixlF16Z1lxXNhjzxD/D2XC0ndgCONhyme2ZjZUmMqXZ6EjoBbN3pJjxmdyLzRd oZjt4Zy98jmyQ== Message-ID: <4AF554B4.2090807@velox.ch> DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=velox.ch; s=cortex-8a58; t=1257591993; bh=3h3PnNALfS5Ozm0A4HJbqBtQbxdW0X++KgfWngNCp24=; h=Date:From:MIME-Version:To:Subject:References:In-Reply-To: Content-Type; b=yjHmaEckC5xx4zJlPF0cq5rpnOi6PD8PFX6eRwZ1mx16W+zYlJppTW6v84YdZwV33 k2W49QQKH6sIXchIN8Za+M8Y6roOFNKXbWHUlwrmAu2DG0ih9wsLm+IY2gyMUs49kQ EfZqprtj2ZocxZOQJzOCF21ZxrphkV+tZBF0pNa84T46PVcqwMYWdr7LhMj6YtRMJ2 Eq5esfFwIe6kfbE3r6c2yv548nUbcQwcfoBMGgD+stcpxeubDifNhUy+9boiarmsoY slVUl3xtWvAqaRYQ7phy1gPZrby1zazyl2a+OYAi7cznBrzjaDI2JLb3rNhYPlazd+ u8RLIMTX9oilg== Date: Sat, 07 Nov 2009 12:06:28 +0100 From: Kaspar Brand User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: dev@httpd.apache.org Subject: Re: [PATCH] mod_ssl: improving session caching for SNI configurations References: <4AF14AEC.6060500@velox.ch> <4AF1A295.5040606@apache.org> <4AF1B2EC.9050301@velox.ch> <4AF1B6D0.6020009@apache.org> <4AF26C0D.2050802@velox.ch> In-Reply-To: <4AF26C0D.2050802@velox.ch> Content-Type: multipart/mixed; boundary="------------060406090005030304070606" This is a multi-part message in MIME format. --------------060406090005030304070606 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Kaspar Brand wrote: > Does that sound reasonable? If so, I would prepare a new patch with > SSL_CTX_set_tlsext_ticket_keys and the new config directive. No reactions = no objections? Would it perhaps be possible to piggyback onto Joe's reneg patch and get this also into 2.2.15...? ;-) Attached are updated patches for trunk and 2.2.x which: - fix TLS session tickets for SNI configurations when OpenSSL versions between 0.9.8f and 0.9.8l are used - add a new (global) "SSLSessionTicketExtension" configuration directive which allows controlling SSL_OP_NO_TICKET (defaulting to "on", i.e. tickets are left enabled, but can be turned off if necessary) - include the fix for the SNI callback which makes sure that the correct session id context is set (to prevent improper session resumption). Kaspar --------------060406090005030304070606 Content-Type: text/plain; name="mod_ssl-sessioncaching.trunk.v2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mod_ssl-sessioncaching.trunk.v2.diff" Index: httpd-trunk/modules/ssl/ssl_private.h =================================================================== --- httpd-trunk/modules/ssl/ssl_private.h (revision 833672) +++ httpd-trunk/modules/ssl/ssl_private.h (working copy) @@ -405,6 +405,9 @@ typedef struct { #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) const char *szCryptoDevice; #endif +#ifndef OPENSSL_NO_TLSEXT + ssl_enabled_t session_tickets_enabled; +#endif #ifdef HAVE_OCSP_STAPLING const ap_socache_provider_t *stapling_cache; @@ -585,6 +588,7 @@ const char *ssl_cmd_SSLUserName(cmd_par const char *ssl_cmd_SSLLogLevelDebugDump(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg); const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag); +const char *ssl_cmd_SSLSessionTicketExtension(cmd_parms *cmd, void *cdfg, int flag); const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); Index: httpd-trunk/modules/ssl/ssl_engine_init.c =================================================================== --- httpd-trunk/modules/ssl/ssl_engine_init.c (revision 833672) +++ httpd-trunk/modules/ssl/ssl_engine_init.c (working copy) @@ -363,6 +363,15 @@ static void ssl_init_server_check(server "(theoretically shouldn't happen!)"); ssl_die(); } + + /* + * Session tickets (stateless resumption) + */ + if ((myModConfig(s))->session_tickets_enabled == SSL_ENABLED_FALSE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Disabling TLS session ticket support"); + SSL_CTX_set_options(mctx->ssl_ctx, SSL_OP_NO_TICKET); + } } #ifndef OPENSSL_NO_TLSEXT @@ -1061,6 +1070,14 @@ void ssl_init_CheckServers(server_rec *b BOOL conflict = FALSE; +#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER < 0x009080d0 +#define TICK_KEYS_LEN sizeof(((SSL_CTX *)0)->tlsext_tick_key_name) \ + + sizeof(((SSL_CTX *)0)->tlsext_tick_hmac_key) \ + + sizeof(((SSL_CTX *)0)->tlsext_tick_aes_key) + unsigned char tlsext_tick_keys[TICK_KEYS_LEN]; + RAND_pseudo_bytes(tlsext_tick_keys, TICK_KEYS_LEN); +#endif + /* * Give out warnings when a server has HTTPS configured * for the HTTP port or vice versa @@ -1085,6 +1102,18 @@ void ssl_init_CheckServers(server_rec *b ssl_util_vhostid(p, s), DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); } + +#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER < 0x009080d0 + /* + * When using OpenSSL versions 0.9.8f through 0.9.8l, also configure + * the same key_name/hmac_key/aes_key combo for every SSL_CTX (workaround + * for SNI+SessionTicket extension interoperability issue in these versions) + */ + if ((sc->enabled == SSL_ENABLED_TRUE) || + (sc->enabled == SSL_ENABLED_OPTIONAL)) + SSL_CTX_set_tlsext_ticket_keys(sc->server->ssl_ctx, + tlsext_tick_keys, TICK_KEYS_LEN); +#endif } /* Index: httpd-trunk/modules/ssl/ssl_engine_config.c =================================================================== --- httpd-trunk/modules/ssl/ssl_engine_config.c (revision 833672) +++ httpd-trunk/modules/ssl/ssl_engine_config.c (working copy) @@ -80,6 +80,9 @@ SSLModConfigRec *ssl_config_global_creat mc->stapling_mutex_file = NULL; mc->stapling_mutex = NULL; #endif +#ifndef OPENSSL_NO_TLSEXT + mc->session_tickets_enabled = SSL_ENABLED_UNSET; +#endif memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys)); @@ -1673,6 +1676,26 @@ const char *ssl_cmd_SSLStaplingForceURL( #endif /* HAVE_OCSP_STAPLING */ +const char *ssl_cmd_SSLSessionTicketExtension(cmd_parms *cmd, void *dcfg, int flag) +{ +#ifndef OPENSSL_NO_TLSEXT + const char *err; + SSLModConfigRec *mc = myModConfig(cmd->server); + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + mc->session_tickets_enabled = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; + + return NULL; +#else + return "SSLSessionTicketExtension failed; OpenSSL is not built with support " + "for TLS extensions. Refer to the documentation, and build " + "a compatible version of OpenSSL."; +#endif +} + void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) { if (!ap_exists_config_define("DUMP_CERTS")) { Index: httpd-trunk/modules/ssl/ssl_engine_kernel.c =================================================================== --- httpd-trunk/modules/ssl/ssl_engine_kernel.c (revision 833672) +++ httpd-trunk/modules/ssl/ssl_engine_kernel.c (working copy) @@ -29,6 +29,7 @@ time I was too famous.'' -- Unknown */ #include "ssl_private.h" +#include "util_md5.h" static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); #ifndef OPENSSL_NO_TLSEXT @@ -1980,6 +1981,7 @@ static int ssl_find_vhost(void *serverna apr_array_header_t *names; int i; SSLConnRec *sslcon; + char *sid_ctx; /* check ServerName */ if (!strcasecmp(servername, s->server_hostname)) { @@ -2044,6 +2046,21 @@ static int ssl_find_vhost(void *serverna SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx), SSL_CTX_get_verify_callback(ssl->ctx)); } + /* + * Adjust the session id context. ssl_init_ssl_connection() + * always picks the configuration of the first vhost when + * calling SSL_new(), but we want to tie the session to the + * vhost we have just switched to. Again, we have to make sure + * that we're not overwriting a session id context which was + * possibly set in ssl_hook_Access(), before triggering + * a renegotation. + */ + if (!SSL_num_renegotiations(ssl)) { + sid_ctx = ap_md5_binary(c->pool, (unsigned char*)sc->vhost_id, + sc->vhost_id_len); + SSL_set_session_id_context(ssl, (unsigned char *)sid_ctx, + APR_MD5_DIGESTSIZE*2); + } /* * Save the found server into our SSLConnRec for later Index: httpd-trunk/modules/ssl/mod_ssl.c =================================================================== --- httpd-trunk/modules/ssl/mod_ssl.c (revision 833672) +++ httpd-trunk/modules/ssl/mod_ssl.c (working copy) @@ -70,6 +70,8 @@ static const command_rec ssl_config_cmds SSL_CMD_SRV(RandomSeed, TAKE23, "SSL Pseudo Random Number Generator (PRNG) seeding source " "('startup|connect builtin|file:/path|exec:/path [bytes]')") + SSL_CMD_SRV(SessionTicketExtension, FLAG, + "TLS Session Ticket extension support") /* * Per-server context configuration directives Index: httpd-trunk/docs/manual/mod/mod_ssl.xml =================================================================== --- httpd-trunk/docs/manual/mod/mod_ssl.xml (revision 833672) +++ httpd-trunk/docs/manual/mod/mod_ssl.xml (working copy) @@ -1849,4 +1849,35 @@ certificate being validated references a + +SSLSessionTicketExtension +Configure TLS session ticket extension support +SSLSessionTicketExtension on|off +SSLSessionTicketExtension on +server config +Available in Apache 2.2.15 and later + + +

+This directive configures support for TLS session tickets (stateless session +resumption, cf. RFC 5077). Session tickets are enabled by default when mod_ssl +is compiled against an OpenSSL version which includes this option. They can +coexist with a stateful session cache (configured through +SSLSessionCache); +it is then up to the client to choose between stateful and stateless session +resumption.

+ +

+Clients based on OpenSSL versions 0.9.8f through 0.9.8l are known to +have problems (parse tlsext errors) when using the SNI and session +ticket extensions at the same time. As a workaround for interoperability issues +like these, this directive allows to completely turn off TLS session ticket support +at the server side.

+ +Example +SSLSessionTicketExtension off + +
+
+ --------------060406090005030304070606 Content-Type: text/plain; name="mod_ssl-sessioncaching.2.2.x.v2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mod_ssl-sessioncaching.2.2.x.v2.diff" Index: httpd-2.2.x/modules/ssl/ssl_private.h =================================================================== --- httpd-2.2.x/modules/ssl/ssl_private.h (revision 833672) +++ httpd-2.2.x/modules/ssl/ssl_private.h (working copy) @@ -395,6 +395,9 @@ typedef struct { #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) const char *szCryptoDevice; #endif +#ifndef OPENSSL_NO_TLSEXT + ssl_enabled_t session_tickets_enabled; +#endif struct { void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10; } rCtx; @@ -545,6 +548,7 @@ const char *ssl_cmd_SSLRequire(cmd_parm const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg); const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag); +const char *ssl_cmd_SSLSessionTicketExtension(cmd_parms *cmd, void *cdfg, int flag); const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); Index: httpd-2.2.x/modules/ssl/ssl_engine_init.c =================================================================== --- httpd-2.2.x/modules/ssl/ssl_engine_init.c (revision 833672) +++ httpd-2.2.x/modules/ssl/ssl_engine_init.c (working copy) @@ -382,6 +382,15 @@ static void ssl_init_ctx_tls_extensions( ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } + + /* + * Session tickets (stateless resumption) + */ + if ((myModConfig(s))->session_tickets_enabled == SSL_ENABLED_FALSE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Disabling TLS session ticket support"); + SSL_CTX_set_options(mctx->ssl_ctx, SSL_OP_NO_TICKET); + } } #endif @@ -1018,6 +1027,14 @@ void ssl_init_CheckServers(server_rec *b BOOL conflict = FALSE; +#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER < 0x009080d0 +#define TICK_KEYS_LEN sizeof(((SSL_CTX *)0)->tlsext_tick_key_name) \ + + sizeof(((SSL_CTX *)0)->tlsext_tick_hmac_key) \ + + sizeof(((SSL_CTX *)0)->tlsext_tick_aes_key) + unsigned char tlsext_tick_keys[TICK_KEYS_LEN]; + RAND_pseudo_bytes(tlsext_tick_keys, TICK_KEYS_LEN); +#endif + /* * Give out warnings when a server has HTTPS configured * for the HTTP port or vice versa @@ -1042,6 +1059,18 @@ void ssl_init_CheckServers(server_rec *b ssl_util_vhostid(p, s), DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); } + +#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER < 0x009080d0 + /* + * When using OpenSSL versions 0.9.8f through 0.9.8l, also configure + * the same key_name/hmac_key/aes_key combo for every SSL_CTX (workaround + * for SNI+SessionTicket extension interoperability issue in these versions) + */ + if ((sc->enabled == SSL_ENABLED_TRUE) || + (sc->enabled == SSL_ENABLED_OPTIONAL)) + SSL_CTX_set_tlsext_ticket_keys(sc->server->ssl_ctx, + tlsext_tick_keys, TICK_KEYS_LEN); +#endif } /* Index: httpd-2.2.x/modules/ssl/ssl_engine_config.c =================================================================== --- httpd-2.2.x/modules/ssl/ssl_engine_config.c (revision 833672) +++ httpd-2.2.x/modules/ssl/ssl_engine_config.c (working copy) @@ -75,6 +75,9 @@ SSLModConfigRec *ssl_config_global_creat #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) mc->szCryptoDevice = NULL; #endif +#ifndef OPENSSL_NO_TLSEXT + mc->session_tickets_enabled = SSL_ENABLED_UNSET; +#endif memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys)); @@ -1471,6 +1474,26 @@ const char *ssl_cmd_SSLStrictSNIVHostCh #endif } +const char *ssl_cmd_SSLSessionTicketExtension(cmd_parms *cmd, void *dcfg, int flag) +{ +#ifndef OPENSSL_NO_TLSEXT + const char *err; + SSLModConfigRec *mc = myModConfig(cmd->server); + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + mc->session_tickets_enabled = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; + + return NULL; +#else + return "SSLSessionTicketExtension failed; OpenSSL is not built with support " + "for TLS extensions. Refer to the documentation, and build " + "a compatible version of OpenSSL."; +#endif +} + void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) { if (!ap_exists_config_define("DUMP_CERTS")) { Index: httpd-2.2.x/modules/ssl/ssl_engine_kernel.c =================================================================== --- httpd-2.2.x/modules/ssl/ssl_engine_kernel.c (revision 833672) +++ httpd-2.2.x/modules/ssl/ssl_engine_kernel.c (working copy) @@ -29,6 +29,7 @@ time I was too famous.'' -- Unknown */ #include "ssl_private.h" +#include "util_md5.h" static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); #ifndef OPENSSL_NO_TLSEXT @@ -2010,6 +2011,7 @@ static int ssl_find_vhost(void *serverna apr_array_header_t *names; int i; SSLConnRec *sslcon; + char *sid_ctx; /* check ServerName */ if (!strcasecmp(servername, s->server_hostname)) { @@ -2074,6 +2076,21 @@ static int ssl_find_vhost(void *serverna SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx), SSL_CTX_get_verify_callback(ssl->ctx)); } + /* + * Adjust the session id context. ssl_init_ssl_connection() + * always picks the configuration of the first vhost when + * calling SSL_new(), but we want to tie the session to the + * vhost we have just switched to. Again, we have to make sure + * that we're not overwriting a session id context which was + * possibly set in ssl_hook_Access(), before triggering + * a renegotation. + */ + if (!SSL_num_renegotiations(ssl)) { + sid_ctx = ap_md5_binary(c->pool, (unsigned char*)sc->vhost_id, + sc->vhost_id_len); + SSL_set_session_id_context(ssl, (unsigned char *)sid_ctx, + APR_MD5_DIGESTSIZE*2); + } /* * Save the found server into our SSLConnRec for later Index: httpd-2.2.x/modules/ssl/mod_ssl.c =================================================================== --- httpd-2.2.x/modules/ssl/mod_ssl.c (revision 833672) +++ httpd-2.2.x/modules/ssl/mod_ssl.c (working copy) @@ -92,6 +92,8 @@ static const command_rec ssl_config_cmds SSL_CMD_SRV(RandomSeed, TAKE23, "SSL Pseudo Random Number Generator (PRNG) seeding source " "(`startup|connect builtin|file:/path|exec:/path [bytes]')") + SSL_CMD_SRV(SessionTicketExtension, FLAG, + "TLS Session Ticket extension support") /* * Per-server context configuration directives Index: httpd-2.2.x/docs/manual/mod/mod_ssl.xml =================================================================== --- httpd-2.2.x/docs/manual/mod/mod_ssl.xml (revision 833672) +++ httpd-2.2.x/docs/manual/mod/mod_ssl.xml (working copy) @@ -1808,4 +1808,35 @@ SSLCryptoDevice ubsec + +SSLSessionTicketExtension +Configure TLS session ticket extension support +SSLSessionTicketExtension on|off +SSLSessionTicketExtension on +server config +Available in Apache 2.2.15 and later + + +

+This directive configures support for TLS session tickets (stateless session +resumption, cf. RFC 5077). Session tickets are enabled by default when mod_ssl +is compiled against an OpenSSL version which includes this option. They can +coexist with a stateful session cache (configured through +SSLSessionCache); +it is then up to the client to choose between stateful and stateless session +resumption.

+ +

+Clients based on OpenSSL versions 0.9.8f through 0.9.8l are known to +have problems (parse tlsext errors) when using the SNI and session +ticket extensions at the same time. As a workaround for interoperability issues +like these, this directive allows to completely turn off TLS session ticket support +at the server side.

+ +Example +SSLSessionTicketExtension off + +
+
+ --------------060406090005030304070606--