[gnome-keyring] [wrap-layer] Implement initialize and change password prompts



commit 92fa5ed13833da27403b932c7d815d8f8a07f880
Author: Stef Walter <stef memberwebs com>
Date:   Sat Jun 12 22:20:34 2010 +0000

    [wrap-layer] Implement initialize and change password prompts

 pkcs11/gkm/gkm-mock.c                   |   10 +-
 pkcs11/wrap-layer/gkm-wrap-layer.c      |   23 +--
 pkcs11/wrap-layer/gkm-wrap-prompt.c     |  308 ++++++++++++++++++++++++++++---
 pkcs11/wrap-layer/gkm-wrap-prompt.h     |    2 -
 pkcs11/wrap-layer/tests/Makefile.am     |    4 +-
 pkcs11/wrap-layer/tests/test-init-pin.c |   92 +++++++++
 pkcs11/wrap-layer/tests/test-set-pin.c  |   92 +++++++++
 ui/gku-prompt.c                         |   16 ++
 ui/gku-prompt.h                         |    3 +
 9 files changed, 501 insertions(+), 49 deletions(-)
---
diff --git a/pkcs11/gkm/gkm-mock.c b/pkcs11/gkm/gkm-mock.c
index a49c382..471f445 100644
--- a/pkcs11/gkm/gkm-mock.c
+++ b/pkcs11/gkm/gkm-mock.c
@@ -666,9 +666,7 @@ gkm_mock_C_InitPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
 	Session *session;
 
 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
-	g_assert (session != NULL && "No such session found");
-	if (!session)
-		return CKR_SESSION_HANDLE_INVALID;
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
 
 	g_free (the_pin);
 	the_pin = g_strndup ((gchar*)pPin, ulPinLen);
@@ -684,12 +682,10 @@ gkm_mock_C_SetPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
 	gchar *old;
 
 	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
-	g_assert (session != NULL && "No such session found");
-	if (!session)
-		return CKR_SESSION_HANDLE_INVALID;
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
 
 	old = g_strndup ((gchar*)pOldPin, ulOldLen);
-	if (!g_str_equal (old, the_pin))
+	if (!old || !g_str_equal (old, the_pin))
 		return CKR_PIN_INCORRECT;
 
 	g_free (the_pin);
diff --git a/pkcs11/wrap-layer/gkm-wrap-layer.c b/pkcs11/wrap-layer/gkm-wrap-layer.c
index 337625e..c72ca5a 100644
--- a/pkcs11/wrap-layer/gkm-wrap-layer.c
+++ b/pkcs11/wrap-layer/gkm-wrap-layer.c
@@ -530,24 +530,22 @@ wrap_C_GetSessionInfo (CK_SESSION_HANDLE handle, CK_SESSION_INFO_PTR info)
 static CK_RV
 wrap_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
 {
-#if 0
 	GkmWrapPrompt *prompt;
-#endif
 	Mapping map;
 	CK_RV rv;
 
 	rv = map_session_to_real (&handle, &map, NULL);
 	if (rv != CKR_OK)
 		return rv;
-#if 0
+
 	prompt = gkm_wrap_prompt_for_init_pin (map.funcs, handle, pin, pin_len);
 
 	for (;;) {
 		if (prompt && !gkm_wrap_prompt_do_init_pin (prompt, rv, &pin, &pin_len))
 			break;
-#endif
+
 		rv = (map.funcs->C_InitPIN) (handle, pin, pin_len);
-#if 0
+
 		if (!prompt || rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
 			break;
 	}
@@ -556,23 +554,21 @@ wrap_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
 		gkm_wrap_prompt_done_init_pin (prompt, rv);
 		g_object_unref (prompt);
 	}
-#endif
+
 	return rv;
 }
 
 static CK_RV
 wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_pin_len, CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len)
 {
-#if 0
 	GkmWrapPrompt *prompt;
-#endif
 	Mapping map;
 	CK_RV rv;
 
 	rv = map_session_to_real (&handle, &map, NULL);
 	if (rv != CKR_OK)
 		return rv;
-#if 0
+
 	prompt = gkm_wrap_prompt_for_set_pin (map.funcs, handle,
 	                                      old_pin, old_pin_len,
 	                                      new_pin, new_pin_len);
@@ -581,10 +577,11 @@ wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_p
 		if (prompt && !gkm_wrap_prompt_do_set_pin (prompt, rv, &old_pin, &old_pin_len,
 		                                           &new_pin, &new_pin_len))
 			break;
-#endif
+
 		rv = (map.funcs->C_SetPIN) (handle, old_pin, old_pin_len, new_pin, new_pin_len);
-#if 0
-		if (!prompt || rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
+
+		if (!prompt || rv != CKR_PIN_INCORRECT ||
+		    rv != CKR_PIN_INVALID || rv != CKR_PIN_LEN_RANGE)
 			break;
 	}
 
@@ -592,7 +589,7 @@ wrap_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_p
 		gkm_wrap_prompt_done_set_pin (prompt, rv);
 		g_object_unref (prompt);
 	}
-#endif
+
 	return rv;
 }
 
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.c b/pkcs11/wrap-layer/gkm-wrap-prompt.c
index f788ac0..1006254 100644
--- a/pkcs11/wrap-layer/gkm-wrap-prompt.c
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.c
@@ -52,12 +52,6 @@ struct _GkmWrapPrompt {
 	GQueue pool;
 };
 
-typedef struct _CredentialPrompt {
-	GArray *template;
-	CK_ULONG n_template;
-	gchar *password;
-} CredentialPrompt;
-
 G_DEFINE_TYPE (GkmWrapPrompt, gkm_wrap_prompt, GKU_TYPE_PROMPT);
 
 /* -----------------------------------------------------------------------------
@@ -128,6 +122,28 @@ auto_unlock_object_unique (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 	return g_strndup (attr->pValue, attr->ulValueLen);
 }
 
+static void
+convert_upper_case (gchar *str)
+{
+	for (; *str; ++str)
+		*str = g_ascii_toupper (*str);
+}
+
+static gchar*
+auto_unlock_object_digest (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
+{
+	CK_ATTRIBUTE_PTR attr;
+	gchar *result;
+
+	attr = gkm_attributes_find (attrs, n_attrs, CKA_GNOME_INTERNAL_SHA1);
+	if (attr == NULL)
+		return NULL;
+
+	result = g_strndup (attr->pValue, attr->ulValueLen);
+	convert_upper_case (result);
+	return result;
+}
+
 static gchar*
 auto_unlock_lookup_keyring (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 {
@@ -148,7 +164,7 @@ static gchar*
 auto_unlock_lookup_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 {
 	CK_OBJECT_CLASS klass;
-	gchar *unique;
+	gchar *value;
 	gchar *password;
 
 	if (!gkm_attributes_find_ulong (attrs, n_attrs, CKA_CLASS, &klass))
@@ -157,13 +173,24 @@ auto_unlock_lookup_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 	if (klass == CKO_G_COLLECTION)
 		return auto_unlock_lookup_keyring (attrs, n_attrs);
 
-	unique = auto_unlock_object_unique (attrs, n_attrs);
-	if (unique == NULL)
-		return NULL;
+	value = auto_unlock_object_unique (attrs, n_attrs);
+	if (value != NULL) {
+		password = gkm_wrap_login_lookup_secret ("unique", value, NULL);
+		g_free (value);
+		if (password)
+			return password;
+	}
 
-	password = gkm_wrap_login_lookup_secret ("unique", unique, NULL);
-	g_free (unique);
-	return password;
+	/* COMPAT: Check old method of storing secrets for objects in login keyring */
+	value = auto_unlock_object_digest (attrs, n_attrs);
+	if (value != NULL) {
+		password = gkm_wrap_login_lookup_secret ("object-digest", value, NULL);
+		g_free (value);
+		if (password)
+			return password;
+	}
+
+	return NULL;
 }
 
 static gchar*
@@ -308,7 +335,7 @@ static void
 auto_unlock_remove_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 {
 	CK_OBJECT_CLASS klass;
-	gchar *unique;
+	gchar *value;
 
 	if (!gkm_attributes_find_ulong (attrs, n_attrs, CKA_CLASS, &klass))
 		return;
@@ -318,12 +345,19 @@ auto_unlock_remove_object (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 		return;
 	}
 
-	unique = auto_unlock_object_unique (attrs, n_attrs);
-	if (unique == NULL)
-		return;
+	value = auto_unlock_object_unique (attrs, n_attrs);
+	if (value != NULL) {
+		gkm_wrap_login_remove_secret ("unique", value, NULL);
+		g_free (value);
+	}
+
+	/* COMPAT: Clear old method of storing secrets for objects in login keyring */
+	value = auto_unlock_object_digest (attrs, n_attrs);
+	if (value != NULL) {
+		gkm_wrap_login_remove_secret ("object-digest", value, NULL);
+		g_free (value);
+	}
 
-	gkm_wrap_login_remove_secret ("unique", unique, NULL);
-	g_free (unique);
 }
 
 static void
@@ -507,7 +541,7 @@ set_unlock_options_on_prompt (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR options, CK_
 static CK_ATTRIBUTE_PTR
 get_attributes_from_object (GkmWrapPrompt *self, CK_ULONG *n_attrs)
 {
-	CK_ATTRIBUTE attrs[5];
+	CK_ATTRIBUTE attrs[6];
 	CK_ULONG i;
 	CK_RV rv;
 
@@ -521,6 +555,7 @@ get_attributes_from_object (GkmWrapPrompt *self, CK_ULONG *n_attrs)
 	attrs[2].type = CKA_CLASS;
 	attrs[3].type = CKA_G_LOGIN_COLLECTION;
 	attrs[4].type = CKA_GNOME_UNIQUE;
+	attrs[5].type = CKA_GNOME_INTERNAL_SHA1;
 
 	rv = (self->module->C_GetAttributeValue) (self->session, self->object, attrs, G_N_ELEMENTS (attrs));
 	if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
@@ -813,6 +848,12 @@ gkm_wrap_prompt_class_init (GkmWrapPromptClass *klass)
  * CREDENTIAL
  */
 
+typedef struct _CredentialPrompt {
+	GArray *template;
+	CK_ULONG n_template;
+	gchar *password;
+} CredentialPrompt;
+
 static void
 credential_prompt_free (gpointer user_data)
 {
@@ -967,25 +1008,168 @@ gkm_wrap_prompt_done_credential (GkmWrapPrompt *self, CK_RV call_result)
 	}
 }
 
-#if 0
+/* ------------------------------------------------------------------------------------
+ * INITPIN
+ */
+
+static void
+prepare_init_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
+{
+	GkuPrompt *prompt;
+	gchar *label;
+	gchar *text;
+
+	g_assert (GKM_WRAP_IS_PROMPT (self));
+	g_assert (tinfo);
+
+	prompt = GKU_PROMPT (self);
+
+	label = g_strndup ((gchar*)tinfo->label, sizeof (tinfo->label));
+	g_strchomp (label);
+
+	/* Build up the prompt */
+	gku_prompt_show_widget (prompt, "password_area");
+	gku_prompt_show_widget (prompt, "confirm_area");
+	gku_prompt_hide_widget (prompt, "original_area");
+	gku_prompt_set_title (prompt, _("New Password Required"));
+	gku_prompt_set_primary_text (prompt, _("New password required for secure storage"));
+
+	text = g_strdup_printf (_("In order to prepare '%s' for storage of certificates or keys, a password is required"), label);
+	gku_prompt_set_secondary_text (prompt, text);
+	g_free (text);
+
+	if (gkm_wrap_login_is_usable ()) {
+		gku_prompt_show_widget (prompt, "details_area");
+		gku_prompt_show_widget (prompt, "lock_area");
+		gku_prompt_hide_widget (prompt, "options_area");
+	}
+
+	g_free (label);
+}
+
 GkmWrapPrompt*
 gkm_wrap_prompt_for_init_pin (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE session,
                               CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
 {
+	GkmWrapPrompt *self;
+
+	g_assert (module);
+
+	if (pin != NULL || pin_len != 0)
+		return NULL;
+
+	/* Build up the prompt */
+	self = g_object_new (GKM_WRAP_TYPE_PROMPT, NULL);
+	self->module = module;
+	self->session = session;
+	self->destroy_data = (GDestroyNotify)egg_secure_strfree;
 
+	return self;
 }
 
 gboolean
-gkm_wrap_prompt_do_init_pin (GkmWrapPrompt *prompt, CK_RV last_result,
+gkm_wrap_prompt_do_init_pin (GkmWrapPrompt *self, CK_RV last_result,
                              CK_UTF8CHAR_PTR *pin, CK_ULONG *n_pin)
 {
+	CK_TOKEN_INFO tinfo;
+
+	g_assert (GKM_WRAP_IS_PROMPT (self));
+	g_assert (self->module);
+	g_assert (pin);
+	g_assert (n_pin);
+
+	g_assert (self->destroy_data == (GDestroyNotify)egg_secure_strfree);
+	egg_secure_strfree (self->prompt_data);
+	self->prompt_data = NULL;
+
+	if (!get_info_for_token (self, &tinfo))
+		return FALSE;
+
+	/* Hard reset on first prompt, soft on later */
+	gku_prompt_reset (GKU_PROMPT (self), last_result == CKR_OK);
+
+	prepare_init_token (self, &tinfo);
+
+	gku_prompt_request_attention_sync (NULL, on_prompt_attention,
+	                                   g_object_ref (self), g_object_unref);
+
+	if (gku_prompt_get_response (GKU_PROMPT (self)) != GKU_RESPONSE_OK)
+		return FALSE;
 
+	self->prompt_data = gku_prompt_get_password (GKU_PROMPT (self), "password");
+	g_return_val_if_fail (self->prompt_data, FALSE);
+
+	*pin = self->prompt_data;
+	*n_pin = strlen (self->prompt_data);
+	return TRUE;
 }
 
 void
-gkm_wrap_prompt_done_init_pin (GkmWrapPrompt *prompt, CK_RV call_result)
+gkm_wrap_prompt_done_init_pin (GkmWrapPrompt *self, CK_RV call_result)
 {
+	CK_TOKEN_INFO tinfo;
+
+	g_assert (GKM_WRAP_IS_PROMPT (self));
+	g_assert (self->destroy_data == (GDestroyNotify)egg_secure_strfree);
+
+	/* Save auto auto unlock */
+	if (call_result == CKR_OK && auto_unlock_should_attach (self)) {
+		if (get_info_for_token (self, &tinfo))
+			auto_unlock_attach_token (&tinfo, self->prompt_data);
+	}
+}
+
+/* ------------------------------------------------------------------------------------
+ * SETPIN
+ */
+
+typedef struct _SetPinPrompt {
+	gchar *original;
+	gchar *password;
+} SetPinPrompt;
+
+static void
+set_pin_prompt_free (gpointer user_data)
+{
+	SetPinPrompt *data = user_data;
+	egg_secure_strfree (data->original);
+	egg_secure_strfree (data->password);
+	g_slice_free (SetPinPrompt, data);
+}
+
+static void
+prepare_set_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
+{
+	GkuPrompt *prompt;
+	gchar *label;
+	gchar *text;
+
+	g_assert (GKM_WRAP_IS_PROMPT (self));
+	g_assert (tinfo);
+
+	prompt = GKU_PROMPT (self);
+
+	label = g_strndup ((gchar*)tinfo->label, sizeof (tinfo->label));
+	g_strchomp (label);
+
+	/* Build up the prompt */
+	gku_prompt_show_widget (prompt, "password_area");
+	gku_prompt_show_widget (prompt, "confirm_area");
+	gku_prompt_show_widget (prompt, "original_area");
+	gku_prompt_set_title (prompt, _("Change Password"));
+	gku_prompt_set_primary_text (prompt, _("Change password for secure storage"));
+
+	text = g_strdup_printf (_("To change the password for '%s', the original and new passwords are required"), label);
+	gku_prompt_set_secondary_text (prompt, text);
+	g_free (text);
 
+	if (gkm_wrap_login_is_usable ()) {
+		gku_prompt_show_widget (prompt, "details_area");
+		gku_prompt_show_widget (prompt, "lock_area");
+		gku_prompt_hide_widget (prompt, "options_area");
+	}
+
+	g_free (label);
 }
 
 GkmWrapPrompt*
@@ -993,23 +1177,95 @@ gkm_wrap_prompt_for_set_pin (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE sess
                              CK_UTF8CHAR_PTR old_pin, CK_ULONG n_old_pin,
                              CK_UTF8CHAR_PTR new_pin, CK_ULONG n_new_pin)
 {
+	GkmWrapPrompt *self;
+
+	g_assert (module);
 
+	if (new_pin != NULL || n_new_pin != 0)
+		return NULL;
+
+	/* Build up the prompt */
+	self = g_object_new (GKM_WRAP_TYPE_PROMPT, NULL);
+	self->module = module;
+	self->session = session;
+	self->destroy_data = set_pin_prompt_free;
+	self->prompt_data = g_slice_new0 (SetPinPrompt);
+
+	return self;
 }
 
 gboolean
-gkm_wrap_prompt_do_set_pin (GkmWrapPrompt *prompt, CK_RV last_result,
+gkm_wrap_prompt_do_set_pin (GkmWrapPrompt *self, CK_RV last_result,
                             CK_UTF8CHAR_PTR *old_pin, CK_ULONG *n_old_pin,
                             CK_UTF8CHAR_PTR *new_pin, CK_ULONG *n_new_pin)
 {
+	gboolean initializing = FALSE;
+	CK_TOKEN_INFO tinfo;
+	SetPinPrompt *data;
 
+	g_assert (GKM_WRAP_IS_PROMPT (self));
+	g_assert (self->module);
+	g_assert (old_pin);
+	g_assert (n_old_pin);
+	g_assert (new_pin);
+	g_assert (n_new_pin);
+
+	g_assert (self->destroy_data == set_pin_prompt_free);
+	data = self->prompt_data;
+
+	if (!get_info_for_token (self, &tinfo))
+		return FALSE;
+
+	/* Hard reset on first prompt, soft on later */
+	gku_prompt_reset (GKU_PROMPT (self), last_result == CKR_OK);
+
+	initializing = !(tinfo.flags & CKF_USER_PIN_INITIALIZED);
+	if (initializing)
+		prepare_init_token (self, &tinfo);
+	else
+		prepare_set_token (self, &tinfo);
+
+	gku_prompt_request_attention_sync (NULL, on_prompt_attention,
+	                                   g_object_ref (self), g_object_unref);
+
+	if (gku_prompt_get_response (GKU_PROMPT (self)) != GKU_RESPONSE_OK)
+		return FALSE;
+
+	egg_secure_strfree (data->password);
+	data->password = gku_prompt_get_password (GKU_PROMPT (self), "password");
+	g_return_val_if_fail (data->password, FALSE);
+
+	*new_pin = (guchar*)data->password;
+	*n_new_pin = strlen (data->password);
+
+	if (!initializing) {
+		egg_secure_strfree (data->original);
+		data->original = gku_prompt_get_password (GKU_PROMPT (self), "original");
+		g_return_val_if_fail (data->original, FALSE);
+
+		*old_pin = (guchar*)data->original;
+		*n_old_pin = strlen (data->original);
+	}
+
+	return TRUE;
 }
 
 void
-gkm_wrap_prompt_done_set_pin (GkmWrapPrompt *prompt, CK_RV call_result)
+gkm_wrap_prompt_done_set_pin (GkmWrapPrompt *self, CK_RV call_result)
 {
+	CK_TOKEN_INFO tinfo;
+	SetPinPrompt *data;
+
+	g_assert (GKM_WRAP_IS_PROMPT (self));
+	g_assert (self->destroy_data == set_pin_prompt_free);
+	data = self->prompt_data;
 
+	/* Save auto auto unlock */
+	if (call_result == CKR_OK && auto_unlock_should_attach (self)) {
+		if (get_info_for_token (self, &tinfo))
+			auto_unlock_attach_token (&tinfo, data->password);
+	}
 }
-#endif
 
 /* -----------------------------------------------------------------------------
  * LOGIN
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.h b/pkcs11/wrap-layer/gkm-wrap-prompt.h
index 8e8c0e7..499ce3a 100644
--- a/pkcs11/wrap-layer/gkm-wrap-prompt.h
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.h
@@ -54,7 +54,6 @@ gboolean            gkm_wrap_prompt_do_credential           (GkmWrapPrompt *self
 void                gkm_wrap_prompt_done_credential         (GkmWrapPrompt *self,
                                                              CK_RV call_result);
 
-#if 0
 GkmWrapPrompt*      gkm_wrap_prompt_for_init_pin            (CK_FUNCTION_LIST_PTR module,
                                                              CK_SESSION_HANDLE session,
                                                              CK_UTF8CHAR_PTR pin,
@@ -84,7 +83,6 @@ gboolean            gkm_wrap_prompt_do_set_pin              (GkmWrapPrompt *prom
 
 void                gkm_wrap_prompt_done_set_pin            (GkmWrapPrompt *prompt,
                                                              CK_RV call_result);
-#endif
 
 GkmWrapPrompt*      gkm_wrap_prompt_for_login               (CK_FUNCTION_LIST_PTR module,
                                                              CK_USER_TYPE user_type,
diff --git a/pkcs11/wrap-layer/tests/Makefile.am b/pkcs11/wrap-layer/tests/Makefile.am
index bcc73cc..007c4d2 100644
--- a/pkcs11/wrap-layer/tests/Makefile.am
+++ b/pkcs11/wrap-layer/tests/Makefile.am
@@ -2,11 +2,13 @@
 TESTING_FILES = \
 	mock-secret-store.c \
 	test-create-credential.c \
+	test-init-pin.c \
 	test-login-auto.c \
 	test-login-hints.c \
 	test-login-keyring.c \
 	test-login-specific.c \
-	test-login-user.c
+	test-login-user.c \
+	test-set-pin.c
 
 TESTING_LIBS = \
 	$(top_builddir)/pkcs11/wrap-layer/libgkm-wrap-layer.la \
diff --git a/pkcs11/wrap-layer/tests/test-init-pin.c b/pkcs11/wrap-layer/tests/test-init-pin.c
new file mode 100644
index 0000000..118930f
--- /dev/null
+++ b/pkcs11/wrap-layer/tests/test-init-pin.c
@@ -0,0 +1,92 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "test-suite.h"
+
+#include "gkm/gkm-mock.h"
+#include "gkm/gkm-test.h"
+
+#include "wrap-layer/gkm-wrap-layer.h"
+
+#include "ui/gku-prompt.h"
+
+static CK_FUNCTION_LIST functions;
+static CK_FUNCTION_LIST_PTR module = NULL;
+static CK_SESSION_HANDLE session = 0;
+
+DEFINE_SETUP (init_pin)
+{
+	CK_FUNCTION_LIST_PTR funcs;
+	CK_SLOT_ID slot_id;
+	CK_ULONG n_slots = 1;
+	CK_RV rv;
+
+	/* Always start off with test functions */
+	rv = gkm_mock_C_GetFunctionList (&funcs);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+	memcpy (&functions, funcs, sizeof (functions));
+
+	gkm_wrap_layer_reset_modules ();
+	gkm_wrap_layer_add_module (&functions);
+	module = gkm_wrap_layer_get_functions ();
+
+	gku_prompt_dummy_prepare_response ();
+
+	/* Open a session */
+	rv = (module->C_Initialize) (NULL);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+
+	rv = (module->C_GetSlotList) (CK_TRUE, &slot_id, &n_slots);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+
+	rv = (module->C_OpenSession) (slot_id, CKF_SERIAL_SESSION, NULL, NULL, &session);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+}
+
+DEFINE_TEARDOWN (init_pin)
+{
+	CK_RV rv;
+
+	g_assert (!gku_prompt_dummy_have_response ());
+
+	rv = (module->C_CloseSession) (session);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+	session = 0;
+
+	rv = (module->C_Finalize) (NULL);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+	module = NULL;
+}
+
+DEFINE_TEST (init_pin_ok_password)
+{
+	CK_RV rv;
+
+	gku_prompt_dummy_queue_ok_password ("new");
+
+	rv = (module->C_InitPIN) (session, NULL, 0);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+
+	rv = (module->C_Login) (session, CKU_USER, (guchar*)"new", 3);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+}
diff --git a/pkcs11/wrap-layer/tests/test-set-pin.c b/pkcs11/wrap-layer/tests/test-set-pin.c
new file mode 100644
index 0000000..8b1a879
--- /dev/null
+++ b/pkcs11/wrap-layer/tests/test-set-pin.c
@@ -0,0 +1,92 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "test-suite.h"
+
+#include "gkm/gkm-mock.h"
+#include "gkm/gkm-test.h"
+
+#include "wrap-layer/gkm-wrap-layer.h"
+
+#include "ui/gku-prompt.h"
+
+static CK_FUNCTION_LIST functions;
+static CK_FUNCTION_LIST_PTR module = NULL;
+static CK_SESSION_HANDLE session = 0;
+
+DEFINE_SETUP (set_pin)
+{
+	CK_FUNCTION_LIST_PTR funcs;
+	CK_SLOT_ID slot_id;
+	CK_ULONG n_slots = 1;
+	CK_RV rv;
+
+	/* Always start off with test functions */
+	rv = gkm_mock_C_GetFunctionList (&funcs);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+	memcpy (&functions, funcs, sizeof (functions));
+
+	gkm_wrap_layer_reset_modules ();
+	gkm_wrap_layer_add_module (&functions);
+	module = gkm_wrap_layer_get_functions ();
+
+	gku_prompt_dummy_prepare_response ();
+
+	/* Open a session */
+	rv = (module->C_Initialize) (NULL);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+
+	rv = (module->C_GetSlotList) (CK_TRUE, &slot_id, &n_slots);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+
+	rv = (module->C_OpenSession) (slot_id, CKF_SERIAL_SESSION, NULL, NULL, &session);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+}
+
+DEFINE_TEARDOWN (set_pin)
+{
+	CK_RV rv;
+
+	g_assert (!gku_prompt_dummy_have_response ());
+
+	rv = (module->C_CloseSession) (session);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+	session = 0;
+
+	rv = (module->C_Finalize) (NULL);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+	module = NULL;
+}
+
+DEFINE_TEST (set_pin_ok_passwords)
+{
+	CK_RV rv;
+
+	gku_prompt_dummy_queue_ok_passwords ("booo", "new");
+
+	rv = (module->C_SetPIN) (session, NULL, 0, NULL, 0);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+
+	rv = (module->C_Login) (session, CKU_USER, (guchar*)"new", 3);
+	gkm_assert_cmprv (rv, ==, CKR_OK);
+}
diff --git a/ui/gku-prompt.c b/ui/gku-prompt.c
index 2801e60..f609bf9 100644
--- a/ui/gku-prompt.c
+++ b/ui/gku-prompt.c
@@ -1208,6 +1208,22 @@ gku_prompt_dummy_queue_ok_password (const gchar *password)
 }
 
 void
+gku_prompt_dummy_queue_ok_passwords (const gchar *original, const gchar *password)
+{
+	const static gchar *RESPONSE = "[password]\nparameter=\nvalue=%s\n"
+	                               "[original]\nparameter=\nvalue=%s\n"
+	                               "[prompt]\nresponse=ok\n";
+	gchar *value, *ovalue;
+
+	g_return_if_fail (password);
+	value = egg_hex_encode ((const guchar*)password, strlen (password));
+	ovalue = egg_hex_encode ((const guchar*)original, strlen (original));
+	queue_dummy_response (g_strdup_printf (RESPONSE, value, ovalue));
+	g_free (value);
+	g_free (ovalue);
+}
+
+void
 gku_prompt_dummy_queue_auto_password (const gchar *password)
 {
 	const static gchar *RESPONSE = "[password]\nparameter=\nvalue=%s\n[prompt]\nresponse=ok\n"
diff --git a/ui/gku-prompt.h b/ui/gku-prompt.h
index 1f82eb5..060bfcf 100644
--- a/ui/gku-prompt.h
+++ b/ui/gku-prompt.h
@@ -149,6 +149,9 @@ void                gku_prompt_dummy_queue_response        (const gchar *respons
 
 void                gku_prompt_dummy_queue_ok_password     (const gchar *password);
 
+void                gku_prompt_dummy_queue_ok_passwords    (const gchar *original,
+                                                            const gchar *password);
+
 void                gku_prompt_dummy_queue_auto_password   (const gchar *password);
 
 void                gku_prompt_dummy_queue_no              (void);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]