diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2014-09-27 11:01:07 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2014-09-27 11:01:07 +0000 |
commit | 76e0e96d6e94ac6306cc0f272dd692a8e5b9f30e (patch) | |
tree | 3ced5f1f6a8b71ac9b57edfec5002545f22ccdd3 /lib/libssl | |
parent | 2ea787e3aa687189cc5efe11c56b79c57161a236 (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.c | 24 | ||||
-rw-r--r-- | lib/libssl/ssl.h | 3 | ||||
-rw-r--r-- | lib/libssl/ssl_err.c | 3 | ||||
-rw-r--r-- | lib/libssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | lib/libssl/t1_lib.c | 45 |
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. */ |