check EC tmp key matches preferences
authorDr. Stephen Henson <steve@openssl.org>
Tue, 24 Jul 2012 13:47:40 +0000 (13:47 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 24 Jul 2012 13:47:40 +0000 (13:47 +0000)
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 7e9e7c53951253fa8dfec613bcb026dd9a4d0ff2..fafaf6ddb326d68f6894413af6659ffc78803f7b 100644 (file)
--- 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
index b6345b5fa82b596022d889fa75728711d19714b1..11ffabb460c335791c00483defad9326c4479717 100644 (file)
@@ -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);
index ff6dcd7d115017957834ed4e44e069dd86bb73df..09085a23b5e7ae03e82b85628a6a3523fffa2be0 100644 (file)
--- 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
index 93010137274fb0f1b08a7f9379e08d1fe14e4349..665d74fe0474fcf749fab494429b0714c0e1a597 100644 (file)
@@ -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"},
index 7b1c12c66250faadbb1bfb6c20affdac3861b7ca..8b0ea0ee71674be385e8cb5be0baa37bc654ff67 100644 (file)
@@ -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);
index 8093f2c29abc1a2ba8f87dba68351792fff0d2a9..06db730adcab33295c7d748d5afb3491953cd399 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 */