aboutsummaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2012-07-24 13:47:40 +0000
committerDr. Stephen Henson <steve@openssl.org>2012-07-24 13:47:40 +0000
commitd18b716d259d6d3b68ff7f49d154b9158b98df65 (patch)
tree28a92652230c79270f21eae9ae16ab6bbd8beca4 /ssl
parent1e4cb467e1a6ea6925a4f4f2781f864e547ea032 (diff)
downloadopenssl-d18b716d259d6d3b68ff7f49d154b9158b98df65.tar.gz
check EC tmp key matches preferences
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s3_clnt.c14
-rw-r--r--ssl/ssl.h1
-rw-r--r--ssl/ssl_err.c1
-rw-r--r--ssl/ssl_locl.h1
-rw-r--r--ssl/t1_lib.c20
5 files changed, 34 insertions, 3 deletions
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 */