From d687ef0a91f405f2fa366d7a356c4af198f10409 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 29 May 2019 13:05:55 +0100 Subject: [PATCH] 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. --- tests/Makefile | 5 +- tests/suites/test_suite_x509parse.data | 20 --- tests/suites/test_suite_x509parse.function | 94 ------------- .../suites/test_suite_x509parse_pthread.data | 19 +++ .../test_suite_x509parse_pthread.function | 125 ++++++++++++++++++ 5 files changed, 148 insertions(+), 115 deletions(-) create mode 100644 tests/suites/test_suite_x509parse_pthread.data create mode 100644 tests/suites/test_suite_x509parse_pthread.function diff --git a/tests/Makefile b/tests/Makefile index 4c784e015..30fbafdff 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -63,6 +63,10 @@ endif # 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 @@ $(EMBEDDED_TESTS): embedded_%: suites/$$(firstword $$(subst ., ,$$*)).function s -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 c2152d9ce..f8d787533 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -2554,23 +2554,3 @@ x509_verify_restart:"data_files/server10_int3-bs.pem":"data_files/test-int-ca2.c 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 ffd9376f9..2df187de0 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -58,44 +58,6 @@ const mbedtls_x509_crt_profile profile_sha512 = 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 @@ exit: } /* 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 000000000..b4b9f0450 --- /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 000000000..2728e9617 --- /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 */