diff --git a/programs/.gitignore b/programs/.gitignore index 88fb9d52b..33593e0e8 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -1,7 +1,13 @@ +# Ignore makefiles generated by CMake, but not the makefile that's checked in. */Makefile +!fuzz/Makefile + *.sln *.vcxproj +*.o +*.exe + aes/aescrypt2 aes/crypt_and_hash hash/generic_sum diff --git a/programs/Makefile b/programs/Makefile index 9cbc47167..e0a324f1e 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -267,21 +267,32 @@ ssl/ssl_client1$(EXEXT): ssl/ssl_client1.c $(DEP) echo " CC ssl/ssl_client1.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client1.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -ssl/ssl_client2$(EXEXT): ssl/ssl_client2.c test/query_config.c $(DEP) +SSL_TEST_OBJECTS = test/query_config.o ssl/ssl_test_lib.o +SSL_TEST_DEPS = $(SSL_TEST_OBJECTS) \ + test/query_config.h \ + ssl/ssl_test_lib.h \ + ssl/ssl_test_common_source.c \ + $(DEP) + +ssl/ssl_test_lib.o: ssl/ssl_test_lib.c ssl/ssl_test_lib.h $(DEP) + echo " CC ssl/ssl_test_lib.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c ssl/ssl_test_lib.c -o $@ + +ssl/ssl_client2$(EXEXT): ssl/ssl_client2.c $(SSL_TEST_DEPS) echo " CC ssl/ssl_client2.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client2.c $(SSL_TEST_OBJECTS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ ssl/ssl_server$(EXEXT): ssl/ssl_server.c $(DEP) echo " CC ssl/ssl_server.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -ssl/ssl_server2$(EXEXT): ssl/ssl_server2.c test/query_config.c $(DEP) +ssl/ssl_server2$(EXEXT): ssl/ssl_server2.c $(SSL_TEST_DEPS) echo " CC ssl/ssl_server2.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c $(SSL_TEST_OBJECTS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -ssl/ssl_context_info$(EXEXT): ssl/ssl_context_info.c test/query_config.c $(DEP) +ssl/ssl_context_info$(EXEXT): ssl/ssl_context_info.c test/query_config.o test/query_config.h $(DEP) echo " CC ssl/ssl_context_info.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_context_info.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_context_info.c test/query_config.o $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ ssl/ssl_fork_server$(EXEXT): ssl/ssl_fork_server.c $(DEP) echo " CC ssl/ssl_fork_server.c" @@ -307,6 +318,10 @@ test/cpp_dummy_build$(EXEXT): test/cpp_dummy_build.cpp $(DEP) echo " CXX test/cpp_dummy_build.cpp" $(CXX) $(LOCAL_CXXFLAGS) $(CXXFLAGS) test/cpp_dummy_build.cpp $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test/query_config.o: test/query_config.c test/query_config.h $(DEP) + echo " CC test/query_config.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c test/query_config.c -o $@ + test/selftest$(EXEXT): test/selftest.c $(DEP) echo " CC test/selftest.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/selftest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ @@ -319,9 +334,9 @@ test/zeroize$(EXEXT): test/zeroize.c $(DEP) echo " CC test/zeroize.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/zeroize.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -test/query_compile_time_config$(EXEXT): test/query_compile_time_config.c test/query_config.c $(DEP) +test/query_compile_time_config$(EXEXT): test/query_compile_time_config.c test/query_config.o test/query_config.h $(DEP) echo " CC test/query_compile_time_config.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_compile_time_config.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_compile_time_config.c test/query_config.o $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ util/pem2der$(EXEXT): util/pem2der.c $(DEP) echo " CC util/pem2der.c" diff --git a/programs/fuzz/.gitignore b/programs/fuzz/.gitignore index 6fcc004b7..5dc096055 100644 --- a/programs/fuzz/.gitignore +++ b/programs/fuzz/.gitignore @@ -1,4 +1,3 @@ -*.o fuzz_client fuzz_dtlsclient fuzz_dtlsserver diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt index 149aa303b..e4038f7b3 100644 --- a/programs/ssl/CMakeLists.txt +++ b/programs/ssl/CMakeLists.txt @@ -32,8 +32,10 @@ foreach(exe IN LISTS executables) target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include) endforeach() -set_property(TARGET ssl_client2 APPEND PROPERTY SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c) -set_property(TARGET ssl_server2 APPEND PROPERTY SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c) +set_property(TARGET ssl_client2 APPEND PROPERTY SOURCES + ssl_test_lib.c ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c) +set_property(TARGET ssl_server2 APPEND PROPERTY SOURCES + ssl_test_lib.c ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c) if(THREADS_FOUND) add_executable(ssl_pthread_server ssl_pthread_server.c $) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 1ddfb804c..0f0e93e07 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -17,68 +17,21 @@ * limitations under the License. */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif +#include "ssl_test_lib.h" -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_time time -#define mbedtls_time_t time_t -#define mbedtls_printf printf -#define mbedtls_fprintf fprintf -#define mbedtls_snprintf snprintf -#define mbedtls_calloc calloc -#define mbedtls_free free -#define mbedtls_exit exit -#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS -#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE -#endif - -#if !defined(MBEDTLS_ENTROPY_C) || \ - !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \ - !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C) || \ - defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) +#if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) int main( void ) { - mbedtls_printf( "MBEDTLS_ENTROPY_C and/or " - "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or " - "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined " - " and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n" ); + mbedtls_printf( MBEDTLS_SSL_TEST_IMPOSSIBLE ); mbedtls_exit( 0 ); } -#else - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#include "mbedtls/memory_buffer_alloc.h" -#endif - -#include "mbedtls/net_sockets.h" -#include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/certs.h" -#include "mbedtls/x509.h" -#include "mbedtls/error.h" -#include "mbedtls/debug.h" -#include "mbedtls/timing.h" -#include "mbedtls/base64.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif - -#include - -#include -#include -#include +#elif !defined(MBEDTLS_SSL_CLI_C) +int main( void ) +{ + mbedtls_printf( "MBEDTLS_SSL_CLI_C not defined.\n" ); + mbedtls_exit( 0 ); +} +#else /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_CLI_C */ /* Size of memory to be allocated for the heap, when using the library's memory * management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled. */ @@ -568,425 +521,7 @@ struct options const char *mki; /* The dtls mki value to use */ } opt; -int query_config( const char *config ); - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -typedef struct eap_tls_keys -{ - unsigned char master_secret[48]; - unsigned char randbytes[64]; - mbedtls_tls_prf_types tls_prf_type; -} eap_tls_keys; - -static int eap_tls_key_derivation ( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) -{ - eap_tls_keys *keys = (eap_tls_keys *)p_expkey; - - ( ( void ) kb ); - memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); - memcpy( keys->randbytes, client_random, 32 ); - memcpy( keys->randbytes + 32, server_random, 32 ); - keys->tls_prf_type = tls_prf_type; - - if( opt.debug_level > 2 ) - { - mbedtls_printf("exported maclen is %u\n", (unsigned)maclen); - mbedtls_printf("exported keylen is %u\n", (unsigned)keylen); - mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen); - } - return( 0 ); -} - -static int nss_keylog_export( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) -{ - char nss_keylog_line[ 200 ]; - size_t const client_random_len = 32; - size_t const master_secret_len = 48; - size_t len = 0; - size_t j; - int ret = 0; - - ((void) p_expkey); - ((void) kb); - ((void) maclen); - ((void) keylen); - ((void) ivlen); - ((void) server_random); - ((void) tls_prf_type); - - len += sprintf( nss_keylog_line + len, - "%s", "CLIENT_RANDOM " ); - - for( j = 0; j < client_random_len; j++ ) - { - len += sprintf( nss_keylog_line + len, - "%02x", client_random[j] ); - } - - len += sprintf( nss_keylog_line + len, " " ); - - for( j = 0; j < master_secret_len; j++ ) - { - len += sprintf( nss_keylog_line + len, - "%02x", ms[j] ); - } - - len += sprintf( nss_keylog_line + len, "\n" ); - nss_keylog_line[ len ] = '\0'; - - mbedtls_printf( "\n" ); - mbedtls_printf( "---------------- NSS KEYLOG -----------------\n" ); - mbedtls_printf( "%s", nss_keylog_line ); - mbedtls_printf( "---------------------------------------------\n" ); - - if( opt.nss_keylog_file != NULL ) - { - FILE *f; - - if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL ) - { - ret = -1; - goto exit; - } - - if( fwrite( nss_keylog_line, 1, len, f ) != len ) - { - ret = -1; - fclose( f ); - goto exit; - } - - fclose( f ); - } - -exit: - mbedtls_platform_zeroize( nss_keylog_line, - sizeof( nss_keylog_line ) ); - return( ret ); -} - -#if defined( MBEDTLS_SSL_DTLS_SRTP ) -/* Supported SRTP mode needs a maximum of : - * - 16 bytes for key (AES-128) - * - 14 bytes SALT - * One for sender, one for receiver context - */ -#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60 -typedef struct dtls_srtp_keys -{ - unsigned char master_secret[48]; - unsigned char randbytes[64]; - mbedtls_tls_prf_types tls_prf_type; -} dtls_srtp_keys; - -static int dtls_srtp_key_derivation( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) -{ - dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; - - ( ( void ) kb ); - memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); - memcpy( keys->randbytes, client_random, 32 ); - memcpy( keys->randbytes + 32, server_random, 32 ); - keys->tls_prf_type = tls_prf_type; - - if( opt.debug_level > 2 ) - { - mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen ); - mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen ); - mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen ); - } - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - -static void my_debug( void *ctx, int level, - const char *file, int line, - const char *str ) -{ - const char *p, *basename; - - /* Extract basename from file */ - for( p = basename = file; *p != '\0'; p++ ) - if( *p == '/' || *p == '\\' ) - basename = p + 1; - - mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", - basename, line, level, str ); - fflush( (FILE *) ctx ); -} - - -mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) -{ - (void) time; - return 0x5af2a056; -} - -int dummy_entropy( void *data, unsigned char *output, size_t len ) -{ - size_t i; - int ret; - (void) data; - - ret = mbedtls_entropy_func( data, output, len ); - for ( i = 0; i < len; i++ ) - { - //replace result with pseudo random - output[i] = (unsigned char) rand(); - } - return( ret ); -} - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -int ca_callback( void *data, mbedtls_x509_crt const *child, - mbedtls_x509_crt **candidates ) -{ - int ret = 0; - mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data; - mbedtls_x509_crt *first; - - /* This is a test-only implementation of the CA callback - * which always returns the entire list of trusted certificates. - * Production implementations managing a large number of CAs - * should use an efficient presentation and lookup for the - * set of trusted certificates (such as a hashtable) and only - * return those trusted certificates which satisfy basic - * parental checks, such as the matching of child `Issuer` - * and parent `Subject` field or matching key identifiers. */ - ((void) child); - - first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - if( first == NULL ) - { - ret = -1; - goto exit; - } - mbedtls_x509_crt_init( first ); - - if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 ) - { - ret = -1; - goto exit; - } - - while( ca->next != NULL ) - { - ca = ca->next; - if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 ) - { - ret = -1; - goto exit; - } - } - -exit: - - if( ret != 0 ) - { - mbedtls_x509_crt_free( first ); - mbedtls_free( first ); - first = NULL; - } - - *candidates = first; - return( ret ); -} -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -/* - * Test recv/send functions that make sure each try returns - * WANT_READ/WANT_WRITE at least once before sucesseding - */ - -static int delayed_recv( void *ctx, unsigned char *buf, size_t len ) -{ - static int first_try = 1; - int ret; - - if( first_try ) - { - first_try = 0; - return( MBEDTLS_ERR_SSL_WANT_READ ); - } - - ret = mbedtls_net_recv( ctx, buf, len ); - if( ret != MBEDTLS_ERR_SSL_WANT_READ ) - first_try = 1; /* Next call will be a new operation */ - return( ret ); -} - -static int delayed_send( void *ctx, const unsigned char *buf, size_t len ) -{ - static int first_try = 1; - int ret; - - if( first_try ) - { - first_try = 0; - return( MBEDTLS_ERR_SSL_WANT_WRITE ); - } - - ret = mbedtls_net_send( ctx, buf, len ); - if( ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - first_try = 1; /* Next call will be a new operation */ - return( ret ); -} - -typedef struct -{ - mbedtls_ssl_context *ssl; - mbedtls_net_context *net; -} io_ctx_t; - -#if defined(MBEDTLS_SSL_RECORD_CHECKING) -static int ssl_check_record( mbedtls_ssl_context const *ssl, - unsigned char const *buf, size_t len ) -{ - int ret; - unsigned char *tmp_buf; - - tmp_buf = mbedtls_calloc( 1, len ); - if( tmp_buf == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - memcpy( tmp_buf, buf, len ); - - ret = mbedtls_ssl_check_record( ssl, tmp_buf, len ); - if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ) - { - int ret_repeated; - - /* Test-only: Make sure that mbedtls_ssl_check_record() - * doesn't alter state. */ - memcpy( tmp_buf, buf, len ); /* Restore buffer */ - ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len ); - if( ret != ret_repeated ) - { - mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" ); - return( -1 ); - } - - switch( ret ) - { - case 0: - break; - - case MBEDTLS_ERR_SSL_INVALID_RECORD: - if( opt.debug_level > 1 ) - mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" ); - break; - - case MBEDTLS_ERR_SSL_INVALID_MAC: - if( opt.debug_level > 1 ) - mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" ); - break; - - case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD: - if( opt.debug_level > 1 ) - mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" ); - break; - - default: - mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", (unsigned int) -ret ); - return( -1 ); - } - - /* Regardless of the outcome, forward the record to the stack. */ - } - - mbedtls_free( tmp_buf ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - -static int recv_cb( void *ctx, unsigned char *buf, size_t len ) -{ - io_ctx_t *io_ctx = (io_ctx_t*) ctx; - size_t recv_len; - int ret; - - if( opt.nbio == 2 ) - ret = delayed_recv( io_ctx->net, buf, len ); - else - ret = mbedtls_net_recv( io_ctx->net, buf, len ); - if( ret < 0 ) - return( ret ); - recv_len = (size_t) ret; - - if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Here's the place to do any datagram/record checking - * in between receiving the packet from the underlying - * transport and passing it on to the TLS stack. */ -#if defined(MBEDTLS_SSL_RECORD_CHECKING) - if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 ) - return( -1 ); -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - } - - return( (int) recv_len ); -} - -static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ) -{ - io_ctx_t *io_ctx = (io_ctx_t*) ctx; - int ret; - size_t recv_len; - - ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout ); - if( ret < 0 ) - return( ret ); - recv_len = (size_t) ret; - - if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Here's the place to do any datagram/record checking - * in between receiving the packet from the underlying - * transport and passing it on to the TLS stack. */ -#if defined(MBEDTLS_SSL_RECORD_CHECKING) - if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 ) - return( -1 ); -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - } - - return( (int) recv_len ); -} - -static int send_cb( void *ctx, unsigned char const *buf, size_t len ) -{ - io_ctx_t *io_ctx = (io_ctx_t*) ctx; - - if( opt.nbio == 2 ) - return( delayed_send( io_ctx->net, buf, len ) ); - - return( mbedtls_net_send( io_ctx->net, buf, len ) ); -} +#include "ssl_test_common_source.c" #if defined(MBEDTLS_X509_CRT_PARSE_C) static unsigned char peer_crt_info[1024]; @@ -1020,75 +555,8 @@ static int my_verify( void *data, mbedtls_x509_crt *crt, return( 0 ); } - -static int ssl_sig_hashes_for_test[] = { -#if defined(MBEDTLS_SHA512_C) - MBEDTLS_MD_SHA512, - MBEDTLS_MD_SHA384, -#endif -#if defined(MBEDTLS_SHA256_C) - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA224, -#endif -#if defined(MBEDTLS_SHA1_C) - /* Allow SHA-1 as we use it extensively in tests. */ - MBEDTLS_MD_SHA1, -#endif - MBEDTLS_MD_NONE -}; #endif /* MBEDTLS_X509_CRT_PARSE_C */ -/* - * Wait for an event from the underlying transport or the timer - * (Used in event-driven IO mode). - */ -#if !defined(MBEDTLS_TIMING_C) -int idle( mbedtls_net_context *fd, - int idle_reason ) -#else -int idle( mbedtls_net_context *fd, - mbedtls_timing_delay_context *timer, - int idle_reason ) -#endif -{ - - int ret; - int poll_type = 0; - - if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE ) - poll_type = MBEDTLS_NET_POLL_WRITE; - else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ ) - poll_type = MBEDTLS_NET_POLL_READ; -#if !defined(MBEDTLS_TIMING_C) - else - return( 0 ); -#endif - - while( 1 ) - { - /* Check if timer has expired */ -#if defined(MBEDTLS_TIMING_C) - if( timer != NULL && - mbedtls_timing_get_delay( timer ) == 2 ) - { - break; - } -#endif /* MBEDTLS_TIMING_C */ - - /* Check if underlying transport became available */ - if( poll_type != 0 ) - { - ret = mbedtls_net_poll( fd, poll_type, 0 ); - if( ret < 0 ) - return( ret ); - if( ret == poll_type ) - break; - } - } - - return( 0 ); -} - #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) int report_cid_usage( mbedtls_ssl_context *ssl, const char *additional_description ) @@ -3612,6 +3080,4 @@ exit: else mbedtls_exit( query_config_ret ); } -#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C && - MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C && - MBEDTLS_CTR_DRBG_C MBEDTLS_TIMING_C */ +#endif /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_CLI_C */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 4e11cb3a0..952769895 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -17,64 +17,22 @@ * limitations under the License. */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif +#include "ssl_test_lib.h" -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#define mbedtls_time time -#define mbedtls_time_t time_t -#define mbedtls_calloc calloc -#define mbedtls_fprintf fprintf -#define mbedtls_printf printf -#define mbedtls_exit exit -#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS -#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE -#endif - -#if !defined(MBEDTLS_ENTROPY_C) || \ - !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \ - !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C) || \ - defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) +#if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) int main( void ) { - mbedtls_printf( "MBEDTLS_ENTROPY_C and/or " - "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or " - "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined " - " and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n" ); + mbedtls_printf( MBEDTLS_SSL_TEST_IMPOSSIBLE ); mbedtls_exit( 0 ); } -#else +#elif !defined(MBEDTLS_SSL_SRV_C) +int main( void ) +{ + mbedtls_printf( "MBEDTLS_SSL_SRV_C not defined.\n" ); + mbedtls_exit( 0 ); +} +#else /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_SRV_C */ -#include "mbedtls/net_sockets.h" -#include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/certs.h" -#include "mbedtls/x509.h" -#include "mbedtls/error.h" -#include "mbedtls/debug.h" -#include "mbedtls/timing.h" -#include "mbedtls/base64.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif - -#include - -#include -#include -#include #include #if !defined(_MSC_VER) @@ -97,10 +55,6 @@ int main( void ) #include "mbedtls/ssl_cookie.h" #endif -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#include "mbedtls/memory_buffer_alloc.h" -#endif - #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_FS_IO) #define SNI_OPTION #endif @@ -670,424 +624,7 @@ struct options int support_mki; /* The dtls mki mki support */ } opt; -int query_config( const char *config ); - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -typedef struct eap_tls_keys -{ - unsigned char master_secret[48]; - unsigned char randbytes[64]; - mbedtls_tls_prf_types tls_prf_type; -} eap_tls_keys; - -static int eap_tls_key_derivation ( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) -{ - eap_tls_keys *keys = (eap_tls_keys *)p_expkey; - - ( ( void ) kb ); - memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); - memcpy( keys->randbytes, client_random, 32 ); - memcpy( keys->randbytes + 32, server_random, 32 ); - keys->tls_prf_type = tls_prf_type; - - if( opt.debug_level > 2 ) - { - mbedtls_printf("exported maclen is %u\n", (unsigned)maclen); - mbedtls_printf("exported keylen is %u\n", (unsigned)keylen); - mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen); - } - return( 0 ); -} - -static int nss_keylog_export( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) -{ - char nss_keylog_line[ 200 ]; - size_t const client_random_len = 32; - size_t const master_secret_len = 48; - size_t len = 0; - size_t j; - int ret = 0; - - ((void) p_expkey); - ((void) kb); - ((void) maclen); - ((void) keylen); - ((void) ivlen); - ((void) server_random); - ((void) tls_prf_type); - - len += sprintf( nss_keylog_line + len, - "%s", "CLIENT_RANDOM " ); - - for( j = 0; j < client_random_len; j++ ) - { - len += sprintf( nss_keylog_line + len, - "%02x", client_random[j] ); - } - - len += sprintf( nss_keylog_line + len, " " ); - - for( j = 0; j < master_secret_len; j++ ) - { - len += sprintf( nss_keylog_line + len, - "%02x", ms[j] ); - } - - len += sprintf( nss_keylog_line + len, "\n" ); - nss_keylog_line[ len ] = '\0'; - - mbedtls_printf( "\n" ); - mbedtls_printf( "---------------- NSS KEYLOG -----------------\n" ); - mbedtls_printf( "%s", nss_keylog_line ); - mbedtls_printf( "---------------------------------------------\n" ); - - if( opt.nss_keylog_file != NULL ) - { - FILE *f; - - if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL ) - { - ret = -1; - goto exit; - } - - if( fwrite( nss_keylog_line, 1, len, f ) != len ) - { - ret = -1; - fclose( f ); - goto exit; - } - - fclose( f ); - } - -exit: - mbedtls_platform_zeroize( nss_keylog_line, - sizeof( nss_keylog_line ) ); - return( ret ); -} - -#if defined( MBEDTLS_SSL_DTLS_SRTP ) -/* Supported SRTP mode needs a maximum of : - * - 16 bytes for key (AES-128) - * - 14 bytes SALT - * One for sender, one for receiver context - */ -#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60 -typedef struct dtls_srtp_keys -{ - unsigned char master_secret[48]; - unsigned char randbytes[64]; - mbedtls_tls_prf_types tls_prf_type; -} dtls_srtp_keys; - -static int dtls_srtp_key_derivation( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) -{ - dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; - - ( ( void ) kb ); - memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); - memcpy( keys->randbytes, client_random, 32 ); - memcpy( keys->randbytes + 32, server_random, 32 ); - keys->tls_prf_type = tls_prf_type; - - if( opt.debug_level > 2 ) - { - mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen ); - mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen ); - mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen ); - } - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - -static void my_debug( void *ctx, int level, - const char *file, int line, - const char *str ) -{ - const char *p, *basename; - - /* Extract basename from file */ - for( p = basename = file; *p != '\0'; p++ ) - if( *p == '/' || *p == '\\' ) - basename = p + 1; - - mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", basename, line, level, str ); - fflush( (FILE *) ctx ); -} - -mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) -{ - (void) time; - return 0x5af2a056; -} - -int dummy_entropy( void *data, unsigned char *output, size_t len ) -{ - size_t i; - int ret; - (void) data; - - ret = mbedtls_entropy_func( data, output, len ); - for (i = 0; i < len; i++ ) { - //replace result with pseudo random - output[i] = (unsigned char) rand(); - } - return( ret ); -} - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -int ca_callback( void *data, mbedtls_x509_crt const *child, - mbedtls_x509_crt **candidates) -{ - int ret = 0; - mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data; - mbedtls_x509_crt *first; - - /* This is a test-only implementation of the CA callback - * which always returns the entire list of trusted certificates. - * Production implementations managing a large number of CAs - * should use an efficient presentation and lookup for the - * set of trusted certificates (such as a hashtable) and only - * return those trusted certificates which satisfy basic - * parental checks, such as the matching of child `Issuer` - * and parent `Subject` field. */ - ((void) child); - - first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - if( first == NULL ) - { - ret = -1; - goto exit; - } - mbedtls_x509_crt_init( first ); - - if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 ) - { - ret = -1; - goto exit; - } - - while( ca->next != NULL ) - { - ca = ca->next; - if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 ) - { - ret = -1; - goto exit; - } - } - -exit: - - if( ret != 0 ) - { - mbedtls_x509_crt_free( first ); - mbedtls_free( first ); - first = NULL; - } - - *candidates = first; - return( ret ); -} -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -/* - * Test recv/send functions that make sure each try returns - * WANT_READ/WANT_WRITE at least once before sucesseding - */ -static int delayed_recv( void *ctx, unsigned char *buf, size_t len ) -{ - static int first_try = 1; - int ret; - - if( first_try ) - { - first_try = 0; - return( MBEDTLS_ERR_SSL_WANT_READ ); - } - - ret = mbedtls_net_recv( ctx, buf, len ); - if( ret != MBEDTLS_ERR_SSL_WANT_READ ) - first_try = 1; /* Next call will be a new operation */ - return( ret ); -} - -static int delayed_send( void *ctx, const unsigned char *buf, size_t len ) -{ - static int first_try = 1; - int ret; - - if( first_try ) - { - first_try = 0; - return( MBEDTLS_ERR_SSL_WANT_WRITE ); - } - - ret = mbedtls_net_send( ctx, buf, len ); - if( ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - first_try = 1; /* Next call will be a new operation */ - return( ret ); -} - -typedef struct -{ - mbedtls_ssl_context *ssl; - mbedtls_net_context *net; -} io_ctx_t; - -#if defined(MBEDTLS_SSL_RECORD_CHECKING) -static int ssl_check_record( mbedtls_ssl_context const *ssl, - unsigned char const *buf, size_t len ) -{ - int ret; - unsigned char *tmp_buf; - - /* Record checking may modify the input buffer, - * so make a copy. */ - tmp_buf = mbedtls_calloc( 1, len ); - if( tmp_buf == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - memcpy( tmp_buf, buf, len ); - - ret = mbedtls_ssl_check_record( ssl, tmp_buf, len ); - if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ) - { - int ret_repeated; - - /* Test-only: Make sure that mbedtls_ssl_check_record() - * doesn't alter state. */ - memcpy( tmp_buf, buf, len ); /* Restore buffer */ - ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len ); - if( ret != ret_repeated ) - { - mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" ); - return( -1 ); - } - - switch( ret ) - { - case 0: - break; - - case MBEDTLS_ERR_SSL_INVALID_RECORD: - if( opt.debug_level > 1 ) - mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" ); - break; - - case MBEDTLS_ERR_SSL_INVALID_MAC: - if( opt.debug_level > 1 ) - mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" ); - break; - - case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD: - if( opt.debug_level > 1 ) - mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" ); - break; - - default: - mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", (unsigned int) -ret ); - return( -1 ); - } - - /* Regardless of the outcome, forward the record to the stack. */ - } - - mbedtls_free( tmp_buf ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - -static int recv_cb( void *ctx, unsigned char *buf, size_t len ) -{ - io_ctx_t *io_ctx = (io_ctx_t*) ctx; - size_t recv_len; - int ret; - - if( opt.nbio == 2 ) - ret = delayed_recv( io_ctx->net, buf, len ); - else - ret = mbedtls_net_recv( io_ctx->net, buf, len ); - if( ret < 0 ) - return( ret ); - recv_len = (size_t) ret; - - if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Here's the place to do any datagram/record checking - * in between receiving the packet from the underlying - * transport and passing it on to the TLS stack. */ -#if defined(MBEDTLS_SSL_RECORD_CHECKING) - if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 ) - return( -1 ); -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - } - - return( (int) recv_len ); -} - -static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ) -{ - io_ctx_t *io_ctx = (io_ctx_t*) ctx; - int ret; - size_t recv_len; - - ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout ); - if( ret < 0 ) - return( ret ); - recv_len = (size_t) ret; - - if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Here's the place to do any datagram/record checking - * in between receiving the packet from the underlying - * transport and passing it on to the TLS stack. */ -#if defined(MBEDTLS_SSL_RECORD_CHECKING) - if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 ) - return( -1 ); -#endif /* MBEDTLS_SSL_RECORD_CHECKING */ - } - - return( (int) recv_len ); -} - -static int send_cb( void *ctx, unsigned char const *buf, size_t len ) -{ - io_ctx_t *io_ctx = (io_ctx_t*) ctx; - - if( opt.nbio == 2 ) - return( delayed_send( io_ctx->net, buf, len ) ); - - return( mbedtls_net_send( io_ctx->net, buf, len ) ); -} +#include "ssl_test_common_source.c" /* * Return authmode from string, or -1 on error @@ -1406,24 +943,6 @@ void term_handler( int sig ) } #endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static int ssl_sig_hashes_for_test[] = { -#if defined(MBEDTLS_SHA512_C) - MBEDTLS_MD_SHA512, - MBEDTLS_MD_SHA384, -#endif -#if defined(MBEDTLS_SHA256_C) - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA224, -#endif -#if defined(MBEDTLS_SHA1_C) - /* Allow SHA-1 as we use it extensively in tests. */ - MBEDTLS_MD_SHA1, -#endif - MBEDTLS_MD_NONE -}; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - /** Return true if \p ret is a status code indicating that there is an * operation in progress on an SSL connection, and false if it indicates * success or a fatal error. @@ -1662,56 +1181,6 @@ static void ssl_async_cancel( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ -/* - * Wait for an event from the underlying transport or the timer - * (Used in event-driven IO mode). - */ -#if !defined(MBEDTLS_TIMING_C) -int idle( mbedtls_net_context *fd, - int idle_reason ) -#else -int idle( mbedtls_net_context *fd, - mbedtls_timing_delay_context *timer, - int idle_reason ) -#endif -{ - int ret; - int poll_type = 0; - - if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE ) - poll_type = MBEDTLS_NET_POLL_WRITE; - else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ ) - poll_type = MBEDTLS_NET_POLL_READ; -#if !defined(MBEDTLS_TIMING_C) - else - return( 0 ); -#endif - - while( 1 ) - { - /* Check if timer has expired */ -#if defined(MBEDTLS_TIMING_C) - if( timer != NULL && - mbedtls_timing_get_delay( timer ) == 2 ) - { - break; - } -#endif /* MBEDTLS_TIMING_C */ - - /* Check if underlying transport became available */ - if( poll_type != 0 ) - { - ret = mbedtls_net_poll( fd, poll_type, 0 ); - if( ret < 0 ) - return( ret ); - if( ret == poll_type ) - break; - } - } - - return( 0 ); -} - #if defined(MBEDTLS_USE_PSA_CRYPTO) static psa_status_t psa_setup_psk_key_slot( psa_key_id_t *slot, psa_algorithm_t alg, @@ -4576,6 +4045,4 @@ exit: else mbedtls_exit( query_config_ret ); } -#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C && - MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && MBEDTLS_RSA_C && - MBEDTLS_CTR_DRBG_C */ +#endif /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_SRV_C */ diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c new file mode 100644 index 000000000..d9e36078d --- /dev/null +++ b/programs/ssl/ssl_test_common_source.c @@ -0,0 +1,305 @@ +/* + * Common source code for SSL test programs. This file is included by + * both ssl_client2.c and ssl_server2.c and is intended for source + * code that is textually identical in both programs, but that cannot be + * compiled separately because it refers to types or macros that are + * different in the two programs, or because it would have an incomplete + * type. + * + * This file is meant to be #include'd and cannot be compiled separately. + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +int eap_tls_key_derivation( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + eap_tls_keys *keys = (eap_tls_keys *)p_expkey; + + ( ( void ) kb ); + memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + memcpy( keys->randbytes, client_random, 32 ); + memcpy( keys->randbytes + 32, server_random, 32 ); + keys->tls_prf_type = tls_prf_type; + + if( opt.debug_level > 2 ) + { + mbedtls_printf("exported maclen is %u\n", (unsigned)maclen); + mbedtls_printf("exported keylen is %u\n", (unsigned)keylen); + mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen); + } + return( 0 ); +} + +int nss_keylog_export( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + char nss_keylog_line[ 200 ]; + size_t const client_random_len = 32; + size_t const master_secret_len = 48; + size_t len = 0; + size_t j; + int ret = 0; + + ((void) p_expkey); + ((void) kb); + ((void) maclen); + ((void) keylen); + ((void) ivlen); + ((void) server_random); + ((void) tls_prf_type); + + len += sprintf( nss_keylog_line + len, + "%s", "CLIENT_RANDOM " ); + + for( j = 0; j < client_random_len; j++ ) + { + len += sprintf( nss_keylog_line + len, + "%02x", client_random[j] ); + } + + len += sprintf( nss_keylog_line + len, " " ); + + for( j = 0; j < master_secret_len; j++ ) + { + len += sprintf( nss_keylog_line + len, + "%02x", ms[j] ); + } + + len += sprintf( nss_keylog_line + len, "\n" ); + nss_keylog_line[ len ] = '\0'; + + mbedtls_printf( "\n" ); + mbedtls_printf( "---------------- NSS KEYLOG -----------------\n" ); + mbedtls_printf( "%s", nss_keylog_line ); + mbedtls_printf( "---------------------------------------------\n" ); + + if( opt.nss_keylog_file != NULL ) + { + FILE *f; + + if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL ) + { + ret = -1; + goto exit; + } + + if( fwrite( nss_keylog_line, 1, len, f ) != len ) + { + ret = -1; + fclose( f ); + goto exit; + } + + fclose( f ); + } + +exit: + mbedtls_platform_zeroize( nss_keylog_line, + sizeof( nss_keylog_line ) ); + return( ret ); +} + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) +int dtls_srtp_key_derivation( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) +{ + dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; + + ( ( void ) kb ); + memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + memcpy( keys->randbytes, client_random, 32 ); + memcpy( keys->randbytes + 32, server_random, 32 ); + keys->tls_prf_type = tls_prf_type; + + if( opt.debug_level > 2 ) + { + mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen ); + mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen ); + mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen ); + } + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + +#if defined(MBEDTLS_SSL_RECORD_CHECKING) +int ssl_check_record( mbedtls_ssl_context const *ssl, + unsigned char const *buf, size_t len ) +{ + int ret; + unsigned char *tmp_buf; + + /* Record checking may modify the input buffer, + * so make a copy. */ + tmp_buf = mbedtls_calloc( 1, len ); + if( tmp_buf == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + memcpy( tmp_buf, buf, len ); + + ret = mbedtls_ssl_check_record( ssl, tmp_buf, len ); + if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ) + { + int ret_repeated; + + /* Test-only: Make sure that mbedtls_ssl_check_record() + * doesn't alter state. */ + memcpy( tmp_buf, buf, len ); /* Restore buffer */ + ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len ); + if( ret != ret_repeated ) + { + mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" ); + return( -1 ); + } + + switch( ret ) + { + case 0: + break; + + case MBEDTLS_ERR_SSL_INVALID_RECORD: + if( opt.debug_level > 1 ) + mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" ); + break; + + case MBEDTLS_ERR_SSL_INVALID_MAC: + if( opt.debug_level > 1 ) + mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" ); + break; + + case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD: + if( opt.debug_level > 1 ) + mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" ); + break; + + default: + mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", (unsigned int) -ret ); + return( -1 ); + } + + /* Regardless of the outcome, forward the record to the stack. */ + } + + mbedtls_free( tmp_buf ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + +int recv_cb( void *ctx, unsigned char *buf, size_t len ) +{ + io_ctx_t *io_ctx = (io_ctx_t*) ctx; + size_t recv_len; + int ret; + + if( opt.nbio == 2 ) + ret = delayed_recv( io_ctx->net, buf, len ); + else + ret = mbedtls_net_recv( io_ctx->net, buf, len ); + if( ret < 0 ) + return( ret ); + recv_len = (size_t) ret; + + if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + /* Here's the place to do any datagram/record checking + * in between receiving the packet from the underlying + * transport and passing it on to the TLS stack. */ +#if defined(MBEDTLS_SSL_RECORD_CHECKING) + if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 ) + return( -1 ); +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + } + + return( (int) recv_len ); +} + +int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ) +{ + io_ctx_t *io_ctx = (io_ctx_t*) ctx; + int ret; + size_t recv_len; + + ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout ); + if( ret < 0 ) + return( ret ); + recv_len = (size_t) ret; + + if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + /* Here's the place to do any datagram/record checking + * in between receiving the packet from the underlying + * transport and passing it on to the TLS stack. */ +#if defined(MBEDTLS_SSL_RECORD_CHECKING) + if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 ) + return( -1 ); +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + } + + return( (int) recv_len ); +} + +int send_cb( void *ctx, unsigned char const *buf, size_t len ) +{ + io_ctx_t *io_ctx = (io_ctx_t*) ctx; + + if( opt.nbio == 2 ) + return( delayed_send( io_ctx->net, buf, len ) ); + + return( mbedtls_net_send( io_ctx->net, buf, len ) ); +} + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +int ssl_sig_hashes_for_test[] = { +#if defined(MBEDTLS_SHA512_C) + MBEDTLS_MD_SHA512, + MBEDTLS_MD_SHA384, +#endif +#if defined(MBEDTLS_SHA256_C) + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA224, +#endif +#if defined(MBEDTLS_SHA1_C) + /* Allow SHA-1 as we use it extensively in tests. */ + MBEDTLS_MD_SHA1, +#endif + MBEDTLS_MD_NONE +}; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c new file mode 100644 index 000000000..22453c19f --- /dev/null +++ b/programs/ssl/ssl_test_lib.c @@ -0,0 +1,200 @@ +/* + * Common code library for SSL test programs. + * + * In addition to the functions in this file, there is shared source code + * that cannot be compiled separately in "ssl_test_common_source.c". + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ssl_test_lib.h" + +#if !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) + +void my_debug( void *ctx, int level, + const char *file, int line, + const char *str ) +{ + const char *p, *basename; + + /* Extract basename from file */ + for( p = basename = file; *p != '\0'; p++ ) + if( *p == '/' || *p == '\\' ) + basename = p + 1; + + mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", + basename, line, level, str ); + fflush( (FILE *) ctx ); +} + +mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) +{ + (void) time; + return 0x5af2a056; +} + +int dummy_entropy( void *data, unsigned char *output, size_t len ) +{ + size_t i; + int ret; + (void) data; + + ret = mbedtls_entropy_func( data, output, len ); + for( i = 0; i < len; i++ ) + { + //replace result with pseudo random + output[i] = (unsigned char) rand(); + } + return( ret ); +} + +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +int ca_callback( void *data, mbedtls_x509_crt const *child, + mbedtls_x509_crt **candidates ) +{ + int ret = 0; + mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data; + mbedtls_x509_crt *first; + + /* This is a test-only implementation of the CA callback + * which always returns the entire list of trusted certificates. + * Production implementations managing a large number of CAs + * should use an efficient presentation and lookup for the + * set of trusted certificates (such as a hashtable) and only + * return those trusted certificates which satisfy basic + * parental checks, such as the matching of child `Issuer` + * and parent `Subject` field or matching key identifiers. */ + ((void) child); + + first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); + if( first == NULL ) + { + ret = -1; + goto exit; + } + mbedtls_x509_crt_init( first ); + + if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 ) + { + ret = -1; + goto exit; + } + + while( ca->next != NULL ) + { + ca = ca->next; + if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 ) + { + ret = -1; + goto exit; + } + } + +exit: + + if( ret != 0 ) + { + mbedtls_x509_crt_free( first ); + mbedtls_free( first ); + first = NULL; + } + + *candidates = first; + return( ret ); +} +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ + +int delayed_recv( void *ctx, unsigned char *buf, size_t len ) +{ + static int first_try = 1; + int ret; + + if( first_try ) + { + first_try = 0; + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + + ret = mbedtls_net_recv( ctx, buf, len ); + if( ret != MBEDTLS_ERR_SSL_WANT_READ ) + first_try = 1; /* Next call will be a new operation */ + return( ret ); +} + +int delayed_send( void *ctx, const unsigned char *buf, size_t len ) +{ + static int first_try = 1; + int ret; + + if( first_try ) + { + first_try = 0; + return( MBEDTLS_ERR_SSL_WANT_WRITE ); + } + + ret = mbedtls_net_send( ctx, buf, len ); + if( ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + first_try = 1; /* Next call will be a new operation */ + return( ret ); +} + +#if !defined(MBEDTLS_TIMING_C) +int idle( mbedtls_net_context *fd, + int idle_reason ) +#else +int idle( mbedtls_net_context *fd, + mbedtls_timing_delay_context *timer, + int idle_reason ) +#endif +{ + int ret; + int poll_type = 0; + + if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE ) + poll_type = MBEDTLS_NET_POLL_WRITE; + else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ ) + poll_type = MBEDTLS_NET_POLL_READ; +#if !defined(MBEDTLS_TIMING_C) + else + return( 0 ); +#endif + + while( 1 ) + { + /* Check if timer has expired */ +#if defined(MBEDTLS_TIMING_C) + if( timer != NULL && + mbedtls_timing_get_delay( timer ) == 2 ) + { + break; + } +#endif /* MBEDTLS_TIMING_C */ + + /* Check if underlying transport became available */ + if( poll_type != 0 ) + { + ret = mbedtls_net_poll( fd, poll_type, 0 ); + if( ret < 0 ) + return( ret ); + if( ret == poll_type ) + break; + } + } + + return( 0 ); +} + +#endif /* !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) */ diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h new file mode 100644 index 000000000..031c872bd --- /dev/null +++ b/programs/ssl/ssl_test_lib.h @@ -0,0 +1,154 @@ +/* + * Common code for SSL test programs + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H +#define MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#define mbedtls_time time +#define mbedtls_time_t time_t +#define mbedtls_printf printf +#define mbedtls_fprintf fprintf +#define mbedtls_snprintf snprintf +#define mbedtls_exit exit +#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS +#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE +#endif + +#if !defined(MBEDTLS_CTR_DRBG_C) || \ + !defined(MBEDTLS_ENTROPY_C) || \ + !defined(MBEDTLS_NET_C) || \ + !defined(MBEDTLS_SSL_TLS_C) || \ + defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) +#define MBEDTLS_SSL_TEST_IMPOSSIBLE \ + "MBEDTLS_CTR_DRBG_C and/or " \ + "MBEDTLS_ENTROPY_C and/or " \ + "MBEDTLS_NET_C and/or " \ + "MBEDTLS_SSL_TLS_C not defined, " \ + "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n" +#else +#undef MBEDTLS_SSL_TEST_IMPOSSIBLE + +#include +#include +#include + +#include "mbedtls/net_sockets.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/certs.h" +#include "mbedtls/x509.h" +#include "mbedtls/error.h" +#include "mbedtls/debug.h" +#include "mbedtls/timing.h" +#include "mbedtls/base64.h" + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#include "mbedtls/memory_buffer_alloc.h" +#endif + +#include + +#include "../test/query_config.h" + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + +typedef struct eap_tls_keys +{ + unsigned char master_secret[48]; + unsigned char randbytes[64]; + mbedtls_tls_prf_types tls_prf_type; +} eap_tls_keys; + +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + +/* Supported SRTP mode needs a maximum of : + * - 16 bytes for key (AES-128) + * - 14 bytes SALT + * One for sender, one for receiver context + */ +#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60 + +typedef struct dtls_srtp_keys +{ + unsigned char master_secret[48]; + unsigned char randbytes[64]; + mbedtls_tls_prf_types tls_prf_type; +} dtls_srtp_keys; + +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + +typedef struct +{ + mbedtls_ssl_context *ssl; + mbedtls_net_context *net; +} io_ctx_t; + +void my_debug( void *ctx, int level, + const char *file, int line, + const char *str ); + +mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); + +int dummy_entropy( void *data, unsigned char *output, size_t len ); + +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +int ca_callback( void *data, mbedtls_x509_crt const *child, + mbedtls_x509_crt **candidates ); +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ + +/* + * Test recv/send functions that make sure each try returns + * WANT_READ/WANT_WRITE at least once before sucesseding + */ +int delayed_recv( void *ctx, unsigned char *buf, size_t len ); +int delayed_send( void *ctx, const unsigned char *buf, size_t len ); + +/* + * Wait for an event from the underlying transport or the timer + * (Used in event-driven IO mode). + */ +int idle( mbedtls_net_context *fd, +#if defined(MBEDTLS_TIMING_C) + mbedtls_timing_delay_context *timer, +#endif + int idle_reason ); + +#endif /* MBEDTLS_SSL_TEST_IMPOSSIBLE conditions: else */ +#endif /* MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H */ diff --git a/programs/test/query_compile_time_config.c b/programs/test/query_compile_time_config.c index abe8f7607..0e356c822 100644 --- a/programs/test/query_compile_time_config.c +++ b/programs/test/query_compile_time_config.c @@ -40,7 +40,7 @@ "Mbed TLS build and the macro expansion of that configuration will be\n" \ "printed (if any). Otherwise, 1 will be returned.\n" -int query_config( const char *config ); +#include "query_config.h" int main( int argc, char *argv[] ) { diff --git a/programs/test/query_config.c b/programs/test/query_config.c index 1fb7384fd..aae8e2e12 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -23,6 +23,8 @@ #include MBEDTLS_CONFIG_FILE #endif +#include "query_config.h" + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else diff --git a/programs/test/query_config.h b/programs/test/query_config.h new file mode 100644 index 000000000..23009c46a --- /dev/null +++ b/programs/test/query_config.h @@ -0,0 +1,42 @@ +/* + * Query Mbed TLS compile time configurations from config.h + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H +#define MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +/** Check whether a given configuration symbol is enabled. + * + * \param config The symbol to query (e.g. "MBEDTLS_RSA_C"). + * \return \c 0 if the symbol was defined at compile time + * (in MBEDTLS_CONFIG_FILE or config.h), + * \c 1 otherwise. + * + * \note This function is defined in `programs/test/query_config.c` + * which is automatically generated by + * `scripts/generate_query_config.pl`. + */ +int query_config( const char *config ); + +#endif /* MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H */ diff --git a/scripts/data_files/query_config.fmt b/scripts/data_files/query_config.fmt index be1faef65..be541cb48 100644 --- a/scripts/data_files/query_config.fmt +++ b/scripts/data_files/query_config.fmt @@ -23,6 +23,8 @@ #include MBEDTLS_CONFIG_FILE #endif +#include "query_config.h" + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl index 6c2b5e4ab..df5d66e81 100755 --- a/scripts/generate_visualc_files.pl +++ b/scripts/generate_visualc_files.pl @@ -161,6 +161,9 @@ sub gen_app { $appname eq "query_compile_time_config" ) { $srcs .= "\r\n "; } + if( $appname eq "ssl_client2" or $appname eq "ssl_server2" ) { + $srcs .= "\r\n "; + } my $content = $template; $content =~ s//$srcs/g; diff --git a/visualc/VS2010/ssl_client2.vcxproj b/visualc/VS2010/ssl_client2.vcxproj index 9021602b6..9884f2370 100644 --- a/visualc/VS2010/ssl_client2.vcxproj +++ b/visualc/VS2010/ssl_client2.vcxproj @@ -21,6 +21,7 @@ + diff --git a/visualc/VS2010/ssl_server2.vcxproj b/visualc/VS2010/ssl_server2.vcxproj index 61eedaaa0..d8f3e592d 100644 --- a/visualc/VS2010/ssl_server2.vcxproj +++ b/visualc/VS2010/ssl_server2.vcxproj @@ -21,6 +21,7 @@ +