Make mbedtls_ssl_check_cert_usage() work for 1.3

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 40d7187..ecb2d03 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1678,6 +1678,8 @@
  * keyUsage and extendedKeyUsage.
  * (Note: nSCertType is deprecated and not standard, we don't check it.)
  *
+ * Note: if tls_version is 1.3, ciphersuite is ignored and can be NULL.
+ *
  * Note: recv_endpoint is the receiver's endpoint.
  *
  * Return 0 if everything is OK, -1 if not.
@@ -1686,6 +1688,7 @@
 int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
                                  const mbedtls_ssl_ciphersuite_t *ciphersuite,
                                  int recv_endpoint,
+                                 mbedtls_ssl_protocol_version tls_version,
                                  uint32_t *flags);
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4376146..3f375be 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -6362,6 +6362,7 @@
 int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
                                  const mbedtls_ssl_ciphersuite_t *ciphersuite,
                                  int recv_endpoint,
+                                 mbedtls_ssl_protocol_version tls_version,
                                  uint32_t *flags)
 {
     int ret = 0;
@@ -6369,11 +6370,17 @@
     const char *ext_oid;
     size_t ext_len;
 
+    /*
+     * keyUsage
+     */
+
     /* Note: don't guard this with MBEDTLS_SSL_CLI_C because the server wants
      * to check what a compliant client will think while choosing which cert
      * to send to the client. */
-    if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
-        /* Server part of the key exchange */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2 &&
+        recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
+        /* TLS 1.2 server part of the key exchange */
         switch (ciphersuite->key_exchange) {
             case MBEDTLS_KEY_EXCHANGE_RSA:
             case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
@@ -6399,8 +6406,14 @@
             case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
                 usage = 0;
         }
-    } else {
-        /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
+    } else
+#endif
+    {
+        /* This is either TLS 1.3 autentication, which always uses signatures,
+         * or 1.2 client auth: rsa_sign and mbedtls_ecdsa_sign are the only
+         * options we implement, both using signatures. */
+        (void) tls_version;
+        (void) ciphersuite;
         usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
     }
 
@@ -6409,6 +6422,10 @@
         ret = -1;
     }
 
+    /*
+     * extKeyUsage
+     */
+
     if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
         ext_oid = MBEDTLS_OID_SERVER_AUTH;
         ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
@@ -8065,6 +8082,7 @@
     if (mbedtls_ssl_check_cert_usage(chain,
                                      ciphersuite_info,
                                      ssl->conf->endpoint,
+                                     MBEDTLS_SSL_VERSION_TLS1_2,
                                      &ssl->session_negotiate->verify_result) != 0) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
         if (ret == 0) {
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 5bfab04..0878749 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -756,7 +756,9 @@
          * and decrypting with the same RSA key.
          */
         if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info,
-                                         MBEDTLS_SSL_IS_CLIENT, &flags) != 0) {
+                                         MBEDTLS_SSL_IS_CLIENT,
+                                         MBEDTLS_SSL_VERSION_TLS1_2,
+                                         &flags) != 0) {
             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: "
                                       "(extended) key usage extension"));
             continue;
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index 651a17b..8d8af2b 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -631,8 +631,6 @@
     int authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
     mbedtls_x509_crt *ca_chain;
     mbedtls_x509_crl *ca_crl;
-    const char *ext_oid;
-    size_t ext_len;
     uint32_t verify_result = 0;
 
     /* If SNI was used, overwrite authentication mode
@@ -714,34 +712,15 @@
     /*
      * Secondary checks: always done, but change 'ret' only if it was 0
      */
-    /* keyUsage */
-    if ((mbedtls_x509_crt_check_key_usage(
-             ssl->session_negotiate->peer_cert,
-             MBEDTLS_X509_KU_DIGITAL_SIGNATURE) != 0)) {
+    if (mbedtls_ssl_check_cert_usage(ssl->session_negotiate->peer_cert,
+                                     NULL,
+                                     ssl->conf->endpoint,
+                                     MBEDTLS_SSL_VERSION_TLS1_3,
+                                     &verify_result) != 0) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
         if (ret == 0) {
             ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
         }
-        verify_result |= MBEDTLS_X509_BADCERT_KEY_USAGE;
-    }
-
-    /* extKeyUsage */
-    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-        ext_oid = MBEDTLS_OID_SERVER_AUTH;
-        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
-    } else {
-        ext_oid = MBEDTLS_OID_CLIENT_AUTH;
-        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
-    }
-
-    if ((mbedtls_x509_crt_check_extended_key_usage(
-             ssl->session_negotiate->peer_cert,
-             ext_oid, ext_len) != 0)) {
-        MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
-        if (ret == 0) {
-            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
-        }
-        verify_result |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
     }
 
     /* mbedtls_x509_crt_verify_with_profile is supposed to report a