httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pque...@apache.org
Subject svn commit: r1200040 - in /httpd/httpd/trunk: CHANGES modules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.c modules/ssl/ssl_engine_init.c modules/ssl/ssl_engine_kernel.c modules/ssl/ssl_private.h
Date Wed, 09 Nov 2011 23:37:37 GMT
Author: pquerna
Date: Wed Nov  9 23:37:37 2011
New Revision: 1200040

URL: http://svn.apache.org/viewvc?rev=1200040&view=rev
Log:
Add support for RFC 5077 TLS Session tickets.  This adds two new directives:

* SSLTicketKeyFile: To store the private information for the encryption of the ticket.
* SSLTicketKeyDefault To set the default, otherwise the first listed token is used.  This
enables key rotation across servers.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/modules/ssl/mod_ssl.c
    httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
    httpd/httpd/trunk/modules/ssl/ssl_engine_init.c
    httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
    httpd/httpd/trunk/modules/ssl/ssl_private.h

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1200040&r1=1200039&r2=1200040&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Wed Nov  9 23:37:37 2011
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.3.16
 
+  *) mod_ssl: Add support for RFC 5077 TLS Session tickets.
+     [Paul Querna]
+
   *) mod_usertrack: Use random value instead of remote IP address.
      [Stefan Fritsch]
 

Modified: httpd/httpd/trunk/modules/ssl/mod_ssl.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/mod_ssl.c?rev=1200040&r1=1200039&r2=1200040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/mod_ssl.c (original)
+++ httpd/httpd/trunk/modules/ssl/mod_ssl.c Wed Nov  9 23:37:37 2011
@@ -79,6 +79,14 @@ static const command_rec ssl_config_cmds
     SSL_CMD_SRV(FIPS, FLAG,
                 "Enable FIPS-140 mode "
                 "(`on', `off')")
+#ifdef HAVE_TLSEXT_TICKETS
+    SSL_CMD_SRV(TicketKeyFile, TAKE2,
+                "Key file to use for encrypting and decrypting the client ticket (RFC 5077)
"
+                "(keyname '/path/to/file')")
+    SSL_CMD_SRV(TicketKeyDefault, TAKE1,
+                "Set the key name used by default for new sessions "
+               "(keyname)")
+#endif
     SSL_CMD_ALL(CipherSuite, TAKE1,
                 "Colon-delimited list of permitted SSL Ciphers "
                 "('XXX:...:XXX' - see manual)")

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=1200040&r1=1200039&r2=1200040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_config.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_config.c Wed Nov  9 23:37:37 2011
@@ -200,6 +200,12 @@ static SSLSrvConfigRec *ssl_config_serve
     sc->fips                   = UNSET;
 #endif
 
+#ifdef HAVE_TLSEXT_TICKETS
+    sc->default_ticket_name = NULL;
+    sc->default_ticket = NULL;
+    sc->tickets = apr_array_make(p, 4, sizeof(modssl_ticket_t*));
+#endif
+
     modssl_ctx_init_proxy(sc, p);
 
     modssl_ctx_init_server(sc, p);
@@ -304,6 +310,11 @@ void *ssl_config_server_merge(apr_pool_t
 
     cfgMerge(mc, NULL);
     cfgMerge(enabled, SSL_ENABLED_UNSET);
+#ifdef HAVE_TLSEXT_TICKETS
+    cfgMergeString(default_ticket_name);
+    apr_array_cat(mrg->tickets, base->tickets);
+    apr_array_cat(mrg->tickets, add->tickets);
+#endif
     cfgMergeBool(proxy_enabled);
     cfgMergeInt(session_cache_timeout);
     cfgMergeBool(cipher_server_pref);
@@ -584,6 +595,62 @@ const char *ssl_cmd_SSLEngine(cmd_parms 
     return "Argument must be On, Off, or Optional";
 }
 
+const char *ssl_cmd_SSLTicketKeyDefault(cmd_parms *cmd, void *dcfg, const char *name)
+{
+#ifdef HAVE_TLSEXT_TICKETS
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    sc->default_ticket_name = name;
+
+    return NULL;
+#else
+    return "TLS Ticket keys are not supported.";
+#endif
+}
+
+const char *ssl_cmd_SSLTicketKeyFile(cmd_parms *cmd, void *dcfg, const char *name, const
char *path)
+{
+#ifdef HAVE_TLSEXT_TICKETS
+    apr_status_t rv;
+    apr_file_t *fp;
+    apr_size_t len;
+    char buf[TLSEXT_TICKET_KEYLEN];
+    modssl_ticket_t* ticket = NULL;
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
+                       APR_OS_DEFAULT, cmd->temp_pool);
+
+    if (rv != APR_SUCCESS) {
+      return apr_psprintf(cmd->pool,
+                          "Failed to open %s: (%d) %pm",
+                          path, rv, &rv);
+    }
+
+    rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEYLEN, &len);
+
+    if (rv != APR_SUCCESS) {
+      return apr_psprintf(cmd->pool,
+                          "Failed to read at least 48 bytes from %s: (%d) %pm",
+                          path, rv, &rv);
+    }
+
+    ticket = apr_palloc(cmd->pool, sizeof(modssl_ticket_t));
+
+    ticket->conf_name = name;
+
+    memcpy(ticket->key_name, buf, 16);
+    memcpy(ticket->hmac_secret, buf + 16, 16);
+    memcpy(ticket->aes_key, buf + 32, 16);
+
+    APR_ARRAY_PUSH(sc->tickets, modssl_ticket_t*) = ticket;
+
+    return NULL;
+#else
+    return "TLS Ticket keys are not supported.";
+#endif
+}
+
 const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
 {
 #ifdef HAVE_FIPS

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_init.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_init.c?rev=1200040&r1=1200039&r2=1200040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_init.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_init.c Wed Nov  9 23:37:37 2011
@@ -1143,6 +1143,43 @@ static void ssl_init_server_certs(server
 #endif
         ssl_die();
     }
+
+#ifdef HAVE_TLSEXT_TICKETS
+    if (mctx->sc->tickets->nelts > 0) { 
+
+        if (mctx->sc->default_ticket_name != NULL) {
+            int i;
+            modssl_ticket_t* ticket = NULL;
+            mctx->sc->default_ticket = NULL;
+
+            for (i = 0; i < mctx->sc->tickets->nelts; i++) {
+                ticket = APR_ARRAY_IDX(mctx->sc->tickets, i, modssl_ticket_t*);
+                if (strcmp(ticket->conf_name, mctx->sc->default_ticket_name) ==
0) {
+                    mctx->sc->default_ticket = ticket;
+                }
+            }
+
+            if (mctx->sc->default_ticket == NULL) {
+                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
+                            "Misconfigured TLS Tickets.  Couldn't find key named '%s'",
+                            mctx->sc->default_ticket_name);
+                ssl_die();
+            }
+        }
+        else {
+            mctx->sc->default_ticket = APR_ARRAY_IDX(mctx->sc->tickets, 0, modssl_ticket_t*);
+        }
+
+        if (!SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx, ssl_callback_tlsext_tickets))
{
+            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
+                        "Unable to initialize TLS session ticket extension "
+                        "(incompatible OpenSSL version?)");
+            ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+            ssl_die();
+        }
+    }
+#endif
+
 }
 
 static void ssl_init_proxy_certs(server_rec *s,

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c?rev=1200040&r1=1200039&r2=1200040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c Wed Nov  9 23:37:37 2011
@@ -2067,3 +2067,94 @@ static int ssl_find_vhost(void *serverna
     return 0;
 }
 #endif
+
+#ifdef HAVE_TLSEXT_TICKETS
+
+#ifndef tlsext_tick_md
+#ifdef OPENSSL_NO_SHA256
+#define tlsext_tick_md	EVP_sha1
+#else
+#define tlsext_tick_md	EVP_sha256
+#endif
+#endif
+
+int ssl_callback_tlsext_tickets(SSL *ssl,
+                                char *keyname,
+                                char *iv,
+                                EVP_CIPHER_CTX *cipher_ctx,
+                                HMAC_CTX *hctx,
+                                int mode)
+{
+    conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
+    server_rec *s       = mySrvFromConn(conn);
+    SSLSrvConfigRec *sc = mySrvConfig(s);
+
+    if (mode == 1) {
+        modssl_ticket_t* ticket = sc->default_ticket;
+
+        /* Setting up the stuff for encrypting:
+         *  - keyname contains at least 16 bytes we can write to.
+         *  - iv contains at least EVP_MAX_IV_LENGTH (16) bytes we can write to.
+         *  - hctx is already allocated, we just need to set the
+         *    secret key via HMAC_Init_ex.
+         *  - cipher_ctx is also allocated, and we need to configure
+         *    the cipher and private key.
+         */
+
+        if (ticket == NULL) {
+            /* this should not happen, we always set the default
+             * ticket.
+             */
+            return -1;
+        }
+
+        memcpy(keyname, ticket->key_name, 16);
+
+        RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH);
+
+        memcpy(iv, iv, EVP_MAX_IV_LENGTH);
+
+        EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL,
+                           ticket->aes_key, iv);
+
+        HMAC_Init_ex(hctx, ticket->hmac_secret, 16, tlsext_tick_md(), NULL);
+
+        return 0;
+    }
+    else if (mode == 0) {
+        /* Setup contextes for decryption, based on the keyname input */
+        int i;
+        modssl_ticket_t* ticket = NULL;
+
+        for (i = 0; i < sc->tickets->nelts; i++) {
+            modssl_ticket_t* itticket = APR_ARRAY_IDX(sc->tickets, i, modssl_ticket_t*);
+            if (memcmp(keyname, itticket->key_name, 16) == 0) {
+                ticket = itticket;
+                break;
+            }
+        }
+
+        if (ticket == NULL) {
+            /* Ticket key not found, but no error */
+            return 0;
+        }
+
+        EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, ticket->aes_key, iv);
+
+        HMAC_Init_ex(hctx, ticket->hmac_secret, 16, tlsext_tick_md(), NULL);
+
+        if (ticket != sc->default_ticket) {
+            /* Ticket key found, we did our stuff, but didn't use the default,
+             * re-issue a ticket with the default ticket */
+            return 2;
+        }
+        else {
+            return 1;
+        }
+    }
+
+    /* TODO: log invalid use */
+    return -1;
+}
+
+#endif

Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=1200040&r1=1200039&r2=1200040&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Wed Nov  9 23:37:37 2011
@@ -157,6 +157,12 @@
 #endif
 #endif
 
+#ifndef OPENSSL_NO_TLSEXT
+#ifdef SSL_CTX_set_tlsext_ticket_key_cb
+#define HAVE_TLSEXT_TICKETS
+#endif
+#endif
+
 /* mod_ssl headers */
 #include "ssl_util_ssl.h"
 
@@ -557,6 +563,21 @@ typedef struct {
     ssl_verify_t verify_mode;
 } modssl_auth_ctx_t;
 
+
+#ifdef HAVE_TLSEXT_TICKETS
+
+/* 48 bytes: 16 for keyname, 16 for HMAC secret, 16 for AES private key */
+#define TLSEXT_TICKET_KEYLEN (48)
+
+typedef struct {
+  /* Human readable name, used in the configuration */
+  const char *conf_name;
+  char key_name[16];
+  char hmac_secret[16];
+  char aes_key[16];
+} modssl_ticket_t;
+#endif
+
 typedef struct SSLSrvConfigRec SSLSrvConfigRec;
 
 typedef struct {
@@ -625,6 +646,11 @@ struct SSLSrvConfigRec {
 #ifdef HAVE_FIPS
     BOOL             fips;
 #endif
+#ifdef HAVE_TLSEXT_TICKETS
+    const char *default_ticket_name;
+    modssl_ticket_t* default_ticket;
+    apr_array_header_t* tickets;
+#endif
 };
 
 /**
@@ -716,6 +742,8 @@ const char *ssl_cmd_SSLOCSPResponderTime
 const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
 
 const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLTicketKeyDefault(cmd_parms *cmd, void *dcfg, const char *name);
+const char *ssl_cmd_SSLTicketKeyFile(cmd_parms *cmd, void *dcfg, const char *name, const
char *path);
 
 /**  module initialization  */
 int          ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *);
@@ -757,6 +785,15 @@ void         ssl_callback_Info(const SSL
 int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
 #endif
 
+#ifdef HAVE_TLSEXT_TICKETS
+int         ssl_callback_tlsext_tickets(SSL *ssl,
+                                        char *keyname,
+                                        char *iv,
+                                        EVP_CIPHER_CTX *cipher_ctx,
+                                        HMAC_CTX *hctx,
+                                        int mode);
+#endif
+
 /**  Session Cache Support  */
 void         ssl_scache_init(server_rec *, apr_pool_t *);
 void         ssl_scache_status_register(apr_pool_t *p);



Mime
View raw message