Merge remote-tracking branch 'upstream-public/pr/1474' into development-proposed
diff --git a/ChangeLog b/ChangeLog
index daddccc..e84c276 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,6 +37,10 @@
    * Do not define global mutexes around readdir() and gmtime() in
      configurations where the feature is disabled. Found and fixed by Gergely
      Budai.
+   * Harden mbedtls_ssl_config_free() against misuse, so that it doesn't
+     leak memory in case the user doesn't use mbedtls_ssl_conf_psk() and
+     instead incorrectly manipulates conf->psk and/or conf->psk_identity
+     directly. Found and fix submitted by junyeonLEE in #1220.
 
 = mbed TLS 2.8.0 branch released 2018-03-16
 
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 401a127..f7a1a01 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -682,10 +682,18 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    unsigned char *psk;             /*!< pre-shared key                     */
-    size_t         psk_len;         /*!< length of the pre-shared key       */
-    unsigned char *psk_identity;    /*!< identity for PSK negotiation       */
-    size_t         psk_identity_len;/*!< length of identity                 */
+    unsigned char *psk;             /*!< pre-shared key. This field should
+                                         only be set via
+                                         mbedtls_ssl_conf_psk() */
+    size_t         psk_len;         /*!< length of the pre-shared key. This
+                                         field should only be set via
+                                         mbedtls_ssl_conf_psk() */
+    unsigned char *psk_identity;    /*!< identity for PSK negotiation. This
+                                         field should only be set via
+                                         mbedtls_ssl_conf_psk() */
+    size_t         psk_identity_len;/*!< length of identity. This field should
+                                         only be set via
+                                         mbedtls_ssl_conf_psk() */
 #endif
 
 #if defined(MBEDTLS_SSL_ALPN)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 236e52d..3802e23 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -7741,10 +7741,16 @@
     if( conf->psk != NULL )
     {
         mbedtls_zeroize( conf->psk, conf->psk_len );
-        mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len );
         mbedtls_free( conf->psk );
-        mbedtls_free( conf->psk_identity );
+        conf->psk = NULL;
         conf->psk_len = 0;
+    }
+
+    if( conf->psk_identity != NULL )
+    {
+        mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len );
+        mbedtls_free( conf->psk_identity );
+        conf->psk_identity = NULL;
         conf->psk_identity_len = 0;
     }
 #endif