Index: src/pkcs11/framework-pkcs15.c
===================================================================
--- src/pkcs11/framework-pkcs15.c	(revision 3916)
+++ src/pkcs11/framework-pkcs15.c	(working copy)
@@ -27,7 +27,7 @@
 #endif
 
 extern int hack_enabled;
-
+#define MAX_CACHE_PIN		32
 struct pkcs15_slot_data {
 	struct sc_pkcs15_object *auth_obj;
 };
@@ -145,8 +145,9 @@
 static CK_RV	get_gostr3410_params(const u8 *, size_t, CK_ATTRIBUTE_PTR);
 static int	lock_card(struct pkcs15_fw_data *);
 static int	unlock_card(struct pkcs15_fw_data *);
-static void	add_pins_to_keycache(struct sc_pkcs11_card *p11card,
-				struct sc_pkcs11_slot *slot);
+//static void	add_pins_to_keycache(struct sc_pkcs11_card *p11card,
+//				struct sc_pkcs11_slot *slot);
+static void	add_pins_to_keycache(void *, int, const sc_path_t *, const void *, size_t);
 static int	reselect_app_df(sc_pkcs15_card_t *p15card);
 
 /* PKCS#15 Framework */
@@ -1042,6 +1043,11 @@
 
 	rc = sc_pkcs15_verify_pin(card, pin, pPin, ulPinLen);
 	sc_debug(context, "PKCS15 verify PIN returned %d\n", rc);
+	if (rc >= 0)
+	{
+		add_pins_to_keycache(fw_token, userType, &pin->path, pPin, ulPinLen);
+	}
+
 	return sc_to_cryptoki_error(rc, p11card->reader);
 }
 
@@ -1110,6 +1116,10 @@
 	}
 
 	sc_debug(context, "PIN change returns %d\n", rc);
+	if (rc >= 0)
+	{
+		add_pins_to_keycache(fw_token, CKU_USER, &pin->path, pNewPin, ulNewLen);
+	}
 	return sc_to_cryptoki_error(rc, p11card->reader);
 }
 
@@ -1176,6 +1186,8 @@
 	pkcs15_init_slot(fw_data->p15_card, slot, auth_obj);
 
 	pin_info = (sc_pkcs15_pin_info_t *) auth_obj->data;
+
+	add_pins_to_keycache(slot->fw_data, CKU_USER, &pin_info->path, pPin, ulPinLen);
 	return CKR_OK;
 }
 
@@ -1548,7 +1560,7 @@
 	}
 
 	/* Add the PINs the user presented so far to the keycache. */
-	add_pins_to_keycache(p11card, slot);
+//	add_pins_to_keycache(p11card, slot);
 
 	switch (_class) {
 	case CKO_PRIVATE_KEY:
@@ -1777,7 +1789,7 @@
 
 	/* 2. Add the PINs the user presented so far to the keycache */
 
-	add_pins_to_keycache(p11card, slot);
+//	add_pins_to_keycache(p11card, slot);
 
 	/* 3.a Try on-card key pair generation */
 
@@ -1922,7 +1934,7 @@
 	}
 
 	/* Add the PINs the user presented so far to the keycache. */
-	add_pins_to_keycache(p11card, session->slot);
+//	add_pins_to_keycache(p11card, session->slot);
 
 	switch(attr->type) {
 	case CKA_LABEL:
@@ -2790,7 +2802,7 @@
 	}
 
 	/* Add the PINs the user presented so far to the keycache */
-	add_pins_to_keycache(card, session->slot);
+//	add_pins_to_keycache(card, session->slot);
 
 	/* Delete object in smartcard */
 	rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object);
@@ -3152,38 +3164,46 @@
  * need to present these PINs again because some  card operations may
  * clobber the authentication state (the GPK for instance). */
 static void
-add_pins_to_keycache(struct sc_pkcs11_card *p11card,
-		struct sc_pkcs11_slot *slot)
+add_pins_to_keycache(void *p, int user, const sc_path_t *path, const void *pin, size_t len)
 {
-#if 0
-//#ifdef USE_PKCS15_INIT
-	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
-	struct sc_pkcs15_card *p15card = fw_data->p15_card;
-	struct pkcs15_slot_data *p15_data = slot_data(slot->fw_data);
+#ifdef USE_PKCS15_INIT
+	struct pkcs15_slot_data *p15_data = (struct pkcs15_slot_data *) p;
 	struct sc_pkcs15_pin_info *pin_info;
 
-	if (p15_data->pin[CKU_SO].len) {
-	        struct sc_pkcs15_object *auth_object;
-	        int rc = sc_pkcs15_find_so_pin(p15card, &auth_object);
-		if (rc >= 0) {
-			pin_info = (struct sc_pkcs15_pin_info *) auth_object->data;
-			sc_keycache_put_key(&p15_data->pin[CKU_SO].path,
+	if (len == 0) {
+		sc_keycache_forget_key(path, SC_AC_SYMBOLIC,
+			user? SC_PKCS15INIT_USER_PIN : SC_PKCS15INIT_SO_PIN);
+	}
+
+	/* Don't cache pins related to user_consent objects/slots */
+//	if (data->user_consent)
+//		return;
+
+	if (len == 0 || len > MAX_CACHE_PIN) {
+		return;
+	}
+
+	if (user == CKU_SO) {
+			pin_info = (struct sc_pkcs15_pin_info *) p15_data->auth_obj->data;
+			sc_keycache_put_key(path,
 				SC_AC_SYMBOLIC, SC_PKCS15INIT_SO_PIN,
-				p15_data->pin[CKU_SO].value, p15_data->pin[CKU_SO].len);
+				pin, len);
 			sc_keycache_set_pin_name(&pin_info->path, pin_info->reference,
 				SC_PKCS15INIT_SO_PIN);
-		}
 	}
-	if (p15_data->pin[CKU_USER].len) {
-		pin_info = slot_data_pin_info(slot->fw_data);
+	else if (user == CKU_USER) {
+		pin_info = slot_data_pin_info(p15_data);
 		if (pin_info != NULL) {
-			sc_keycache_put_key(&p15_data->pin[CKU_USER].path,
+			sc_keycache_put_key(path,
 				SC_AC_SYMBOLIC, SC_PKCS15INIT_USER_PIN,
-				p15_data->pin[CKU_USER].value, p15_data->pin[CKU_USER].len);
+				pin, len);
 			sc_keycache_set_pin_name(&pin_info->path, pin_info->reference,
 				SC_PKCS15INIT_USER_PIN);
 		}
 	}
+	else {
+	}
+	return;
 #endif
 }
 
