Move X.509 threading test to separate test suite

This allows to build the library + tests via `make` without
specifying `PTHREAD=1`, in which case the X.509 threading
test suite will be silently dropped.

This is analogous to the pre-existing handling of the example
application `ssl_pthread_server`, which is only build if `PTHREAD=1`
and silently dropped otherwise.
diff --git a/tests/Makefile b/tests/Makefile
index 4c784e0..30fbafd 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -63,6 +63,10 @@
 # constructed by stripping path 'suites/' and extension .data.
 APPS = $(basename $(subst suites/,,$(wildcard suites/test_suite_*.data)))
 
+ifndef PTHREAD
+APPS := $(filter-out test_suite_x509parse_pthread, $(APPS))
+endif
+
 # Construct executable name by adding OS specific suffix $(EXEXT).
 BINARIES := $(addsuffix $(EXEXT),$(APPS))
 
@@ -141,4 +145,3 @@
 		-o ./TESTS/mbedtls/$*
 
 generate-target-tests: $(EMBEDDED_TESTS)
-
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index c2152d9..f8d7875 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -2554,23 +2554,3 @@
 X509 CRT verify restart: one int, int badsign, max_ops=500
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_RSA_C
 x509_verify_restart:"data_files/server10_int3-bs.pem":"data_files/test-int-ca2.crt":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_NOT_TRUSTED:500:25:100
-
-X509 CRT concurrent verification #1 (RSA cert, RSA CA)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
-x509_verify_thread:"data_files/server1.crt":"data_files/test-ca.crt":0:0:100:10
-
-X509 CRT concurrent verification #2 (EC cert, RSA CA)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
-x509_verify_thread:"data_files/server3.crt":"data_files/test-ca.crt":0:0:100:10
-
-X509 CRT concurrent verification #3 (RSA cert, EC CA)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-x509_verify_thread:"data_files/server4.crt":"data_files/test-ca2.crt":0:0:100:10
-
-X509 CRT concurrent verification #4 (EC cert, EC CA)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-x509_verify_thread:"data_files/server5.crt":"data_files/test-ca2.crt":0:0:100:10
-
-X509 CRT concurrent verification #5 (RSA cert, RSA CA, RSASSA-PSS)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_SHA1_C
-x509_verify_thread:"data_files/server9-with-ca.crt":"data_files/test-ca.crt":0:0:100:10
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index ffd9376..2df187d 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -58,44 +58,6 @@
     1024,
 };
 
-
-typedef struct
-{
-    mbedtls_x509_crt *crt;
-    mbedtls_x509_crt *ca;
-    uint32_t expected_flags;
-    unsigned id;
-    int expected_result;
-    int iter_total;
-    int result;
-} x509_verify_thread_ctx;
-
-void* x509_verify_thread_worker( void *p )
-{
-    unsigned iter_cnt;
-    x509_verify_thread_ctx *ctx = (x509_verify_thread_ctx *) p;
-
-    for( iter_cnt=0; iter_cnt < (unsigned) ctx->iter_total; iter_cnt++ )
-    {
-        uint32_t flags;
-        int res;
-
-        res = mbedtls_x509_crt_verify_with_profile( ctx->crt, ctx->ca,
-                                                    NULL, &compat_profile,
-                                                    NULL, &flags, NULL, NULL );
-        if( res   != ctx->expected_result ||
-            flags != ctx->expected_flags )
-        {
-            ctx->result = 1;
-            pthread_exit( NULL );
-        }
-    }
-
-    ctx->result = 0;
-    pthread_exit( NULL );
-    return( NULL );
-}
-
 int verify_none( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags )
 {
     ((void) data);
@@ -390,62 +352,6 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
-void x509_verify_thread( char *crt_file, char *ca_file,
-                         int result, int flags_result,
-                         int thread_total,
-                         int iterations_per_thread )
-{
-    x509_verify_thread_ctx *thread_ctx;
-    pthread_t *threads;
-    int cur_thread;
-
-    mbedtls_x509_crt crt;
-    mbedtls_x509_crt ca;
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-    TEST_ASSERT( psa_crypto_init() == 0 );
-#endif
-
-    mbedtls_x509_crt_init( &crt );
-    mbedtls_x509_crt_init( &ca );
-    threads = mbedtls_calloc( thread_total, sizeof( pthread_t ) );
-    thread_ctx = mbedtls_calloc( thread_total, sizeof( x509_verify_thread_ctx ) );
-
-    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
-    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
-    TEST_ASSERT( threads != NULL );
-
-    /* Start all verify threads */
-    for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
-    {
-        thread_ctx[ cur_thread ].id = (unsigned) cur_thread;
-        thread_ctx[ cur_thread ].ca  = &ca;
-        thread_ctx[ cur_thread ].crt = &crt;
-        thread_ctx[ cur_thread ].expected_result = result;
-        thread_ctx[ cur_thread ].expected_flags = flags_result;
-        thread_ctx[ cur_thread ].iter_total = iterations_per_thread;
-        TEST_ASSERT( pthread_create( &threads[ cur_thread ], NULL,
-                                     &x509_verify_thread_worker,
-                                     &thread_ctx[ cur_thread ] ) == 0 );
-    }
-
-    /* Wait for all threads to complete */
-    for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
-        TEST_ASSERT( pthread_join( threads[ cur_thread ], NULL ) == 0 );
-
-    /* Check their results */
-    for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
-        TEST_ASSERT( thread_ctx[ cur_thread ].result == 0 );
-
-exit:
-    mbedtls_free( threads );
-    mbedtls_free( thread_ctx );
-    mbedtls_x509_crt_free( &crt );
-    mbedtls_x509_crt_free( &ca );
-}
-/* END_CASE */
-
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_CRL_PARSE_C */
 void x509_verify( char *crt_file, char *ca_file, char *crl_file,
                   char *cn_name_str, int result, int flags_result,
diff --git a/tests/suites/test_suite_x509parse_pthread.data b/tests/suites/test_suite_x509parse_pthread.data
new file mode 100644
index 0000000..b4b9f04
--- /dev/null
+++ b/tests/suites/test_suite_x509parse_pthread.data
@@ -0,0 +1,19 @@
+X509 CRT concurrent verification #1 (RSA cert, RSA CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
+x509_verify_thread:"data_files/server1.crt":"data_files/test-ca.crt":0:0:100:10
+
+X509 CRT concurrent verification #2 (EC cert, RSA CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
+x509_verify_thread:"data_files/server3.crt":"data_files/test-ca.crt":0:0:100:10
+
+X509 CRT concurrent verification #3 (RSA cert, EC CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+x509_verify_thread:"data_files/server4.crt":"data_files/test-ca2.crt":0:0:100:10
+
+X509 CRT concurrent verification #4 (EC cert, EC CA)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+x509_verify_thread:"data_files/server5.crt":"data_files/test-ca2.crt":0:0:100:10
+
+X509 CRT concurrent verification #5 (RSA cert, RSA CA, RSASSA-PSS)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_SHA1_C
+x509_verify_thread:"data_files/server9-with-ca.crt":"data_files/test-ca.crt":0:0:100:10
diff --git a/tests/suites/test_suite_x509parse_pthread.function b/tests/suites/test_suite_x509parse_pthread.function
new file mode 100644
index 0000000..2728e96
--- /dev/null
+++ b/tests/suites/test_suite_x509parse_pthread.function
@@ -0,0 +1,125 @@
+/* BEGIN_HEADER */
+#include "mbedtls/bignum.h"
+#include "mbedtls/x509.h"
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/x509_crl.h"
+#include "mbedtls/x509_csr.h"
+#include "mbedtls/x509_internal.h"
+#include "mbedtls/pem.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/base64.h"
+#include "string.h"
+
+/* Profile for backward compatibility. Allows SHA-1, unlike the default
+   profile. */
+const mbedtls_x509_crt_profile compat_profile =
+{
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
+    0xFFFFFFF, /* Any PK alg    */
+    0xFFFFFFF, /* Any curve     */
+    1024,
+};
+
+typedef struct
+{
+    mbedtls_x509_crt *crt;
+    mbedtls_x509_crt *ca;
+    uint32_t expected_flags;
+    unsigned id;
+    int expected_result;
+    int iter_total;
+    int result;
+} x509_verify_thread_ctx;
+
+void* x509_verify_thread_worker( void *p )
+{
+    unsigned iter_cnt;
+    x509_verify_thread_ctx *ctx = (x509_verify_thread_ctx *) p;
+
+    for( iter_cnt=0; iter_cnt < (unsigned) ctx->iter_total; iter_cnt++ )
+    {
+        uint32_t flags;
+        int res;
+
+        res = mbedtls_x509_crt_verify_with_profile( ctx->crt, ctx->ca,
+                                                    NULL, &compat_profile,
+                                                    NULL, &flags, NULL, NULL );
+        if( res   != ctx->expected_result ||
+            flags != ctx->expected_flags )
+        {
+            ctx->result = 1;
+            pthread_exit( NULL );
+        }
+    }
+
+    ctx->result = 0;
+    pthread_exit( NULL );
+    return( NULL );
+}
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_X509_CRT_PARSE_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
+void x509_verify_thread( char *crt_file, char *ca_file,
+                         int result, int flags_result,
+                         int thread_total,
+                         int iterations_per_thread )
+{
+    x509_verify_thread_ctx *thread_ctx;
+    pthread_t *threads;
+    int cur_thread;
+
+    mbedtls_x509_crt crt;
+    mbedtls_x509_crt ca;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    TEST_ASSERT( psa_crypto_init() == 0 );
+#endif
+
+    mbedtls_x509_crt_init( &crt );
+    mbedtls_x509_crt_init( &ca );
+    threads = mbedtls_calloc( thread_total, sizeof( pthread_t ) );
+    thread_ctx = mbedtls_calloc( thread_total, sizeof( x509_verify_thread_ctx ) );
+
+    TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
+    TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
+    TEST_ASSERT( threads != NULL );
+
+    /* Start all verify threads */
+    for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
+    {
+        thread_ctx[ cur_thread ].id = (unsigned) cur_thread;
+        thread_ctx[ cur_thread ].ca  = &ca;
+        thread_ctx[ cur_thread ].crt = &crt;
+        thread_ctx[ cur_thread ].expected_result = result;
+        thread_ctx[ cur_thread ].expected_flags = flags_result;
+        thread_ctx[ cur_thread ].iter_total = iterations_per_thread;
+        TEST_ASSERT( pthread_create( &threads[ cur_thread ], NULL,
+                                     &x509_verify_thread_worker,
+                                     &thread_ctx[ cur_thread ] ) == 0 );
+    }
+
+    /* Wait for all threads to complete */
+    for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
+        TEST_ASSERT( pthread_join( threads[ cur_thread ], NULL ) == 0 );
+
+    /* Check their results */
+    for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
+        TEST_ASSERT( thread_ctx[ cur_thread ].result == 0 );
+
+exit:
+    mbedtls_free( threads );
+    mbedtls_free( thread_ctx );
+    mbedtls_x509_crt_free( &crt );
+    mbedtls_x509_crt_free( &ca );
+}
+/* END_CASE */