From 0761a5ea02d4bd7f0256991b7adccff7c5f6183f Mon Sep 17 00:00:00 2001 From: Viktor Tarasov Date: Wed, 25 Dec 2013 23:12:33 +0100 Subject: [PATCH] pkcs11: use 'ignore-pin-length' config option When doing C_Login default behavior is to ignore the applied PINs with lengths less then value of PKCS#15 PIN attribure 'min-length'. Such a PINs are not really verified by card. With 'ignore-pin-length' option in 'true' all applied PINs are verified by card. --- src/pkcs11/framework-pkcs15.c | 27 ++++++++++++++++++++------- src/pkcs11/misc.c | 3 +++ src/pkcs11/sc-pkcs11.h | 1 + 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index a5d1d170..ba14d9fd 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1396,7 +1396,7 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, struct sc_pkcs15_card *p15card = NULL; struct sc_pkcs15_object *auth_object = NULL; struct sc_pkcs15_auth_info *pin_info = NULL; - int rc; + int rc, pin_min_length = 0; fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx]; if (!fw_data) @@ -1495,12 +1495,19 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, pPin = NULL; } else { /* - * If PIN is out of range, - * it cannot be correct. + * If PIN is out of range, it cannot be correct. */ - if (ulPinLen < pin_info->attrs.pin.min_length || - ulPinLen > pin_info->attrs.pin.max_length) + if (sc_pkcs11_conf.ignore_pin_length) { + sc_log(context, "Ignore minimal PIN length"); + pin_min_length = pin_info->attrs.pin.min_length; + pin_info->attrs.pin.min_length = 1; + } + + if (ulPinLen < pin_info->attrs.pin.min_length || ulPinLen > pin_info->attrs.pin.max_length) { + if (pin_min_length) + pin_info->attrs.pin.min_length = pin_min_length; return CKR_PIN_INCORRECT; + } } @@ -1516,13 +1523,19 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType, * before the crypto operation that requires the assertion */ if (userType != CKU_CONTEXT_SPECIFIC) { - if (sc_pkcs11_conf.lock_login && (rc = lock_card(fw_data)) < 0) - return sc_to_cryptoki_error(rc, "C_Login"); + if (sc_pkcs11_conf.lock_login && (rc = lock_card(fw_data)) < 0) { + if (pin_min_length) + pin_info->attrs.pin.min_length = pin_min_length; + return sc_to_cryptoki_error(rc, "C_Login"); + } } rc = sc_pkcs15_verify_pin(p15card, auth_object, pPin, ulPinLen); sc_log(context, "PKCS15 verify PIN returned %d", rc); + if (pin_min_length) + pin_info->attrs.pin.min_length = pin_min_length; + if (rc != SC_SUCCESS) return sc_to_cryptoki_error(rc, "C_Login"); diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 02109f97..2528d0a5 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -300,6 +300,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) conf->create_puk_slot = 0; conf->zero_ckaid_for_ca_certs = 0; conf->create_slots_flags = 0; + conf->ignore_pin_length = 0; conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1); if (!conf_block) @@ -323,6 +324,8 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot); conf->zero_ckaid_for_ca_certs = scconf_get_bool(conf_block, "zero_ckaid_for_ca_certs", conf->zero_ckaid_for_ca_certs); + conf->ignore_pin_length = scconf_get_bool(conf_block, "ignore_pin_length", conf->ignore_pin_length); + create_slots_for_pins = (char *)scconf_get_str(conf_block, "create_slots_for_pins", "all"); tmp = strdup(create_slots_for_pins); op = strtok(tmp, " ,"); diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index aaa40ed1..3783fde8 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -82,6 +82,7 @@ struct sc_pkcs11_config { unsigned int create_puk_slot; unsigned int zero_ckaid_for_ca_certs; unsigned int create_slots_flags; + unsigned char ignore_pin_length; }; /*