diff --git a/docs/help/in/connect.in b/docs/help/in/connect.in
index a00e383..9d63318 100644
--- a/docs/help/in/connect.in
+++ b/docs/help/in/connect.in
@@ -3,6 +3,7 @@
 
      -4, -6: specify explicitly whether to use IPv4 or IPv6 address
      -ssl: use SSL when connecting
+     -ssl_tpm: use TPM chip, and set SRK password.
      -ssl_cert: The SSL client certificate file (implies -ssl)
      -ssl_pkey: The SSL client private key (if not included in the certificate file)
      -ssl_verify: Verify servers SSL certificate
diff --git a/docs/help/in/server.in b/docs/help/in/server.in
index 18d837b..3f01246 100644
--- a/docs/help/in/server.in
+++ b/docs/help/in/server.in
@@ -3,6 +3,7 @@
 
      -4, -6: specify explicitly whether to use IPv4 or IPv6 address
      -ssl: use SSL when connecting
+     -ssl_tpm: use TPM chip, and set SRK password.
      -ssl_cert: The SSL client certificate file (implies -ssl)
      -ssl_pkey: The SSL client private key (if not included in the certificate file)
      -ssl_verify: Verify servers SSL certificate
diff --git a/src/core/chat-commands.c b/src/core/chat-commands.c
index f5d0e9f..9737624 100644
--- a/src/core/chat-commands.c
+++ b/src/core/chat-commands.c
@@ -94,6 +94,8 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
 
 	if (g_hash_table_lookup(optlist, "ssl") != NULL)
 		conn->use_ssl = TRUE;
+	if ((tmp = g_hash_table_lookup(optlist, "ssl_tpm")) != NULL)
+		conn->ssl_tpm = g_strdup(tmp);
 	if ((tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL)
 		conn->ssl_cert = g_strdup(tmp);
 	if ((tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL)
@@ -107,7 +109,9 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
 	if ((conn->ssl_capath != NULL && conn->ssl_capath[0] != '\0')
 	||  (conn->ssl_cafile != NULL && conn->ssl_cafile[0] != '\0'))
 		conn->ssl_verify = TRUE;
-	if ((conn->ssl_cert != NULL && conn->ssl_cert[0] != '\0') || conn->ssl_verify)
+	if ((conn->ssl_cert != NULL && conn->ssl_cert[0] != '\0')
+	    || conn->ssl_verify
+	    || (conn->ssl_tpm != NULL && conn->ssl_tpm[0] != '\0'))
 		conn->use_ssl = TRUE;
 
 	if (g_hash_table_lookup(optlist, "!") != NULL)
@@ -134,7 +138,8 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
         return conn;
 }
 
-/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ssl_cert <cert>] [-ssl_pkey <pkey>]
+/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ssl_tpm <SRK Pass>]
+                   [-ssl_cert <cert>] [-ssl_pkey <pkey>]
                    [-ssl_verify] [-ssl_cafile <cafile>] [-ssl_capath <capath>]
                    [-!] [-noautosendcmd]
 		   [-noproxy] [-network <network>] [-host <hostname>]
@@ -458,7 +463,7 @@ void chat_commands_init(void)
 	signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server);
 	signal_add("server sendmsg", (SIGNAL_FUNC) sig_server_sendmsg);
 
-	command_set_options("connect", "4 6 !! -network ssl +ssl_cert +ssl_pkey ssl_verify +ssl_cafile +ssl_capath +host noproxy -rawlog noautosendcmd");
+	command_set_options("connect", "4 6 !! -network ssl +ssl_tpm +ssl_cert +ssl_pkey ssl_verify +ssl_cafile +ssl_capath +host noproxy -rawlog noautosendcmd");
 	command_set_options("msg", "channel nick");
 }
 
diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c
index eaa51a1..c6b25e1 100644
--- a/src/core/network-openssl.c
+++ b/src/core/network-openssl.c
@@ -25,6 +25,7 @@
 #ifdef HAVE_OPENSSL
 
 #include <openssl/crypto.h>
+#include <openssl/engine.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
@@ -389,7 +390,113 @@ static gboolean irssi_ssl_init(void)
 
 }
 
-static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostname, const char *mycert, const char *mypkey, const char *cafile, const char *capath, gboolean verify)
+static char *ssl_tpm_for_ui_callback;
+/**
+ *
+ * Challenge: UI_get0_output_string(uis)
+ */
+static int
+ui_read(UI *ui, UI_STRING *uis)
+{
+	UI_set_result(ui, uis, ssl_tpm_for_ui_callback);
+	return 1;
+}
+
+/**
+ *
+ */
+static int
+ui_write(UI *ui, UI_STRING *uis)
+{
+        return 1;
+}
+
+/**
+ *
+ */
+static UI_METHOD*
+irssi_setup_ui_method(void)
+{
+        UI_METHOD *ui_method;
+        ui_method = UI_create_method((char*)"OpenSSL application user interface");
+        UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
+        UI_method_set_reader(ui_method, ui_read);
+        UI_method_set_writer(ui_method, ui_write);
+        UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
+        return ui_method;
+}
+
+static void irssi_print_ssl_error()
+{
+        char buf[1024];
+	int err = ERR_get_error();
+	ERR_error_string(err, buf);
+	g_warning("SSL error: %d: %s", err, buf);
+}
+
+static void irssi_ssl_load_credentials(SSL *ssl,
+				       SSL_CTX *ctx,
+				       const char *ssl_tpm,
+				       const char *mycert,
+				       const char *mypkey)
+{
+	char *scert = NULL, *spkey = NULL;
+	char *file_with_pkey;
+	char *myfile_with_pkey;
+
+	scert = convert_home(mycert);
+	if (mypkey && *mypkey) {
+		spkey = convert_home(mypkey);
+	}
+	if (! SSL_CTX_use_certificate_file(ctx, scert,
+					   SSL_FILETYPE_PEM)) {
+		g_warning("Loading of client certificate '%s' failed", mycert);
+		goto errout;
+	}
+
+	file_with_pkey = spkey ? spkey : scert;
+	myfile_with_pkey = mypkey ? mypkey : mycert;
+
+	if (ssl_tpm) {
+		ENGINE_load_builtin_engines();
+		ENGINE* engine = ENGINE_by_id("tpm");
+		if (!ENGINE_init(engine)) {
+			g_warning("Engine init failed");
+			goto errout;
+		}
+		UI_METHOD* ui_method = irssi_setup_ui_method();
+		UI* ui = UI_new_method(ui_method);
+		ssl_tpm_for_ui_callback = ssl_tpm;
+		EVP_PKEY* pkey = ENGINE_load_private_key(engine, file_with_pkey, ui_method, ssl_tpm);
+		if (! SSL_CTX_use_PrivateKey(ctx, pkey)) {
+			g_warning("Loading of TPM-protected private key '%s' failed", myfile_with_pkey);
+			goto errout;
+		}
+		UI_destroy_method(ui_method);
+	} else {
+		if (! SSL_CTX_use_PrivateKey_file(ctx, file_with_pkey,
+						  SSL_FILETYPE_PEM)) {
+			g_warning("Loading of private key '%s' failed",
+				  myfile_with_pkey);
+			goto errout;
+		}
+	}
+	if (! SSL_CTX_check_private_key(ctx)) {
+		g_warning("Private key does not match the certificate");
+		goto errout;
+	}
+
+ out:
+	g_free(scert);
+	g_free(spkey);
+	return;
+
+ errout:
+	irssi_print_ssl_error();
+	goto out;
+}
+
+static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostname, const char *ssl_tpm, const char *mycert, const char *mypkey, const char *cafile, const char *capath, gboolean verify)
 {
 	GIOSSLChannel *chan;
 	GIOChannel *gchan;
@@ -413,18 +520,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostn
 	SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
 
 	if (mycert && *mycert) {
-		char *scert = NULL, *spkey = NULL;
-		scert = convert_home(mycert);
-		if (mypkey && *mypkey)
-			spkey = convert_home(mypkey);
-		if (! SSL_CTX_use_certificate_file(ctx, scert, SSL_FILETYPE_PEM))
-			g_warning("Loading of client certificate '%s' failed", mycert);
-		else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM))
-			g_warning("Loading of private key '%s' failed", mypkey ? mypkey : mycert);
-		else if (! SSL_CTX_check_private_key(ctx))
-			g_warning("Private key does not match the certificate");
-		g_free(scert);
-		g_free(spkey);
+	        irssi_ssl_load_credentials(ssl, ctx, ssl_tpm, mycert, mypkey);
 	}
 
 	if ((cafile && *cafile) || (capath && *capath)) {
@@ -484,14 +580,14 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostn
 	return gchan;
 }
 
-GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, const char* hostname, IPADDR *my_ip, const char *cert, const char *pkey, const char *cafile, const char *capath, gboolean verify)
+GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, const char* hostname, IPADDR *my_ip, const char *ssl_tpm, const char *cert, const char *pkey, const char *cafile, const char *capath, gboolean verify)
 {
 	GIOChannel *handle, *ssl_handle;
 
 	handle = net_connect_ip(ip, port, my_ip);
 	if (handle == NULL)
 		return NULL;
-	ssl_handle  = irssi_ssl_get_iochannel(handle, hostname, cert, pkey, cafile, capath, verify);
+	ssl_handle  = irssi_ssl_get_iochannel(handle, hostname, ssl_tpm, cert, pkey, cafile, capath, verify);
 	if (ssl_handle == NULL)
 		g_io_channel_unref(handle);
 	return ssl_handle;
diff --git a/src/core/network.h b/src/core/network.h
index 142a179..75d92ea 100644
--- a/src/core/network.h
+++ b/src/core/network.h
@@ -49,7 +49,7 @@ int net_ip_compare(IPADDR *ip1, IPADDR *ip2);
 /* Connect to socket */
 GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip);
 /* Connect to socket with ip address and SSL*/
-GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, const char* hostname, IPADDR *my_ip, const char *cert, const char *pkey, const char *cafile, const char *capath, gboolean verify);
+GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, const char* hostname, IPADDR *my_ip, const char *ssl_tpm, const char *cert, const char *pkey, const char *cafile, const char *capath, gboolean verify);
 int irssi_ssl_handshake(GIOChannel *handle);
 /* Connect to socket with ip address */
 GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
diff --git a/src/core/server-connect-rec.h b/src/core/server-connect-rec.h
index a9588f0..e1d3bbb 100644
--- a/src/core/server-connect-rec.h
+++ b/src/core/server-connect-rec.h
@@ -23,6 +23,7 @@ char *nick;
 char *username;
 char *realname;
 
+char *ssl_tpm;
 char *ssl_cert;
 char *ssl_pkey;
 char *ssl_cafile;
diff --git a/src/core/server-setup-rec.h b/src/core/server-setup-rec.h
index b7a0c80..56f8cdc 100644
--- a/src/core/server-setup-rec.h
+++ b/src/core/server-setup-rec.h
@@ -8,6 +8,7 @@ char *address;
 int port;
 char *password;
 
+char *ssl_tpm;
 char *ssl_cert;
 char *ssl_pkey;
 char *ssl_cafile;
diff --git a/src/core/servers-reconnect.c b/src/core/servers-reconnect.c
index 15f9f35..c5f9720 100644
--- a/src/core/servers-reconnect.c
+++ b/src/core/servers-reconnect.c
@@ -192,6 +192,7 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
 	dest->no_autosendcmd = src->no_autosendcmd;
 
 	dest->use_ssl = src->use_ssl;
+	dest->ssl_tpm = g_strdup(src->ssl_tpm);
 	dest->ssl_cert = g_strdup(src->ssl_cert);
 	dest->ssl_pkey = g_strdup(src->ssl_pkey);
 	dest->ssl_verify = src->ssl_verify;
diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c
index 83b90db..52d6ac4 100644
--- a/src/core/servers-setup.c
+++ b/src/core/servers-setup.c
@@ -165,6 +165,8 @@ static void server_setup_fill_server(SERVER_CONNECT_REC *conn,
 		conn->port = sserver->port;
 
 	conn->use_ssl = sserver->use_ssl;
+	if (conn->ssl_tpm == NULL && sserver->ssl_tpm != NULL)
+		conn->ssl_tpm = g_strdup(sserver->ssl_tpm);
 	if (conn->ssl_cert == NULL && sserver->ssl_cert != NULL && sserver->ssl_cert[0] != '\0')
 		conn->ssl_cert = g_strdup(sserver->ssl_cert);
 	if (conn->ssl_pkey == NULL && sserver->ssl_pkey != NULL && sserver->ssl_pkey[0] != '\0')
@@ -394,6 +396,7 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node)
 	rec->address = g_strdup(server);
 	rec->password = g_strdup(config_node_get_str(node, "password", NULL));
 	rec->use_ssl = config_node_get_bool(node, "use_ssl", FALSE);
+	rec->ssl_tpm = g_strdup(config_node_get_str(node, "ssl_tpm", NULL));
 	rec->ssl_cert = g_strdup(config_node_get_str(node, "ssl_cert", NULL));
 	rec->ssl_pkey = g_strdup(config_node_get_str(node, "ssl_pkey", NULL));
 	rec->ssl_verify = config_node_get_bool(node, "ssl_verify", FALSE);
@@ -433,6 +436,7 @@ static void server_setup_save(SERVER_SETUP_REC *rec)
 	iconfig_node_set_int(node, "port", rec->port);
 	iconfig_node_set_str(node, "password", rec->password);
 	iconfig_node_set_bool(node, "use_ssl", rec->use_ssl);
+	iconfig_node_set_str(node, "ssl_tpm", rec->ssl_tpm);
 	iconfig_node_set_str(node, "ssl_cert", rec->ssl_cert);
 	iconfig_node_set_str(node, "ssl_pkey", rec->ssl_pkey);
 	iconfig_node_set_bool(node, "ssl_verify", rec->ssl_verify);
@@ -474,6 +478,7 @@ static void server_setup_destroy(SERVER_SETUP_REC *rec)
 	g_free_not_null(rec->own_ip6);
 	g_free_not_null(rec->chatnet);
 	g_free_not_null(rec->password);
+	g_free_not_null(rec->ssl_tpm);
 	g_free_not_null(rec->ssl_cert);
 	g_free_not_null(rec->ssl_pkey);
 	g_free_not_null(rec->ssl_cafile);
diff --git a/src/core/servers.c b/src/core/servers.c
index d4827b6..e96fa54 100644
--- a/src/core/servers.c
+++ b/src/core/servers.c
@@ -224,7 +224,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
 		port = server->connrec->proxy != NULL ?
 			server->connrec->proxy_port : server->connrec->port;
 		handle = server->connrec->use_ssl ?
-			net_connect_ip_ssl(ip, port, server->connrec->address, own_ip, server->connrec->ssl_cert, server->connrec->ssl_pkey,
+		        net_connect_ip_ssl(ip, port, server->connrec->address, own_ip, server->connrec->ssl_tpm, server->connrec->ssl_cert, server->connrec->ssl_pkey,
 server->connrec->ssl_cafile, server->connrec->ssl_capath, server->connrec->ssl_verify) :
 			net_connect_ip(ip, port, own_ip);
 	} else {
@@ -635,6 +635,7 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
         g_free_not_null(conn->username);
 	g_free_not_null(conn->realname);
 
+	g_free_not_null(conn->ssl_tpm);
 	g_free_not_null(conn->ssl_cert);
 	g_free_not_null(conn->ssl_pkey);
 	g_free_not_null(conn->ssl_cafile);
diff --git a/src/core/session.c b/src/core/session.c
index b300263..db0e128 100644
--- a/src/core/session.c
+++ b/src/core/session.c
@@ -160,6 +160,7 @@ static void session_save_server(SERVER_REC *server, CONFIG_REC *config,
 	config_node_set_str(config, node, "version", server->version);
 
 	config_node_set_bool(config, node, "use_ssl", server->connrec->use_ssl);
+	config_node_set_str(config, node, "ssl_tpm", server->connrec->ssl_tpm);
 	config_node_set_str(config, node, "ssl_cert", server->connrec->ssl_cert);
 	config_node_set_str(config, node, "ssl_pkey", server->connrec->ssl_pkey);
 	config_node_set_bool(config, node, "ssl_verify", server->connrec->ssl_verify);
diff --git a/src/fe-common/core/fe-server.c b/src/fe-common/core/fe-server.c
index e4b32bd..836e271 100644
--- a/src/fe-common/core/fe-server.c
+++ b/src/fe-common/core/fe-server.c
@@ -150,6 +150,10 @@ static void cmd_server_add(const char *data)
 	if (g_hash_table_lookup(optlist, "ssl"))
 		rec->use_ssl = TRUE;
 
+	value = g_hash_table_lookup(optlist, "ssl_tpm");
+	if (value != NULL)
+		rec->ssl_tpm = g_strdup(value);
+
 	value = g_hash_table_lookup(optlist, "ssl_cert");
 	if (value != NULL && *value != '\0')
 		rec->ssl_cert = g_strdup(value);
@@ -383,7 +387,7 @@ void fe_server_init(void)
 	command_bind("server remove", NULL, (SIGNAL_FUNC) cmd_server_remove);
 	command_bind_first("server", NULL, (SIGNAL_FUNC) server_command);
 	command_bind_first("disconnect", NULL, (SIGNAL_FUNC) server_command);
-	command_set_options("server add", "4 6 ssl +ssl_cert +ssl_pkey ssl_verify +ssl_cafile +ssl_capath auto noauto proxy noproxy -host -port");
+	command_set_options("server add", "4 6 ssl +ssl_tpm +ssl_cert +ssl_pkey ssl_verify +ssl_cafile +ssl_capath auto noauto proxy noproxy -host -port");
 
 	signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
 	signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting);
diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c
index 9bc6876..c4b5341 100644
--- a/src/fe-common/irc/fe-irc-server.c
+++ b/src/fe-common/irc/fe-irc-server.c
@@ -50,7 +50,8 @@ const char *get_visible_target(IRC_SERVER_REC *server, const char *target)
 
 	return target;
 }
-/* SYNTAX: SERVER ADD [-4 | -6] [-ssl] [-ssl_cert <cert>] [-ssl_pkey <pkey>]
+/* SYNTAX: SERVER ADD [-4 | -6] [-ssl] [-ssl_tpm <SRK password>]
+                      [-ssl_cert <cert>] [-ssl_pkey <pkey>]
                       [-ssl_verify] [-ssl_cafile <cafile>] [-ssl_capath <capath>]
                       [-auto | -noauto] [-network <network>] [-host <hostname>]
                       [-cmdspeed <ms>] [-cmdmax <count>] [-port <port>]
@@ -108,6 +109,10 @@ static void cmd_server_list(const char *data)
 			g_string_append(str, "noproxy, ");
 		if (rec->use_ssl) {
 			g_string_append(str, "ssl, ");
+			if (rec->ssl_tpm) {
+				g_string_append_printf(str, "ssl_tpm: %s, ",
+						       rec->ssl_tpm);
+			}
 			if (rec->ssl_cert) {
 				g_string_append_printf(str, "ssl_cert: %s, ", rec->ssl_cert);
 				if (rec->ssl_pkey)
