Implement MBEDTLS_X509_ALWAYS_FLUSH
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index c3ef438..c7f816b 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -811,6 +811,9 @@
  * They are not part of the public API and may change
  * at any time. */
 
+int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt );
+int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt );
+
 int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt );
 int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt );
 
@@ -839,7 +842,7 @@
 }
 
 static inline int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
-                                         mbedtls_x509_crt_frame **frame_ptr )
+                                                  mbedtls_x509_crt_frame **frame_ptr )
 {
 #if defined(MBEDTLS_THREADING_C)
     if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
@@ -871,6 +874,10 @@
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_unlock( &crt->cache->frame_mutex );
 #endif
+
+#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
+    (void) mbedtls_x509_crt_flush_cache_frame( crt );
+#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
 }
 
 static inline int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt,
@@ -906,6 +913,10 @@
 #if defined(MBEDTLS_THREADING_C)
     mbedtls_mutex_unlock( &crt->cache->pk_mutex );
 #endif
+
+#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
+    (void) mbedtls_x509_crt_flush_cache_pk( crt );
+#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
 }
 
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index b5710ed..91b29b6 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -106,6 +106,59 @@
 static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame *frame,
                                         mbedtls_x509_sequence *ext_key_usage );
 
+int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt )
+{
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
+    /* The cache holds a shallow copy of the PK context
+     * in the legacy struct, so don't free PK context. */
+    mbedtls_free( crt->cache->pk );
+#else
+    mbedtls_pk_free( crt->cache->pk );
+    mbedtls_free( crt->cache->pk );
+#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
+    crt->cache->pk = NULL;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+    return( 0 );
+}
+
+int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt )
+{
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    mbedtls_free( crt->cache->frame );
+    crt->cache->frame = NULL;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+    return( 0 );
+}
+
+int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt )
+{
+    int ret;
+    ret = mbedtls_x509_crt_flush_cache_frame( crt );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_x509_crt_flush_cache_pk( crt );
+    if( ret != 0 )
+        return( ret );
+    return( 0 );
+}
+
 static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame );
 int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt )
 {
@@ -224,25 +277,6 @@
     memset( cache, 0, sizeof( *cache ) );
 }
 
-int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt )
-{
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-    if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif
-    x509_crt_cache_clear_frame( crt->cache );
-    x509_crt_cache_clear_pk( crt->cache );
-#if defined(MBEDTLS_THREADING_C)
-    if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-    if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
-        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
-#endif
-    return( 0 );
-}
-
 int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt,
                                             mbedtls_x509_sequence **subj_alt )
 {