On Tue, 10 Nov 2009 18:48:21 +0100 Pierre Ossman <[email protected]> wrote:
> I'm looking at implementing support for unblocking a locked PIN in my > application, but looking at OpenSC that doesn't seem to be possible. In > fact, there are a number of issues along the way. > I've had another look at this and implemented a somewhat ugly hack to provide this functionality. Basically C_Login will return success for CKU_SO if it can't find an auth object and then rely on the PIN cache in C_InitPIN. Comment away! -- Pierre Ossman OpenSource-based Thin Client Technology System Developer Telephone: +46-13-21 46 00 Cendio AB Web: http://www.cendio.com
Index: src/pkcs11/framework-pkcs15.c
===================================================================
--- src/pkcs11/framework-pkcs15.c (revision 18564)
+++ src/pkcs11/framework-pkcs15.c (working copy)
@@ -907,13 +907,18 @@
/* A card with no SO PIN is treated as if no SO login
* is required */
rc = sc_pkcs15_find_so_pin(card, &auth_object);
-
- /* If there's no SO PIN on the card, silently
- * accept any PIN, and lock the card if required */
- if (rc == SC_ERROR_OBJECT_NOT_FOUND
- && sc_pkcs11_conf.lock_login)
+ if (rc == SC_ERROR_OBJECT_NOT_FOUND) {
+ /* Need to lock the card though */
rc = lock_card(fw_data);
- if (rc < 0)
+ if (rc < 0) {
+ return sc_to_cryptoki_error(rc,
+ p11card->reader);
+ }
+ /* And cache the PIN as init_pin might need it */
+ cache_pin(fw_token, userType, NULL, pPin, ulPinLen);
+ return CKR_OK;
+ }
+ else if (rc < 0)
return sc_to_cryptoki_error(rc, p11card->reader);
break;
default:
@@ -1006,11 +1011,11 @@
return sc_to_cryptoki_error(rc, p11card->reader);
}
-#ifdef USE_PKCS15_INIT
-static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
+static CK_RV pkcs15_create_pin(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
{
+#ifdef USE_PKCS15_INIT
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs15init_pinargs args;
struct sc_profile *profile;
@@ -1052,8 +1057,52 @@
cache_pin(slot->fw_data, CKU_USER, &pin_info->path, pPin, ulPinLen);
return CKR_OK;
+#else
+ return CKR_FUNCTION_NOT_SUPPORTED;
+#endif
}
+static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
+ struct sc_pkcs11_slot *slot,
+ CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
+{
+ struct pkcs15_fw_data *fw_data;
+ struct pkcs15_slot_data *slot_data;
+ struct sc_pkcs15_pin_info *pin;
+ int rc;
+
+ fw_data = (struct pkcs15_fw_data *)p11card->fw_data;
+ slot_data = (struct pkcs15_slot_data *)slot->fw_data;
+
+ pin = slot_data_pin_info(slot_data);
+
+ /* If we don't have a PIN then we want to create it */
+ if (!pin) {
+ sc_debug(context, "No PIN found. Attempting to create one...\n");
+ return pkcs15_create_pin(p11card, slot, pPin, ulPinLen);
+ }
+
+ /* Otherwise we want to reset the one we have */
+
+ if (ulPinLen < pin->min_length ||
+ ulPinLen > pin->max_length)
+ return CKR_PIN_LEN_RANGE;
+
+ /* This assumes that either:
+ * (a) We have a cached SO PIN
+ * (b) We have previously logged in as CKU_SO and the card
+ * will therefore accept the unblock request. */
+ rc = sc_pkcs15_unblock_pin(fw_data->p15_card, pin,
+ slot_data->pin[CKU_SO].value,
+ slot_data->pin[CKU_SO].len,
+ pPin, ulPinLen);
+ if (rc < 0)
+ return sc_to_cryptoki_error(rc, p11card->reader);
+
+ return CKR_OK;
+}
+
+#ifdef USE_PKCS15_INIT
static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
struct sc_profile *profile,
@@ -1690,14 +1739,13 @@
pkcs15_logout,
pkcs15_change_pin,
NULL, /* init_token */
+ pkcs15_init_pin,
#ifdef USE_PKCS15_INIT
- pkcs15_init_pin,
pkcs15_create_object,
pkcs15_gen_keypair,
#else
NULL,
NULL,
- NULL,
#endif
NULL, /* seed_random */
pkcs15_get_random
signature.asc
Description: PGP signature
_______________________________________________ opensc-devel mailing list [email protected] http://www.opensc-project.org/mailman/listinfo/opensc-devel
