check EC tmp key matches preferences
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 15:27:04 +0000 (15:27 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 15:27:04 +0000 (15:27 +0000)
(backport from HEAD)

CHANGES
ssl/s3_clnt.c
ssl/ssl.h
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/t1_lib.c

diff --git a/CHANGES b/CHANGES
index 7b58b296032e6a766c35cffdc2596e83251c0c5a..df99053807229d7272796dc40ca083d2f1cb6972 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,9 @@
      OID NID.
      [Steve Henson]
 
+  *) 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
index 4c1967ea01944098c9056409689dc1e0b386796b..a5f3d02b4c5c4d7cbd4d0d355b44c59e85d91a09 100644 (file)
@@ -1648,9 +1648,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);
index e9ed52bb41a370dfa5023d5657b836ba5485da0c..d399fbc971d424a2da5a5c2a1dbf73d16315cd36 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2745,6 +2745,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
index 99192e918288a0ee063426a55a4a2eda4211af15..d3429403df3982b734d68637d2c068b617b9e8e0 100644 (file)
@@ -604,6 +604,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"},
index 874d12b3b9e7b38d1d3b40c9107e86278c94ab75..2e021450823e864324444f7ba360a48b68e7ade4 100644 (file)
@@ -1188,6 +1188,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);
index d84c24df8f1c70a3890698d8494e441043c7942e..101cfa12a6515a2e1a465f958d7f49e9d4319162 100644 (file)
@@ -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 */