[apache2] 03/05: Backport support for SSL/TLS ECC keys and ECDH ciphers

Stefan Fritsch sf at moszumanska.debian.org
Sun May 25 15:43:59 UTC 2014


This is an automated email from the git hooks/post-receive script.

sf pushed a commit to branch wheezy
in repository apache2.

commit a23ff4aab8d8e52c52f4561827cf90a50b9c0a2e
Author: Stefan Fritsch <sf at sfritsch.de>
Date:   Sun May 25 17:33:16 2014 +0200

    Backport support for SSL/TLS ECC keys and ECDH ciphers
---
 debian/NEWS                  |   9 ++
 debian/README.Debian         |  12 ++
 debian/changelog             |   8 ++
 debian/control               |   2 +-
 debian/patches/SSL-ECC.patch | 332 +++++++++++++++++++++++++++++++++++++++++++
 debian/patches/series        |   1 +
 6 files changed, 363 insertions(+), 1 deletion(-)

diff --git a/debian/NEWS b/debian/NEWS
index c0c6285..5d101bd 100644
--- a/debian/NEWS
+++ b/debian/NEWS
@@ -1,3 +1,12 @@
+apache2 (2.2.22-13+deb7u2) stable; urgency=medium
+
+  * This release adds support for SSL/TLS ECC keys and ECDH ciphers.
+
+    If this change causes problems with some older clients, see
+    /usr/share/doc/apache2/README.Debian.gz for a work-around.
+
+ -- Stefan Fritsch <sf at debian.org>  Sun, 25 May 2014 13:05:40 +0200
+
 apache2 (2.2.15-4) unstable; urgency=low
 
   * Note to people using mod_proxy as forward proxy, i.e. with
diff --git a/debian/README.Debian b/debian/README.Debian
index 79da676..cfe8826 100644
--- a/debian/README.Debian
+++ b/debian/README.Debian
@@ -234,6 +234,18 @@ disabled even for non-SSL connections):
 The default SSL virtual host in /etc/apache2/sites-available/default-ssl
 already contains this workaround.
 
+ECC keys and ECDH ciphers
+-------------------------
+
+The package in Debian has support for ECC keys and ECDH ciphers backported
+from Apache 2.2.26.
+
+If these ciphers causes any problems, they may be disabled by adding ":!ECDH"
+to the SSLCipherSuite directive in /etc/apache2/mods-enabled/ssl.conf .
+
+A special compatibility fix for older Safari browsers is enabled if using an
+up-to-date libssl-1.0.0 (version 1.0.1e-2+deb7u8 or newer).
+
 
 Suexec
 ======
diff --git a/debian/changelog b/debian/changelog
index 39375ec..9163d66 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,13 @@
 apache2 (2.2.22-13+deb7u2) UNRELEASED; urgency=medium
 
+  * Backport support for SSL ECC keys and ECDH ciphers.
+
+    Bump build-dependency for libssl-dev to 1.0.1e-2+deb7u8 to get the
+    compatibility fix for older Safari browsers. Apache2 will still
+    run with older libssl-1.0.0 but without the compatibility fix.
+
+    In case of problems, see README.Debian.
+
   * CVE-2013-6438: mod_dav: Fix potential denial of service from
     specifically crafted DAV WRITE requests.
 
diff --git a/debian/control b/debian/control
index a6ae734..484059a 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Section: httpd
 Priority: optional
 Maintainer: Debian Apache Maintainers <debian-apache at lists.debian.org>
 Uploaders: Stefan Fritsch <sf at debian.org>, Steinar H. Gunderson <sesse at debian.org>, Arno Töll <arno at debian.org>
-Build-Depends: debhelper (>= 8.9.7~), lsb-release, libaprutil1-dev (>= 1.3.4), libapr1-dev, openssl, libpcre3-dev, mawk, zlib1g-dev, libssl-dev (>= 0.9.8m), sharutils, libcap-dev [linux-any], autoconf, autotools-dev
+Build-Depends: debhelper (>= 8.9.7~), lsb-release, libaprutil1-dev (>= 1.3.4), libapr1-dev, openssl, libpcre3-dev, mawk, zlib1g-dev, libssl-dev (>= 1.0.1e-2+deb7u8), sharutils, libcap-dev [linux-any], autoconf, autotools-dev
 Build-Conflicts: autoconf2.13
 Standards-Version: 3.9.3
 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-apache/apache2.git
diff --git a/debian/patches/SSL-ECC.patch b/debian/patches/SSL-ECC.patch
new file mode 100644
index 0000000..3977d72
--- /dev/null
+++ b/debian/patches/SSL-ECC.patch
@@ -0,0 +1,332 @@
+# https://svn.apache.org/r1540727
+#
+# Backport from 2.2.26: mod_ssl: enable support for ECC keys and ECDH ciphers.
+#
+diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
+index b9e3f93..19794f0 100644
+--- a/modules/ssl/mod_ssl.c
++++ b/modules/ssl/mod_ssl.c
+@@ -441,6 +441,9 @@ int ssl_init_ssl_connection(conn_rec *c)
+      */
+     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);
+ 
+diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
+index dcae945..d8b4802 100644
+--- a/modules/ssl/ssl_engine_init.c
++++ b/modules/ssl/ssl_engine_init.c
+@@ -72,6 +72,9 @@ static void ssl_tmp_keys_free(server_rec *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,
+@@ -133,6 +136,40 @@ static int ssl_tmp_key_init_dh(server_rec *s,
+     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,
++                     "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,
++                     "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)
+ 
+@@ -157,6 +194,15 @@ static int ssl_tmp_keys_init(server_rec *s)
+         return !OK;
+     }
+ 
++#ifndef OPENSSL_NO_EC
++    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
++                 "Init: Generating temporary EC parameters (256 bits)");
++
++    if (MODSSL_TMP_KEY_INIT_EC(s, 256)) {
++        return !OK;
++    }
++#endif
++
+     return OK;
+ }
+ 
+@@ -399,7 +445,11 @@ static void ssl_init_server_check(server_rec *s,
+      *  Check for problematic re-initializations
+      */
+     if (mctx->pks->certs[SSL_AIDX_RSA] ||
+-        mctx->pks->certs[SSL_AIDX_DSA])
++        mctx->pks->certs[SSL_AIDX_DSA]
++#ifndef OPENSSL_NO_EC
++      || mctx->pks->certs[SSL_AIDX_ECC]
++#endif
++        )
+     {
+         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                 "Illegal attempt to re-initialise SSL for server "
+@@ -599,6 +649,9 @@ static void ssl_init_ctx_callbacks(server_rec *s,
+ 
+     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);
+ }
+@@ -866,9 +919,16 @@ static int ssl_server_import_key(server_rec *s,
+     ssl_asn1_t *asn1;
+     MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
+     const char *type = ssl_asn1_keystr(idx);
+-    int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
++    int pkey_type;
+     EVP_PKEY *pkey;
+ 
++#ifndef OPENSSL_NO_EC
++    if (idx == SSL_AIDX_ECC)
++      pkey_type = EVP_PKEY_EC;
++    else
++#endif
++    pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
++
+     if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
+         return FALSE;
+     }
+@@ -979,19 +1039,39 @@ static void ssl_init_server_certs(server_rec *s,
+                                   modssl_ctx_t *mctx)
+ {
+     const char *rsa_id, *dsa_id;
++#ifndef OPENSSL_NO_EC
++    const char *ecc_id;
++#endif
+     const char *vhost_id = mctx->sc->vhost_id;
+     int i;
+     int have_rsa, have_dsa;
++#ifndef OPENSSL_NO_EC
++    int have_ecc;
++#endif
+ 
+     rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
+     dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
++#ifndef OPENSSL_NO_EC
++    ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
++#endif
+ 
+     have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
+     have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
++#ifndef OPENSSL_NO_EC
++    have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
++#endif
+ 
+-    if (!(have_rsa || have_dsa)) {
++    if (!(have_rsa || have_dsa
++#ifndef OPENSSL_NO_EC
++        || have_ecc
++#endif
++)) {
+         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
++#ifndef OPENSSL_NO_EC
++                "Oops, no RSA, DSA or ECC server certificate found "
++#else
+                 "Oops, no RSA or DSA server certificate found "
++#endif
+                 "for '%s:%d'?!", s->server_hostname, s->port);
+         ssl_die();
+     }
+@@ -1002,10 +1082,21 @@ static void ssl_init_server_certs(server_rec *s,
+ 
+     have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
+     have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
++#ifndef OPENSSL_NO_EC
++    have_ecc = ssl_server_import_key(s, mctx, ecc_id, SSL_AIDX_ECC);
++#endif
+ 
+-    if (!(have_rsa || have_dsa)) {
++    if (!(have_rsa || have_dsa
++#ifndef OPENSSL_NO_EC
++        || have_ecc
++#endif
++          )) {
+         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
++#ifndef OPENSSL_NO_EC
++                "Oops, no RSA, DSA or ECC server private key found?!");
++#else
+                 "Oops, no RSA or DSA server private key found?!");
++#endif
+         ssl_die();
+     }
+ }
+diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
+index 6cb2087..28bc47a 100644
+--- a/modules/ssl/ssl_engine_kernel.c
++++ b/modules/ssl/ssl_engine_kernel.c
+@@ -1267,6 +1267,27 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
+     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_DEBUG, 0, c,
++                  "handing out temporary 256 bit ECC key");
++
++    switch (keylen) {
++      case 256:
++      default:
++        idx = SSL_TMP_KEY_EC_256;
++    }
++
++    return (EC_KEY *)mc->pTmpKeys[idx];
++}
++#endif
++
+ /*
+  * This OpenSSL callback function is called when OpenSSL
+  * does client authentication and verifies the certificate chain.
+diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
+index 650043d..79d222e 100644
+--- a/modules/ssl/ssl_private.h
++++ b/modules/ssl/ssl_private.h
+@@ -191,11 +191,21 @@ typedef int ssl_algo_t;
+ #define SSL_ALGO_UNKNOWN (0)
+ #define SSL_ALGO_RSA     (1<<0)
+ #define SSL_ALGO_DSA     (1<<1)
++#ifndef OPENSSL_NO_EC
++#define SSL_ALGO_ECC     (1<<2)
++#define SSL_ALGO_ALL     (SSL_ALGO_RSA|SSL_ALGO_DSA|SSL_ALGO_ECC)
++#else
+ #define SSL_ALGO_ALL     (SSL_ALGO_RSA|SSL_ALGO_DSA)
++#endif
+ 
+ #define SSL_AIDX_RSA     (0)
+ #define SSL_AIDX_DSA     (1)
++#ifndef OPENSSL_NO_EC
++#define SSL_AIDX_ECC     (2)
++#define SSL_AIDX_MAX     (3)
++#else
+ #define SSL_AIDX_MAX     (2)
++#endif
+ 
+ 
+ /**
+@@ -206,7 +216,12 @@ typedef int ssl_algo_t;
+ #define SSL_TMP_KEY_RSA_1024 (1)
+ #define SSL_TMP_KEY_DH_512   (2)
+ #define SSL_TMP_KEY_DH_1024  (3)
++#ifndef OPENSSL_NO_EC
++#define SSL_TMP_KEY_EC_256   (4)
++#define SSL_TMP_KEY_MAX      (5)
++#else
+ #define SSL_TMP_KEY_MAX      (4)
++#endif
+ 
+ /**
+  * Define the SSL options
+@@ -625,6 +640,9 @@ void         ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
+ /**  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, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey);
+diff --git a/modules/ssl/ssl_toolkit_compat.h b/modules/ssl/ssl_toolkit_compat.h
+index bd57a17..6f49f30 100644
+--- a/modules/ssl/ssl_toolkit_compat.h
++++ b/modules/ssl/ssl_toolkit_compat.h
+@@ -38,6 +38,12 @@
+ #include <openssl/evp.h>
+ #include <openssl/rand.h>
+ #include <openssl/x509v3.h>
++
++/* ECC support came along in OpenSSL 1.0.0 */
++#if (OPENSSL_VERSION_NUMBER < 0x10000000)
++#define OPENSSL_NO_EC
++#endif
++
+ /** Avoid tripping over an engine build installed globally and detected
+  * when the user points at an explicit non-engine flavor of OpenSSL
+  */
+diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c
+index e4387e6..efac310 100644
+--- a/modules/ssl/ssl_util.c
++++ b/modules/ssl/ssl_util.c
+@@ -150,6 +150,11 @@ ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
+             case EVP_PKEY_DSA:
+                 t = SSL_ALGO_DSA;
+                 break;
++#ifndef OPENSSL_NO_EC
++            case EVP_PKEY_EC:
++                t = SSL_ALGO_ECC;
++                break;
++#endif 
+             default:
+                 break;
+         }
+@@ -174,6 +179,11 @@ char *ssl_util_algotypestr(ssl_algo_t t)
+         case SSL_ALGO_DSA:
+             cp = "DSA";
+             break;
++#ifndef OPENSSL_NO_EC
++        case SSL_ALGO_ECC:
++            cp = "ECC";
++            break;
++#endif
+         default:
+             break;
+     }
+@@ -245,7 +255,11 @@ void ssl_asn1_table_unset(apr_hash_t *table,
+     apr_hash_set(table, key, klen, NULL);
+ }
+ 
++#ifndef OPENSSL_NO_EC
++static const char *ssl_asn1_key_types[] = {"RSA", "DSA", "ECC"};
++#else
+ static const char *ssl_asn1_key_types[] = {"RSA", "DSA"};
++#endif
+ 
+ const char *ssl_asn1_keystr(int keytype)
+ {
diff --git a/debian/patches/series b/debian/patches/series
index 152ffbb..0db7751 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -40,3 +40,4 @@ CVE-2013-1896.patch
 mod_dav_crash_PR_52559.patch
 mod_dav-CVE-2013-6438.patch
 cookie-logging-CVE-2014-0098.diff
+SSL-ECC.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-apache/apache2.git



More information about the Pkg-apache-commits mailing list