You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Sander Temme <sc...@apache.org> on 2009/11/07 01:41:02 UTC

[PATCH] Enable Elliptic Curve Keys and ciphers

Folks,

This is Vipul Gupta's patch (Bugzilla 40132) against today's trunk.   
This compiles and works under some manual testing.  Looks like OpenSSL  
1.0 and Safari know about ECC, but Firefox doesn't.

I have not been successful in getting the perl-framework to exercise  
this.

Opinions?

S.

Index: docs/conf/extra/httpd-ssl.conf.in
===================================================================
--- docs/conf/extra/httpd-ssl.conf.in	(revision 833615)
+++ docs/conf/extra/httpd-ssl.conf.in	(working copy)
@@ -81,6 +81,9 @@
  #   SSL Cipher Suite:
  #   List the ciphers that the client is permitted to negotiate.
  #   See the mod_ssl documentation for a complete list.
+#   Recent OpenSSL snapshots include Elliptic Curve Cryptograhpy (ECC)
+#   cipher suites (see RFC 4492) as part of "ALL". Edit this line
+#   if you need to disable any of those ciphers.
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW: 
+SSLv2:+EXP:+eNULL

  #   Server Certificate:
@@ -90,16 +93,22 @@
  #   in mind that if you have both an RSA and a DSA certificate you
  #   can configure both in parallel (to also allow the use of DSA
  #   ciphers, etc.)
+#   Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt)
+#   require an ECC certificate which can also be configured in
+#   parallel.
  SSLCertificateFile "@exp_sysconfdir@/server.crt"
  #SSLCertificateFile "@exp_sysconfdir@/server-dsa.crt"
+#SSLCertificateFile "@exp_sysconfdir@/server-ecc.crt"

  #   Server Private Key:
  #   If the key is not combined with the certificate, use this
  #   directive to point at the key file.  Keep in mind that if
  #   you've both a RSA and a DSA private key you can configure
  #   both in parallel (to also allow the use of DSA ciphers, etc.)
+#   ECC keys, when in use, can also be configured in parallel
  SSLCertificateKeyFile "@exp_sysconfdir@/server.key"
  #SSLCertificateKeyFile "@exp_sysconfdir@/server-dsa.key"
+#SSLCertificateKeyFile "@exp_sysconfdir@/server-ecc.key"

  #   Server Certificate Chain:
  #   Point SSLCertificateChainFile at a file containing the
Index: modules/ssl/ssl_private.h
===================================================================
--- modules/ssl/ssl_private.h	(revision 833615)
+++ modules/ssl/ssl_private.h	(working copy)
@@ -172,11 +172,21 @@
  #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 /* SSL_LIBRARY_VERSION */

  #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 /* SSL_LIBRARY_VERSION */


  /**
@@ -626,6 +636,9 @@
  /**  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 /* SSL_LIBRARY_VERSION */
  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);
Index: modules/ssl/ssl_engine_init.c
===================================================================
--- modules/ssl/ssl_engine_init.c	(revision 833615)
+++ modules/ssl/ssl_engine_init.c	(working copy)
@@ -356,7 +356,11 @@
       *  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 "
@@ -519,6 +523,9 @@

      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);
  }
@@ -810,9 +817,16 @@
      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 /* SSL_LIBRARY_VERSION */
+    pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+
      if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
          return FALSE;
      }
@@ -922,20 +936,34 @@
                                    apr_pool_t *ptemp,
                                    modssl_ctx_t *mctx)
  {
-    const char *rsa_id, *dsa_id;
+    const char *rsa_id, *dsa_id, *ecc_id;
      const char *vhost_id = mctx->sc->vhost_id;
      int i;
-    int have_rsa, have_dsa;
+    int have_rsa, have_dsa, have_ecc;

      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();
      }
@@ -946,10 +974,21 @@

      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);
+#if SSL_LIBRARY_VERSION >= 0x00908000
+    have_ecc = ssl_server_import_key(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif

-    if (!(have_rsa || have_dsa)) {
+    if (!(have_rsa || have_dsa
+#if SSL_LIBRARY_VERSION >= 0x00908000
+        || have_ecc
+#endif
+          )) {
          ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+#if SSL_LIBRARY_VERSION >= 0x00908000
+                "Oops, no RSA, DSA or ECC server private key found?!");
+#else
                  "Oops, no RSA or DSA server private key found?!");
+#endif
          ssl_die();
      }
  }
Index: modules/ssl/ssl_engine_kernel.c
===================================================================
--- modules/ssl/ssl_engine_kernel.c	(revision 833615)
+++ modules/ssl/ssl_engine_kernel.c	(working copy)
@@ -1244,6 +1244,33 @@
      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 = myModConfig(c->base_server);
+    int idx;
+    static EC_KEY *ecdh = NULL;
+    static init = 0;
+
+    /* 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");
+
+    if (init == 0) {
+        ecdh = EC_KEY_new();
+        if (ecdh != NULL) {
+            /* ecdh->group = EC_GROUP_new_by_nid(NID_secp160r2); */
+            EC_KEY_set_group(ecdh,
+              EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+        }
+        init = 1;
+    }
+
+    return ecdh;
+}
+#endif
+
  /*
   * This OpenSSL callback function is called when OpenSSL
   * does client authentication and verifies the certificate chain.
Index: modules/ssl/ssl_util.c
===================================================================
--- modules/ssl/ssl_util.c	(revision 833615)
+++ modules/ssl/ssl_util.c	(working copy)
@@ -150,6 +150,11 @@
              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 @@
          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 @@
      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)
  {
Index: modules/ssl/mod_ssl.c
===================================================================
--- modules/ssl/mod_ssl.c	(revision 833615)
+++ modules/ssl/mod_ssl.c	(working copy)
@@ -440,6 +440,9 @@
       */
      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);

Index: modules/ssl/ssl_toolkit_compat.h
===================================================================
--- modules/ssl/ssl_toolkit_compat.h	(revision 833615)
+++ modules/ssl/ssl_toolkit_compat.h	(working copy)
@@ -48,6 +48,11 @@
  #include <openssl/ocsp.h>
  #endif

+/* ECC support came along in OpenSSL 0.9.8 */
+#if (OPENSSL_VERSION_NUMBER < 0x00908000)
+#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
   */



-- 
Sander Temme
sctemme@apache.org
PGP FP: 51B4 8727 466A 0BC3 69F4  B7B8 B2BE BC40 1529 24AF