From d18b716d259d6d3b68ff7f49d154b9158b98df65 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 24 Jul 2012 13:47:40 +0000 Subject: [PATCH 1/1] check EC tmp key matches preferences --- CHANGES | 3 +++ ssl/s3_clnt.c | 14 +++++++++++--- ssl/ssl.h | 1 + ssl/ssl_err.c | 1 + ssl/ssl_locl.h | 1 + ssl/t1_lib.c | 20 ++++++++++++++++++++ 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 7e9e7c5395..fafaf6ddb3 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] + *) If server EC tmp key is not in client preference list abort handshake. + [Steve Henson] + *) Add support for certificate stores in CERT structure. This makes it possible to have different stores per SSL structure or one store in the parent SSL_CTX. Include distint stores for certificate chain diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index b6345b5fa8..11ffabb460 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -1647,9 +1647,17 @@ int 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)) + /* Check curve is one of our prefrences, if not server has + * sent an invalid curve. + */ + if (!tls1_check_curve(s, p, param_len)) + { + 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/ssl/ssl.h b/ssl/ssl.h index ff6dcd7d11..09085a23b5 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -2764,6 +2764,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/ssl/ssl_err.c b/ssl/ssl_err.c index 9301013727..665d74fe04 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -603,6 +603,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/ssl/ssl_locl.h b/ssl/ssl_locl.h index 7b1c12c662..8b0ea0ee71 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1186,6 +1186,7 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); #ifndef OPENSSL_NO_EC 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); int tls1_shared_curve(SSL *s, int nmatch); int tls1_set_curves(unsigned char **pext, size_t *pextlen, int *curves, size_t ncurves); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 8093f2c29a..06db730adc 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -333,6 +333,21 @@ static void tls1_get_curvelist(SSL *s, int sess, *pcurveslen = sizeof(eccurves_default); } } +/* Check 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; + 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; + } /* Return nth shared curve. If nmatch == -1 return number of * matches. @@ -584,7 +599,12 @@ int tls1_check_ec_tmp_key(SSL *s) } if (!tls1_set_ec_id(curve_id, NULL, ec)) return 0; +/* Set this to allow use of invalid curves for testing */ +#if 0 + return 1; +#else return tls1_check_ec_key(s, curve_id, NULL); +#endif } #endif /* OPENSSL_NO_EC */ -- 2.34.1