Add CSR write testing using opaque keys

Parse and verify CSR programatically instead of using predetermined data,
to not tamper with randomness in tests.
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 5b54d85..c932c68 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -42,6 +42,10 @@
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 x509_csr_check:"data_files/server5.key":"data_files/server5.req.ku.sha1":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION:0
 
+Certificate Request check opaque Server5 ECDSA, key_usage
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+x509_csr_check_opaque:"data_files/server5.key":MBEDTLS_MD_SHA256:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION:0
+
 Certificate write check Server1 SHA1
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
 x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA1:0:0:1:-1:"data_files/server1.crt":0
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index c00b1ac..f1aeaa0 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -5,6 +5,11 @@
 #include "mbedtls/pem.h"
 #include "mbedtls/oid.h"
 #include "mbedtls/rsa.h"
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
+
 
 #if defined(MBEDTLS_RSA_C)
 int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
@@ -28,6 +33,29 @@
 }
 #endif /* MBEDTLS_RSA_C */
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int x509_crt_verifycsr( const unsigned char *buf, size_t buflen )
+{
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info;
+    mbedtls_x509_csr csr;
+
+    if( mbedtls_x509_csr_parse( &csr, buf, buflen ) != 0 )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    md_info = mbedtls_md_info_from_type( csr.sig_md );
+    if( mbedtls_md( md_info, csr.cri.p, csr.cri.len, hash ) != 0 )
+        return ( MBEDTLS_ERR_X509_BAD_INPUT_DATA );/* Note: this can't happen except after an internal error */
+
+    if( mbedtls_pk_verify_ext( csr.sig_pk, csr.sig_opts, &csr.pk,
+                       csr.sig_md, hash, mbedtls_md_get_size( md_info ),
+                       csr.sig.p, csr.sig.len ) != 0 )
+        return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -95,6 +123,53 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C:MBEDTLS_USE_PSA_CRYPTO */
+void x509_csr_check_opaque( char *key_file, int md_type, int key_usage,
+                                 int cert_type )
+{
+    mbedtls_pk_context key;
+    psa_key_slot_t slot;
+    psa_algorithm_t md_alg_psa;
+    mbedtls_x509write_csr req;
+    unsigned char buf[4096];
+    int ret;
+    size_t pem_len = 0;
+    const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
+    rnd_pseudo_info rnd_info;
+
+    psa_crypto_init();
+    memset( &rnd_info, 0x2a, sizeof( rnd_pseudo_info ) );
+
+    md_alg_psa = mbedtls_psa_translate_md( (mbedtls_md_type_t) md_type );
+    TEST_ASSERT( md_alg_psa != MBEDTLS_MD_NONE );
+    
+    mbedtls_pk_init( &key );
+    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_wrap_as_opaque( &key, &slot, md_alg_psa ) == 0 );
+
+    mbedtls_x509write_csr_init( &req );
+    mbedtls_x509write_csr_set_md_alg( &req, md_type );
+    mbedtls_x509write_csr_set_key( &req, &key );
+    TEST_ASSERT( mbedtls_x509write_csr_set_subject_name( &req, subject_name ) == 0 );
+    if( key_usage != 0 )
+        TEST_ASSERT( mbedtls_x509write_csr_set_key_usage( &req, key_usage ) == 0 );
+    if( cert_type != 0 )
+        TEST_ASSERT( mbedtls_x509write_csr_set_ns_cert_type( &req, cert_type ) == 0 );
+
+    ret = mbedtls_x509write_csr_pem( &req, buf, sizeof( buf ),
+                             rnd_pseudo_rand, &rnd_info );
+    TEST_ASSERT( ret == 0 );
+
+    pem_len = strlen( (char *) buf );
+    buf[pem_len] = '\0';
+    TEST_ASSERT( x509_crt_verifycsr( buf, pem_len+1 ) == 0 );
+
+exit:
+    mbedtls_x509write_csr_free( &req );
+    mbedtls_pk_free( &key );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CRT_WRITE_C:MBEDTLS_SHA1_C */
 void x509_crt_check( char *subject_key_file, char *subject_pwd,
                      char *subject_name, char *issuer_key_file,