The PKCS#11 specifies that the PIN parameter(s) in C_Login and C_SetPIN

always should be used, even if a PIN pad reader is used. PIN must only
be fetched from the PIN pad reader if the corresponding parameter is
null.
Before this commit PIN was always fetch from the reader if the PIN could
be fetched from the reader.
The 'pkcs11-tool has also been updated. Before parameters was never
taken from the command line if a PID pad reader was used. Now PINs from
the command line is always used but if not existing the PIN is fetched
from the reader if a reader with a PIN pad is used, otherwise the user
is prompted for PIN(s) from the CLI.
This commit is contained in:
Lars Silvén 2020-03-30 14:38:25 +02:00 committed by Frank Morgner
parent a771450ab2
commit 8257e0186d
2 changed files with 29 additions and 67 deletions

View File

@ -1668,22 +1668,6 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType,
if (!p11card)
return CKR_TOKEN_NOT_RECOGNIZED;
if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* pPin should be NULL in case of a pin pad reader, but
* some apps (e.g. older Netscapes) don't know about it.
* So we don't require that pPin == NULL, but set it to
* NULL ourselves. This way, you can supply an empty (if
* possible) or fake PIN if an application asks a PIN).
*/
/* But we want to be able to specify a PIN on the command
* line (e.g. for the test scripts). So we don't do anything
* here - this gives the user the choice of entering
* an empty pin (which makes us use the pin pad) or
* a valid pin (which is processed normally). --okir */
if (ulPinLen == 0)
pPin = NULL;
}
/* By default, we make the reader resource manager keep other
* processes from accessing the card while we're logged in.
@ -1843,18 +1827,7 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
return CKR_USER_PIN_NOT_INITIALIZED;
sc_log(context, "Change '%.*s' (ref:%i,type:%i)", (int) sizeof pin_obj->label, pin_obj->label, auth_info->attrs.pin.reference, login_user);
if ((p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
|| (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* pPin should be NULL in case of a pin pad reader, but
* some apps (e.g. older Netscapes) don't know about it.
* So we don't require that pPin == NULL, but set it to
* NULL ourselves. This way, you can supply an empty (if
* possible) or fake PIN if an application asks a PIN).
*/
pOldPin = pNewPin = NULL;
ulOldLen = ulNewLen = 0;
}
else if (ulNewLen < auth_info->attrs.pin.min_length || ulNewLen > auth_info->attrs.pin.max_length) {
if (pNewPin && (ulNewLen < auth_info->attrs.pin.min_length || ulNewLen > auth_info->attrs.pin.max_length)) {
return CKR_PIN_LEN_RANGE;
}

View File

@ -1597,53 +1597,42 @@ static void init_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
static int change_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
{
char old_buf[21], *old_pin = NULL;
char new_buf[21], *new_pin = NULL;
char old_buf[21], *old_pin = opt_so_pin ? (char*)opt_so_pin : (char*)opt_pin;
char new_buf[21], *new_pin = (char *)opt_new_pin;
CK_TOKEN_INFO info;
CK_RV rv;
int r;
size_t len = 0;
get_token_info(slot, &info);
const CK_FLAGS hasReaderPinPad = info.flags & CKF_PROTECTED_AUTHENTICATION_PATH;
if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
if (!opt_pin && !opt_so_pin) {
printf("Please enter the current PIN: ");
r = util_getpass(&old_pin, &len, stdin);
if (r < 0)
return 1;
if (!old_pin || !*old_pin || strlen(old_pin) > 20)
return 1;
strcpy(old_buf, old_pin);
old_pin = old_buf;
}
else {
if (opt_so_pin)
old_pin = (char *) opt_so_pin;
else
old_pin = (char *) opt_pin;
}
if (!hasReaderPinPad && !old_pin) {
printf("Please enter the current PIN: ");
r = util_getpass(&old_pin, &len, stdin);
if (r < 0)
return 1;
if (!old_pin || !*old_pin || strlen(old_pin) > 20)
return 1;
strcpy(old_buf, old_pin);
old_pin = old_buf;
}
if (!hasReaderPinPad && !new_pin) {
printf("Please enter the new PIN: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strlen(new_pin) > 20)
return 1;
strcpy(new_buf, new_pin);
if (!opt_new_pin) {
printf("Please enter the new PIN: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strlen(new_pin) > 20)
return 1;
strcpy(new_buf, new_pin);
printf("Please enter the new PIN again: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
free(new_pin);
return 1;
}
}
else {
new_pin = (char *) opt_new_pin;
printf("Please enter the new PIN again: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
free(new_pin);
return 1;
}
}