From 1b4a2bad7ab78f45f951f1129769a9c25ac0b8b8 Mon Sep 17 00:00:00 2001 From: Jarno Lamsa Date: Wed, 27 Mar 2019 17:55:27 +0200 Subject: [PATCH] Add possibility to use ca_callbacks in ssl programs --- programs/ssl/ssl_client2.c | 46 +++++++++++++++++++++++++++++++++++++- programs/ssl/ssl_server2.c | 46 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index f7e24598d..2e297e362 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -122,6 +122,8 @@ int main( void ) #define DFL_FALLBACK -1 #define DFL_EXTENDED_MS -1 #define DFL_ETM -1 +#define DFL_CA_CALLBACK 0 + #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: " #define GET_REQUEST_END "\r\n\r\n" @@ -169,6 +171,13 @@ int main( void ) #else #define USAGE_PSK_SLOT "" #endif /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +#define USAGE_CA_CALLBACK \ + " ca_callback=%%d default: 0 (disabled)\n" \ + " Enable this to use the trusted certificate callback function\n" +#else +#define USAGE_CA_CALLBACK "" +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ #define USAGE_PSK USAGE_PSK_RAW USAGE_PSK_SLOT #else #define USAGE_PSK "" @@ -312,6 +321,7 @@ int main( void ) " options: none, optional, required\n" \ USAGE_IO \ USAGE_KEY_OPAQUE \ + USAGE_CA_CALLBACK \ "\n" \ USAGE_PSK \ USAGE_ECJPAKE \ @@ -385,6 +395,9 @@ struct options int key_opaque; /* handle private key as if it were opaque */ #if defined(MBEDTLS_USE_PSA_CRYPTO) int psk_opaque; +#endif +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + int use_ca_callback /* Use a callback for a trusted certificate list */ #endif const char *psk; /* the pre-shared key */ const char *psk_identity; /* the pre-shared key identity */ @@ -439,6 +452,25 @@ static void my_debug( void *ctx, int level, fflush( (FILE *) ctx ); } +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +int ca_callback( void *data, mbedtls_x509_crt *child, mbedtls_x509_crt **candidates) +{ + mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data; + + mbedtls_x509_crt *first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); + TEST_ASSERT( first != NULL); + TEST_ASSERT( mbedtls_x509_crt_init( first ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) == 0); + while( ca->next != NULL ) + { + ca = ca->next; + TEST_ASSERT( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) == 0); + } + *candidates = first; + return 0; +} +#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 @@ -697,6 +729,9 @@ int main( int argc, char *argv[] ) opt.psk = DFL_PSK; #if defined(MBEDTLS_USE_PSA_CRYPTO) opt.psk_opaque = DFL_PSK_OPAQUE; +#endif +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + opt.ca_callback = DFL_CA_CALLBACK; #endif opt.psk_identity = DFL_PSK_IDENTITY; opt.ecjpake_pw = DFL_ECJPAKE_PW; @@ -805,6 +840,10 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_USE_PSA_CRYPTO) else if( strcmp( p, "psk_opaque" ) == 0 ) opt.psk_opaque = atoi( q ); +#endif +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + else if( strcmp( p, "ca_callback" ) == 0) + opt.ca_callback = atoi( q ); #endif else if( strcmp( p, "psk_identity" ) == 0 ) opt.psk_identity = q; @@ -1600,7 +1639,12 @@ int main( int argc, char *argv[] ) if( strcmp( opt.ca_path, "none" ) != 0 && strcmp( opt.ca_file, "none" ) != 0 ) { - mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + if( opt.ca_callback != 0 ) + mbedtls_ssl_conf_ca_cb( &conf, ca_callback, &cacert); + else +#endif + mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); } if( strcmp( opt.crt_file, "none" ) != 0 && strcmp( opt.key_file, "none" ) != 0 ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 7858db305..887fe4e96 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -166,6 +166,7 @@ int main( void ) #define DFL_DGRAM_PACKING 1 #define DFL_EXTENDED_MS -1 #define DFL_ETM -1 +#define DFL_CA_CALLBACK 0 #define LONG_RESPONSE "

01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \ @@ -264,7 +265,13 @@ int main( void ) #else #define USAGE_PSK "" #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +#define USAGE_CA_CALLBACK \ + " ca_callback=%%d default: 0 (disabled)\n" \ + " Enable this to use the trusted certificate callback function\n" +#else +#define USAGE_CA_CALLBACK "" +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) #define USAGE_TICKETS \ " tickets=%%d default: 1 (enabled)\n" \ @@ -420,6 +427,7 @@ int main( void ) USAGE_SNI \ "\n" \ USAGE_PSK \ + USAGE_CA_CALLBACK \ USAGE_ECJPAKE \ "\n" \ " allow_legacy=%%d default: (library default: no)\n" \ @@ -506,6 +514,9 @@ struct options #if defined(MBEDTLS_USE_PSA_CRYPTO) int psk_opaque; int psk_list_opaque; +#endif +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + int use_ca_callback /* Use a callback for a trusted certificate list */ #endif const char *psk; /* the pre-shared key */ const char *psk_identity; /* the pre-shared key identity */ @@ -564,6 +575,25 @@ static void my_debug( void *ctx, int level, fflush( (FILE *) ctx ); } +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +int ca_callback( void *data, mbedtls_x509_crt *child, mbedtls_x509_crt **candidates) +{ + mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data; + + mbedtls_x509_crt *first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); + TEST_ASSERT( first != NULL); + TEST_ASSERT( mbedtls_x509_crt_init( first ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) == 0); + while( ca->next != NULL ) + { + ca = ca->next; + TEST_ASSERT( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) == 0); + } + *candidates = first; + return 0; +} +#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 @@ -1457,6 +1487,9 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_USE_PSA_CRYPTO) opt.psk_opaque = DFL_PSK_OPAQUE; opt.psk_list_opaque = DFL_PSK_LIST_OPAQUE; +#endif +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + opt.ca_callback = DFL_CA_CALLBACK; #endif opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_list = DFL_PSK_LIST; @@ -1591,6 +1624,10 @@ int main( int argc, char *argv[] ) opt.psk_opaque = atoi( q ); else if( strcmp( p, "psk_list_opaque" ) == 0 ) opt.psk_list_opaque = atoi( q ); +#endif +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + else if( strcmp( p, "ca_callback" ) == 0) + opt.ca_callback = atoi( q ); #endif else if( strcmp( p, "psk_identity" ) == 0 ) opt.psk_identity = q; @@ -2570,7 +2607,12 @@ int main( int argc, char *argv[] ) if( strcmp( opt.ca_path, "none" ) != 0 && strcmp( opt.ca_file, "none" ) != 0 ) { - mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + if( opt.ca_callback != 0 ) + mbedtls_ssl_conf_ca_cb( &conf, ca_callback, &cacert); + else +#endif + mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); } if( key_cert_init ) {