summaryrefslogtreecommitdiff
path: root/lib/libssl
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2014-09-27 11:01:07 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2014-09-27 11:01:07 +0000
commit76e0e96d6e94ac6306cc0f272dd692a8e5b9f30e (patch)
tree3ced5f1f6a8b71ac9b57edfec5002545f22ccdd3 /lib/libssl
parent2ea787e3aa687189cc5efe11c56b79c57161a236 (diff)
Check that the specified curve is one of the client preferences.
Based on OpenSSL. ok miod@
Diffstat (limited to 'lib/libssl')
-rw-r--r--lib/libssl/s3_clnt.c24
-rw-r--r--lib/libssl/ssl.h3
-rw-r--r--lib/libssl/ssl_err.c3
-rw-r--r--lib/libssl/ssl_locl.h3
-rw-r--r--lib/libssl/t1_lib.c45
5 files changed, 70 insertions, 8 deletions
diff --git a/lib/libssl/s3_clnt.c b/lib/libssl/s3_clnt.c
index 1f64091f87e..9aa599a1c6c 100644
--- a/lib/libssl/s3_clnt.c
+++ b/lib/libssl/s3_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_clnt.c,v 1.90 2014/09/19 14:32:23 tedu Exp $ */
+/* $OpenBSD: s3_clnt.c,v 1.91 2014/09/27 11:01:05 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1330,8 +1330,8 @@ ssl3_get_key_exchange(SSL *s)
s->session->sess_cert->peer_dh_tmp = dh;
dh = NULL;
} else if (alg_k & SSL_kECDHE) {
- EC_GROUP *ngroup;
const EC_GROUP *group;
+ EC_GROUP *ngroup;
if ((ecdh = EC_KEY_new()) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
@@ -1351,8 +1351,24 @@ ssl3_get_key_exchange(SSL *s)
* and the ECParameters in this case is just three bytes.
*/
param_len = 3;
- if ((param_len > n) || (*p != NAMED_CURVE_TYPE) ||
- ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) {
+ if (param_len > n) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+
+ /*
+ * Check curve is one of our preferences, if not server has
+ * sent an invalid curve.
+ */
+ if (tls1_check_curve(s, p, param_len) != 1) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE);
+ goto f_err;
+ }
+
+ if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
diff --git a/lib/libssl/ssl.h b/lib/libssl/ssl.h
index 1851cd95259..3b948245f20 100644
--- a/lib/libssl/ssl.h
+++ b/lib/libssl/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.64 2014/09/21 17:11:04 jsing Exp $ */
+/* $OpenBSD: ssl.h,v 1.65 2014/09/27 11:01:06 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2318,6 +2318,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369
#define SSL_R_WRITE_BIO_NOT_SET 260
#define SSL_R_WRONG_CIPHER_RETURNED 261
+#define SSL_R_WRONG_CURVE 378
#define SSL_R_WRONG_MESSAGE_TYPE 262
#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263
#define SSL_R_WRONG_SIGNATURE_LENGTH 264
diff --git a/lib/libssl/ssl_err.c b/lib/libssl/ssl_err.c
index 9abd28bf880..33cd5f2f96f 100644
--- a/lib/libssl/ssl_err.c
+++ b/lib/libssl/ssl_err.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_err.c,v 1.25 2014/06/13 11:52:03 jsing Exp $ */
+/* $OpenBSD: ssl_err.c,v 1.26 2014/09/27 11:01:06 jsing Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@@ -584,6 +584,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {
{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"},
{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) , "write bio not set"},
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) , "wrong cipher returned"},
+ {ERR_REASON(SSL_R_WRONG_CURVE) , "wrong curve"},
{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) , "wrong message type"},
{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h
index 7c1aef68b14..3eee18cbd60 100644
--- a/lib/libssl/ssl_locl.h
+++ b/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.68 2014/09/07 12:16:23 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.69 2014/09/27 11:01:06 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -798,6 +798,7 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
int tls1_ec_curve_id2nid(int curve_id);
int tls1_ec_nid2curve_id(int nid);
+int tls1_check_curve(SSL *s, const unsigned char *p, size_t len);
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p,
unsigned char *limit);
diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c
index 38f7fcfe7b1..20f576e796e 100644
--- a/lib/libssl/t1_lib.c
+++ b/lib/libssl/t1_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_lib.c,v 1.57 2014/09/26 14:58:42 jsing Exp $ */
+/* $OpenBSD: t1_lib.c,v 1.58 2014/09/27 11:01:06 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -364,6 +364,49 @@ tls1_get_formatlist(SSL *s, const unsigned char **pformats, size_t *pformatslen)
}
/*
+ * Return the appropriate curve list. If client_curves is non-zero, return
+ * the client/session curves. Otherwise return the custom curve list if one
+ * exists, or the default curves if a custom list has not been specified.
+ */
+static void
+tls1_get_curvelist(SSL *s, int client_curves, const unsigned char **pcurves,
+ size_t *pcurveslen)
+{
+ if (client_curves != 0) {
+ *pcurves = s->session->tlsext_ellipticcurvelist;
+ *pcurveslen = s->session->tlsext_ellipticcurvelist_length;
+ return;
+ }
+
+ *pcurves = s->tlsext_ellipticcurvelist;
+ *pcurveslen = s->tlsext_ellipticcurvelist_length;
+ if (*pcurves == NULL) {
+ *pcurves = eccurves_default;
+ *pcurveslen = sizeof(eccurves_default);
+ }
+}
+
+/* Check that a curve is one of our preferences. */
+int
+tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
+{
+ const unsigned char *curves;
+ size_t curveslen, i;
+
+ /* Only named curves are supported. */
+ if (len != 3 || p[0] != NAMED_CURVE_TYPE)
+ return (0);
+
+ tls1_get_curvelist(s, 0, &curves, &curveslen);
+
+ for (i = 0; i < curveslen; i += 2, curves += 2) {
+ if (p[1] == curves[0] && p[2] == curves[1])
+ return (1);
+ }
+ return (0);
+}
+
+/*
* List of supported signature algorithms and hashes. Should make this
* customisable at some point, for now include everything we support.
*/