diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index 6b291cb..c15be06 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -56,6 +56,7 @@
 #include "wireless-dialog.h"
 #include "applet-polkit-manager.h"
 #include "applet-menu-item.h"
+#include "gconf-helpers.h"
 
 #define PREF_SUPPRESS_WIRELESS_NEWORKS_AVAILABLE    APPLET_PREFS_PATH "/suppress-wireless-networks-available"
 
@@ -1460,6 +1461,227 @@ wireless_dialog_auth_end_cb (PolKitGnomeAction *action, gboolean gained_privileg
     wireless_menu_item_info_destroy (user_data);
 }
 
+typedef struct {
+	GtkDialog *dialog;
+	guint ca_cert_id;
+	guint timeout_id;
+	NMDevice *device;
+} WirelessDialogInfo;
+
+static gboolean
+need_ca_cert_probe (NMConnection *connection)
+{
+	NMSetting8021x *s_8021x;
+	int i, num_eap;
+	char *subject, *ca_hash, *ca_path;
+	gboolean need_ca = FALSE;
+
+	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	if (!s_8021x)
+		return FALSE;
+
+	num_eap = nm_setting_802_1x_get_num_eap_methods (s_8021x);
+	for (i = 0; i < num_eap; i++) {
+		const char *eap;
+		eap = nm_setting_802_1x_get_eap_method (s_8021x, i);
+		if (   g_strcmp0 (eap, "ttls") == 0
+		    || g_strcmp0 (eap, "peap") == 0) {
+			need_ca = TRUE;
+			break;
+		}
+	}
+
+	if (!need_ca)
+		return FALSE;
+
+	subject = g_object_get_data (G_OBJECT (connection), NMA_SERVER_SUBJECT_TAG);
+	ca_hash = g_object_get_data (G_OBJECT (connection), NMA_SERVER_CERT_HASH_TAG);
+	ca_path = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
+
+	if (!subject || (!ca_hash && !ca_path))
+		return TRUE;
+
+	return FALSE;
+}
+
+static gboolean
+show_probe_result_dialog (NMConnection *connection,
+                          NMSetting8021x *s_8021x,
+                          const char *subject,
+                          const char *hash)
+{
+	GtkWidget *notify_dialog, *content;
+	GtkWidget *table;
+	GtkWidget *context, *label, *entry;
+	NMSettingConnection *s_con;
+	char *id, *string;
+	int response_id;
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	id = (char *) nm_setting_connection_get_id (s_con);
+
+	notify_dialog = gtk_dialog_new_with_buttons (id, NULL,
+	                                             GTK_DIALOG_MODAL,
+	                                             GTK_STOCK_NO, GTK_RESPONSE_NO,
+	                                             GTK_STOCK_YES, GTK_RESPONSE_YES,
+	                                             NULL);
+	content = gtk_dialog_get_content_area (GTK_DIALOG (notify_dialog));
+
+	table = gtk_table_new (2, 3, FALSE);
+	gtk_table_set_row_spacings (GTK_TABLE (table), 10);
+	gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+	gtk_container_add (GTK_CONTAINER (content), table);
+
+	entry = gtk_entry_new ();
+	gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE);
+	if (   g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG)
+            || nm_setting_802_1x_get_system_ca_certs (s_8021x)) {
+		string = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">Server Certificate Probed</span>\n\nThe subject of <b>%s</b> is going to be filled with the probe result. Do you agree?"),
+		                          id);
+		label = gtk_label_new (_("Subject:"));
+		gtk_entry_set_text (GTK_ENTRY (entry), subject);
+	} else {
+		char *ca_hash;
+		string = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">Server Certificate Probed</span>\n\nThe CA certificate of <b>%s</b> is going to be filled with the probed server hash. Do you agree?"),
+		                          id);
+		label = gtk_label_new (_("CA Certificate:"));
+		ca_hash = g_strconcat ("hash://server/sha256/", hash, NULL);
+		gtk_entry_set_text (GTK_ENTRY (entry), ca_hash);
+		g_free (ca_hash);
+	}
+	context = gtk_label_new (string);
+	g_free (string);
+	gtk_label_set_line_wrap (GTK_LABEL (context), TRUE);
+	gtk_label_set_use_markup (GTK_LABEL (context), TRUE);
+	gtk_table_attach (GTK_TABLE (table), context, 0, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+	gtk_table_attach (GTK_TABLE (table), entry, 1, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+	gtk_widget_show_all (notify_dialog);
+
+	response_id = gtk_dialog_run (GTK_DIALOG (notify_dialog));
+
+	gtk_widget_destroy (notify_dialog);
+
+	if (response_id == GTK_RESPONSE_YES)
+		return TRUE;
+
+	return FALSE;
+}
+
+static void
+wireless_ca_cert_cb (NMDeviceWifi *wifi,
+                     GHashTable *ca_cert,
+                     gpointer user_data)
+{
+	WirelessDialogInfo *info = (WirelessDialogInfo *) user_data;
+	NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (info->dialog);
+	NMDevice *device = NULL;
+	NMAccessPoint *ap = NULL;
+	NMSetting8021x *s_8021x;
+	NMConnection *connection = NULL;
+	gboolean response = FALSE;
+
+	connection = nma_wireless_dialog_get_connection (dialog, &device, &ap);
+	g_assert (connection);
+	g_assert (device);
+
+	g_signal_handler_disconnect (wifi, info->ca_cert_id);
+	if (info->timeout_id) {
+		g_source_remove (info->timeout_id);
+		info->timeout_id = 0;
+	}
+
+	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	if (s_8021x) {
+		char *subject, *hash;
+		subject = g_hash_table_lookup (ca_cert, "subject");
+		hash = g_hash_table_lookup (ca_cert, "hash");
+
+		if (!subject || !hash)
+			goto error;
+
+		if (   !nm_setting_802_1x_get_subject_match (s_8021x)
+		    || !g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG))
+			if (!show_probe_result_dialog (connection, s_8021x, subject, hash))
+				goto error;
+
+		if (!g_object_get_data (G_OBJECT (connection), NMA_SERVER_SUBJECT_TAG)) {
+			g_object_set_data_full (G_OBJECT (connection),
+		                                NMA_SERVER_SUBJECT_TAG, g_strdup (subject),
+		                                (GDestroyNotify) g_free);
+		}
+
+		if (!g_object_get_data (G_OBJECT (connection), NMA_SERVER_CERT_HASH_TAG)) {
+			g_object_set_data_full (G_OBJECT (connection),
+		                                NMA_SERVER_CERT_HASH_TAG, g_strdup (hash),
+		                                (GDestroyNotify) g_free);
+		}
+
+		response = TRUE;
+	}
+
+error:
+	if (response)
+		gtk_dialog_response (info->dialog, GTK_RESPONSE_OK);
+	else
+		gtk_widget_show (GTK_WIDGET (dialog));
+
+	g_free (info);
+}
+
+static gboolean
+wireless_ca_cert_probe_timeout_cb (gpointer user_data)
+{
+	WirelessDialogInfo *info = (WirelessDialogInfo *)user_data;
+	NMDeviceWifi *wifi = NM_DEVICE_WIFI (info->device);
+
+	info->timeout_id = 0;
+
+	g_signal_handler_disconnect (wifi, info->ca_cert_id);
+
+	gtk_widget_show (GTK_WIDGET (info->dialog));
+
+	g_free (info);
+
+	return FALSE;
+}
+
+static gboolean
+start_ca_cert_probe_timeout (GtkDialog *dialog,
+                             NMDevice *device,
+                             NMConnection *connection)
+{
+	NMSettingWireless *s_wireless;
+	WirelessDialogInfo *dialog_info;
+	guint id;
+
+	s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	if (!nm_device_wifi_probe_ca_cert (NM_DEVICE_WIFI (device), nm_setting_wireless_get_ssid (s_wireless)))
+		return FALSE;
+
+	dialog_info = g_new (WirelessDialogInfo, 1);
+	dialog_info->dialog = dialog;
+	dialog_info->device = device;
+
+	id = g_timeout_add_seconds (30,
+	                            (GSourceFunc)wireless_ca_cert_probe_timeout_cb,
+	                            (gpointer)dialog_info);
+	if (id <= 0) {
+		g_warning ("Failed to add timeout for CA certificate probe");
+		return FALSE;
+	}
+	dialog_info->timeout_id = id;
+
+	id = g_signal_connect (NM_DEVICE_WIFI (device), "ca-cert-received",
+	                       G_CALLBACK (wireless_ca_cert_cb), dialog_info);
+	dialog_info->ca_cert_id = id;
+
+	gtk_widget_hide (GTK_WIDGET (dialog));
+
+	return TRUE;
+}
+
 static void
 wireless_dialog_response_cb (GtkDialog *foo,
                              gint response,
@@ -1496,6 +1718,11 @@ wireless_dialog_response_cb (GtkDialog *foo,
 	g_assert (connection);
 	g_assert (device);
 
+	if (need_ca_cert_probe (connection)) {
+		start_ca_cert_probe_timeout (foo, device, connection);
+		return;
+	}
+
 	gconf_connection = nma_gconf_settings_get_by_connection (applet->gconf_settings, connection);
 	if (gconf_connection) {
 		/* Not a new or system connection, save the updated settings to GConf */
diff --git a/src/applet.glade b/src/applet.glade
index eee1442..156d944 100644
--- a/src/applet.glade
+++ b/src/applet.glade
@@ -1977,7 +1977,7 @@ Shared Key</property>
       <child>
 	<widget class="GtkTable" id="table10">
 	  <property name="visible">True</property>
-	  <property name="n_rows">5</property>
+	  <property name="n_rows">7</property>
 	  <property name="n_columns">2</property>
 	  <property name="homogeneous">False</property>
 	  <property name="row_spacing">6</property>
@@ -2052,8 +2052,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">1</property>
-	      <property name="top_attach">1</property>
-	      <property name="bottom_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options"></property>
 	    </packing>
@@ -2072,8 +2072,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">1</property>
-	      <property name="bottom_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
@@ -2092,8 +2092,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">4</property>
-	      <property name="bottom_attach">5</property>
+	      <property name="top_attach">6</property>
+	      <property name="bottom_attach">7</property>
 	      <property name="x_options">fill</property>
 	    </packing>
 	  </child>
@@ -2119,8 +2119,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">1</property>
-	      <property name="top_attach">3</property>
-	      <property name="bottom_attach">4</property>
+	      <property name="top_attach">5</property>
+	      <property name="bottom_attach">6</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options"></property>
 	    </packing>
@@ -2136,8 +2136,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">3</property>
-	      <property name="bottom_attach">4</property>
+	      <property name="top_attach">5</property>
+	      <property name="bottom_attach">6</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
@@ -2158,12 +2158,73 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">2</property>
-	      <property name="bottom_attach">3</property>
+	      <property name="top_attach">3</property>
+	      <property name="bottom_attach">4</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
 	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="eap_ttls_subject_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Subject:</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkEntry" id="eap_ttls_subject_entry">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="editable">True</property>
+	      <property name="visibility">True</property>
+	      <property name="max_length">0</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="activates_default">False</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+          <child>
+            <widget class="GtkLabel" id="eap_ttls_note_label">
+              <property name="visible">True</property>
+              <property name="label" translatable="yes">Note</property>
+              <property name="track_visited_links">False</property>
+            </widget>
+            <packing>
+              <property name="right_attach">2</property>
+              <property name="top_attach">4</property>
+              <property name="bottom_attach">5</property>
+            </packing>
+          </child>
 	</widget>
 	<packing>
 	  <property name="tab_expand">False</property>
@@ -2815,7 +2876,7 @@ Shared Key</property>
       <child>
 	<widget class="GtkTable" id="table13">
 	  <property name="visible">True</property>
-	  <property name="n_rows">6</property>
+	  <property name="n_rows">8</property>
 	  <property name="n_columns">2</property>
 	  <property name="homogeneous">False</property>
 	  <property name="row_spacing">6</property>
@@ -2890,8 +2951,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">1</property>
-	      <property name="top_attach">1</property>
-	      <property name="bottom_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options"></property>
 	    </packing>
@@ -2910,8 +2971,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">1</property>
-	      <property name="bottom_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
@@ -2930,8 +2991,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">5</property>
-	      <property name="bottom_attach">6</property>
+	      <property name="top_attach">7</property>
+	      <property name="bottom_attach">8</property>
 	      <property name="x_options">fill</property>
 	    </packing>
 	  </child>
@@ -2957,8 +3018,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">1</property>
-	      <property name="top_attach">4</property>
-	      <property name="bottom_attach">5</property>
+	      <property name="top_attach">6</property>
+	      <property name="bottom_attach">7</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options"></property>
 	    </packing>
@@ -2985,8 +3046,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">0</property>
 	      <property name="right_attach">1</property>
-	      <property name="top_attach">3</property>
-	      <property name="bottom_attach">4</property>
+	      <property name="top_attach">5</property>
+	      <property name="bottom_attach">6</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options"></property>
 	    </packing>
@@ -3002,8 +3063,8 @@ Shared Key</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">4</property>
-	      <property name="bottom_attach">5</property>
+	      <property name="top_attach">6</property>
+	      <property name="bottom_attach">7</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
@@ -3021,8 +3082,8 @@ Version 1</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">3</property>
-	      <property name="bottom_attach">4</property>
+	      <property name="top_attach">5</property>
+	      <property name="bottom_attach">6</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
@@ -3043,12 +3104,73 @@ Version 1</property>
 	    <packing>
 	      <property name="left_attach">1</property>
 	      <property name="right_attach">2</property>
-	      <property name="top_attach">2</property>
-	      <property name="bottom_attach">3</property>
+	      <property name="top_attach">3</property>
+	      <property name="bottom_attach">4</property>
 	      <property name="x_options">fill</property>
 	      <property name="y_options">fill</property>
 	    </packing>
 	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="eap_peap_subject_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Subject:</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkEntry" id="eap_peap_subject_entry">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="editable">True</property>
+	      <property name="visibility">True</property>
+	      <property name="max_length">0</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="activates_default">False</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+          <child>
+            <widget class="GtkLabel" id="eap_peap_note_label">
+              <property name="visible">True</property>
+              <property name="label" translatable="yes">Note</property>
+              <property name="track_visited_links">False</property>
+            </widget>
+            <packing>
+              <property name="right_attach">2</property>
+              <property name="top_attach">4</property>
+              <property name="bottom_attach">5</property>
+            </packing>
+          </child>
 	</widget>
 	<packing>
 	  <property name="tab_expand">False</property>
diff --git a/src/gconf-helpers/gconf-helpers.c b/src/gconf-helpers/gconf-helpers.c
index 5faf3cc..4eb3005 100644
--- a/src/gconf-helpers/gconf-helpers.c
+++ b/src/gconf-helpers/gconf-helpers.c
@@ -1165,6 +1165,7 @@ read_applet_private_values_from_gconf (NMSetting *setting,
 {
 	const char *setting_name = nm_setting_get_name (setting);
 	gboolean value;
+	char *string;
 	GError *error = NULL;
 
 	if (!NM_IS_SETTING_802_1X (setting))
@@ -1186,6 +1187,26 @@ read_applet_private_values_from_gconf (NMSetting *setting,
 		                   GUINT_TO_POINTER (value));
 	}
 
+	string = NULL;
+	if (nm_gconf_get_string_helper (info->client, info->dir,
+	                                NMA_SERVER_CERT_HASH_TAG,
+	                                setting_name, &string)) {
+		g_object_set_data_full (G_OBJECT (info->connection),
+	                                NMA_SERVER_CERT_HASH_TAG,
+	                                string,
+	                                (GDestroyNotify) g_free);
+	}
+
+	string = NULL;
+	if (nm_gconf_get_string_helper (info->client, info->dir,
+	                                NMA_SERVER_SUBJECT_TAG,
+	                                setting_name, &string)) {
+		g_object_set_data_full (G_OBJECT (info->connection),
+	                                NMA_SERVER_SUBJECT_TAG,
+	                                string,
+	                                (GDestroyNotify) g_free);
+	}
+
 	/* Binary certificate and key data doesn't get stored in GConf.  Instead,
 	 * the path to the certificate gets stored in a special key and the
 	 * certificate is read and stuffed into the setting right before
@@ -1568,6 +1589,9 @@ write_applet_private_values_to_gconf (CopyOneSettingValueInfo *info)
 		write_one_private_string_value (info, NMA_PATH_PHASE2_CLIENT_CERT_TAG);
 		write_one_private_string_value (info, NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
 
+		write_one_private_string_value (info, NMA_SERVER_CERT_HASH_TAG);
+		write_one_private_string_value (info, NMA_SERVER_SUBJECT_TAG);
+
 		write_one_password (info, NMA_PRIVATE_KEY_PASSWORD_TAG);
 		write_one_password (info, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG);
 	}
@@ -1923,6 +1947,9 @@ nm_gconf_copy_private_connection_values (NMConnection *dst, NMConnection *src)
 	copy_str_item (dst, src, NMA_PRIVATE_KEY_PASSWORD_TAG);
 	copy_str_item (dst, src, NMA_PATH_PHASE2_PRIVATE_KEY_TAG);
 	copy_str_item (dst, src, NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG);
+
+	copy_str_item (dst, src, NMA_SERVER_CERT_HASH_TAG);
+	copy_str_item (dst, src, NMA_SERVER_SUBJECT_TAG);
 }
 
 void
@@ -1941,6 +1968,9 @@ nm_gconf_clear_private_connection_values (NMConnection *connection)
 	g_object_set_data (G_OBJECT (connection), NMA_PRIVATE_KEY_PASSWORD_TAG, NULL);
 	g_object_set_data (G_OBJECT (connection), NMA_PATH_PHASE2_PRIVATE_KEY_TAG, NULL);
 	g_object_set_data (G_OBJECT (connection), NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG, NULL);
+
+	g_object_set_data (G_OBJECT (connection), NMA_SERVER_CERT_HASH_TAG, NULL);
+	g_object_set_data (G_OBJECT (connection), NMA_SERVER_SUBJECT_TAG, NULL);
 }
 
 NMConnection *
diff --git a/src/gconf-helpers/gconf-helpers.h b/src/gconf-helpers/gconf-helpers.h
index 8d62f3a..e066594 100644
--- a/src/gconf-helpers/gconf-helpers.h
+++ b/src/gconf-helpers/gconf-helpers.h
@@ -51,6 +51,8 @@
 #define NMA_PRIVATE_KEY_PASSWORD_TAG "nma-private-key-password"
 #define NMA_PATH_PHASE2_PRIVATE_KEY_TAG "nma-path-phase2-private-key"
 #define NMA_PHASE2_PRIVATE_KEY_PASSWORD_TAG "nma-phase2-private-key-password"
+#define NMA_SERVER_CERT_HASH_TAG "nma-server-cert-hash"
+#define NMA_SERVER_SUBJECT_TAG "nma-server-subject"
 
 NMConnection *nm_gconf_connection_duplicate (NMConnection *connection);
 
diff --git a/src/utils/utils.c b/src/utils/utils.c
index d9e3e19..75aded1 100644
--- a/src/utils/utils.c
+++ b/src/utils/utils.c
@@ -284,6 +284,8 @@ utils_fill_connection_certs (NMConnection *connection, GError **error)
 {
 	NMSetting8021x *s_8021x;
 	const char *filename;
+	const char *subject;
+	const char *string;
 	GError *tmp_error = NULL;
 	gboolean need_client_cert = TRUE;
 
@@ -293,6 +295,11 @@ utils_fill_connection_certs (NMConnection *connection, GError **error)
 	if (!s_8021x)
 		return TRUE;
 
+	subject = nm_setting_802_1x_get_subject_match (s_8021x);
+	string = g_object_get_data (G_OBJECT (connection), NMA_SERVER_SUBJECT_TAG);
+	if ((!subject || strlen (subject) == 0) && string)
+		g_object_set (s_8021x, NM_SETTING_802_1X_SUBJECT_MATCH, string, NULL);
+
 	filename = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
 	if (filename) {
 		if (!nm_setting_802_1x_set_ca_cert_from_file (s_8021x, filename, NULL, &tmp_error)) {
@@ -301,6 +308,16 @@ utils_fill_connection_certs (NMConnection *connection, GError **error)
 			g_clear_error (&tmp_error);
 			return FALSE;
 		}
+	} else {
+		string = g_object_get_data (G_OBJECT (connection), NMA_SERVER_CERT_HASH_TAG);
+		if (string) {
+			GByteArray *cert;
+			char *cert_hash;
+			cert_hash = g_strconcat ("hash://server/sha256/", string, NULL);
+			cert = g_byte_array_new ();
+			cert = g_byte_array_append (cert, (guint8 *)cert_hash, strlen (cert_hash));
+			g_object_set (s_8021x, NM_SETTING_802_1X_CA_CERT, cert, NULL);
+		}
 	}
 
 	/* If the private key is PKCS#12, don't set the client cert */
diff --git a/src/wireless-security/eap-method-peap.c b/src/wireless-security/eap-method-peap.c
index 58d1500..59a995f 100644
--- a/src/wireless-security/eap-method-peap.c
+++ b/src/wireless-security/eap-method-peap.c
@@ -32,6 +32,8 @@
 #define I_NAME_COLUMN   0
 #define I_METHOD_COLUMN 1
 
+#define SUBJECT_NOTE _("<will be filled automatically>")
+
 static void
 destroy (EAPMethod *parent)
 {
@@ -95,6 +97,10 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 	g_assert (widget);
 	gtk_size_group_add_widget (group, widget);
 
+	widget = glade_xml_get_widget (parent->xml, "eap_peap_subject_label");
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
 	widget = glade_xml_get_widget (parent->xml, "eap_peap_inner_auth_combo");
 	g_assert (widget);
 
@@ -129,6 +135,12 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
 	if (text && strlen (text))
 		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL);
 
+	widget = glade_xml_get_widget (parent->xml, "eap_peap_subject_entry");
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (text && strlen (text) && g_strcmp0 (text, SUBJECT_NOTE) != 0)
+		g_object_set (s_8021x, NM_SETTING_802_1X_SUBJECT_MATCH, text, NULL);
+
 	widget = glade_xml_get_widget (parent->xml, "eap_peap_ca_cert_button");
 	g_assert (widget);
 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
@@ -287,6 +299,36 @@ ca_cert_system_toggled (GtkToggleButton *togglebutton, gpointer user_data)
   gtk_widget_set_sensitive (GTK_WIDGET (user_data), !gtk_toggle_button_get_active (togglebutton));
 }
 
+static gboolean
+subject_entry_focus_in_cb (GtkWidget *widget,
+                           GdkEvent  *event,
+                           gpointer user_data)
+{
+	const char *text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (g_strcmp0 (text, SUBJECT_NOTE) == 0) {
+		gtk_entry_set_text (GTK_ENTRY (widget), "");
+		gtk_widget_modify_text (GTK_WIDGET (widget), GTK_STATE_NORMAL, NULL);
+	}
+	return FALSE;
+}
+
+static gboolean
+subject_entry_focus_out_cb (GtkWidget *widget,
+                            GdkEvent  *event,
+                            gpointer user_data)
+{
+	const char *text = gtk_entry_get_text (GTK_ENTRY (widget));
+	GtkStyle *style;
+	if (g_strcmp0 (text, "") == 0) {
+		gtk_entry_set_text (GTK_ENTRY (widget), SUBJECT_NOTE);
+		style = gtk_widget_get_style (widget);
+		gtk_widget_modify_text (GTK_WIDGET (widget),
+		                        GTK_STATE_NORMAL,
+		                        &style->text[GTK_STATE_INSENSITIVE]);
+	}
+	return FALSE;
+}
+
 EAPMethodPEAP *
 eap_method_peap_new (const char *glade_file,
                      WirelessSecurity *parent,
@@ -395,6 +437,43 @@ eap_method_peap_new (const char *glade_file,
 	                  (GCallback) wireless_security_changed_cb,
 	                  parent);
 
+	widget = glade_xml_get_widget (xml, "eap_peap_subject_entry");
+	if (s_8021x) {
+		const char *text = nm_setting_802_1x_get_subject_match (s_8021x);
+		if (!text) {
+			GtkStyle *style;
+			style = gtk_widget_get_style (widget);
+			gtk_widget_modify_text (widget,
+			                        GTK_STATE_NORMAL,
+			                        &style->text[GTK_STATE_INSENSITIVE]);
+			gtk_entry_set_text (GTK_ENTRY (widget), SUBJECT_NOTE);
+		} else {
+			gtk_entry_set_text (GTK_ENTRY (widget), text);
+		}
+	}
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  parent);
+	g_signal_connect (G_OBJECT (widget), "focus-in-event",
+	                  (GCallback) subject_entry_focus_in_cb,
+	                  NULL);
+	g_signal_connect (G_OBJECT (widget), "focus-out-event",
+	                  (GCallback) subject_entry_focus_out_cb,
+	                  NULL);
+
+	widget = glade_xml_get_widget (xml, "eap_peap_note_label");
+	if (s_8021x) {
+		const char *ca_hash = g_object_get_data (G_OBJECT (connection), NMA_SERVER_CERT_HASH_TAG);
+		const char *ca_cert = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
+		if (!ca_cert && ca_hash) {
+			gtk_label_set_text (GTK_LABEL (widget),
+			                    _("<b>Note:</b> Server hash is used instead of CA certificate"));
+			gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+		} else {
+			gtk_widget_hide (widget);
+		}
+	}
+
 	return method;
 }
 
diff --git a/src/wireless-security/eap-method-ttls.c b/src/wireless-security/eap-method-ttls.c
index fdfd5ae..c78328c 100644
--- a/src/wireless-security/eap-method-ttls.c
+++ b/src/wireless-security/eap-method-ttls.c
@@ -32,6 +32,8 @@
 #define I_NAME_COLUMN   0
 #define I_METHOD_COLUMN 1
 
+#define SUBJECT_NOTE _("<will be filled automatically>")
+
 static void
 destroy (EAPMethod *parent)
 {
@@ -83,6 +85,10 @@ add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
 	g_assert (widget);
 	gtk_size_group_add_widget (group, widget);
 
+	widget = glade_xml_get_widget (parent->xml, "eap_ttls_subject_label");
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
 	widget = glade_xml_get_widget (parent->xml, "eap_ttls_ca_cert_label");
 	g_assert (widget);
 	gtk_size_group_add_widget (group, widget);
@@ -124,6 +130,12 @@ fill_connection (EAPMethod *parent, NMConnection *connection)
 	if (text && strlen (text))
 		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL);
 
+	widget = glade_xml_get_widget (parent->xml, "eap_ttls_subject_entry");
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (text && strlen (text) && g_strcmp0 (text, SUBJECT_NOTE) != 0)
+		g_object_set (s_8021x, NM_SETTING_802_1X_SUBJECT_MATCH, text, NULL);
+
 	widget = glade_xml_get_widget (parent->xml, "eap_ttls_ca_cert_button");
 	g_assert (widget);
 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
@@ -298,6 +310,36 @@ ca_cert_system_toggled (GtkToggleButton *togglebutton, gpointer user_data)
   gtk_widget_set_sensitive (GTK_WIDGET (user_data), !gtk_toggle_button_get_active (togglebutton));
 }
 
+static gboolean
+subject_entry_focus_in_cb (GtkWidget *widget,
+                           GdkEvent  *event,
+                           gpointer user_data)
+{
+	const char *text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (g_strcmp0 (text, SUBJECT_NOTE) == 0) {
+		gtk_entry_set_text (GTK_ENTRY (widget), "");
+		gtk_widget_modify_text (GTK_WIDGET (widget), GTK_STATE_NORMAL, NULL);
+	}
+	return FALSE;
+}
+
+static gboolean
+subject_entry_focus_out_cb (GtkWidget *widget,
+                            GdkEvent  *event,
+                            gpointer user_data)
+{
+	const char *text = gtk_entry_get_text (GTK_ENTRY (widget));
+	GtkStyle *style;
+	if (g_strcmp0 (text, "") == 0) {
+		gtk_entry_set_text (GTK_ENTRY (widget), SUBJECT_NOTE);
+		style = gtk_widget_get_style (widget);
+		gtk_widget_modify_text (GTK_WIDGET (widget),
+		                        GTK_STATE_NORMAL,
+		                        &style->text[GTK_STATE_INSENSITIVE]);
+	}
+	return FALSE;
+}
+
 EAPMethodTTLS *
 eap_method_ttls_new (const char *glade_file,
                      WirelessSecurity *parent,
@@ -384,6 +426,43 @@ eap_method_ttls_new (const char *glade_file,
 	                  (GCallback) wireless_security_changed_cb,
 	                  parent);
 
+	widget = glade_xml_get_widget (xml, "eap_ttls_subject_entry");
+	if (s_8021x) {
+		const char *text = nm_setting_802_1x_get_subject_match (s_8021x);
+		if (!text) {
+			GtkStyle *style;
+			style = gtk_widget_get_style (widget);
+			gtk_widget_modify_text (widget,
+			                        GTK_STATE_NORMAL,
+			                        &style->text[GTK_STATE_INSENSITIVE]);
+			gtk_entry_set_text (GTK_ENTRY (widget), SUBJECT_NOTE);
+		} else {
+			gtk_entry_set_text (GTK_ENTRY (widget), text);
+		}
+	}
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  parent);
+	g_signal_connect (G_OBJECT (widget), "focus-in-event",
+	                  (GCallback) subject_entry_focus_in_cb,
+	                  NULL);
+	g_signal_connect (G_OBJECT (widget), "focus-out-event",
+	                  (GCallback) subject_entry_focus_out_cb,
+	                  NULL);
+
+	widget = glade_xml_get_widget (xml, "eap_ttls_note_label");
+	if (s_8021x) {
+		const char *ca_hash = g_object_get_data (G_OBJECT (connection), NMA_SERVER_CERT_HASH_TAG);
+		const char *ca_cert = g_object_get_data (G_OBJECT (connection), NMA_PATH_CA_CERT_TAG);
+		if (!ca_cert && ca_hash) {
+			gtk_label_set_text (GTK_LABEL (widget),
+			                    _("<b>Note:</b> Server hash is used instead of CA certificate"));
+			gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+		} else {
+			gtk_widget_hide (widget);
+		}
+	}
+
 	widget = inner_auth_combo_init (method, glade_file, connection, s_8021x);
 	inner_auth_combo_changed_cb (widget, (gpointer) method);
 
