Merge pull request #8942 from valeriosetti/fix-null-dereference

[Bugfix] Fix null dereference in `mbedtls_pk_verify_ext()`
diff --git a/ChangeLog.d/fix-null-dereference-verify-ext.txt b/ChangeLog.d/fix-null-dereference-verify-ext.txt
new file mode 100644
index 0000000..4654178
--- /dev/null
+++ b/ChangeLog.d/fix-null-dereference-verify-ext.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix NULL pointer dereference in mbedtls_pk_verify_ext() when called using
+     an opaque RSA context and specifying MBEDTLS_PK_RSASSA_PSS as key type.
diff --git a/library/pk.c b/library/pk.c
index ec3741b..097777f 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -1126,6 +1126,12 @@
         return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
     }
 
+    /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa()
+     * below would return a NULL pointer. */
+    if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) {
+        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
+    }
+
 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     const mbedtls_pk_rsassa_pss_options *pss_opts;
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 7df9aa9..afc1e34 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -2060,6 +2060,21 @@
                                    sig, sizeof(sig), &sig_len,
                                    mbedtls_test_rnd_std_rand, NULL), 0);
 
+    /* verify_ext() is not supported when using an opaque context. */
+    if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
+        mbedtls_pk_rsassa_pss_options pss_opts = {
+            .mgf1_hash_id = md_alg,
+            .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY,
+        };
+        TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, &pss_opts, &pk, md_alg,
+                                         hash, hash_len, sig, sig_len),
+                   MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE);
+    } else {
+        TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, NULL, &pk, md_alg,
+                                         hash, hash_len, sig, sig_len),
+                   MBEDTLS_ERR_PK_TYPE_MISMATCH);
+    }
+
     mbedtls_pk_free(&pk);
     TEST_EQUAL(PSA_SUCCESS, psa_destroy_key(key_id));