The code erroneously sets callback on the SSL_CTX, but the code uses SSL_use_PrivateKey_file, which accepts con->ssl and in turn invokes PEM_read_bio_PrivateKey as follows: pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->default_passwd_callback, ssl->default_passwd_callback_userdata); So the tls_connection_private_key always fails first time around, and when it does so, it leaves callback pointer in SSL_CTX set to tls_passwd_cb, and callback userdata set to strdup-ed and then freed string. So, at the time of the next iteraction, these callback and dangling data are copied from SSL_CTX to SSL and callback does get invoked and it accesses the freed memory as the password string. To fix the issue, remove the code to set/clear callback in SSL_CTX and set it only in conn->ssl for the duration of the function. Signed-off-by: Alexander Kabaev <kan@xxxxxxxxxxx> --- src/crypto/tls_openssl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 07c61193a..63279f8f1 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -2782,7 +2782,6 @@ static int tls_connection_private_key(struct tls_data *data, const u8 *private_key_blob, size_t private_key_blob_len) { - SSL_CTX *ssl_ctx = data->ssl; char *passwd; int ok; @@ -2796,8 +2795,8 @@ static int tls_connection_private_key(struct tls_data *data, } else passwd = NULL; - SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); - SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); + SSL_set_default_passwd_cb(conn->ssl, tls_passwd_cb); + SSL_set_default_passwd_cb_userdata(conn->ssl, passwd); ok = 0; while (private_key_blob) { @@ -2879,15 +2878,14 @@ static int tls_connection_private_key(struct tls_data *data, break; } + SSL_set_default_passwd_cb(conn->ssl, NULL); + os_free(passwd); if (!ok) { tls_show_errors(MSG_INFO, __func__, "Failed to load private key"); - os_free(passwd); return -1; } ERR_clear_error(); - SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); - os_free(passwd); if (!SSL_check_private_key(conn->ssl)) { tls_show_errors(MSG_INFO, __func__, "Private key failed " -- 2.13.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap