On Fri, 12 Jul 2013, Joel Sing wrote:
> On Mon, 8 Jul 2013, Damien Miller wrote:
> > On Sun, 7 Jul 2013, Aaron Stellman wrote:
> > > On Tue, Apr 23, 2013 at 09:08:19AM +0200, Otto Moerbeek wrote:
> > > > If there is any interest, I might add the manual stuff, get ok's and
> > > > commit it.
> > >
> > > I find it useful to have SSLHonorCipherOrder in OpenBSD's apache.
> >
> > More than that, AFAIK it is necessary to mitigate some of the TLS crypto
> > attacks. IMO it is well worth having.
> >
> > It would also be good if someone could make a patch to enable ECDHE
> > cipher suites in Apache-1.x.
> > This nginx patch is a good reference to what needs to
> > be done:
> >
> > http://hg.nginx.org/nginx/rev/0832a6997227
>
> The following should do the trick...
>
> $ openssl s_client -connect localhost:443 2>&1 </dev/null | grep "Cipher
> is" New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
>
And an improved version, after feedback from djm:
Index: conf/httpd.conf
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/conf/httpd.conf,v
retrieving revision 1.26
diff -u -p -u -p -r1.26 httpd.conf
--- conf/httpd.conf 3 Jun 2009 18:28:21 -0000 1.26
+++ conf/httpd.conf 15 Jul 2013 15:31:19 -0000
@@ -1034,6 +1034,11 @@ SSLEngine on
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
#SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
+
+# SSL ECDH Curve:
+# Named curve to use when generating ephemeral EC keys for an
+# ECDHE-based cipher suite, or `none' to disable.
+SSLECDHCurve prime256v1
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
Index: conf/httpd.conf-dist
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/conf/httpd.conf-dist,v
retrieving revision 1.20
diff -u -p -u -p -r1.20 httpd.conf-dist
--- conf/httpd.conf-dist 1 Apr 2009 06:47:34 -0000 1.20
+++ conf/httpd.conf-dist 15 Jul 2013 15:31:19 -0000
@@ -1045,6 +1045,11 @@ SSLEngine on
# See the mod_ssl documentation for a complete list.
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
+# SSL ECDH Curve:
+# Named curve to use when generating ephemeral EC keys for an
+# ECDHE-based cipher suite, or `none' to disable.
+SSLECDHCurve prime256v1
+
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
Index: src/modules/ssl/mod_ssl.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/ssl/mod_ssl.c,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 mod_ssl.c
--- src/modules/ssl/mod_ssl.c 11 Jul 2013 12:41:52 -0000 1.11
+++ src/modules/ssl/mod_ssl.c 15 Jul 2013 15:31:19 -0000
@@ -113,6 +113,9 @@ static command_rec ssl_config_cmds[] = {
AP_ALL_CMD(CipherSuite, TAKE1,
"Colon-delimited list of permitted SSL Ciphers "
"(`XXX:...:XXX' - see manual)")
+ AP_SRV_CMD(ECDHCurve, TAKE1,
+ "Name of ECDH curve to use for ephemeral EC keys "
+ "(`curve' - see manual)")
AP_SRV_CMD(CertificateFile, TAKE1,
"SSL Server Certificate file "
"(`/path/to/file' - PEM or DER encoded)")
Index: src/modules/ssl/mod_ssl.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/ssl/mod_ssl.h,v
retrieving revision 1.22
diff -u -p -u -p -r1.22 mod_ssl.h
--- src/modules/ssl/mod_ssl.h 11 Jul 2013 12:41:52 -0000 1.22
+++ src/modules/ssl/mod_ssl.h 15 Jul 2013 15:31:19 -0000
@@ -514,6 +514,7 @@ typedef struct {
char *szCACertificateFile;
char *szLogFile;
char *szCipherSuite;
+ int nECDHCurve;
FILE *fileLogFile;
int nLogLevel;
BOOL cipher_server_pref;
@@ -592,6 +593,7 @@ const char *ssl_cmd_SSLRandomSeed(cmd_p
const char *ssl_cmd_SSLEngine(cmd_parms *, char *, int);
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *, char *, int);
const char *ssl_cmd_SSLCipherSuite(cmd_parms *, SSLDirConfigRec *, char *);
+const char *ssl_cmd_SSLECDHCurve(cmd_parms *, char *, char *);
const char *ssl_cmd_SSLCertificateFile(cmd_parms *, char *, char *);
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, char *, char *);
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, char *, char *);
Index: src/modules/ssl/ssl_engine_config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c,v
retrieving revision 1.20
diff -u -p -u -p -r1.20 ssl_engine_config.c
--- src/modules/ssl/ssl_engine_config.c 11 Jul 2013 12:41:52 -0000 1.20
+++ src/modules/ssl/ssl_engine_config.c 15 Jul 2013 15:31:19 -0000
@@ -196,6 +196,7 @@ void *ssl_config_server_create(pool *p,
sc->szCertificateChain = NULL;
sc->szLogFile = NULL;
sc->szCipherSuite = NULL;
+ sc->nECDHCurve = NID_X9_62_prime256v1;
sc->nLogLevel = SSL_LOG_NONE;
sc->cipher_server_pref = UNSET;
sc->nVerifyDepth = UNSET;
@@ -253,6 +254,7 @@ void *ssl_config_server_merge(pool *p, v
cfgMergeString(szCertificateChain);
cfgMergeString(szLogFile);
cfgMergeString(szCipherSuite);
+ cfgMerge(nECDHCurve, NID_X9_62_prime256v1);
cfgMergeBool(cipher_server_pref);
cfgMerge(nLogLevel, SSL_LOG_NONE);
cfgMergeInt(nVerifyDepth);
@@ -549,6 +551,25 @@ const char *ssl_cmd_SSLCipherSuite(
sc->szCipherSuite = arg;
else
dc->szCipherSuite = arg;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLECDHCurve(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ if (strcEQ(arg, "none")) {
+ sc->nECDHCurve = 0;
+ return NULL;
+ }
+
+ sc->nECDHCurve = OBJ_sn2nid((const char *)arg);
+ if (sc->nECDHCurve == 0) {
+ return ap_pstrcat(cmd->pool, "SSLECDHCurve: unknown named curve '",
+ arg, "'", NULL);
+ }
+
return NULL;
}
Index: src/modules/ssl/ssl_engine_init.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c,v
retrieving revision 1.29
diff -u -p -u -p -r1.29 ssl_engine_init.c
--- src/modules/ssl/ssl_engine_init.c 11 Jul 2013 12:41:52 -0000 1.29
+++ src/modules/ssl/ssl_engine_init.c 15 Jul 2013 15:31:19 -0000
@@ -530,6 +530,7 @@ void ssl_init_ConfigureServer(server_rec
char *cpVHostID;
EVP_PKEY *pKey;
SSL_CTX *ctx;
+ EC_KEY *ecdhKey;
STACK_OF(X509_NAME) *skCAList;
ssl_asn1_t *asn1;
unsigned char *ucp;
@@ -639,6 +640,22 @@ void ssl_init_ConfigureServer(server_rec
cpVHostID);
ssl_die();
}
+ }
+
+ /*
+ * Configure ECDH Curve
+ */
+ if (sc->nECDHCurve > 0) {
+ ecdhKey = EC_KEY_new_by_curve_name(sc->nECDHCurve);
+ if (ecdhKey == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Init: (%s) Failed to create new EC key using named curve",
+ cpVHostID);
+ ssl_die();
+ }
+ SSL_CTX_set_tmp_ecdh(ctx, ecdhKey);
+ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
+ EC_KEY_free(ecdhKey);
}
/*
--
"Action without study is fatal. Study without action is futile."
-- Mary Ritter Beard