mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-31 03:30:35 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			358 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			358 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  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_TEST_HOOKS)
 | |
| #include "test/helpers.h"
 | |
| #endif
 | |
| 
 | |
| #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;
 | |
| }
 | |
| 
 | |
| #if !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
 | |
| static 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 );
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void rng_init( rng_context_t *rng )
 | |
| {
 | |
| #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
 | |
|     (void) rng;
 | |
|     psa_crypto_init( );
 | |
| #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
| 
 | |
| #if defined(MBEDTLS_CTR_DRBG_C)
 | |
|     mbedtls_ctr_drbg_init( &rng->drbg );
 | |
| #elif defined(MBEDTLS_HMAC_DRBG_C)
 | |
|     mbedtls_hmac_drbg_init( &rng->drbg );
 | |
| #else
 | |
| #error "No DRBG available"
 | |
| #endif
 | |
| 
 | |
|     mbedtls_entropy_init( &rng->entropy );
 | |
| #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
| }
 | |
| 
 | |
| int rng_seed( rng_context_t *rng, int reproducible, const char *pers )
 | |
| {
 | |
| #if defined(MBEDTLS_USE_PSA_CRYPTO)
 | |
|     if( reproducible )
 | |
|     {
 | |
|         mbedtls_fprintf( stderr,
 | |
|                          "MBEDTLS_USE_PSA_CRYPTO does not support reproducible mode.\n" );
 | |
|         return( -1 );
 | |
|     }
 | |
| #endif
 | |
| #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
 | |
|     /* The PSA crypto RNG does its own seeding. */
 | |
|     (void) rng;
 | |
|     (void) pers;
 | |
|     if( reproducible )
 | |
|     {
 | |
|         mbedtls_fprintf( stderr,
 | |
|                          "The PSA RNG does not support reproducible mode.\n" );
 | |
|         return( -1 );
 | |
|     }
 | |
|     return( 0 );
 | |
| #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
|     int ( *f_entropy )( void *, unsigned char *, size_t ) =
 | |
|         ( reproducible ? dummy_entropy : mbedtls_entropy_func );
 | |
| 
 | |
|     if ( reproducible )
 | |
|         srand( 1 );
 | |
| 
 | |
| #if defined(MBEDTLS_CTR_DRBG_C)
 | |
|     int ret = mbedtls_ctr_drbg_seed( &rng->drbg,
 | |
|                                      f_entropy, &rng->entropy,
 | |
|                                      (const unsigned char *) pers,
 | |
|                                      strlen( pers ) );
 | |
| #elif defined(MBEDTLS_HMAC_DRBG_C)
 | |
| #if defined(MBEDTLS_SHA256_C)
 | |
|     const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
 | |
| #elif defined(MBEDTLS_SHA512_C)
 | |
|     const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA512;
 | |
| #else
 | |
| #error "No message digest available for HMAC_DRBG"
 | |
| #endif
 | |
|     int ret = mbedtls_hmac_drbg_seed( &rng->drbg,
 | |
|                                       mbedtls_md_info_from_type( md_type ),
 | |
|                                       f_entropy, &rng->entropy,
 | |
|                                       (const unsigned char *) pers,
 | |
|                                       strlen( pers ) );
 | |
| #else /* !defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_HMAC_DRBG_C) */
 | |
| #error "No DRBG available"
 | |
| #endif /* !defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_HMAC_DRBG_C) */
 | |
| 
 | |
|     if( ret != 0 )
 | |
|     {
 | |
|         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
 | |
|                         (unsigned int) -ret );
 | |
|         return( ret );
 | |
|     }
 | |
| #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
| 
 | |
|     return( 0 );
 | |
| }
 | |
| 
 | |
| void rng_free( rng_context_t *rng )
 | |
| {
 | |
| #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
 | |
|     (void) rng;
 | |
|     /* Deinitialize the PSA crypto subsystem. This deactivates all PSA APIs.
 | |
|      * This is ok because none of our applications try to do any crypto after
 | |
|      * deinitializing the RNG. */
 | |
|     mbedtls_psa_crypto_free( );
 | |
| #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
| 
 | |
| #if defined(MBEDTLS_CTR_DRBG_C)
 | |
|     mbedtls_ctr_drbg_free( &rng->drbg );
 | |
| #elif defined(MBEDTLS_HMAC_DRBG_C)
 | |
|     mbedtls_hmac_drbg_free( &rng->drbg );
 | |
| #else
 | |
| #error "No DRBG available"
 | |
| #endif
 | |
| 
 | |
|     mbedtls_entropy_free( &rng->entropy );
 | |
| #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
| }
 | |
| 
 | |
| int rng_get( void *p_rng, unsigned char *output, size_t output_len )
 | |
| {
 | |
| #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
 | |
|     (void) p_rng;
 | |
|     return( mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
 | |
|                                     output, output_len ) );
 | |
| #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
|     rng_context_t *rng = p_rng;
 | |
| 
 | |
| #if defined(MBEDTLS_CTR_DRBG_C)
 | |
|     return( mbedtls_ctr_drbg_random( &rng->drbg, output, output_len ) );
 | |
| #elif defined(MBEDTLS_HMAC_DRBG_C)
 | |
|     return( mbedtls_hmac_drbg_random( &rng->drbg, output, output_len ) );
 | |
| #else
 | |
| #error "No DRBG available"
 | |
| #endif
 | |
| 
 | |
| #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
 | |
| }
 | |
| 
 | |
| #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 );
 | |
| }
 | |
| 
 | |
| #if defined(MBEDTLS_TEST_HOOKS)
 | |
| 
 | |
| void test_hooks_init( void )
 | |
| {
 | |
|     mbedtls_test_info_reset( );
 | |
| 
 | |
| #if defined(MBEDTLS_TEST_MUTEX_USAGE)
 | |
|     mbedtls_test_mutex_usage_init( );
 | |
| #endif
 | |
| }
 | |
| 
 | |
| int test_hooks_failure_detected( void )
 | |
| {
 | |
| #if defined(MBEDTLS_TEST_MUTEX_USAGE)
 | |
|     /* Errors are reported via mbedtls_test_info. */
 | |
|     mbedtls_test_mutex_usage_check( );
 | |
| #endif
 | |
| 
 | |
|     if( mbedtls_test_info.result != MBEDTLS_TEST_RESULT_SUCCESS )
 | |
|         return( 1 );
 | |
|     return( 0 );
 | |
| }
 | |
| 
 | |
| void test_hooks_free( void )
 | |
| {
 | |
| }
 | |
| 
 | |
| #endif /* MBEDTLS_TEST_HOOKS */
 | |
| 
 | |
| #endif /* !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) */
 | 
