diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index d57fb4a..37eb64a 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -26,10 +26,15 @@ global:
 	nm_connection_to_hash;
 	nm_connection_update_secrets;
 	nm_connection_verify;
+	nm_setting_802_1x_add_altsubject_match;
 	nm_setting_802_1x_add_eap_method;
+	nm_setting_802_1x_add_phase2_altsubject_match;
+	nm_setting_802_1x_clear_altsubject_matches;
 	nm_setting_802_1x_clear_eap_methods;
+	nm_setting_802_1x_clear_phase2_altsubject_matches;
 	nm_setting_802_1x_error_get_type;
 	nm_setting_802_1x_error_quark;
+	nm_setting_802_1x_get_altsubject_match;
 	nm_setting_802_1x_get_anonymous_identity;
 	nm_setting_802_1x_get_ca_cert;
 	nm_setting_802_1x_set_ca_cert_from_file;
@@ -38,11 +43,14 @@ global:
 	nm_setting_802_1x_set_client_cert_from_file;
 	nm_setting_802_1x_get_eap_method;
 	nm_setting_802_1x_get_identity;
+	nm_setting_802_1x_get_num_altsubject_matches;
 	nm_setting_802_1x_get_num_eap_methods;
+	nm_setting_802_1x_get_num_phase2_altsubject_matches;
 	nm_setting_802_1x_get_password;
 	nm_setting_802_1x_get_phase1_fast_provisioning;
 	nm_setting_802_1x_get_phase1_peaplabel;
 	nm_setting_802_1x_get_phase1_peapver;
+	nm_setting_802_1x_get_phase2_altsubject_match;
 	nm_setting_802_1x_get_phase2_auth;
 	nm_setting_802_1x_get_phase2_autheap;
 	nm_setting_802_1x_get_phase2_ca_cert;
@@ -54,6 +62,7 @@ global:
 	nm_setting_802_1x_set_phase2_private_key_from_file;
 	nm_setting_802_1x_get_phase2_private_key_password;
 	nm_setting_802_1x_get_phase2_private_key_type;
+	nm_setting_802_1x_get_phase2_subject_match;
 	nm_setting_802_1x_get_pin;
 	nm_setting_802_1x_get_pkcs11_engine_path;
 	nm_setting_802_1x_get_pkcs11_module_path;
@@ -65,9 +74,12 @@ global:
 	nm_setting_802_1x_get_private_key_type;
 	nm_setting_802_1x_get_psk;
 	nm_setting_802_1x_get_system_ca_certs;
+	nm_setting_802_1x_get_subject_match;
 	nm_setting_802_1x_get_type;
 	nm_setting_802_1x_new;
+	nm_setting_802_1x_remove_altsubject_match;
 	nm_setting_802_1x_remove_eap_method;
+	nm_setting_802_1x_remove_phase2_altsubject_match;
 	nm_setting_cdma_error_get_type;
 	nm_setting_cdma_error_quark;
 	nm_setting_cdma_get_type;
diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c
index 6dcdb20..999f7e7 100644
--- a/libnm-util/nm-setting-8021x.c
+++ b/libnm-util/nm-setting-8021x.c
@@ -77,6 +77,8 @@ typedef struct {
 	char *anonymous_identity;
 	GByteArray *ca_cert;
 	char *ca_path;
+	char *subject_match;
+	GSList *altsubject_matches;
 	GByteArray *client_cert;
 	char *phase1_peapver;
 	char *phase1_peaplabel;
@@ -85,6 +87,8 @@ typedef struct {
 	char *phase2_autheap;
 	GByteArray *phase2_ca_cert;
 	char *phase2_ca_path;
+	char *phase2_subject_match;
+	GSList *phase2_altsubject_matches;
 	GByteArray *phase2_client_cert;
 	char *password;
 	char *pin;
@@ -107,6 +111,8 @@ enum {
 	PROP_ANONYMOUS_IDENTITY,
 	PROP_CA_CERT,
 	PROP_CA_PATH,
+	PROP_SUBJECT_MATCH,
+	PROP_ALTSUBJECT_MATCHES,
 	PROP_CLIENT_CERT,
 	PROP_PHASE1_PEAPVER,
 	PROP_PHASE1_PEAPLABEL,
@@ -115,6 +121,8 @@ enum {
 	PROP_PHASE2_AUTHEAP,
 	PROP_PHASE2_CA_CERT,
 	PROP_PHASE2_CA_PATH,
+	PROP_PHASE2_SUBJECT_MATCH,
+	PROP_PHASE2_ALTSUBJECT_MATCHES,
 	PROP_PHASE2_CLIENT_CERT,
 	PROP_PASSWORD,
 	PROP_PRIVATE_KEY,
@@ -286,6 +294,135 @@ nm_setting_802_1x_get_system_ca_certs (NMSetting8021x *setting)
 	return NM_SETTING_802_1X_GET_PRIVATE (setting)->system_ca_certs;
 }
 
+/**
+ * nm_setting_802_1x_get_subject_match:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns: the #NMSetting8021x:subject-match property. This is the
+ * substring to be matched against the subject of the authentication
+ * server certificate, or NULL no subject verification is to be
+ * performed.
+ **/
+const char *
+nm_setting_802_1x_get_subject_match (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->subject_match;
+}
+
+/**
+ * nm_setting_802_1x_get_num_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns the number of entries in the
+ * #NMSetting8021x:altsubject-matches property of this setting.
+ *
+ * Returns: the number of altsubject-matches entries.
+ **/
+guint32
+nm_setting_802_1x_get_num_altsubject_matches (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
+
+	return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->altsubject_matches);
+}
+
+/**
+ * nm_setting_802_1x_get_altsubject_match:
+ * @setting: the #NMSettingConnection
+ * @i: the zero-based index of the array of altSubjectName matches
+ *
+ * Returns the altSubjectName match at index @i.
+ *
+ * Returns: the altSubjectName match at index @i
+ **/
+const char *
+nm_setting_802_1x_get_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	g_return_val_if_fail (i <= g_slist_length (priv->altsubject_matches), NULL);
+
+	return (const char *) g_slist_nth_data (priv->altsubject_matches, i);
+}
+
+/**
+ * nm_setting_802_1x_add_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @altsubject_match: the altSubjectName to allow for this connection
+ *
+ * Adds an allowed alternate subject name match.  Until at least one
+ * match is added, the altSubjectName of the remote authentication
+ * server is not verified.
+ *
+ * Returns: TRUE if the alternative subject name match was
+ *  successfully added, FALSE if it was already allowed.
+ **/
+gboolean
+nm_setting_802_1x_add_altsubject_match (NMSetting8021x *setting,
+										const char *altsubject_match)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *iter;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
+	g_return_val_if_fail (altsubject_match != NULL, FALSE);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	for (iter = priv->altsubject_matches; iter; iter = g_slist_next (iter)) {
+		if (!strcmp (altsubject_match, (char *) iter->data))
+			return FALSE;
+	}
+
+	priv->altsubject_matches = g_slist_append (priv->altsubject_matches, g_strdup (altsubject_match));
+	return TRUE;
+}
+
+/**
+ * nm_setting_802_1x_remove_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @i: the index of the altSubjectName match to remove
+ *
+ * Removes the allowed altSubjectName at the specified index.
+ **/
+void
+nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *elt;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	elt = g_slist_nth (priv->altsubject_matches, i);
+	g_return_if_fail (elt != NULL);
+
+	g_free (elt->data);
+	priv->altsubject_matches = g_slist_delete_link (priv->altsubject_matches, elt);
+}
+
+/**
+ * nm_setting_802_1x_clear_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Clears all altSubjectName matches.
+ **/
+void
+nm_setting_802_1x_clear_altsubject_matches (NMSetting8021x *setting)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	nm_utils_slist_free (priv->altsubject_matches, g_free);
+	priv->altsubject_matches = NULL;
+}
+
 const GByteArray *
 nm_setting_802_1x_get_client_cert (NMSetting8021x *setting)
 {
@@ -377,6 +514,137 @@ nm_setting_802_1x_get_phase2_autheap (NMSetting8021x *setting)
 	return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_autheap;
 }
 
+/**
+ * nm_setting_802_1x_get_phase2_subject_match:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns: the #NMSetting8021x:phase2-subject-match property. This is
+ * the substring to be matched against the subject of the "phase 2"
+ * authentication server certificate, or NULL no subject verification
+ * is to be performed.
+ **/
+const char *
+nm_setting_802_1x_get_phase2_subject_match (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_subject_match;
+}
+
+/**
+ * nm_setting_802_1x_get_num_phase2_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns the number of entries in the
+ * #NMSetting8021x:phase2-altsubject-matches property of this setting.
+ *
+ * Returns: the number of phase2-altsubject-matches entries.
+ **/
+guint32
+nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
+
+	return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_altsubject_matches);
+}
+
+/**
+ * nm_setting_802_1x_get_phase2_altsubject_match:
+ * @setting: the #NMSettingConnection
+ * @i: the zero-based index of the array of "phase 2" altSubjectName matches
+ *
+ * Returns the "phase 2" altSubjectName match at index @i.
+ *
+ * Returns: the "phase 2" altSubjectName match at index @i
+ **/
+const char *
+nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	g_return_val_if_fail (i <= g_slist_length (priv->phase2_altsubject_matches), NULL);
+
+	return (const char *) g_slist_nth_data (priv->phase2_altsubject_matches, i);
+}
+
+/**
+ * nm_setting_802_1x_add_phase2_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @altsubject_match: the "phase 2" altSubjectName to allow for this
+ * connection
+ *
+ * Adds an allowed alternate subject name match for "phase 2".  Until
+ * at least one match is added, the altSubjectName of the "phase 2"
+ * remote authentication server is not verified.
+ *
+ * Returns: TRUE if the "phase 2" alternative subject name match was
+ *  successfully added, FALSE if it was already allowed.
+ **/
+gboolean
+nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting,
+											   const char *phase2_altsubject_match)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *iter;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
+	g_return_val_if_fail (phase2_altsubject_match != NULL, FALSE);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next (iter)) {
+		if (!strcmp (phase2_altsubject_match, (char *) iter->data))
+			return FALSE;
+	}
+
+	priv->phase2_altsubject_matches = g_slist_append (priv->altsubject_matches,
+													  g_strdup (phase2_altsubject_match));
+	return TRUE;
+}
+
+/**
+ * nm_setting_802_1x_remove_phase2_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @i: the index of the "phase 2" altSubjectName match to remove
+ *
+ * Removes the allowed "phase 2" altSubjectName at the specified index.
+ **/
+void
+nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *elt;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	elt = g_slist_nth (priv->phase2_altsubject_matches, i);
+	g_return_if_fail (elt != NULL);
+
+	g_free (elt->data);
+	priv->phase2_altsubject_matches = g_slist_delete_link (priv->phase2_altsubject_matches, elt);
+}
+
+/**
+ * nm_setting_802_1x_clear_phase2_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Clears all "phase 2" altSubjectName matches.
+ **/
+void
+nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	nm_utils_slist_free (priv->phase2_altsubject_matches, g_free);
+	priv->phase2_altsubject_matches = NULL;
+}
+
 const GByteArray *
 nm_setting_802_1x_get_phase2_ca_cert (NMSetting8021x *setting)
 {
@@ -1182,12 +1450,14 @@ finalize (GObject *object)
 	g_free (priv->identity);
 	g_free (priv->anonymous_identity);
 	g_free (priv->ca_path);
+	g_free (priv->subject_match);
 	g_free (priv->phase1_peapver);
 	g_free (priv->phase1_peaplabel);
 	g_free (priv->phase1_fast_provisioning);
 	g_free (priv->phase2_auth);
 	g_free (priv->phase2_autheap);
 	g_free (priv->phase2_ca_path);
+	g_free (priv->phase2_subject_match);
 	g_free (priv->password);
 	g_free (priv->pin);
 	g_free (priv->pkcs11_engine_path);
@@ -1195,6 +1465,8 @@ finalize (GObject *object)
 	g_free (priv->pkcs11_module_init_args);
 
 	nm_utils_slist_free (priv->eap, g_free);
+	nm_utils_slist_free (priv->altsubject_matches, g_free);
+	nm_utils_slist_free (priv->phase2_altsubject_matches, g_free);
 
 	if (priv->ca_cert)
 		g_byte_array_free (priv->ca_cert, TRUE);
@@ -1243,6 +1515,14 @@ set_property (GObject *object, guint prop_id,
 		g_free (priv->ca_path);
 		priv->ca_path = g_value_dup_string (value);
 		break;
+	case PROP_SUBJECT_MATCH:
+		g_free (priv->subject_match);
+		priv->subject_match = g_value_dup_string (value);
+		break;
+	case PROP_ALTSUBJECT_MATCHES:
+		nm_utils_slist_free (priv->altsubject_matches, g_free);
+		priv->altsubject_matches = g_value_dup_boxed (value);
+		break;
 	case PROP_CLIENT_CERT:
 		if (priv->client_cert)
 			g_byte_array_free (priv->client_cert, TRUE);
@@ -1277,6 +1557,14 @@ set_property (GObject *object, guint prop_id,
 		g_free (priv->phase2_ca_path);
 		priv->phase2_ca_path = g_value_dup_string (value);
 		break;
+	case PROP_PHASE2_SUBJECT_MATCH:
+		g_free (priv->phase2_subject_match);
+		priv->phase2_subject_match = g_value_dup_string (value);
+		break;
+	case PROP_PHASE2_ALTSUBJECT_MATCHES:
+		nm_utils_slist_free (priv->phase2_altsubject_matches, g_free);
+		priv->phase2_altsubject_matches = g_value_dup_boxed (value);
+		break;
 	case PROP_PHASE2_CLIENT_CERT:
 		if (priv->phase2_client_cert)
 			g_byte_array_free (priv->phase2_client_cert, TRUE);
@@ -1354,6 +1642,12 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CA_PATH:
 		g_value_set_string (value, priv->ca_path);
 		break;
+	case PROP_SUBJECT_MATCH:
+		g_value_set_string (value, priv->subject_match);
+		break;
+	case PROP_ALTSUBJECT_MATCHES:
+		g_value_set_boxed (value, priv->altsubject_matches);
+		break;
 	case PROP_CLIENT_CERT:
 		g_value_set_boxed (value, priv->client_cert);
 		break;
@@ -1378,6 +1672,12 @@ get_property (GObject *object, guint prop_id,
 	case PROP_PHASE2_CA_PATH:
 		g_value_set_string (value, priv->phase2_ca_path);
 		break;
+	case PROP_PHASE2_SUBJECT_MATCH:
+		g_value_set_string (value, priv->phase2_subject_match);
+		break;
+	case PROP_PHASE2_ALTSUBJECT_MATCHES:
+		g_value_set_boxed (value, priv->phase2_altsubject_matches);
+		break;
 	case PROP_PHASE2_CLIENT_CERT:
 		g_value_set_boxed (value, priv->phase2_client_cert);
 		break;
@@ -1478,6 +1778,47 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 						  NULL,
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
+	/**
+	 * NMSetting8021x:subject-match:
+	 *
+	 * Substring to be matched against the subject of the certificate
+	 * presented by the authentication server. When unset, no
+	 * verification of the authentication server certificate's subject
+	 * is performed.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_SUBJECT_MATCH,
+		 g_param_spec_string (NM_SETTING_802_1X_SUBJECT_MATCH,
+							  "Subject match",
+							  "Substring to be matched against the subject of "
+							  "the certificate presented by the authentication "
+							  "server. When unset, no verification of the "
+							  "authentication server certificate's subject is "
+							  "performed.",
+							  NULL,
+							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
+	 * NMSetting8021x:altsubject-matches:
+	 *
+	 * List of strings to be matched against the altSubjectName of the
+	 * certificate presented by the authentication server. If the list
+	 * is empty, no verification of the server certificate's
+	 * altSubjectName is performed.
+	 **/
+	 g_object_class_install_property
+		 (object_class, PROP_ALTSUBJECT_MATCHES,
+		  _nm_param_spec_specialized (NM_SETTING_802_1X_ALTSUBJECT_MATCHES,
+									  "altSubjectName matches",
+									  "List of strings to be matched against "
+									  "the altSubjectName of the certificate "
+									  "presented by the authentication server. "
+									  "If the list is empty, no verification "
+									  "of the server certificate's "
+									  "altSubjectName is performed.",
+									  DBUS_TYPE_G_LIST_OF_STRING,
+									  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
 	g_object_class_install_property
 		(object_class, PROP_CLIENT_CERT,
 		 _nm_param_spec_specialized (NM_SETTING_802_1X_CLIENT_CERT,
@@ -1542,6 +1883,51 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 						  NULL,
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
+	/**
+	 * NMSetting8021x:phase2-subject-match:
+	 *
+	 * Substring to be matched against the subject of the certificate
+	 * presented by the authentication server during the inner "phase
+	 * 2" authentication. When unset, no verification of the
+	 * authentication server certificate's subject is performed.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_PHASE2_SUBJECT_MATCH,
+		 g_param_spec_string (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH,
+							  "Phase2 subject match",
+							  "Substring to be matched against the subject of "
+							  "the certificate presented by the authentication "
+							  "server during the inner 'phase2' "
+							  "authentication. When unset, no verification of "
+							  "the authentication server certificate's subject "
+							  "is performed.",
+							  NULL,
+							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
+	 * NMSetting8021x:phase2-altsubject-matches:
+	 *
+	 * List of strings to be matched against the altSubjectName of the
+	 * certificate presented by the authentication server during the
+	 * inner "phase 2" authentication. If the list is empty, no
+	 * verification of the server certificate's altSubjectName is
+	 * performed.
+	 **/
+	 g_object_class_install_property
+		 (object_class, PROP_PHASE2_ALTSUBJECT_MATCHES,
+		  _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES,
+									  "altSubjectName matches",
+									  "List of strings to be matched against "
+									  "List of strings to be matched against "
+									  "the altSubjectName of the certificate "
+									  "presented by the authentication server "
+									  "during the inner 'phase 2' "
+									  "authentication. If the list is empty, no "
+									  "verification of the server certificate's "
+									  "altSubjectName is performed.",
+									  DBUS_TYPE_G_LIST_OF_STRING,
+									  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
 	g_object_class_install_property
 		(object_class, PROP_PHASE2_CLIENT_CERT,
 		 _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h
index 681347b..140ea2d 100644
--- a/libnm-util/nm-setting-8021x.h
+++ b/libnm-util/nm-setting-8021x.h
@@ -65,6 +65,8 @@ GQuark nm_setting_802_1x_error_quark (void);
 #define NM_SETTING_802_1X_ANONYMOUS_IDENTITY "anonymous-identity"
 #define NM_SETTING_802_1X_CA_CERT "ca-cert"
 #define NM_SETTING_802_1X_CA_PATH "ca-path"
+#define NM_SETTING_802_1X_SUBJECT_MATCH "subject-match"
+#define NM_SETTING_802_1X_ALTSUBJECT_MATCHES "altsubject-matches"
 #define NM_SETTING_802_1X_CLIENT_CERT "client-cert"
 #define NM_SETTING_802_1X_PHASE1_PEAPVER "phase1-peapver"
 #define NM_SETTING_802_1X_PHASE1_PEAPLABEL "phase1-peaplabel"
@@ -73,6 +75,8 @@ GQuark nm_setting_802_1x_error_quark (void);
 #define NM_SETTING_802_1X_PHASE2_AUTHEAP "phase2-autheap"
 #define NM_SETTING_802_1X_PHASE2_CA_CERT "phase2-ca-cert"
 #define NM_SETTING_802_1X_PHASE2_CA_PATH "phase2-ca-path"
+#define NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH "phase2-subject-match"
+#define NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES "phase2-altsubject-matches"
 #define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert"
 #define NM_SETTING_802_1X_PASSWORD "password"
 #define NM_SETTING_802_1X_PRIVATE_KEY "private-key"
@@ -119,6 +123,17 @@ gboolean          nm_setting_802_1x_set_ca_cert_from_file            (NMSetting8
                                                                       NMSetting8021xCKType *out_ck_type,
                                                                       GError **err);
 
+const char *      nm_setting_802_1x_get_subject_match                (NMSetting8021x *setting);
+
+guint32           nm_setting_802_1x_get_num_altsubject_matches       (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_altsubject_match             (NMSetting8021x *setting,
+                                                                      guint32 i);
+gboolean          nm_setting_802_1x_add_altsubject_match             (NMSetting8021x *setting,
+                                                                      const char *altsubject_match);
+void              nm_setting_802_1x_remove_altsubject_match          (NMSetting8021x *setting,
+                                                                      guint32 i);
+void              nm_setting_802_1x_clear_altsubject_matches         (NMSetting8021x *setting);
+
 const GByteArray *nm_setting_802_1x_get_client_cert                  (NMSetting8021x *setting);
 gboolean          nm_setting_802_1x_set_client_cert_from_file        (NMSetting8021x *setting,
                                                                       const char *filename,
@@ -135,6 +150,16 @@ const char *      nm_setting_802_1x_get_phase2_auth                  (NMSetting8
 
 const char *      nm_setting_802_1x_get_phase2_autheap               (NMSetting8021x *setting);
 
+const char *      nm_setting_802_1x_get_phase2_subject_match            (NMSetting8021x *setting);
+guint32           nm_setting_802_1x_get_num_phase2_altsubject_matches   (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_phase2_altsubject_match         (NMSetting8021x *setting,
+                                                                         guint32 i);
+gboolean          nm_setting_802_1x_add_phase2_altsubject_match         (NMSetting8021x *setting,
+                                                                         const char *phase2_altsubject_match);
+void              nm_setting_802_1x_remove_phase2_altsubject_match      (NMSetting8021x *setting,
+                                                                         guint32 i);
+void              nm_setting_802_1x_clear_phase2_altsubject_matches     (NMSetting8021x *setting);
+
 const GByteArray *nm_setting_802_1x_get_phase2_ca_cert               (NMSetting8021x *setting);
 const char *      nm_setting_802_1x_get_phase2_ca_path               (NMSetting8021x *setting);
 gboolean          nm_setting_802_1x_set_phase2_ca_cert_from_file     (NMSetting8021x *setting,
diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c
index 4c62fa7..274b3f0 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -525,7 +525,7 @@ add_string_val (NMSupplicantConfig *self,
 	return success;
 }
 
-#define ADD_STRING_LIST_VAL(setting, setting_name, field, field_plural, name, ucase, secret) \
+#define ADD_STRING_LIST_VAL(setting, setting_name, field, field_plural, name, separator, ucase, secret) \
 	if (nm_setting_##setting_name##_get_num_##field_plural (setting)) { \
 		guint32 k; \
 		GString *str = g_string_new (NULL); \
@@ -534,7 +534,7 @@ add_string_val (NMSupplicantConfig *self,
 			if (!str->len) { \
 				g_string_append (str, item); \
 			} else { \
-				g_string_append_c (str, ' '); \
+				g_string_append_c (str, separator); \
 				g_string_append (str, item); \
 			} \
 		} \
@@ -703,9 +703,9 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
 	if (   !strcmp (key_mgmt, "wpa-none")
 	    || !strcmp (key_mgmt, "wpa-psk")
 	    || !strcmp (key_mgmt, "wpa-eap")) {
-		ADD_STRING_LIST_VAL (setting, wireless_security, proto, protos, "proto", TRUE, FALSE);
-		ADD_STRING_LIST_VAL (setting, wireless_security, pairwise, pairwise, "pairwise", TRUE, FALSE);
-		ADD_STRING_LIST_VAL (setting, wireless_security, group, groups, "group", TRUE, FALSE);
+		ADD_STRING_LIST_VAL (setting, wireless_security, proto, protos, "proto", ' ', TRUE, FALSE);
+		ADD_STRING_LIST_VAL (setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, FALSE);
+		ADD_STRING_LIST_VAL (setting, wireless_security, group, groups, "group", ' ', TRUE, FALSE);
 	}
 
 	/* WEP keys if required */
@@ -970,7 +970,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
 			return FALSE;
 	}
 
-	ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", TRUE, FALSE);
+	ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE);
 
 	/* Drop the fragment size a bit for better compatibility */
 	if (!nm_supplicant_config_add_option (self, "fragment_size", "1300", -1, FALSE))
@@ -1022,6 +1022,18 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
 	}
 	g_string_free (phase2, TRUE);
 
+	/* Subject match */
+	value = nm_setting_802_1x_get_subject_match (setting);
+	if (!add_string_val (self, value, "subject_match", FALSE, FALSE))
+		return FALSE;
+	value = nm_setting_802_1x_get_phase2_subject_match (setting);
+	if (!add_string_val (self, value, "subject_match2", FALSE, FALSE))
+		return FALSE;
+
+	/* altSubjectName match */
+	ADD_STRING_LIST_VAL (setting, 802_1x, altsubject_match, altsubject_matches, "altsubject_match", ';', FALSE, FALSE);
+	ADD_STRING_LIST_VAL (setting, 802_1x, phase2_altsubject_match, phase2_altsubject_matches, "altsubject_match2", ';', FALSE, FALSE);
+
 	value = nm_setting_802_1x_get_identity (setting);
 	if (!add_string_val (self, value, "identity", FALSE, FALSE))
 		return FALSE;
diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.c b/src/supplicant-manager/nm-supplicant-settings-verify.c
index 2c70d22..a9b6355 100644
--- a/src/supplicant-manager/nm-supplicant-settings-verify.c
+++ b/src/supplicant-manager/nm-supplicant-settings-verify.c
@@ -102,6 +102,8 @@ static const struct Opt opt_table[] = {
 	{ "identity",           TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "password",           TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "ca_path",            TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "subject_match",      TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "altsubject_match",   TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "ca_cert",            TYPE_BYTES,   0, 65536, FALSE,  NULL },
 	{ "ca_cert_id",         TYPE_BYTES,   0, 65536, FALSE,  NULL },
 	{ "client_cert",        TYPE_BYTES,   0, 65536, FALSE,  NULL },
@@ -112,6 +114,8 @@ static const struct Opt opt_table[] = {
 	{ "phase1",             TYPE_KEYWORD, 0, 0, TRUE, phase1_allowed },
 	{ "phase2",             TYPE_KEYWORD, 0, 0, TRUE, phase2_allowed },
 	{ "anonymous_identity", TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "subject_match2",     TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "altsubject_match2",  TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "ca_cert2",           TYPE_BYTES,   0, 65536, FALSE,  NULL },
 	{ "ca_cert2_id",        TYPE_BYTES,   0, 65536, FALSE,  NULL },
 	{ "client_cert2",       TYPE_BYTES,   0, 65536, FALSE,  NULL },
