check EC tmp key matches preferences
diff --git a/CHANGES b/CHANGES index 7e9e7c5..fafaf6d 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 b6345b5..11ffabb 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c
@@ -1647,9 +1647,17 @@ * 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 ff6dcd7..09085a2 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h
@@ -2764,6 +2764,7 @@ #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 9301013..665d74f 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c
@@ -603,6 +603,7 @@ {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 7b1c12c..8b0ea0e 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h
@@ -1186,6 +1186,7 @@ #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 8093f2c..06db730 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -333,6 +333,21 @@ *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 @@ } 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 */