]> granicus.if.org Git - apache/commitdiff
Streamline ephemeral key handling:
authorKaspar Brand <kbrand@apache.org>
Wed, 25 Sep 2013 12:52:35 +0000 (12:52 +0000)
committerKaspar Brand <kbrand@apache.org>
Wed, 25 Sep 2013 12:52:35 +0000 (12:52 +0000)
- drop support for ephemeral RSA keys (only allowed/needed
  for export ciphers)

- drop pTmpKeys from the per-process SSLModConfigRec, and remove
  the temp key generation at startup (unnecessary for DHE/ECDHE)

- unconditionally disable null and export-grade ciphers by always
  prepending "!aNULL:!eNULL:!EXP:" to any cipher suite string

- do not configure per-connection SSL_tmp_*_callbacks, as it is
  sufficient to set them for the SSL_CTX

- set default curve for ECDHE at startup, obviating the need
  for a per-handshake callback, for the time being (and also
  configure SSL_OP_SINGLE_ECDH_USE, previously left out)

For additional background, see
https://mail-archives.apache.org/mod_mbox/httpd-dev/201309.mbox/%3C52358ED1.2070704@velox.ch%3E

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1526168 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_ssl.xml
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

diff --git a/CHANGES b/CHANGES
index 9ffc8733319a48fd05be29977fe8c915ae227fe6..4585487814371116c2af8523486e3a5e6bc8579b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_ssl: drop support for export-grade ciphers with ephemeral RSA
+     keys, and unconditionally disable aNULL, eNULL and EXP ciphers
+     (not overridable via SSLCipherSuite). [Kaspar Brand]
+
   *) Suppress formatting of startup messages written to the console when
      ErrorLogFormat is used.  [Jeff Trawick]
 
index d4b26f3b8087fb36d7e8a8441fec337619312b90..62d1c3d64490dd3c98f6228590740939074692ca 100644 (file)
@@ -728,6 +728,15 @@ prefixes are:</p>
 <li><code>-</code>: remove cipher from list (can be added later again)</li>
 <li><code>!</code>: kill cipher from list completely (can <strong>not</strong> be added later again)</li>
 </ul>
+
+<note>
+<title><code>aNULL</code>, <code>eNULL</code> and <code>EXP</code>
+ciphers are always disabled</title>
+<p>Beginning with version 2.5.0-dev as of 2013-09-25, null and export-grade
+ciphers are always disabled, as mod_ssl unconditionally prepends any supplied
+cipher suite string with <code>!aNULL:!eNULL:!EXP:</code> at initialization.</p>
+</note>
+
 <p>A simpler way to look at all of this is to use the ``<code>openssl ciphers
 -v</code>'' command which provides a nice way to successively create the
 correct <em>cipher-spec</em> string. The default <em>cipher-spec</em> string
index 33556d69a03c85e6341bb2c319b62a9898de27a5..881c44331105eb0375fe3af25844aad2f54f2cfc 100644 (file)
@@ -521,15 +521,6 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
 
     sslconn->ssl = ssl;
 
-    /*
-     *  Configure callbacks for SSL connection
-     */
-    SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
-    SSL_set_tmp_dh_callback(ssl,  ssl_callback_TmpDH);
-#ifndef OPENSSL_NO_EC
-    SSL_set_tmp_ecdh_callback(ssl, ssl_callback_TmpECDH);
-#endif
-
     SSL_set_verify_result(ssl, X509_V_OK);
 
     ssl_io_filter_init(c, r, ssl);
index 5b973c783bdf03970b500870bd59cf5c4e60fd87..e6e4d9b76e8e82bb84b531ea57cc968356c3da02 100644 (file)
@@ -75,8 +75,6 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
     mc->stapling_mutex         = NULL;
 #endif
 
-    memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
-
     apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
                           apr_pool_cleanup_null,
                           pool);
index 8a37b1e111b471e4ebaf2c74f0e6a06b38bc8db7..025be3c71e62b5292f7e1c8e72ba693f13f5a534 100644 (file)
@@ -56,180 +56,6 @@ static void ssl_add_version_components(apr_pool_t *p,
                  modver, AP_SERVER_BASEVERSION, incver);
 }
 
-
-/*
- * Handle the Temporary RSA Keys and DH Params
- */
-
-#define MODSSL_TMP_KEY_FREE(mc, type, idx) \
-    if (mc->pTmpKeys[idx]) { \
-        type##_free((type *)mc->pTmpKeys[idx]); \
-        mc->pTmpKeys[idx] = NULL; \
-    }
-
-#define MODSSL_TMP_KEYS_FREE(mc, type) \
-    MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \
-    MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024)
-
-static void ssl_tmp_keys_free(server_rec *s)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-
-    MODSSL_TMP_KEYS_FREE(mc, RSA);
-    MODSSL_TMP_KEYS_FREE(mc, DH);
-#ifndef OPENSSL_NO_EC
-    MODSSL_TMP_KEY_FREE(mc, EC_KEY, SSL_TMP_KEY_EC_256);
-#endif
-}
-
-static int ssl_tmp_key_init_rsa(server_rec *s,
-                                int bits, int idx)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-
-#ifdef HAVE_FIPS
-
-    if (FIPS_mode() && bits < 1024) {
-        mc->pTmpKeys[idx] = NULL;
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01877)
-                     "Init: Skipping generating temporary "
-                     "%d bit RSA private key in FIPS mode", bits);
-        return OK;
-    }
-
-#endif
-#ifdef HAVE_GENERATE_EX
-    {
-        RSA *tkey;
-        BIGNUM *bn_f4;
-        if (!(tkey = RSA_new())
-          || !(bn_f4 = BN_new())
-          || !BN_set_word(bn_f4, RSA_F4)
-          || !RSA_generate_key_ex(tkey, bits, bn_f4, NULL))
-        {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01878)
-                         "Init: Failed to generate temporary "
-                         "%d bit RSA private key", bits);
-            ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
-            return !OK;
-        }
-        BN_free(bn_f4);
-        mc->pTmpKeys[idx] = tkey;
-    }
-#else
-    if (!(mc->pTmpKeys[idx] =
-          RSA_generate_key(bits, RSA_F4, NULL, NULL)))
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01879)
-                     "Init: Failed to generate temporary "
-                     "%d bit RSA private key", bits);
-        ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
-        return !OK;
-    }
-#endif
-
-    return OK;
-}
-
-static int ssl_tmp_key_init_dh(server_rec *s,
-                               int bits, int idx)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-
-#ifdef HAVE_FIPS
-
-    if (FIPS_mode() && bits < 1024) {
-        mc->pTmpKeys[idx] = NULL;
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01880)
-                     "Init: Skipping generating temporary "
-                     "%d bit DH parameters in FIPS mode", bits);
-        return OK;
-    }
-
-#endif
-
-    if (!(mc->pTmpKeys[idx] =
-          ssl_dh_GetTmpParam(bits)))
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01881)
-                     "Init: Failed to generate temporary "
-                     "%d bit DH parameters", bits);
-        return !OK;
-    }
-
-    return OK;
-}
-
-#ifndef OPENSSL_NO_EC
-static int ssl_tmp_key_init_ec(server_rec *s,
-                               int bits, int idx)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-    EC_KEY *ecdh = NULL;
-
-    /* XXX: Are there any FIPS constraints we should enforce? */
-
-    if (bits != 256) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02298)
-                     "Init: Failed to generate temporary "
-                     "%d bit EC parameters, only 256 bits supported", bits);
-        return !OK;
-    }
-
-    if ((ecdh = EC_KEY_new()) == NULL ||
-        EC_KEY_set_group(ecdh, EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) != 1)
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02299)
-                     "Init: Failed to generate temporary "
-                     "%d bit EC parameters", bits);
-        return !OK;
-    }
-
-    mc->pTmpKeys[idx] = ecdh;
-    return OK;
-}
-
-#define MODSSL_TMP_KEY_INIT_EC(s, bits) \
-    ssl_tmp_key_init_ec(s, bits, SSL_TMP_KEY_EC_##bits)
-
-#endif
-
-#define MODSSL_TMP_KEY_INIT_RSA(s, bits) \
-    ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits)
-
-#define MODSSL_TMP_KEY_INIT_DH(s, bits) \
-    ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits)
-
-static int ssl_tmp_keys_init(server_rec *s)
-{
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
-                 "Init: Generating temporary RSA private keys (512/1024 bits)");
-
-    if (MODSSL_TMP_KEY_INIT_RSA(s, 512) ||
-        MODSSL_TMP_KEY_INIT_RSA(s, 1024)) {
-        return !OK;
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
-                 "Init: Generating temporary DH parameters (512/1024 bits)");
-
-    if (MODSSL_TMP_KEY_INIT_DH(s, 512) ||
-        MODSSL_TMP_KEY_INIT_DH(s, 1024)) {
-        return !OK;
-    }
-
-#ifndef OPENSSL_NO_EC
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
-                 "Init: Generating temporary EC parameters (256 bits)");
-
-    if (MODSSL_TMP_KEY_INIT_EC(s, 256)) {
-        return !OK;
-    }
-#endif
-
-    return OK;
-}
-
 /*
  *  Per-module initialization
  */
@@ -367,10 +193,6 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
      */
     ssl_pphrase_Handle(base_server, ptemp);
 
-    if (ssl_tmp_keys_init(base_server)) {
-        return !OK;
-    }
-
     /*
      * initialize the mutex handling
      */
@@ -678,6 +500,9 @@ static void ssl_init_ctx_protocol(server_rec *s,
      * Configure additional context ingredients
      */
     SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
+#ifndef OPENSSL_NO_EC
+    SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
+#endif
 
 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
     /*
@@ -738,11 +563,7 @@ static void ssl_init_ctx_callbacks(server_rec *s,
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
 
-    SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
     SSL_CTX_set_tmp_dh_callback(ctx,  ssl_callback_TmpDH);
-#ifndef OPENSSL_NO_EC
-    SSL_CTX_set_tmp_ecdh_callback(ctx,ssl_callback_TmpECDH);
-#endif
 
     SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
 
@@ -843,14 +664,15 @@ static void ssl_init_ctx_cipher_suite(server_rec *s,
                                       modssl_ctx_t *mctx)
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
-    const char *suite = mctx->auth.cipher_suite;
+    const char *suite;
 
     /*
-     *  Configure SSL Cipher Suite
+     *  Configure SSL Cipher Suite. Always disable NULL and export ciphers,
+     *  no matter what SSLCipherSuite directive is appearing in the config.
      */
-    if (!suite) {
-        return;
-    }
+    suite = apr_pstrcat(ptemp, "!aNULL:!eNULL:!EXP:", mctx->auth.cipher_suite ?
+                        mctx->auth.cipher_suite : SSL_DEFAULT_CIPHER_LIST,
+                        NULL);
 
     ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
                  "Configuring permitted SSL ciphers [%s]",
@@ -1234,6 +1056,12 @@ static void ssl_init_server_certs(server_rec *s,
                 "Oops, no " KEYTYPES " server private key found?!");
         ssl_die(s);
     }
+
+#ifndef OPENSSL_NO_EC
+    /* Enable ECDHE by configuring a default curve */
+    SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx,
+                         EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+#endif
 }
 
 #ifdef HAVE_TLS_SESSION_TICKETS
@@ -1769,11 +1597,6 @@ apr_status_t ssl_init_ModuleKill(void *data)
      */
     ssl_scache_kill(base_server);
 
-    /*
-     * Destroy the temporary keys and params
-     */
-    ssl_tmp_keys_free(base_server);
-
     /*
      * Free the non-pool allocated structures
      * in the per-server configurations
index 28cc19a4d4a80f47c09b8db90877fb075ca2c452..12d73d5924a3ac5f2c678f8043b59698a7d5143b 100644 (file)
@@ -1299,118 +1299,18 @@ const authz_provider ssl_authz_provider_verify_client =
 **  _________________________________________________________________
 */
 
-/*
- * Handle out temporary RSA private keys on demand
- *
- * The background of this as the TLSv1 standard explains it:
- *
- * | D.1. Temporary RSA keys
- * |
- * |    US Export restrictions limit RSA keys used for encryption to 512
- * |    bits, but do not place any limit on lengths of RSA keys used for
- * |    signing operations. Certificates often need to be larger than 512
- * |    bits, since 512-bit RSA keys are not secure enough for high-value
- * |    transactions or for applications requiring long-term security. Some
- * |    certificates are also designated signing-only, in which case they
- * |    cannot be used for key exchange.
- * |
- * |    When the public key in the certificate cannot be used for encryption,
- * |    the server signs a temporary RSA key, which is then exchanged. In
- * |    exportable applications, the temporary RSA key should be the maximum
- * |    allowable length (i.e., 512 bits). Because 512-bit RSA keys are
- * |    relatively insecure, they should be changed often. For typical
- * |    electronic commerce applications, it is suggested that keys be
- * |    changed daily or every 500 transactions, and more often if possible.
- * |    Note that while it is acceptable to use the same temporary key for
- * |    multiple transactions, it must be signed each time it is used.
- * |
- * |    RSA key generation is a time-consuming process. In many cases, a
- * |    low-priority process can be assigned the task of key generation.
- * |    Whenever a new key is completed, the existing temporary key can be
- * |    replaced with the new one.
- *
- * XXX: base on comment above, if thread support is enabled,
- * we should spawn a low-priority thread to generate new keys
- * on the fly.
- *
- * So we generated 512 and 1024 bit temporary keys on startup
- * which we now just hand out on demand....
- */
-
-RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen)
-{
-    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
-    SSLModConfigRec *mc = myModConfigFromConn(c);
-    int idx;
-
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                  "handing out temporary %d bit RSA key", keylen);
-
-    /* doesn't matter if export flag is on,
-     * we won't be asked for keylen > 512 in that case.
-     * if we are asked for a keylen > 1024, it is too expensive
-     * to generate on the fly.
-     * XXX: any reason not to generate 2048 bit keys at startup?
-     */
-
-    switch (keylen) {
-      case 512:
-        idx = SSL_TMP_KEY_RSA_512;
-        break;
-
-      case 1024:
-      default:
-        idx = SSL_TMP_KEY_RSA_1024;
-    }
-
-    return (RSA *)mc->pTmpKeys[idx];
-}
-
 /*
  * Hand out the already generated DH parameters...
  */
 DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
 {
     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
-    SSLModConfigRec *mc = myModConfigFromConn(c);
-    int idx;
-
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                  "handing out temporary %d bit DH key", keylen);
-
-    switch (keylen) {
-      case 512:
-        idx = SSL_TMP_KEY_DH_512;
-        break;
-
-      case 1024:
-      default:
-        idx = SSL_TMP_KEY_DH_1024;
-    }
-
-    return (DH *)mc->pTmpKeys[idx];
-}
-
-#ifndef OPENSSL_NO_EC
-EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen)
-{
-    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
-    SSLModConfigRec *mc = myModConfigFromConn(c);
-    int idx;
 
-    /* XXX Uses 256-bit key for now. TODO: support other sizes. */
     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
-                  "handing out temporary 256 bit ECC key");
-
-    switch (keylen) {
-      case 256:
-      default:
-        idx = SSL_TMP_KEY_EC_256;
-    }
+                  "handing out parameters for temporary %d bit DH key", keylen);
 
-    return (EC_KEY *)mc->pTmpKeys[idx];
+    return ssl_dh_GetTmpParam(keylen);
 }
-#endif
 
 /*
  * This OpenSSL callback function is called when OpenSSL
index ef7e8e3d877dc1c182270cf141c013b7f6cf857c..ef14f7ad5a3f0ae44cab97fb202e3765e9b6a682 100644 (file)
@@ -549,7 +549,6 @@ typedef struct {
     apr_global_mutex_t   *pMutex;
     apr_array_header_t   *aRandSeed;
     apr_hash_t     *tVHostKeys;
-    void           *pTmpKeys[SSL_TMP_KEY_MAX];
 
     /* Two hash tables of pointers to ssl_asn1_t structures.  The
      * structures are used to store certificates and private keys
@@ -849,11 +848,7 @@ extern const authz_provider ssl_authz_provider_require_ssl;
 extern const authz_provider ssl_authz_provider_verify_client;
 
 /**  OpenSSL callbacks */
-RSA         *ssl_callback_TmpRSA(SSL *, int, int);
 DH          *ssl_callback_TmpDH(SSL *, int, int);
-#ifndef OPENSSL_NO_EC
-EC_KEY      *ssl_callback_TmpECDH(SSL *, int, int);
-#endif
 int          ssl_callback_SSLVerify(int, X509_STORE_CTX *);
 int          ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *);
 int          ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey);