added support for max pin length
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@922 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
a69a309c6e
commit
a7a5701e0c
|
@ -430,6 +430,7 @@ struct sc_card {
|
||||||
struct sc_card_driver *driver;
|
struct sc_card_driver *driver;
|
||||||
struct sc_card_operations *ops;
|
struct sc_card_operations *ops;
|
||||||
void *drv_data;
|
void *drv_data;
|
||||||
|
int max_pin_len;
|
||||||
|
|
||||||
struct sc_card_cache cache;
|
struct sc_card_cache cache;
|
||||||
int cache_valid;
|
int cache_valid;
|
||||||
|
|
|
@ -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 + 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 + 2, &info.min_length, NULL, 0);
|
||||||
sc_format_asn1_entry(asn1_pin_attr + 3, &info.stored_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 + 5, &info.reference, NULL, 0);
|
||||||
sc_format_asn1_entry(asn1_pin_attr + 6, &info.pad_char, &padchar_len, 0);
|
sc_format_asn1_entry(asn1_pin_attr + 6, &info.pad_char, &padchar_len, 0);
|
||||||
/* We don't support lastPinChange yet. */
|
/* 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));
|
obj->data = malloc(sizeof(info));
|
||||||
if (obj->data == NULL)
|
if (obj->data == NULL)
|
||||||
SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
|
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));
|
memcpy(obj->data, &info, sizeof(info));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -166,12 +175,12 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
|
||||||
return SC_ERROR_OBJECT_NOT_VALID;
|
return SC_ERROR_OBJECT_NOT_VALID;
|
||||||
|
|
||||||
/* prevent buffer overflow from hostile card */
|
/* 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;
|
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
/* If application gave us a PIN, make sure it's within
|
/* If application gave us a PIN, make sure it's within
|
||||||
* the valid range */
|
* 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;
|
return SC_ERROR_INVALID_PIN_LENGTH;
|
||||||
|
|
||||||
card = p15card->card;
|
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_type = SC_AC_CHV;
|
||||||
args.pin_reference = pin->reference;
|
args.pin_reference = pin->reference;
|
||||||
args.pin1.min_length = pin->min_length;
|
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;
|
args.pin1.pad_char = pin->pad_char;
|
||||||
|
|
||||||
if (pin->flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDING)
|
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))
|
(oldpin == NULL || newpin == NULL || oldpinlen == 0 || newpinlen == 0))
|
||||||
return SC_ERROR_NOT_SUPPORTED;
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
|
||||||
if ((oldpinlen > pin->stored_length)
|
if ((oldpinlen > pin->max_length)
|
||||||
|| (newpinlen > pin->stored_length))
|
|| (newpinlen > pin->max_length))
|
||||||
return SC_ERROR_INVALID_PIN_LENGTH;
|
return SC_ERROR_INVALID_PIN_LENGTH;
|
||||||
if ((oldpinlen < pin->min_length) || (newpinlen < pin->min_length))
|
if ((oldpinlen < pin->min_length) || (newpinlen < pin->min_length))
|
||||||
return SC_ERROR_INVALID_PIN_LENGTH;
|
return SC_ERROR_INVALID_PIN_LENGTH;
|
||||||
|
@ -255,13 +264,14 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
|
||||||
sc_unlock(card);
|
sc_unlock(card);
|
||||||
return r;
|
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, 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,
|
r = sc_change_reference_data(card, SC_AC_CHV, pin->reference, pinbuf,
|
||||||
pin->stored_length, pinbuf+pin->stored_length,
|
pin->max_length, pinbuf+pin->max_length,
|
||||||
pin->stored_length, &pin->tries_left);
|
pin->max_length, &pin->tries_left);
|
||||||
memset(pinbuf, 0, pin->stored_length * 2);
|
memset(pinbuf, 0, pin->max_length * 2);
|
||||||
sc_unlock(card);
|
sc_unlock(card);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ struct sc_pkcs15_pin_info {
|
||||||
struct sc_pkcs15_id auth_id;
|
struct sc_pkcs15_id auth_id;
|
||||||
int reference;
|
int reference;
|
||||||
int flags, type;
|
int flags, type;
|
||||||
int min_length, stored_length;
|
int min_length, stored_length, max_length;
|
||||||
u8 pad_char;
|
u8 pad_char;
|
||||||
struct sc_path path;
|
struct sc_path path;
|
||||||
int tries_left;
|
int tries_left;
|
||||||
|
|
|
@ -275,7 +275,7 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card,
|
||||||
strcpy_bp(slot->token_info.label, tmp, 32);
|
strcpy_bp(slot->token_info.label, tmp, 32);
|
||||||
|
|
||||||
if (pin_info && pin_info->magic == SC_PKCS15_PIN_MAGIC) {
|
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;
|
slot->token_info.ulMinPinLen = pin_info->min_length;
|
||||||
} else {
|
} else {
|
||||||
/* choose reasonable defaults */
|
/* 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
|
/* Add all public objects to a virtual slot without
|
||||||
* pin protection */
|
* pin protection */
|
||||||
slot = NULL;
|
slot = NULL;
|
||||||
|
|
||||||
/* Add all the remaining private keys */
|
/* Add all the remaining private keys */
|
||||||
|
@ -473,7 +473,7 @@ static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card,
|
||||||
ulPinLen = 0;
|
ulPinLen = 0;
|
||||||
} else
|
} else
|
||||||
if (ulPinLen < pin->min_length ||
|
if (ulPinLen < pin->min_length ||
|
||||||
ulPinLen > pin->stored_length)
|
ulPinLen > pin->max_length)
|
||||||
return CKR_PIN_LEN_RANGE;
|
return CKR_PIN_LEN_RANGE;
|
||||||
|
|
||||||
/* By default, we make the pcsc daemon keep other processes
|
/* 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;
|
ulOldLen = ulNewLen = 0;
|
||||||
} else
|
} else
|
||||||
if (ulNewLen < pin->min_length ||
|
if (ulNewLen < pin->min_length ||
|
||||||
ulNewLen > pin->stored_length)
|
ulNewLen > pin->max_length)
|
||||||
return CKR_PIN_LEN_RANGE;
|
return CKR_PIN_LEN_RANGE;
|
||||||
|
|
||||||
rc = sc_pkcs15_change_pin(card, pin, pOldPin, ulOldLen,
|
rc = sc_pkcs15_change_pin(card, pin, pOldPin, ulOldLen,
|
||||||
|
|
|
@ -347,16 +347,16 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile,
|
||||||
pin_info.min_length);
|
pin_info.min_length);
|
||||||
return SC_ERROR_WRONG_LENGTH;
|
return SC_ERROR_WRONG_LENGTH;
|
||||||
}
|
}
|
||||||
if (args->so_pin_len > pin_info.stored_length)
|
if (args->so_pin_len > pin_info.max_length)
|
||||||
args->so_pin_len = pin_info.stored_length;
|
args->so_pin_len = pin_info.max_length;
|
||||||
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PUK, &pin_info);
|
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) {
|
if (args->so_puk_len && args->so_puk_len < pin_info.min_length) {
|
||||||
p15init_error("SO PUK too short (min length %u)",
|
p15init_error("SO PUK too short (min length %u)",
|
||||||
pin_info.min_length);
|
pin_info.min_length);
|
||||||
return SC_ERROR_WRONG_LENGTH;
|
return SC_ERROR_WRONG_LENGTH;
|
||||||
}
|
}
|
||||||
if (args->so_puk_len > pin_info.stored_length)
|
if (args->so_puk_len > pin_info.max_length)
|
||||||
args->so_puk_len = pin_info.stored_length;
|
args->so_puk_len = pin_info.max_length;
|
||||||
|
|
||||||
/* Create the application DF and store the PINs */
|
/* Create the application DF and store the PINs */
|
||||||
r = profile->ops->init_app(profile, card,
|
r = profile->ops->init_app(profile, card,
|
||||||
|
|
|
@ -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);
|
sprintf(errtext, "PIN code too short, min. %d digits", pinfo->min_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (r > pinfo->stored_length) {
|
if (r > pinfo->max_length) {
|
||||||
sprintf(errtext, "PIN code too long, max. %d digits", pinfo->stored_length);
|
sprintf(errtext, "PIN code too long, max. %d digits", pinfo->max_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
r = sc_pkcs15_verify_pin(p15card, pinfo, (const u8 *) buf, strlen(buf));
|
r = sc_pkcs15_verify_pin(p15card, pinfo, (const u8 *) buf, strlen(buf));
|
||||||
|
|
|
@ -61,7 +61,7 @@ int ask_and_verify_pin(struct sc_pkcs15_object *obj)
|
||||||
}
|
}
|
||||||
if (strlen((char *) pass) < pin->min_length)
|
if (strlen((char *) pass) < pin->min_length)
|
||||||
break;
|
break;
|
||||||
if (strlen((char *) pass) > pin->stored_length)
|
if (strlen((char *) pass) > pin->max_length)
|
||||||
break;
|
break;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ static void print_pin(const struct sc_pkcs15_object *obj)
|
||||||
printf(", %s", pin_flags[i]);
|
printf(", %s", pin_flags[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
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("\tPad char : 0x%02X\n", pin->pad_char);
|
||||||
printf("\tReference : %d\n", pin->reference);
|
printf("\tReference : %d\n", pin->reference);
|
||||||
printf("\tType : %d\n", pin->type);
|
printf("\tType : %d\n", pin->type);
|
||||||
|
|
|
@ -100,7 +100,7 @@ char * get_pin(struct sc_pkcs15_object *obj)
|
||||||
if (strlen(pincode) == 0)
|
if (strlen(pincode) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (strlen(pincode) < pinfo->min_length ||
|
if (strlen(pincode) < pinfo->min_length ||
|
||||||
strlen(pincode) > pinfo->stored_length)
|
strlen(pincode) > pinfo->max_length)
|
||||||
continue;
|
continue;
|
||||||
return pincode;
|
return pincode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -728,9 +728,9 @@ read_one_pin(struct sc_profile *profile, const char *name,
|
||||||
info->min_length);
|
info->min_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (info && len > info->stored_length) {
|
if (info && len > info->max_length) {
|
||||||
error("Password too long (%u characters max)",
|
error("Password too long (%u characters max)",
|
||||||
info->stored_length);
|
info->max_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
printf("PIN code too short, try again.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strlen(pincode) > pinfo->stored_length) {
|
if (strlen(pincode) > pinfo->max_length) {
|
||||||
printf("PIN code too long, try again.\n");
|
printf("PIN code too long, try again.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -585,7 +585,7 @@ void print_pin_info(const struct sc_pkcs15_object *obj)
|
||||||
printf(", %s", pin_flags[i]);
|
printf(", %s", pin_flags[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
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("\tPad char : 0x%02X\n", pin->pad_char);
|
||||||
printf("\tReference : %d\n", pin->reference);
|
printf("\tReference : %d\n", pin->reference);
|
||||||
printf("\tType : %d\n", pin->type);
|
printf("\tType : %d\n", pin->type);
|
||||||
|
|
Loading…
Reference in New Issue