Provide means to reset handshake cert list

Extend mbedtls_ssl_set_hs_own_cert() to reset handshake cert list
if cert provided is null.  Previously, mbedtls_ssl_set_hs_own_cert()
only provided a way to append to the handshake certificate list,
without providing a way to replace the handshake certificate list.

Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
diff --git a/ChangeLog.d/mbedtls_ssl_cert_cb.txt b/ChangeLog.d/mbedtls_ssl_cert_cb.txt
index 89e9fdf..9a00c54 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 0e93849..d1fec95 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3546,6 +3546,9 @@
  * \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 9d41cb4..089f239 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1299,6 +1299,18 @@
     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 @@
 {
     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 @@
     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 @@
 }
 #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 @@
      * 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 4f5ee97..0c8928f 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -854,6 +854,15 @@
     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 )