On Tue, 10 Nov 2009 18:48:21 +0100 Pierre Ossman <oss...@cendio.se> 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 opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel