summaryrefslogtreecommitdiff
path: root/lib/libtls
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2017-08-10 18:18:31 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2017-08-10 18:18:31 +0000
commitf0477a05af9bcd65559bababe6e1929c68184bf2 (patch)
treee5f6084eb22d388966785be2c94b3935c6b3fa1f /lib/libtls
parent6c57c8afe3cbcaf5b831c447f6bb299d43e81fdd (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.list1
-rw-r--r--lib/libtls/man/tls_config_set_protocols.319
-rw-r--r--lib/libtls/tls.h5
-rw-r--r--lib/libtls/tls_client.c10
-rw-r--r--lib/libtls/tls_config.c84
-rw-r--r--lib/libtls/tls_internal.h7
-rw-r--r--lib/libtls/tls_server.c16
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)