diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2017-08-10 18:18:31 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2017-08-10 18:18:31 +0000 |
commit | f0477a05af9bcd65559bababe6e1929c68184bf2 (patch) | |
tree | e5f6084eb22d388966785be2c94b3935c6b3fa1f /lib/libtls | |
parent | 6c57c8afe3cbcaf5b831c447f6bb299d43e81fdd (diff) |
Add a tls_config_set_ecdhecurves() function to libtls, which allows the
names of the elliptic curves that may be used during client and server
key exchange to be specified.
This deprecates tls_config_set_ecdhecurve(), which could only be used to
specify a single supported curve.
ok beck@
Diffstat (limited to 'lib/libtls')
-rw-r--r-- | lib/libtls/Symbols.list | 1 | ||||
-rw-r--r-- | lib/libtls/man/tls_config_set_protocols.3 | 19 | ||||
-rw-r--r-- | lib/libtls/tls.h | 5 | ||||
-rw-r--r-- | lib/libtls/tls_client.c | 10 | ||||
-rw-r--r-- | lib/libtls/tls_config.c | 84 | ||||
-rw-r--r-- | lib/libtls/tls_internal.h | 7 | ||||
-rw-r--r-- | lib/libtls/tls_server.c | 16 |
7 files changed, 108 insertions, 34 deletions
diff --git a/lib/libtls/Symbols.list b/lib/libtls/Symbols.list index 6d174bc83a7..1e7538cfd43 100644 --- a/lib/libtls/Symbols.list +++ b/lib/libtls/Symbols.list @@ -30,6 +30,7 @@ tls_config_set_crl_file tls_config_set_crl_mem tls_config_set_dheparams tls_config_set_ecdhecurve +tls_config_set_ecdhecurves tls_config_set_key_file tls_config_set_key_mem tls_config_set_keypair_file diff --git a/lib/libtls/man/tls_config_set_protocols.3 b/lib/libtls/man/tls_config_set_protocols.3 index b2f31eabd5a..e16abe44d5a 100644 --- a/lib/libtls/man/tls_config_set_protocols.3 +++ b/lib/libtls/man/tls_config_set_protocols.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tls_config_set_protocols.3,v 1.3 2017/01/28 00:59:36 schwarze Exp $ +.\" $OpenBSD: tls_config_set_protocols.3,v 1.4 2017/08/10 18:18:30 jsing Exp $ .\" .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> .\" Copyright (c) 2015, 2016 Joel Sing <jsing@openbsd.org> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 28 2017 $ +.Dd $Mdocdate: August 10 2017 $ .Dt TLS_CONFIG_SET_PROTOCOLS 3 .Os .Sh NAME @@ -25,7 +25,7 @@ .Nm tls_config_set_alpn , .Nm tls_config_set_ciphers , .Nm tls_config_set_dheparams , -.Nm tls_config_set_ecdhecurve , +.Nm tls_config_set_ecdhecurves , .Nm tls_config_prefer_ciphers_client , .Nm tls_config_prefer_ciphers_server .Nd TLS protocol and cipher selection @@ -57,9 +57,9 @@ .Fa "const char *params" .Fc .Ft int -.Fo tls_config_set_ecdhecurve +.Fo tls_config_set_ecdhecurves .Fa "struct tls_config *config" -.Fa "const char *name" +.Fa "const char *curves" .Fc .Ft void .Fn tls_config_prefer_ciphers_client "struct tls_config *config" @@ -126,7 +126,14 @@ See the CIPHERS section of .Xr openssl 1 for further information. .\" XXX tls_config_set_dheparams does what? -.\" XXX tls_config_set_ecdhecurve does what? +.Pp +.Fn tls_config_set_ecdhecurves +specifies the names of the elliptic curves that may be used during key exchange. +This is a comma separated list, given in order of preference. +The special value of "default" will use the default curves (currently X25519, +P-256 and P-384). This function replaces +.Fn tls_config_set_ecdhecurve , +which is deprecated. .Pp .Fn tls_config_prefer_ciphers_client prefers ciphers in the client's cipher list when selecting a cipher suite diff --git a/lib/libtls/tls.h b/lib/libtls/tls.h index 1a6701b581c..cc8627f2af2 100644 --- a/lib/libtls/tls.h +++ b/lib/libtls/tls.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.h,v 1.50 2017/07/06 17:12:22 jsing Exp $ */ +/* $OpenBSD: tls.h,v 1.51 2017/08/10 18:18:30 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -109,7 +109,8 @@ int tls_config_set_crl_file(struct tls_config *_config, const char *_crl_file); int tls_config_set_crl_mem(struct tls_config *_config, const uint8_t *_crl, size_t _len); int tls_config_set_dheparams(struct tls_config *_config, const char *_params); -int tls_config_set_ecdhecurve(struct tls_config *_config, const char *_name); +int tls_config_set_ecdhecurve(struct tls_config *_config, const char *_curve); +int tls_config_set_ecdhecurves(struct tls_config *_config, const char *_curves); int tls_config_set_key_file(struct tls_config *_config, const char *_key_file); int tls_config_set_key_mem(struct tls_config *_config, const uint8_t *_key, size_t _len); diff --git a/lib/libtls/tls_client.c b/lib/libtls/tls_client.c index b92490f25d1..c79f462a3a5 100644 --- a/lib/libtls/tls_client.c +++ b/lib/libtls/tls_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_client.c,v 1.42 2017/05/07 03:27:06 jsing Exp $ */ +/* $OpenBSD: tls_client.c,v 1.43 2017/08/10 18:18:30 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -198,6 +198,14 @@ tls_connect_common(struct tls *ctx, const char *servername) if (tls_configure_ssl_verify(ctx, ctx->ssl_ctx, SSL_VERIFY_PEER) == -1) goto err; + if (ctx->config->ecdhecurves != NULL) { + if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves, + ctx->config->ecdhecurves_len) != 1) { + tls_set_errorx(ctx, "failed to set ecdhe curves"); + goto err; + } + } + if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) { tls_set_errorx(ctx, "ssl OCSP verification setup failure"); goto err; diff --git a/lib/libtls/tls_config.c b/lib/libtls/tls_config.c index 40374ea2203..581c493a559 100644 --- a/lib/libtls/tls_config.c +++ b/lib/libtls/tls_config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_config.c,v 1.42 2017/08/09 21:27:24 claudio Exp $ */ +/* $OpenBSD: tls_config.c,v 1.43 2017/08/10 18:18:30 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -214,7 +214,7 @@ tls_config_new(void) */ if (tls_config_set_dheparams(config, "none") != 0) goto err; - if (tls_config_set_ecdhecurve(config, "auto") != 0) + if (tls_config_set_ecdhecurves(config, "default") != 0) goto err; if (tls_config_set_ciphers(config, "secure") != 0) goto err; @@ -269,6 +269,7 @@ tls_config_free(struct tls_config *config) free((char *)config->ca_path); free((char *)config->ciphers); free((char *)config->crl_mem); + free(config->ecdhecurves); free(config); } @@ -616,22 +617,81 @@ tls_config_set_dheparams(struct tls_config *config, const char *params) } int -tls_config_set_ecdhecurve(struct tls_config *config, const char *name) +tls_config_set_ecdhecurve(struct tls_config *config, const char *curve) { + if (strchr(curve, ',') != NULL || strchr(curve, ':') != NULL) { + tls_config_set_errorx(config, "invalid ecdhe curve '%s'", + curve); + return (-1); + } + + if (curve == NULL || + strcasecmp(curve, "none") == 0 || + strcasecmp(curve, "auto") == 0) + curve = TLS_ECDHE_CURVES; + + return tls_config_set_ecdhecurves(config, curve); +} + +int +tls_config_set_ecdhecurves(struct tls_config *config, const char *curves) +{ + int *curves_list = NULL, *curves_new; + size_t curves_num = 0; + char *cs = NULL; + char *p, *q; + int rv = -1; int nid; - if (name == NULL || strcasecmp(name, "none") == 0) - nid = NID_undef; - else if (strcasecmp(name, "auto") == 0) - nid = -1; - else if ((nid = OBJ_txt2nid(name)) == NID_undef) { - tls_config_set_errorx(config, "invalid ecdhe curve '%s'", name); - return (-1); + free(config->ecdhecurves); + config->ecdhecurves = NULL; + config->ecdhecurves_len = 0; + + if (curves == NULL || strcasecmp(curves, "default") == 0) + curves = TLS_ECDHE_CURVES; + + if ((cs = strdup(curves)) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + + q = cs; + while ((p = strsep(&q, ",:")) != NULL) { + while (*p == ' ' || *p == '\t') + p++; + + nid = OBJ_sn2nid(p); + if (nid == NID_undef) + nid = OBJ_ln2nid(p); + if (nid == NID_undef) + nid = EC_curve_nist2nid(p); + if (nid == NID_undef) { + tls_config_set_errorx(config, + "invalid ecdhe curve '%s'", p); + goto err; + } + + if ((curves_new = reallocarray(curves_list, curves_num + 1, + sizeof(int))) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + curves_list = curves_new; + curves_list[curves_num] = nid; + curves_num++; } - config->ecdhecurve = nid; + config->ecdhecurves = curves_list; + config->ecdhecurves_len = curves_num; + curves_list = NULL; - return (0); + rv = 0; + + err: + free(cs); + free(curves_list); + + return (rv); } int diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h index 6079babccf8..9e9443dbafd 100644 --- a/lib/libtls/tls_internal.h +++ b/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.63 2017/08/09 21:27:24 claudio Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.64 2017/08/10 18:18:30 jsing Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> @@ -33,6 +33,8 @@ __BEGIN_HIDDEN_DECLS #define TLS_CIPHERS_LEGACY "HIGH:MEDIUM:!aNULL" #define TLS_CIPHERS_ALL "ALL:!aNULL:!eNULL" +#define TLS_ECDHE_CURVES "X25519,P-256,P-384" + union tls_addr { struct in_addr ip4; struct in6_addr ip6; @@ -87,7 +89,8 @@ struct tls_config { char *crl_mem; size_t crl_len; int dheparams; - int ecdhecurve; + int *ecdhecurves; + size_t ecdhecurves_len; struct tls_keypair *keypair; int ocsp_require_stapling; uint32_t protocols; diff --git a/lib/libtls/tls_server.c b/lib/libtls/tls_server.c index 394cea1e8db..2622e4464f4 100644 --- a/lib/libtls/tls_server.c +++ b/lib/libtls/tls_server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_server.c,v 1.40 2017/07/05 15:38:35 jsing Exp $ */ +/* $OpenBSD: tls_server.c,v 1.41 2017/08/10 18:18:30 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -241,8 +241,6 @@ static int tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, struct tls_keypair *keypair) { - EC_KEY *ecdh_key; - SSL_CTX_free(*ssl_ctx); if ((*ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) { @@ -283,17 +281,13 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, else if (ctx->config->dheparams == 1024) SSL_CTX_set_dh_auto(*ssl_ctx, 2); - if (ctx->config->ecdhecurve == -1) { + if (ctx->config->ecdhecurves != NULL) { SSL_CTX_set_ecdh_auto(*ssl_ctx, 1); - } else if (ctx->config->ecdhecurve != NID_undef) { - if ((ecdh_key = EC_KEY_new_by_curve_name( - ctx->config->ecdhecurve)) == NULL) { - tls_set_errorx(ctx, "failed to set ECDHE curve"); + if (SSL_CTX_set1_groups(*ssl_ctx, ctx->config->ecdhecurves, + ctx->config->ecdhecurves_len) != 1) { + tls_set_errorx(ctx, "failed to set ecdhe curves"); goto err; } - SSL_CTX_set_options(*ssl_ctx, SSL_OP_SINGLE_ECDH_USE); - SSL_CTX_set_tmp_ecdh(*ssl_ctx, ecdh_key); - EC_KEY_free(ecdh_key); } if (ctx->config->ciphers_server == 1) |