diff --git a/ChangeLog.d/mbedtls_ssl_cert_cb.txt b/ChangeLog.d/mbedtls_ssl_cert_cb.txt index 89e9fdff7..9a00c547d 100644 --- a/ChangeLog.d/mbedtls_ssl_cert_cb.txt +++ b/ChangeLog.d/mbedtls_ssl_cert_cb.txt @@ -1,3 +1,5 @@ Features * Add server certificate selection callback near end of Client Hello. Register callback with mbedtls_ssl_conf_cert_cb(). + * Provide mechanism to reset handshake cert list by calling + mbedtls_ssl_set_hs_own_cert() with NULL value for own_cert param. diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 0e93849db..d1fec9511 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -3546,6 +3546,9 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ); * \note Same as \c mbedtls_ssl_conf_own_cert() but for use within * the SNI callback. * + * \note Passing null \c own_cert clears the certificate list for + * the current handshake. + * * \param ssl SSL context * \param own_cert own public certificate chain * \param pk_key own private key diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9d41cb42f..089f23912 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1299,6 +1299,18 @@ void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, conf->cert_profile = profile; } +static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) +{ + mbedtls_ssl_key_cert *cur = key_cert, *next; + + while( cur != NULL ) + { + next = cur->next; + mbedtls_free( cur ); + cur = next; + } +} + /* Append a new keycert entry to a (possibly empty) list */ static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, mbedtls_x509_crt *cert, @@ -1306,6 +1318,14 @@ static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, { mbedtls_ssl_key_cert *new_cert; + if( cert == NULL ) + { + /* Free list if cert is null */ + ssl_key_cert_free( *head ); + *head = NULL; + return( 0 ); + } + new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); if( new_cert == NULL ) return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); @@ -1314,7 +1334,7 @@ static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, new_cert->key = key; new_cert->next = NULL; - /* Update head is the list was null, else add to the end */ + /* Update head if the list was null, else add to the end */ if( *head == NULL ) { *head = new_cert; @@ -2949,20 +2969,6 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_RENEGOTIATION */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) -{ - mbedtls_ssl_key_cert *cur = key_cert, *next; - - while( cur != NULL ) - { - next = cur->next; - mbedtls_free( cur ); - cur = next; - } -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) { mbedtls_ssl_handshake_params *handshake = ssl->handshake; @@ -3050,17 +3056,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) * Free only the linked list wrapper, not the keys themselves * since the belong to the SNI callback */ - if( handshake->sni_key_cert != NULL ) - { - mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next; - - while( cur != NULL ) - { - next = cur->next; - mbedtls_free( cur ); - cur = next; - } - } + ssl_key_cert_free( handshake->sni_key_cert ); #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 4f5ee9762..0c8928f16 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -854,6 +854,15 @@ int mbedtls_endpoint_certificate_init( mbedtls_endpoint *ep, int pk_alg ) ret = mbedtls_ssl_conf_own_cert( &( ep->conf ), &( cert->cert ), &( cert->pkey ) ); TEST_ASSERT( ret == 0 ); + TEST_ASSERT( ep->conf.key_cert != NULL ); + + ret = mbedtls_ssl_conf_own_cert( &( ep->conf ), NULL, NULL ); + TEST_ASSERT( ret == 0 ); + TEST_ASSERT( ep->conf.key_cert == NULL ); + + ret = mbedtls_ssl_conf_own_cert( &( ep->conf ), &( cert->cert ), + &( cert->pkey ) ); + TEST_ASSERT( ret == 0 ); exit: if( ret != 0 )