diff --git a/src/common/socket.h b/src/common/socket.h
index fb20233..dc4c5b9 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -61,8 +61,13 @@ struct _SockInfo
 #if USE_GNUTLS
 	gnutls_session_t ssl;
 	gnutls_certificate_credentials_t xcred;
+#if GNUTLS_VERSION_NUMBER < 0x030000
 	gnutls_x509_crt_t client_crt;
 	gnutls_x509_privkey_t client_key;
+#else
+	gnutls_pcert_st client_crt;
+	gnutls_privkey_t client_key;
+#endif /* GNUTLS_VERSION_NUMBER < 0x030000 */
 	gchar *gnutls_priority;
 #endif
 	guint g_source;
diff --git a/src/common/ssl.c b/src/common/ssl.c
index 6649878..48d2391 100644
--- a/src/common/ssl.c
+++ b/src/common/ssl.c
@@ -63,6 +63,10 @@ typedef struct _thread_data {
 #define DEFAULT_GNUTLS_PRIORITY "NORMAL"
 #endif
 
+#if GNUTLS_VERSION_NUMBER < 0x030000
+/* GnuTLS 3.0 introduced new API for certificate callback,
+ * gnutls_certificate_set_retrieve_function2() */
+
 #if GNUTLS_VERSION_NUMBER <= 0x020c00
 static int gnutls_client_cert_cb(gnutls_session_t session,
                                const gnutls_datum_t *req_ca_rdn, int nreqs,
@@ -73,7 +77,7 @@ static int gnutls_cert_cb(gnutls_session_t session,
                                const gnutls_datum_t *req_ca_rdn, int nreqs,
                                const gnutls_pk_algorithm_t *sign_algos,
                                int sign_algos_length, gnutls_retr2_st *st)
-#endif
+#endif /* GNUTLS_VERSION_NUMBER <= 0x020c00 */
 {
 	SSLClientCertHookData hookdata;
 	SockInfo *sockinfo = (SockInfo *)gnutls_session_get_ptr(session);
@@ -121,6 +125,70 @@ static int gnutls_cert_cb(gnutls_session_t session,
 	return 0;
 }
 
+#else /* GNUTLS_VERSION_NUMBER < 0x030000 */
+
+static int gnutls_cert_cb(gnutls_session_t session,
+		const gnutls_datum_t *req_ca_rdn,
+		int nreqs,
+		const gnutls_pk_algorithm_t *pk_algos,
+		int pk_algos_length,
+		gnutls_pcert_st **pcert,
+		unsigned int *pcert_length,
+		gnutls_privkey_t *privkey)
+{
+	SSLClientCertHookData hookdata;
+	SockInfo *sockinfo = (SockInfo *)gnutls_session_get_ptr(session);
+	gnutls_datum_t tmp;
+
+	hookdata.account = sockinfo->account;
+	hookdata.cert_path = NULL;
+	hookdata.password = NULL;
+	hookdata.is_smtp = sockinfo->is_smtp;
+	hooks_invoke(SSLCERT_GET_CLIENT_CERT_HOOKLIST, &hookdata);
+
+	if (hookdata.cert_path == NULL) {
+		g_free(hookdata.password);
+		return 0;
+	}
+
+	gnutls_privkey_init(&sockinfo->client_key);
+
+	if (gnutls_load_file(hookdata.cert_path, &tmp) != 0) {
+		debug_print("couldn't load file '%s'\n", hookdata.cert_path);
+		g_free(hookdata.password);
+		return 0;
+	}
+	debug_print("trying to load client cert+key from file '%s'\n",
+			hookdata.cert_path);
+
+	if (gnutls_pcert_import_x509_raw(&sockinfo->client_crt, &tmp,
+				GNUTLS_X509_FMT_PEM, 0) != 0) {
+		debug_print("couldn't import x509 cert from file '%s'\n",
+				hookdata.cert_path);
+		g_free(hookdata.password);
+		return 0;
+	}
+	debug_print("loaded certificate(s)...\n");
+
+	if (gnutls_privkey_import_x509_raw(sockinfo->client_key, &tmp,
+				GNUTLS_X509_FMT_PEM, hookdata.password, 0) != 0) {
+		debug_print("couldn't import x509 pkey from file '%s'\n",
+				hookdata.cert_path);
+		g_free(hookdata.password);
+		return 0;
+	}
+	debug_print("loaded private key...\n");
+
+	gnutls_free(tmp.data);
+
+	*pcert_length = 1;
+	*pcert = &sockinfo->client_crt;
+	*privkey = sockinfo->client_key;
+
+	return 0;
+}
+#endif /* GNUTLS_VERSION_NUMBER < 0x030000 */
+
 const gchar *claws_ssl_get_cert_file(void)
 {
 #ifndef G_OS_WIN32
@@ -358,10 +426,16 @@ gboolean ssl_init_socket(SockInfo *sockinfo)
 
 	gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) GINT_TO_POINTER(sockinfo->sock));
 	gnutls_session_set_ptr(session, sockinfo);
-#if GNUTLS_VERSION_NUMBER <= 0x020c00
+
+#if GNUTLS_VERSION_NUMBER < 0x030000
+#  if GNUTLS_VERSION_NUMBER <= 0x020c00
 	gnutls_certificate_client_set_retrieve_function(xcred, gnutls_client_cert_cb);
-#else
+#  else
 	gnutls_certificate_set_retrieve_function(xcred, gnutls_cert_cb);
+#  endif
+#else
+	debug_print("setting certificate callback function\n");
+	gnutls_certificate_set_retrieve_function2(xcred, gnutls_cert_cb);
 #endif
 
 #if GNUTLS_VERSION_NUMBER < 0x030107
@@ -412,12 +486,20 @@ void ssl_done_socket(SockInfo *sockinfo)
 		if (sockinfo->xcred)
 			gnutls_certificate_free_credentials(sockinfo->xcred);
 		gnutls_deinit(sockinfo->ssl);
+#if GNUTLS_VERSION_NUMBER < 0x030000
 		if (sockinfo->client_crt)
 			gnutls_x509_crt_deinit(sockinfo->client_crt);
 		if (sockinfo->client_key)
 			gnutls_x509_privkey_deinit(sockinfo->client_key);
 		sockinfo->client_key = NULL;
 		sockinfo->client_crt = NULL;
+#else
+//		if (&sockinfo->client_crt)
+			gnutls_pcert_deinit(&sockinfo->client_crt);
+		if (sockinfo->client_key)
+			gnutls_privkey_deinit(sockinfo->client_key);
+#endif
+		sockinfo->client_key = NULL;
 		sockinfo->xcred = NULL;
 		sockinfo->ssl = NULL;
 	}
diff --git a/src/common/ssl.h b/src/common/ssl.h
index 3d6523a..625976b 100644
--- a/src/common/ssl.h
+++ b/src/common/ssl.h
@@ -35,6 +35,10 @@ typedef enum {
 
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
+#if GNUTLS_VERSION_NUMBER >= 0x030000
+#include <gnutls/abstract.h>
+#endif
+
 #include "socket.h"
 
 void ssl_init				(void);
