diff --git a/configure.ac b/configure.ac
index aa0d674..2014e6e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,15 @@ AM_CONDITIONAL([ENABLE_GTK3], [test "$enable_gtk3" = yes])
 GTK_MODULE="$GTK_PACKAGE >= $gtk_minimum_version"
 AC_SUBST(GTK_MODULE)
 
+PKG_CHECK_EXISTS([gnome-certauth-0.0],[
+	gnome_certauth="yes"
+	AC_DEFINE([HAVE_GNOME_CERTAUTH], [1], [Define if you have gnome-certauth])
+])
+
+if test "x${gnome_certauth}" = "xyes"; then
+	PKG_CHECK_MODULES(GNOME_CERTAUTH, gnome-certauth-0.0 >= 0.0)
+fi
+	
 dnl *****************************
 dnl Check for GNOME Platform
 dnl *****************************
@@ -230,6 +239,7 @@ dnl *******************************
 EVO_PLUGIN_RULE=$srcdir/eplugin-rule.mk
 AC_SUBST_FILE(EVO_PLUGIN_RULE)
 
+
 dnl *******************
 dnl Special directories
 dnl *******************
diff --git a/src/account-setup-eplugin/exchange-ews-account-out-of-office.c b/src/account-setup-eplugin/exchange-ews-account-out-of-office.c
index 6134a0c..12107d6 100644
--- a/src/account-setup-eplugin/exchange-ews-account-out-of-office.c
+++ b/src/account-setup-eplugin/exchange-ews-account-out-of-office.c
@@ -249,7 +249,7 @@ get_connection (EMConfigTargetAccount *target)
 	/* Create a new connection */
 	password = get_password (target);
 
-	cnc = e_ews_connection_new (camel_url_get_param (url, "hosturl"), url->user, password, NULL, NULL, &error);
+	cnc = e_ews_connection_new (camel_url_get_param (url, "hosturl"), url->user, password, NULL, NULL, TRUE, &error);
 
 	if (!cnc) {
 		g_warning ("Error in connection: %s\n", error->message);
diff --git a/src/account-setup-eplugin/exchange-ews-account-setup.c b/src/account-setup-eplugin/exchange-ews-account-setup.c
index 574f317..1b8e819 100644
--- a/src/account-setup-eplugin/exchange-ews-account-setup.c
+++ b/src/account-setup-eplugin/exchange-ews-account-setup.c
@@ -527,9 +527,11 @@ fetch_button_clicked_cb (GtkButton *button, gpointer user_data)
 	password = get_password (target);
 
 	/* pass user name while creating connection  to fetch oals */
-	cnc = e_ews_connection_new (oab_url, url->user, password, NULL, NULL, NULL);
+	cnc = e_ews_connection_new (oab_url, url->user, password, NULL, NULL, FALSE, NULL);
 	cbdata->cancellable = cancellable;
-	e_ews_connection_get_oal_list_start (cnc, ews_oal_list_ready, cancellable, cbdata);
+	
+	if (cnc)
+		e_ews_connection_get_oal_list_start (cnc, ews_oal_list_ready, cancellable, cbdata);
 
 	camel_url_free (url);
 	g_free (password);
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 371f58e..33c21d7 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -1537,7 +1537,7 @@ ews_download_full_gal (EBookBackendEws *cbews, EwsOALDetails *full, GCancellable
 	cache_dir = ews_get_cache_dir (E_BOOK_BACKEND (cbews), source);
 	comp_cache_file = g_build_filename (cache_dir, full->filename, NULL);
 
-	oab_cnc = e_ews_connection_new (full_url, priv->username, priv->password, NULL, NULL, NULL);
+	oab_cnc = e_ews_connection_new (full_url, priv->username, priv->password, NULL, NULL, FALSE, NULL);
 	if (!e_ews_connection_download_oal_file (oab_cnc, comp_cache_file, NULL, NULL, cancellable, error))
 		goto exit;
 
@@ -1675,7 +1675,7 @@ ebews_start_gal_sync	(gpointer data)
 	priv = cbews->priv;
 
 	cancellable = g_cancellable_new ();
-	oab_cnc = e_ews_connection_new (priv->oab_url, priv->username, priv->password, NULL, NULL, NULL);
+	oab_cnc = e_ews_connection_new (priv->oab_url, priv->username, priv->password, NULL, NULL, FALSE, NULL);
 
 	d(printf ("Ewsgal: Fetching oal full details file \n");)
 
@@ -2431,7 +2431,7 @@ e_book_backend_ews_authenticate_user (EBookBackend *backend,
 		read_only = e_source_get_property (esource, "read_only");
 
 		priv->cnc = e_ews_connection_new (host_url, user, passwd,
-						  NULL, NULL, &error);
+						  NULL, NULL, TRUE, &error);
 
 		if ((read_only && !strcmp (read_only, "true")) || priv->is_gal) {
 			priv->is_writable = FALSE;
@@ -2764,7 +2764,7 @@ e_book_backend_ews_authenticate_user (EBookBackend *backend,
 
 		priv->cnc = e_ews_connection_new (host_url, e_credentials_peek (credentials, E_CREDENTIALS_KEY_USERNAME), 
 						  e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD),
-						  NULL, NULL, &error);
+						  NULL, NULL, TRUE, &error);
 
 		if ((read_only && !strcmp (read_only, "true")) || priv->is_gal) {
 			priv->is_writable = FALSE;
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 34dc0e4..bda7673 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -222,6 +222,7 @@ e_cal_backend_ews_get_static_capabilities (ECalBackend *backend, EDataCal *cal)
 			 CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK ","
 		//	 CAL_STATIC_CAPABILITY_NO_CONV_TO_RECUR ","
 			 CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT ","
+			 CAL_STATIC_CAPABILITY_SMART_CARD_AUTH_SUPPORTED ","
 			 CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
 
 	e_data_cal_notify_static_capabilities (cal, 0, capabilities);
@@ -282,6 +283,8 @@ e_cal_backend_ews_set_mode (ECalBackend *backend, CalMode mode)
 		e_cal_backend_notify_mode (backend, GNOME_Evolution_Calendar_CalListener_MODE_SET,
 						GNOME_Evolution_Calendar_MODE_REMOTE);
 		e_cal_backend_notify_readonly (backend, priv->read_only);
+
+		/*FIXME auth_requred notification should inform the client whether an authentication prompt is required or not */
 		if (e_cal_backend_ews_is_loaded (backend))
 			      e_cal_backend_notify_auth_required (backend);
 		break;
@@ -741,6 +744,7 @@ connect_to_server (ECalBackendEws *cbews, const gchar *username, const gchar *pa
 
 	if (priv->mode != GNOME_Evolution_Calendar_MODE_LOCAL && !priv->cnc && password) {
 		const gchar *host_url;
+		GError *err = NULL;
 
 		/* If we can be called a second time while the first is still
 		   "outstanding", we need a bit of a rethink... */
@@ -750,7 +754,16 @@ connect_to_server (ECalBackendEws *cbews, const gchar *username, const gchar *pa
 
 		host_url = e_source_get_property (esource, "hosturl");
 		priv->cnc = e_ews_connection_new (host_url, username, password,
-						  NULL, NULL, error);
+						  NULL, NULL, TRUE, &err);
+
+		/* This will trigger a authentication prompt in case the certicate based authentication fails */
+		if (!priv->cnc && err->code == EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED) {
+			      e_cal_backend_notify_auth_required (E_CAL_BACKEND (cbews));
+		}
+
+		if (err)
+			g_propagate_error (error, err);
+		
 		/* Trigger an update request, which will test our authentication */
 		if (priv->cnc) {
 			ews_start_sync (cbews);
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 0e82e0f..969606c 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -260,6 +260,7 @@ ews_connect_sync (CamelService *service, EVO3(GCancellable *cancellable,) GError
 	CamelEwsStore *ews_store;
 	CamelEwsStorePrivate *priv;
 	CamelURL *url;
+	GError *err = NULL;
 
 	ews_store = (CamelEwsStore *) service;
 	priv = ews_store->priv;
@@ -276,12 +277,22 @@ ews_connect_sync (CamelService *service, EVO3(GCancellable *cancellable,) GError
 	}
 
 	priv->cnc = e_ews_connection_new (priv->host_url, url->user, NULL,
-					  G_CALLBACK (ews_store_authenticate), service,
-					  error);
+					  NULL, NULL, TRUE, &err);
+	
+	/* Fallback to password based authentication if we are not using smart-card based one. It would be better 
+	   to have a preference option for this. */
+	if (!priv->cnc && err->code == EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)
+	{
+		g_clear_error (&err);
+		priv->cnc = e_ews_connection_new (priv->host_url, url->user, NULL,
+				G_CALLBACK (ews_store_authenticate), service, TRUE,
+				&err);
+	}
 
 	if (!priv->cnc) {
 		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 		EVO3_sync(camel_service_disconnect) (service, TRUE, NULL);
+		g_propagate_error (error, err);
 		return FALSE;
 	}
 
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index 66d9184..1389508 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -26,6 +26,7 @@ libeews_1_2_la_CPPFLAGS = \
 	$(LIBECAL_CFLAGS)				\
 	$(LIBICAL_CFLAGS)				\
 	$(LIBEDATASERVER_CFLAGS)			\
+	$(GNOME_CERTAUTH_CFLAGS)			\
 	$(DEBUG_CFLAGS)
 
 libeews_1_2_la_SOURCES =		\
@@ -50,6 +51,7 @@ libeews_1_2_la_LIBADD =						\
 	$(LIBECAL_LIBS)						\
 	$(LIBICAL_LIBS)						\
 	$(LIBEDATASERVER_LIBS)					\
+	$(GNOME_CERTAUTH_LIBS)					\
 	$(SOCKET_LIBS)
 
 libeews_1_2_la_LDFLAGS = $(NO_UNDEFINED)
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 4d18509..9ca44d1 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -40,6 +40,10 @@
 #include "e-ews-item-change.h"
 #include "ews-marshal.h"
 
+#ifdef HAVE_GNOME_CERTAUTH
+#include <gnome-certauth/gca-nss.h>
+#endif /* HAVE_GNOME_CERTAUTH */
+
 #define d(x) x
 
 /* For the number of connections */
@@ -473,6 +477,8 @@ ews_response_cb (SoupSession *session, SoupMessage *msg, gpointer data)
 	}
 
 exit:
+	g_object_ref (enode->cnc);
+	
 	if (enode->complete_sync) {
 		GAsyncResult *async = G_ASYNC_RESULT (enode->simple);
 
@@ -487,6 +493,8 @@ exit:
 		g_simple_async_result_complete_in_idle (enode->simple);
 	}
 	ews_active_job_done (enode->cnc, enode);
+	
+	g_object_unref (enode->cnc);
 }
 
 typedef gpointer (*ItemParser) (ESoapParameter *param);
@@ -856,9 +864,12 @@ e_ews_connection_dispose (GObject *object)
 
 	if (priv->soup_session) {
 		g_main_loop_quit(priv->soup_loop);
-		g_thread_join(priv->soup_thread);
+//		g_thread_join(priv->soup_thread);
 		priv->soup_thread = NULL;
 
+		g_object_unref (priv->soup_session);
+		priv->soup_session = NULL;
+
 		g_main_loop_unref(priv->soup_loop);
 		priv->soup_loop = NULL;
 		g_main_context_unref(priv->soup_context);
@@ -950,10 +961,10 @@ static gpointer e_ews_soup_thread (gpointer user_data)
 
 	g_main_context_push_thread_default (priv->soup_context);
 	g_main_loop_run (priv->soup_loop);
-	g_main_context_pop_thread_default (priv->soup_context);
+//	g_main_context_pop_thread_default (priv->soup_context);
 
-	g_object_unref (priv->soup_session);
-	priv->soup_session = NULL;
+//	g_object_unref (priv->soup_session);
+//	priv->soup_session = NULL;
 
 	return NULL;
 }
@@ -970,7 +981,7 @@ e_ews_connection_init (EEwsConnection *cnc)
 	priv->soup_context = g_main_context_new ();
 	priv->soup_loop = g_main_loop_new (priv->soup_context, FALSE);
 
-	priv->soup_thread = g_thread_create(e_ews_soup_thread, priv, TRUE, NULL);
+	priv->soup_thread = g_thread_create(e_ews_soup_thread, priv, FALSE, NULL);
 
 	/* create the SoupSession for this connection */
 	priv->soup_session = soup_session_async_new_with_options (SOUP_SESSION_USE_NTLM, TRUE,
@@ -1084,6 +1095,37 @@ e_ews_connection_find (const gchar *uri, const gchar *username)
 	return NULL;
 }
 
+
+#ifdef HAVE_GNOME_CERTAUTH
+static int
+session_certificate_requested (SoupSession *session,
+		const gnutls_datum_t *req_ca_rdn,
+		int nreqs,
+		gnutls_datum_t **cert_der_ret,
+		int *cert_der_ret_length,
+		gpointer user_data)
+{
+	d(g_print ("EwsConnection: Certificate requested \n");)
+	gca_nss_request_certificate (req_ca_rdn, nreqs,
+			cert_der_ret, cert_der_ret_length);
+
+	return 0;
+}
+
+static int
+session_sign_data (SoupSession *session,
+		gnutls_datum_t *cert,
+		const gnutls_datum_t *hash_data,
+		gnutls_datum_t *sig_data,
+		gpointer user_data)
+{
+	d(g_print ("EwsConnection: Certificate sign data \n");)
+	gca_nss_sign_data (cert, hash_data, sig_data);
+
+	return 0;
+}
+#endif /* HAVE_GNOME_CERTAUTH */
+
 /**
  * e_ews_connection_new
  * @uri: Exchange server uri
@@ -1098,11 +1140,14 @@ e_ews_connection_find (const gchar *uri, const gchar *username)
  **/
 EEwsConnection *
 e_ews_connection_new (const gchar *uri, const gchar *username, const gchar *password,
-		      GCallback authenticate_cb, gpointer authenticate_ctx,
+		      GCallback authenticate_cb, gpointer authenticate_ctx, gboolean check_ews_auth,
 		      GError **error)
 {
 	EEwsConnection *cnc;
 	gchar *hash_key;
+	GError *err = NULL;
+	GSList *folders = NULL, *ids = NULL;
+	EwsFolderId *fid = NULL;
 
 	g_static_mutex_lock (&connecting);
 
@@ -1132,6 +1177,34 @@ e_ews_connection_new (const gchar *uri, const gchar *username, const gchar *pass
 	if (authenticate_cb)
 		g_signal_connect (cnc, "authenticate",
 				  authenticate_cb, authenticate_ctx);
+	
+#ifdef HAVE_GNOME_CERTAUTH
+	g_signal_connect (cnc->priv->soup_session, "certificate-requested",
+			  G_CALLBACK (session_certificate_requested), cnc);
+	g_signal_connect (cnc->priv->soup_session, "sign-data",
+			  G_CALLBACK (session_sign_data), cnc);
+#endif /* HAVE_GNOME_CERTAUTH */
+
+	if (check_ews_auth)
+	{
+		/* a dummy request to make sure we have a authenticated connection */
+		fid = g_new0 (EwsFolderId, 1);
+		fid->id = g_strdup ("contacts");
+		fid->is_distinguished_id = TRUE;
+		ids = g_slist_append (ids, fid);
+		e_ews_connection_get_folder (cnc, EWS_PRIORITY_MEDIUM, "Default", NULL, ids, &folders, NULL, &err);
+
+		e_ews_folder_free_fid (fid);
+		g_slist_free (ids);
+		ids = NULL;
+
+		if (err) {
+			g_propagate_error (error, err);
+			g_object_unref (cnc);
+			g_static_mutex_unlock (&connecting);
+			return NULL;
+		}
+	}
 
 	/* add the connection to the loaded_connections_permissions hash table */
 	hash_key = g_strdup_printf ("%s@%s",
@@ -1142,6 +1215,7 @@ e_ews_connection_new (const gchar *uri, const gchar *username, const gchar *pass
 				g_free, NULL);
 	g_hash_table_insert (loaded_connections_permissions, hash_key, cnc);
 
+
 	/* free memory */
 	g_static_mutex_unlock (&connecting);
 	return cnc;
@@ -1448,7 +1522,7 @@ e_ews_autodiscover_ws_url (EEwsAutoDiscoverCallback cb, gpointer cbdata,
 	url3 = g_strdup_printf ("http%s://%s/autodiscover/autodiscover.xml", use_secure ? "s" : "", domain);
 	url4 = g_strdup_printf ("http%s://autodiscover.%s/autodiscover/autodiscover.xml", use_secure ? "s" : "", domain);
 
-	cnc = e_ews_connection_new (url3, (username && *username) ? username : email, password, NULL, NULL, &error);
+	cnc = e_ews_connection_new (url3, (username && *username) ? username : email, password, NULL, NULL, FALSE, &error);
 	if (!cnc) {
 		g_free (url1);
 		g_free (url2);
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 1f47ba8..24d8a46 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -185,6 +185,7 @@ EEwsConnection *e_ews_connection_new		(const gchar *uri,
 						 const gchar *password,
 						 GCallback authenticate_cb,
 						 gpointer authenticate_ctx,
+						 gboolean check_ews_auth,
 						 GError **error);
 EEwsConnection *e_ews_connection_find		(const gchar *uri,
 						 const gchar *username);
diff --git a/src/utils/ews-test-finditem-query.c b/src/utils/ews-test-finditem-query.c
index 3818870..5bfed97 100644
--- a/src/utils/ews-test-finditem-query.c
+++ b/src/utils/ews-test-finditem-query.c
@@ -107,7 +107,7 @@ op_test_finditem_run (void)
 	g_assert_cmpstr (password, !=, NULL);
 	g_assert_cmpstr (uri, !=, NULL);
 
-	cnc = e_ews_connection_new (uri, username, password, NULL, NULL, NULL);
+	cnc = e_ews_connection_new (uri, username, password, NULL, NULL, TRUE, NULL);
 	g_assert (cnc != NULL);
 
 	/*Along with finditem api we check query conversion too*/
