diff -Naur network-manager-0.7.bak/libnm-util/libnm-util.ver network-manager-0.7.dev/libnm-util/libnm-util.ver
--- network-manager-0.7.bak/libnm-util/libnm-util.ver	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/libnm-util/libnm-util.ver	2009-01-07 00:59:02.000000000 +0900
@@ -55,6 +55,16 @@
 	nm_setting_802_1x_get_phase2_private_key_password;
 	nm_setting_802_1x_get_phase2_private_key_type;
 	nm_setting_802_1x_get_pin;
+	nm_setting_802_1x_get_pkcs11_engine_path;
+	nm_setting_802_1x_get_pkcs11_module_path;
+	nm_setting_802_1x_get_pkcs11_module_init_args;
+	nm_setting_802_1x_get_pkcs11_slot;
+	nm_setting_802_1x_get_pkcs11_ca_cert;
+	nm_setting_802_1x_get_pkcs11_client_cert;
+	nm_setting_802_1x_get_pkcs11_private_key;
+	nm_setting_802_1x_get_pkcs11_phase2_ca_cert;
+	nm_setting_802_1x_get_pkcs11_phase2_client_cert;
+	nm_setting_802_1x_get_pkcs11_phase2_private_key;
 	nm_setting_802_1x_get_private_key;
 	nm_setting_802_1x_set_private_key_from_file;
 	nm_setting_802_1x_get_private_key_password;
diff -Naur network-manager-0.7.bak/libnm-util/nm-setting-8021x.c network-manager-0.7.dev/libnm-util/nm-setting-8021x.c
--- network-manager-0.7.bak/libnm-util/nm-setting-8021x.c	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/libnm-util/nm-setting-8021x.c	2009-01-07 01:23:26.000000000 +0900
@@ -94,6 +94,16 @@
 	GByteArray *phase2_private_key;
 	char *phase2_private_key_password;
 	gboolean system_ca_certs;
+	char *pkcs11_engine_path;
+	char *pkcs11_module_path;
+	char *pkcs11_module_init_args;
+	guint pkcs11_slot;
+	char *pkcs11_ca_cert;
+	char *pkcs11_client_cert;
+	char *pkcs11_private_key;
+	char *pkcs11_phase2_ca_cert;
+	char *pkcs11_phase2_client_cert;
+	char *pkcs11_phase2_private_key;
 } NMSetting8021xPrivate;
 
 enum {
@@ -120,6 +130,16 @@
 	PROP_PIN,
 	PROP_PSK,
 	PROP_SYSTEM_CA_CERTS,
+	PROP_PKCS11_ENGINE_PATH,
+	PROP_PKCS11_MODULE_PATH,
+	PROP_PKCS11_MODULE_INIT_ARGS,
+	PROP_PKCS11_SLOT,
+	PROP_PKCS11_CA_CERT,
+	PROP_PKCS11_CLIENT_CERT,
+	PROP_PKCS11_PRIVATE_KEY,
+	PROP_PKCS11_PHASE2_CA_CERT,
+	PROP_PKCS11_PHASE2_CLIENT_CERT,
+	PROP_PKCS11_PHASE2_PRIVATE_KEY,
 
 	LAST_PROP
 };
@@ -689,6 +709,86 @@
 	return NM_SETTING_802_1X_CK_TYPE_X509;
 }
 
+const char *
+nm_setting_802_1x_get_pkcs11_engine_path (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_engine_path;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_module_path (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_module_path;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_module_init_args (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_module_init_args;
+}
+
+guint
+nm_setting_802_1x_get_pkcs11_slot (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_slot;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_ca_cert (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_ca_cert;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_client_cert (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_client_cert;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_private_key (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_private_key;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_phase2_ca_cert (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_phase2_ca_cert;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_phase2_client_cert (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_phase2_client_cert;
+}
+
+const char *
+nm_setting_802_1x_get_pkcs11_phase2_private_key (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_phase2_private_key;
+}
+
 static void
 need_secrets_password (NMSetting8021x *self,
                        GPtrArray *secrets,
@@ -742,6 +842,11 @@
 {
 	NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
 
+	if (priv->pkcs11_module_path &&
+		(!priv->pin || !strlen (priv->pin)) &&
+		(priv->pkcs11_private_key || priv->pkcs11_phase2_private_key))
+		g_ptr_array_add (secrets, NM_SETTING_802_1X_PIN);
+
 	if (phase2) {
 		if (!priv->phase2_private_key || !priv->phase2_private_key->len)
 			g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
@@ -760,6 +865,7 @@
 {
 	NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
 
+	/* TODO: add checks for pkcs11 case */
 	if (phase2) {
 		if (!priv->phase2_client_cert) {
 			g_set_error (error,
@@ -1142,6 +1248,16 @@
 	g_free (priv->phase2_autheap);
 	g_free (priv->phase2_ca_path);
 	g_free (priv->password);
+	g_free (priv->pin);
+	g_free (priv->pkcs11_engine_path);
+	g_free (priv->pkcs11_module_path);
+	g_free (priv->pkcs11_module_init_args);
+	g_free (priv->pkcs11_ca_cert);
+	g_free (priv->pkcs11_client_cert);
+	g_free (priv->pkcs11_private_key);
+	g_free (priv->pkcs11_phase2_ca_cert);
+	g_free (priv->pkcs11_phase2_client_cert);
+	g_free (priv->pkcs11_phase2_private_key);
 
 	nm_utils_slist_free (priv->eap, g_free);
 
@@ -1235,6 +1351,10 @@
 		g_free (priv->password);
 		priv->password = g_value_dup_string (value);
 		break;
+	case PROP_PIN:
+		g_free (priv->pin);
+		priv->pin = g_value_dup_string (value);
+		break;
 	case PROP_PRIVATE_KEY:
 		if (priv->private_key)
 			g_byte_array_free (priv->private_key, TRUE);
@@ -1256,6 +1376,45 @@
 	case PROP_SYSTEM_CA_CERTS:
 		priv->system_ca_certs = g_value_get_boolean (value);
 		break;
+	case PROP_PKCS11_ENGINE_PATH:
+		g_free (priv->pkcs11_engine_path);
+		priv->pkcs11_engine_path = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_MODULE_PATH:
+		g_free (priv->pkcs11_module_path);
+		priv->pkcs11_module_path = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_MODULE_INIT_ARGS:
+		g_free (priv->pkcs11_module_init_args);
+		priv->pkcs11_module_init_args = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_SLOT:
+		priv->pkcs11_slot = g_value_get_uint (value);
+		break;
+	case PROP_PKCS11_CA_CERT:
+		g_free (priv->pkcs11_ca_cert);
+		priv->pkcs11_ca_cert = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_CLIENT_CERT:
+		g_free (priv->pkcs11_client_cert);
+		priv->pkcs11_client_cert = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_PRIVATE_KEY:
+		g_free (priv->pkcs11_private_key);
+		priv->pkcs11_private_key = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_PHASE2_CA_CERT:
+		g_free (priv->pkcs11_phase2_ca_cert);
+		priv->pkcs11_phase2_ca_cert = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_PHASE2_CLIENT_CERT:
+		g_free (priv->pkcs11_phase2_client_cert);
+		priv->pkcs11_phase2_client_cert = g_value_dup_string (value);
+		break;
+	case PROP_PKCS11_PHASE2_PRIVATE_KEY:
+		g_free (priv->pkcs11_phase2_private_key);
+		priv->pkcs11_phase2_private_key = g_value_dup_string (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1315,6 +1474,9 @@
 	case PROP_PASSWORD:
 		g_value_set_string (value, priv->password);
 		break;
+	case PROP_PIN:
+		g_value_set_string (value, priv->pin);
+		break;
 	case PROP_PRIVATE_KEY:
 		g_value_set_boxed (value, priv->private_key);
 		break;
@@ -1330,6 +1492,36 @@
 	case PROP_SYSTEM_CA_CERTS:
 		g_value_set_boolean (value, priv->system_ca_certs);
 		break;
+	case PROP_PKCS11_ENGINE_PATH:
+		g_value_set_string (value, priv->pkcs11_engine_path);
+		break;
+	case PROP_PKCS11_MODULE_PATH:
+		g_value_set_string (value, priv->pkcs11_module_path);
+		break;
+	case PROP_PKCS11_MODULE_INIT_ARGS:
+		g_value_set_string (value, priv->pkcs11_module_init_args);
+		break;
+	case PROP_PKCS11_SLOT:
+		g_value_set_uint (value, priv->pkcs11_slot);
+		break;
+	case PROP_PKCS11_CA_CERT:
+		g_value_set_string (value, priv->pkcs11_ca_cert);
+		break;
+	case PROP_PKCS11_CLIENT_CERT:
+		g_value_set_string (value, priv->pkcs11_client_cert);
+		break;
+	case PROP_PKCS11_PRIVATE_KEY:
+		g_value_set_string (value, priv->pkcs11_private_key);
+		break;
+	case PROP_PKCS11_PHASE2_CA_CERT:
+		g_value_set_string (value, priv->pkcs11_phase2_ca_cert);
+		break;
+	case PROP_PKCS11_PHASE2_CLIENT_CERT:
+		g_value_set_string (value, priv->pkcs11_phase2_client_cert);
+		break;
+	case PROP_PKCS11_PHASE2_PRIVATE_KEY:
+		g_value_set_string (value, priv->pkcs11_phase2_private_key);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1467,6 +1659,14 @@
 							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	g_object_class_install_property
+		(object_class, PROP_PIN,
+		 g_param_spec_string (NM_SETTING_802_1X_PIN,
+							  "PIN",
+							  "PIN",
+							  NULL,
+							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
+
+	g_object_class_install_property
 		(object_class, PROP_PASSWORD,
 		 g_param_spec_string (NM_SETTING_802_1X_PASSWORD,
 						  "Password",
@@ -1514,6 +1714,87 @@
 							   FALSE,
 							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_ENGINE_PATH,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_ENGINE_PATH,
+						  "OpenSSL pkcs11 engine path",
+						  "OpenSSL pkcs11 engine path",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_MODULE_PATH,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_MODULE_PATH,
+						  "PKCS11 smartcard library module path",
+						  "PKCS11 smartcard library module path",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_MODULE_INIT_ARGS,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_MODULE_INIT_ARGS,
+						  "PKCS11 smartcard library initialization arguments",
+						  "PKCS11 smartcard library initialization arguments",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_SLOT,
+		 g_param_spec_uint (NM_SETTING_802_1X_PKCS11_SLOT,
+						"PKCS11 slot",
+						"PKCS11 slot",
+						0, 1000, 0,
+						G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_CA_CERT,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_CA_CERT,
+						  "PKCS11 object ID of CA certificate",
+						  "PKCS11 object ID of CA certificate",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_CLIENT_CERT,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_CLIENT_CERT,
+						  "PKCS11 object ID of client certificate",
+						  "PKCS11 object ID of client certificate",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_PRIVATE_KEY,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_PRIVATE_KEY,
+						  "PKCS11 object ID of private key",
+						  "PKCS11 object ID of private key",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_PHASE2_CA_CERT,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_PHASE2_CA_CERT,
+						  "PKCS11 object ID of phase2 CA certificate",
+						  "PKCS11 object ID of phase2 CA certificate",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_PHASE2_CLIENT_CERT,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_PHASE2_CLIENT_CERT,
+						  "PKCS11 object ID of phase2 client certificate",
+						  "PKCS11 object ID of phase2 client certificate",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_PKCS11_PHASE2_PRIVATE_KEY,
+		 g_param_spec_string (NM_SETTING_802_1X_PKCS11_PHASE2_PRIVATE_KEY,
+						  "PKCS11 object ID of phase2 private key",
+						  "PKCS11 object ID of phase2 private key",
+						  NULL,
+						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+
 	/* Initialize crypto lbrary. */
 	if (!nm_utils_init (&error)) {
 		g_warning ("Couldn't initilize nm-utils/crypto system: %d %s",
diff -Naur network-manager-0.7.bak/libnm-util/nm-setting-8021x.h network-manager-0.7.dev/libnm-util/nm-setting-8021x.h
--- network-manager-0.7.bak/libnm-util/nm-setting-8021x.h	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/libnm-util/nm-setting-8021x.h	2009-01-07 01:39:34.000000000 +0900
@@ -82,6 +82,16 @@
 #define NM_SETTING_802_1X_PIN "pin"
 #define NM_SETTING_802_1X_PSK "psk"
 #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs"
+#define NM_SETTING_802_1X_PKCS11_ENGINE_PATH "pkcs11-engine-path"
+#define NM_SETTING_802_1X_PKCS11_MODULE_PATH "pkcs11-module-path"
+#define NM_SETTING_802_1X_PKCS11_MODULE_INIT_ARGS "pkcs11-module-init-args"
+#define NM_SETTING_802_1X_PKCS11_SLOT "pkcs11-slot"
+#define NM_SETTING_802_1X_PKCS11_CA_CERT "pkcs11-ca-cert"
+#define NM_SETTING_802_1X_PKCS11_CLIENT_CERT "pkcs11-client-cert"
+#define NM_SETTING_802_1X_PKCS11_PRIVATE_KEY "pkcs11-private-key"
+#define NM_SETTING_802_1X_PKCS11_PHASE2_CA_CERT "pkcs11-phase2-ca-cert"
+#define NM_SETTING_802_1X_PKCS11_PHASE2_CLIENT_CERT "pkcs11-phase2-client-cert"
+#define NM_SETTING_802_1X_PKCS11_PHASE2_PRIVATE_KEY "pkcs11-phase2-private-key"
 
 typedef struct {
 	NMSetting parent;
@@ -182,6 +192,17 @@
                                                                       GError **err);
 NMSetting8021xCKType nm_setting_802_1x_get_phase2_private_key_type   (NMSetting8021x *setting);
 
+const char *      nm_setting_802_1x_get_pkcs11_engine_path           (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_module_path           (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_module_init_args      (NMSetting8021x *setting);
+guint             nm_setting_802_1x_get_pkcs11_slot                  (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_ca_cert               (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_client_cert           (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_private_key           (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_phase2_ca_cert        (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_phase2_client_cert    (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_pkcs11_phase2_private_key    (NMSetting8021x *setting);
+
 G_END_DECLS
 
 #endif /* NM_SETTING_8021X_H */
diff -Naur network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-config.c network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-config.c
--- network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-config.c	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-config.c	2009-01-07 01:54:33.000000000 +0900
@@ -53,6 +53,9 @@
 	GHashTable *blobs;
 	guint32    ap_scan;
 	gboolean   dispose_has_run;
+	char       *pkcs11_engine_path;
+	char       *pkcs11_module_path;
+	char       *pkcs11_module_init_args;
 } NMSupplicantConfigPrivate;
 
 NMSupplicantConfig *
@@ -89,6 +92,7 @@
 
 	priv->ap_scan = 1;
 	priv->dispose_has_run = FALSE;
+	priv->pkcs11_engine_path = g_strdup ("/usr/lib/engines/engine_pkcs11.so");
 }
 
 gboolean
@@ -224,9 +228,14 @@
 static void
 nm_supplicant_config_finalize (GObject *object)
 {
+	NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (object);
+
 	/* Complete object destruction */
-	g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config);
-	g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->blobs);
+	g_hash_table_destroy (priv->config);
+	g_hash_table_destroy (priv->blobs);
+	g_free (priv->pkcs11_engine_path);
+	g_free (priv->pkcs11_module_path);
+	g_free (priv->pkcs11_module_init_args);
 
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object);
@@ -261,6 +270,69 @@
 	NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan;
 }
 
+const char *
+nm_supplicant_config_get_pkcs11_engine_path (NMSupplicantConfig * self)
+{
+	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
+
+	return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->pkcs11_engine_path;
+}
+
+void
+nm_supplicant_config_set_pkcs11_engine_path (NMSupplicantConfig * self,
+                                             const char *pkcs11_engine_path)
+{
+	NMSupplicantConfigPrivate *priv;
+
+	g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self));
+
+	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
+	g_free (priv->pkcs11_engine_path);
+	priv->pkcs11_engine_path = g_strdup (pkcs11_engine_path);
+}
+
+const char *
+nm_supplicant_config_get_pkcs11_module_path (NMSupplicantConfig * self)
+{
+	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
+
+	return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->pkcs11_module_path;
+}
+
+void
+nm_supplicant_config_set_pkcs11_module_path (NMSupplicantConfig * self,
+                                             const char *pkcs11_module_path)
+{
+	NMSupplicantConfigPrivate *priv;
+
+	g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self));
+
+	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
+	g_free (priv->pkcs11_module_path);
+	priv->pkcs11_module_path = g_strdup (pkcs11_module_path);
+}
+
+const char *
+nm_supplicant_config_get_pkcs11_module_init_args (NMSupplicantConfig * self)
+{
+	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
+
+	return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->pkcs11_module_init_args;
+}
+
+void
+nm_supplicant_config_set_pkcs11_module_init_args (NMSupplicantConfig * self,
+                                                  const char *pkcs11_module_init_args)
+{
+	NMSupplicantConfigPrivate *priv;
+
+	g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self));
+
+	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
+	g_free (priv->pkcs11_module_init_args);
+	priv->pkcs11_module_init_args = g_strdup (pkcs11_module_init_args);
+}
+
 static void
 get_hash_cb (gpointer key, gpointer value, gpointer user_data)
 {
@@ -489,6 +561,8 @@
 	char *value;
 	gboolean success;
 	const char *key_mgmt, *auth_alg;
+	const char *pkcs11_engine_path;
+	const char *pkcs11_module_path;
 
 	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
 	g_return_val_if_fail (setting != NULL, FALSE);
@@ -555,6 +629,27 @@
 		}
 	}
 
+	pkcs11_engine_path = nm_setting_802_1x_get_pkcs11_engine_path (setting_8021x);
+	pkcs11_module_path = nm_setting_802_1x_get_pkcs11_module_path (setting_8021x);
+
+	if (pkcs11_engine_path && pkcs11_module_path) {
+		nm_supplicant_config_set_pkcs11_engine_path (self, pkcs11_engine_path);
+		nm_supplicant_config_set_pkcs11_module_path (self, pkcs11_module_path);
+		nm_supplicant_config_set_pkcs11_module_init_args (self,
+														  nm_setting_802_1x_get_pkcs11_module_init_args (setting_8021x));
+
+		ADD_STRING_VAL ("1", "engine", FALSE, FALSE, FALSE);
+		ADD_STRING_VAL ("pkcs11", "engine_id", FALSE, FALSE, FALSE);
+
+		/* TODO: handle more than one slot */
+		ADD_STRING_VAL (nm_setting_802_1x_get_pkcs11_ca_cert (setting_8021x), "ca_cert_id", FALSE, FALSE, FALSE);
+		ADD_STRING_VAL (nm_setting_802_1x_get_pkcs11_client_cert (setting_8021x), "cert_id", FALSE, FALSE, FALSE);
+		ADD_STRING_VAL (nm_setting_802_1x_get_pkcs11_private_key (setting_8021x), "key_id", FALSE, FALSE, FALSE);
+		ADD_STRING_VAL (nm_setting_802_1x_get_pkcs11_phase2_ca_cert (setting_8021x), "ca_cert2_id", FALSE, FALSE, FALSE);
+		ADD_STRING_VAL (nm_setting_802_1x_get_pkcs11_phase2_client_cert (setting_8021x), "cert2_id", FALSE, FALSE, FALSE);
+		ADD_STRING_VAL (nm_setting_802_1x_get_pkcs11_phase2_private_key (setting_8021x), "key2_id", FALSE, FALSE, FALSE);
+	}
+
 	return TRUE;
 }
 
diff -Naur network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-config.h network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-config.h
--- network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-config.h	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-config.h	2009-01-07 01:30:36.000000000 +0900
@@ -57,6 +57,21 @@
 void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
                                        guint32 ap_scan);
 
+const char *nm_supplicant_config_get_pkcs11_engine_path (NMSupplicantConfig * self);
+
+void nm_supplicant_config_set_pkcs11_engine_path (NMSupplicantConfig * self,
+                                                  const char *pkcs11_engine_path);
+
+const char *nm_supplicant_config_get_pkcs11_module_path (NMSupplicantConfig * self);
+
+void nm_supplicant_config_set_pkcs11_module_path (NMSupplicantConfig * self,
+                                                  const char *pkcs11_module_path);
+
+const char *nm_supplicant_config_get_pkcs11_module_init_args (NMSupplicantConfig * self);
+
+void nm_supplicant_config_set_pkcs11_module_init_args (NMSupplicantConfig * self,
+													   const char *pkcs11_module_init_args);
+
 gboolean nm_supplicant_config_add_option (NMSupplicantConfig *self,
                                           const char * key,
                                           const char * value,
diff -Naur network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-interface.c network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-interface.c
--- network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-interface.c	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-interface.c	2009-01-07 02:00:32.000000000 +0900
@@ -1157,6 +1157,8 @@
 	NMSupplicantInfo *info;
 	DBusGProxyCall *call;
 	guint32 ap_scan;
+	const char *pkcs11_engine_path;
+	const char *pkcs11_module_path;
 
 	g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
 
@@ -1182,6 +1184,41 @@
 									G_TYPE_INVALID);
 	nm_supplicant_info_set_call (info, call);
 
+	if (!call)
+		return FALSE;
+
+	pkcs11_engine_path = nm_supplicant_config_get_pkcs11_engine_path (priv->cfg);
+	pkcs11_module_path = nm_supplicant_config_get_pkcs11_module_path (priv->cfg);
+
+	if (pkcs11_engine_path && pkcs11_module_path) {
+		GHashTable *pkcs11_config_hash;
+		GValue *val;
+
+		pkcs11_config_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) blob_free);
+
+		val = g_slice_new0 (GValue);
+		g_value_init (val, G_TYPE_STRING);
+		g_value_set_string (val, pkcs11_engine_path);
+		g_hash_table_insert (pkcs11_config_hash, "pkcs11_engine_path", val);
+
+		val = g_slice_new0 (GValue);
+		g_value_init (val, G_TYPE_STRING);
+		g_value_set_string (val, pkcs11_module_path);
+		g_hash_table_insert (pkcs11_config_hash, "pkcs11_module_path", val);
+
+		/* TODO: waiting on pkcs11_module_init_args support in wpasupplicant
+		tmp = nm_supplicant_config_get_pkcs11_module_init_args (priv->cfg);
+		g_hash_table_insert (pkcs11_config_hash, "pkcs11_module_init_args",
+		                     str_to_gvalue(tmp));
+		*/
+
+		dbus_g_proxy_call_no_reply (priv->iface_proxy, "setSmartcardModules",
+									DBUS_TYPE_G_MAP_OF_VARIANT,
+									pkcs11_config_hash,
+									G_TYPE_INVALID);
+		g_hash_table_destroy (pkcs11_config_hash);
+	}
+
 	return call != NULL;
 }
 
diff -Naur network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-settings-verify.c network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-settings-verify.c
--- network-manager-0.7.bak/src/supplicant-manager/nm-supplicant-settings-verify.c	2008-11-29 02:55:17.000000000 +0900
+++ network-manager-0.7.dev/src/supplicant-manager/nm-supplicant-settings-verify.c	2009-01-07 01:34:32.000000000 +0900
@@ -120,7 +120,12 @@
 	{ "pac_file",           TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "engine",             TYPE_INT,     0, 1, FALSE,  NULL },
 	{ "engine_id",          TYPE_BYTES,   0, 0, FALSE,  NULL },
-	{ "key_id",             TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "ca_cert_id",         TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "cert_id",            TYPE_BYTES,   0, 0, FALSE,  NULL },
+ 	{ "key_id",             TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "ca_cert2_id",        TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "cert2_id",           TYPE_BYTES,   0, 0, FALSE,  NULL },
+	{ "key2_id",            TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "fragment_size",      TYPE_INT,     1, 2000, FALSE,  NULL },
 };
 
