Enable SNI test for both tls12 and tls13

Change-Id: Iae5c39668db7caa1a59d7e67f226a5286d91db22
CustomizedGitHooks: yes
Signed-off-by: XiaokangQian <xiaokang.qian@arm.com>
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index e130fa5..25faa06 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -335,6 +335,98 @@
     return( 1 );
 }
 
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/*
+ * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
+ */
+#if defined(MBEDTLS_ECDSA_C)
+static int ssl_check_key_curve( mbedtls_pk_context *pk,
+                                const mbedtls_ecp_curve_info **curves )
+{
+    const mbedtls_ecp_curve_info **crv = curves;
+    mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id;
+
+    while( *crv != NULL )
+    {
+        if( (*crv)->grp_id == grp_id )
+            return( 0 );
+        crv++;
+    }
+
+    return( -1 );
+}
+#endif /* MBEDTLS_ECDSA_C */
+
+/*
+ * Try picking a certificate for this ciphersuite,
+ * return 0 on success and -1 on failure.
+ */
+static int ssl_pick_cert( mbedtls_ssl_context *ssl,
+                          const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
+{
+    mbedtls_ssl_key_cert *cur, *list;
+#if defined(MBEDTLS_ECDSA_C)
+    mbedtls_pk_type_t pk_alg =
+        mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+#endif /* MBEDTLS_ECDSA_C */
+    uint32_t flags;
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    if( ssl->handshake->sni_key_cert != NULL )
+        list = ssl->handshake->sni_key_cert;
+    else
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+        list = ssl->conf->key_cert;
+
+    if( list == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) );
+        return( -1 );
+    }
+
+    for( cur = list; cur != NULL; cur = cur->next )
+    {
+        flags = 0;
+        MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
+                               cur->cert );
+
+        /*
+         * This avoids sending the client a cert it'll reject based on
+         * keyUsage or other extensions.
+         */
+        if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info,
+                                  MBEDTLS_SSL_IS_SERVER, &flags ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
+                                      "(extended) key usage extension" ) );
+            continue;
+        }
+
+#if defined(MBEDTLS_ECDSA_C)
+        if( pk_alg == MBEDTLS_PK_ECDSA &&
+            ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
+            continue;
+        }
+#endif /* MBEDTLS_ECDSA_C */
+
+        break;
+    }
+
+    /* Do not update ssl->handshake->key_cert unless there is a match */
+    if( cur != NULL )
+    {
+        ssl->handshake->key_cert = cur;
+        MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate",
+                               ssl->handshake->key_cert->cert );
+        return( 0 );
+    }
+
+    return( -1 );
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
 /*
  *
  * STATE HANDLING: ClientHello
@@ -699,7 +791,16 @@
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     ssl->handshake->sni_name = NULL;
     ssl->handshake->sni_name_len = 0;
-#endif
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( (ssl_pick_cert( ssl, ssl->handshake->ciphersuite_info ) != 0) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
+                            "no suitable certificate" ) );
+        return( 0 );
+    }
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
 
     /* Update checksum with either
      * - The entire content of the CH message, if no PSK extension is present