From a7a5701e0c73e7f6266900525e7fdef2e76c617b Mon Sep 17 00:00:00 2001 From: sth Date: Thu, 20 Feb 2003 23:19:01 +0000 Subject: [PATCH] added support for max pin length git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@922 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/opensc.h | 1 + src/libopensc/pkcs15-pin.c | 32 +++++++++++++++++++++----------- src/libopensc/pkcs15.h | 2 +- src/pkcs11/framework-pkcs15.c | 8 ++++---- src/pkcs15init/pkcs15-lib.c | 8 ++++---- src/signer/dialog.c | 4 ++-- src/tests/pintest.c | 2 +- src/tests/print.c | 2 +- src/tools/pkcs15-crypt.c | 2 +- src/tools/pkcs15-init.c | 4 ++-- src/tools/pkcs15-tool.c | 4 ++-- 11 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 558880c6..7919234b 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -430,6 +430,7 @@ struct sc_card { struct sc_card_driver *driver; struct sc_card_operations *ops; void *drv_data; + int max_pin_len; struct sc_card_cache cache; int cache_valid; diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index fb95a811..605defc5 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -77,7 +77,7 @@ int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_pin_attr + 1, &info.type, NULL, 0); sc_format_asn1_entry(asn1_pin_attr + 2, &info.min_length, NULL, 0); sc_format_asn1_entry(asn1_pin_attr + 3, &info.stored_length, NULL, 0); - /* fixme: we should also support max_length [wk] */ + sc_format_asn1_entry(asn1_pin_attr + 4, &info.max_length, NULL, 0); sc_format_asn1_entry(asn1_pin_attr + 5, &info.reference, NULL, 0); sc_format_asn1_entry(asn1_pin_attr + 6, &info.pad_char, &padchar_len, 0); /* We don't support lastPinChange yet. */ @@ -98,6 +98,15 @@ int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, obj->data = malloc(sizeof(info)); if (obj->data == NULL) SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY); + if (info.max_length == 0) { + if (p15card->card->max_pin_len != 0) + info.max_length = p15card->card->max_pin_len; + else if (info.stored_length != 0) + info.max_length = info.type != SC_PKCS15_PIN_TYPE_BCD ? + info.stored_length : 2 * info.stored_length; + else + info.max_length = 8; /* shouldn't happen */ + } memcpy(obj->data, &info, sizeof(info)); return 0; @@ -166,12 +175,12 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, return SC_ERROR_OBJECT_NOT_VALID; /* prevent buffer overflow from hostile card */ - if (pin->stored_length > SC_MAX_PIN_SIZE) + if (pin->max_length > SC_MAX_PIN_SIZE) return SC_ERROR_BUFFER_TOO_SMALL; /* If application gave us a PIN, make sure it's within * the valid range */ - if (pinlen && (pinlen > pin->stored_length || pinlen < pin->min_length)) + if (pinlen && (pinlen > pin->max_length || pinlen < pin->min_length)) return SC_ERROR_INVALID_PIN_LENGTH; card = p15card->card; @@ -189,7 +198,7 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, args.pin_type = SC_AC_CHV; args.pin_reference = pin->reference; args.pin1.min_length = pin->min_length; - args.pin1.max_length = pin->stored_length; + args.pin1.max_length = pin->max_length; args.pin1.pad_char = pin->pad_char; if (pin->flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDING) @@ -241,8 +250,8 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card, (oldpin == NULL || newpin == NULL || oldpinlen == 0 || newpinlen == 0)) return SC_ERROR_NOT_SUPPORTED; - if ((oldpinlen > pin->stored_length) - || (newpinlen > pin->stored_length)) + if ((oldpinlen > pin->max_length) + || (newpinlen > pin->max_length)) return SC_ERROR_INVALID_PIN_LENGTH; if ((oldpinlen < pin->min_length) || (newpinlen < pin->min_length)) return SC_ERROR_INVALID_PIN_LENGTH; @@ -255,13 +264,14 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card, sc_unlock(card); return r; } - memset(pinbuf, pin->pad_char, pin->stored_length * 2); + memset(pinbuf, pin->pad_char, pin->max_length * 2); memcpy(pinbuf, oldpin, oldpinlen); - memcpy(pinbuf + pin->stored_length, newpin, newpinlen); + memcpy(pinbuf + pin->max_length, newpin, newpinlen); +change_pin: r = sc_change_reference_data(card, SC_AC_CHV, pin->reference, pinbuf, - pin->stored_length, pinbuf+pin->stored_length, - pin->stored_length, &pin->tries_left); - memset(pinbuf, 0, pin->stored_length * 2); + pin->max_length, pinbuf+pin->max_length, + pin->max_length, &pin->tries_left); + memset(pinbuf, 0, pin->max_length * 2); sc_unlock(card); return r; } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index de15f6f7..4810c45a 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -69,7 +69,7 @@ struct sc_pkcs15_pin_info { struct sc_pkcs15_id auth_id; int reference; int flags, type; - int min_length, stored_length; + int min_length, stored_length, max_length; u8 pad_char; struct sc_path path; int tries_left; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 03ee295c..3acf6632 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -275,7 +275,7 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card, strcpy_bp(slot->token_info.label, tmp, 32); if (pin_info && pin_info->magic == SC_PKCS15_PIN_MAGIC) { - slot->token_info.ulMaxPinLen = pin_info->stored_length; + slot->token_info.ulMaxPinLen = pin_info->max_length; slot->token_info.ulMinPinLen = pin_info->min_length; } else { /* choose reasonable defaults */ @@ -369,7 +369,7 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card) } /* Add all public objects to a virtual slot without - * pin protection */ + * pin protection */ slot = NULL; /* Add all the remaining private keys */ @@ -473,7 +473,7 @@ static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card, ulPinLen = 0; } else if (ulPinLen < pin->min_length || - ulPinLen > pin->stored_length) + ulPinLen > pin->max_length) return CKR_PIN_LEN_RANGE; /* By default, we make the pcsc daemon keep other processes @@ -533,7 +533,7 @@ static CK_RV pkcs15_change_pin(struct sc_pkcs11_card *p11card, ulOldLen = ulNewLen = 0; } else if (ulNewLen < pin->min_length || - ulNewLen > pin->stored_length) + ulNewLen > pin->max_length) return CKR_PIN_LEN_RANGE; rc = sc_pkcs15_change_pin(card, pin, pOldPin, ulOldLen, diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index b4e704d5..4c61e2f9 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -347,16 +347,16 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile, pin_info.min_length); return SC_ERROR_WRONG_LENGTH; } - if (args->so_pin_len > pin_info.stored_length) - args->so_pin_len = pin_info.stored_length; + if (args->so_pin_len > pin_info.max_length) + args->so_pin_len = pin_info.max_length; sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PUK, &pin_info); if (args->so_puk_len && args->so_puk_len < pin_info.min_length) { p15init_error("SO PUK too short (min length %u)", pin_info.min_length); return SC_ERROR_WRONG_LENGTH; } - if (args->so_puk_len > pin_info.stored_length) - args->so_puk_len = pin_info.stored_length; + if (args->so_puk_len > pin_info.max_length) + args->so_puk_len = pin_info.max_length; /* Create the application DF and store the PINs */ r = profile->ops->init_app(profile, card, diff --git a/src/signer/dialog.c b/src/signer/dialog.c index b4f3c1ef..3d4df07d 100644 --- a/src/signer/dialog.c +++ b/src/signer/dialog.c @@ -80,8 +80,8 @@ int ask_and_verify_pin_code(struct sc_pkcs15_card *p15card, sprintf(errtext, "PIN code too short, min. %d digits", pinfo->min_length); continue; } - if (r > pinfo->stored_length) { - sprintf(errtext, "PIN code too long, max. %d digits", pinfo->stored_length); + if (r > pinfo->max_length) { + sprintf(errtext, "PIN code too long, max. %d digits", pinfo->max_length); continue; } r = sc_pkcs15_verify_pin(p15card, pinfo, (const u8 *) buf, strlen(buf)); diff --git a/src/tests/pintest.c b/src/tests/pintest.c index 8976ae7e..fbcf0a61 100644 --- a/src/tests/pintest.c +++ b/src/tests/pintest.c @@ -61,7 +61,7 @@ int ask_and_verify_pin(struct sc_pkcs15_object *obj) } if (strlen((char *) pass) < pin->min_length) break; - if (strlen((char *) pass) > pin->stored_length) + if (strlen((char *) pass) > pin->max_length) break; break; } diff --git a/src/tests/print.c b/src/tests/print.c index bae8ee8e..a63884f2 100644 --- a/src/tests/print.c +++ b/src/tests/print.c @@ -38,7 +38,7 @@ static void print_pin(const struct sc_pkcs15_object *obj) printf(", %s", pin_flags[i]); } printf("\n"); - printf("\tLength : %d..%d\n", pin->min_length, pin->stored_length); + printf("\tLength : min_len:%d, max_len:%d, stored_len:%d\n", pin->min_length, pin->max_length, pin->stored_length); printf("\tPad char : 0x%02X\n", pin->pad_char); printf("\tReference : %d\n", pin->reference); printf("\tType : %d\n", pin->type); diff --git a/src/tools/pkcs15-crypt.c b/src/tools/pkcs15-crypt.c index 14c2fd88..750aecbc 100644 --- a/src/tools/pkcs15-crypt.c +++ b/src/tools/pkcs15-crypt.c @@ -100,7 +100,7 @@ char * get_pin(struct sc_pkcs15_object *obj) if (strlen(pincode) == 0) return NULL; if (strlen(pincode) < pinfo->min_length || - strlen(pincode) > pinfo->stored_length) + strlen(pincode) > pinfo->max_length) continue; return pincode; } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 9f75bf0c..5b3da6a4 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -728,9 +728,9 @@ read_one_pin(struct sc_profile *profile, const char *name, info->min_length); continue; } - if (info && len > info->stored_length) { + if (info && len > info->max_length) { error("Password too long (%u characters max)", - info->stored_length); + info->max_length); continue; } diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 22a22b3b..435e4bee 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -545,7 +545,7 @@ u8 * get_pin(const char *prompt, struct sc_pkcs15_pin_info **pin_out) printf("PIN code too short, try again.\n"); continue; } - if (strlen(pincode) > pinfo->stored_length) { + if (strlen(pincode) > pinfo->max_length) { printf("PIN code too long, try again.\n"); continue; } @@ -585,7 +585,7 @@ void print_pin_info(const struct sc_pkcs15_object *obj) printf(", %s", pin_flags[i]); } printf("\n"); - printf("\tLength : %d..%d\n", pin->min_length, pin->stored_length); + printf("\tLength : min_len:%d, max_len:%d, stored_len:d\n", pin->min_length, pin->max_length, pin->stored_length); printf("\tPad char : 0x%02X\n", pin->pad_char); printf("\tReference : %d\n", pin->reference); printf("\tType : %d\n", pin->type);