Check our ECDSA cert(s) against supported curves
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index f357b46..144c852 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -490,7 +490,7 @@
     ecdh_context ecdh_ctx;              /*!<  ECDH key exchange       */
 #endif
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
-    int ec_curve;                       /*!<  Selected elliptic curve */
+    const ecp_curve_info **curves;      /*!<  Supported elliptic curves */
 #endif
 #if defined(POLARSSL_X509_CRT_PARSE_C)
     ssl_key_cert *key_cert;             /*!<  Own key/cert in use     */
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 9c90268..df7709b 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -501,9 +501,9 @@
                                                 const unsigned char *buf,
                                                 size_t len )
 {
-    size_t list_size;
+    size_t list_size, our_size;
     const unsigned char *p;
-    const ecp_curve_info *curve_info;
+    const ecp_curve_info *curve_info, **curves;
 
     list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( list_size + 2 != len ||
@@ -513,15 +513,27 @@
         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
+    /* Don't allow our peer to make use allocated too much memory,
+     * and leave room for a final 0 */
+    our_size = list_size / 2 + 1;
+    if( our_size > POLARSSL_ECP_DP_MAX )
+        our_size = POLARSSL_ECP_DP_MAX;
+
+    if( ( curves = polarssl_malloc( our_size * sizeof( *curves ) ) ) == NULL )
+        return( POLARSSL_ERR_SSL_MALLOC_FAILED );
+
+    memset( curves, 0, our_size * sizeof( *curves ) );
+    ssl->handshake->curves = curves;
+
     p = buf + 2;
-    while( list_size > 0 )
+    while( list_size > 0 && our_size > 1 )
     {
         curve_info = ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] );
 
         if( curve_info != NULL )
         {
-            ssl->handshake->ec_curve = curve_info->grp_id;
-            return( 0 );
+            *curves++ = curve_info;
+            our_size--;
         }
 
         list_size -= 2;
@@ -875,6 +887,62 @@
 }
 #endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
 
+#if defined(POLARSSL_X509_CRT_PARSE_C)
+#if defined(POLARSSL_ECDSA_C)
+static int ssl_key_matches_curves( pk_context *pk,
+                                   const ecp_curve_info **curves )
+{
+    const ecp_curve_info **crv = curves;
+    ecp_group_id grp_id = pk_ec( *pk )->grp.id;
+
+    while( *crv != NULL )
+    {
+        if( (*crv)->grp_id == grp_id )
+            return( 1 );
+        crv++;
+    }
+
+    return( 0 );
+}
+#endif /* POLARSSL_ECDSA_C */
+
+/*
+ * Try picking a certificate for this ciphersuite,
+ * return 0 on success and -1 on failure.
+ */
+static int ssl_pick_cert( ssl_context *ssl,
+                          const ssl_ciphersuite_t * ciphersuite_info )
+{
+    ssl_key_cert *cur;
+    pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+
+    if( pk_alg == POLARSSL_PK_NONE )
+        return( 0 );
+
+    for( cur = ssl->key_cert; cur != NULL; cur = cur->next )
+    {
+        if( ! pk_can_do( cur->key, pk_alg ) )
+            continue;
+
+#if defined(POLARSSL_ECDSA_C)
+        if( pk_alg == POLARSSL_PK_ECDSA )
+        {
+            if( ssl_key_matches_curves( cur->key, ssl->handshake->curves ) )
+                break;
+        }
+        else
+#endif
+            break;
+    }
+
+    if( cur == NULL )
+        return( -1 );
+
+    ssl->handshake->key_cert = cur;
+    return( 0 );
+}
+#endif /* POLARSSL_X509_CRT_PARSE_C */
+
 static int ssl_parse_client_hello( ssl_context *ssl )
 {
     int ret;
@@ -888,9 +956,6 @@
     int handshake_failure = 0;
     const int *ciphersuites;
     const ssl_ciphersuite_t *ciphersuite_info;
-#if defined(POLARSSL_PK_C)
-    pk_type_t pk_alg;
-#endif
 
     SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
 
@@ -1298,7 +1363,7 @@
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
                 if( ssl_ciphersuite_uses_ec( ciphersuite_info ) &&
-                    ssl->handshake->ec_curve == 0 )
+                    ssl->handshake->curves[0] == NULL )
                     continue;
 #endif
 
@@ -1310,24 +1375,8 @@
                  * - try the next ciphersuite if we don't
                  * This must be done last since we modify the key_cert list.
                  */
-                pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
-                if( pk_alg != POLARSSL_PK_NONE )
-                {
-                    ssl_key_cert *good = NULL;
-                    ssl_key_cert *cur = ssl->key_cert;
-
-                    while( cur != NULL && good == NULL )
-                    {
-                        if( pk_can_do( cur->key, pk_alg ) )
-                            good = cur;
-                        cur = cur->next;
-                    }
-
-                    if( good == NULL )
-                        continue;
-                    else
-                        ssl->handshake->key_cert = good;
-                }
+                if( ssl_pick_cert( ssl, ciphersuite_info ) != 0 )
+                    continue;
 #endif
 
                 goto have_ciphersuite;
@@ -1928,7 +1977,7 @@
          * } ServerECDHParams;
          */
         if( ( ret = ecp_use_known_dp( &ssl->handshake->ecdh_ctx.grp,
-                                       ssl->handshake->ec_curve ) ) != 0 )
+                                   ssl->handshake->curves[0]->grp_id ) ) != 0 )
         {
             SSL_DEBUG_RET( 1, "ecp_use_known_dp", ret );
             return( ret );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5ab4a5c..cafdcf0 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4145,6 +4145,10 @@
     ecdh_free( &handshake->ecdh_ctx );
 #endif
 
+#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
+    polarssl_free( handshake->curves );
+#endif
+
     memset( handshake, 0, sizeof( ssl_handshake_params ) );
 }