From: Emeric Brun Date: Thu, 20 Sep 2012 15:10:03 +0000 (+0200) Subject: MINOR: ssl: add elliptic curve Diffie-Hellman support for ssl key generation X-Git-Tag: v1.5-dev13~252 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b58d040b692ea10edeb2205e02130aeffc9a910;p=thirdparty%2Fhaproxy.git MINOR: ssl: add elliptic curve Diffie-Hellman support for ssl key generation Add 'ecdhe' on 'bind' statement: to set named curve used to generate ECDHE keys (ex: ecdhe secp521r1) --- diff --git a/include/types/listener.h b/include/types/listener.h index 82f23f1af1..a6b81f4543 100644 --- a/include/types/listener.h +++ b/include/types/listener.h @@ -97,6 +97,7 @@ enum { struct bind_conf { #ifdef USE_OPENSSL char *ciphers; /* cipher suite to use if non-null */ + char *ecdhe; /* named curve to use for ECDHE */ int nosslv3; /* disable SSLv3 */ int notlsv1; /* disable TLSv1 */ int prefer_server_ciphers; /* Prefer server ciphers */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 8a04499cb2..2afd5e7464 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -6600,6 +6600,7 @@ out_uri_auth_compat: #ifdef USE_OPENSSL ssl_sock_free_all_ctx(bind_conf); free(bind_conf->ciphers); + free(bind_conf->ecdhe); #endif /* USE_OPENSSL */ } diff --git a/src/haproxy.c b/src/haproxy.c index 767ac2e688..8b06743076 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1038,6 +1038,7 @@ void deinit(void) #ifdef USE_OPENSSL ssl_sock_free_all_ctx(bind_conf); free(bind_conf->ciphers); + free(bind_conf->ecdhe); #endif /* USE_OPENSSL */ free(bind_conf->file); free(bind_conf->arg); diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 5a7f01d979..abaef02c45 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -389,12 +389,18 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *cu #ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */ #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 #endif +#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */ +#define SSL_OP_SINGLE_ECDH_USE 0 +#endif #ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */ #define SSL_OP_NO_COMPRESSION 0 #endif #ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */ #define SSL_OP_SINGLE_DH_USE 0 #endif +#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */ +#define SSL_OP_SINGLE_ECDH_USE 0 +#endif #ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */ #define SSL_MODE_RELEASE_BUFFERS 0 #endif @@ -406,6 +412,7 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_DH_USE | + SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; int sslmode = SSL_MODE_ENABLE_PARTIAL_WRITE | @@ -436,6 +443,24 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk); SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf); #endif +#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH) + if (bind_conf->ecdhe) { + int i; + EC_KEY *ecdh; + + i = OBJ_sn2nid(bind_conf->ecdhe); + if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) { + Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n", + curproxy->id, bind_conf->ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line); + cfgerr++; + } + else { + SSL_CTX_set_tmp_ecdh(ctx, ecdh); + EC_KEY_free(ecdh); + } + } +#endif + return cfgerr; } @@ -888,6 +913,30 @@ static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bin return 0; } +/* parse the "ecdhe" bind keyword keywords */ +static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) +{ +#if OPENSSL_VERSION_NUMBER < 0x0090800fL + if (err) + memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; +#elif defined(OPENSSL_NO_ECDH) + if (err) + memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; +#else + if (!*args[cur_arg + 1]) { + if (err) + memprintf(err, "'%s' : missing named curve", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + + conf->ecdhe = strdup(args[cur_arg + 1]); + + return 0; +#endif +} + /* parse the "nosslv3" bind keyword */ static int bind_parse_nosslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) { @@ -951,12 +1000,13 @@ static struct acl_kw_list acl_kws = {{ },{ * not enabled. */ static struct bind_kw_list bind_kws = { "SSL", { }, { - { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */ - { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */ - { "nosslv3", bind_parse_nosslv3, 0 }, /* disable SSLv3 */ - { "notlsv1", bind_parse_notlsv1, 0 }, /* disable TLSv1 */ - { "prefer-server-ciphers", bind_parse_psc, 0 }, /* prefer server ciphers */ - { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */ + { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */ + { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */ + { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */ + { "nosslv3", bind_parse_nosslv3, 0 }, /* disable SSLv3 */ + { "notlsv1", bind_parse_notlsv1, 0 }, /* disable TLSv1 */ + { "prefer-server-ciphers", bind_parse_psc, 0 }, /* prefer server ciphers */ + { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */ { NULL, NULL, 0 }, }};