mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-25 15:27:03 +01:00
SCD: Support fixed length PIN input for keypad.
* scd/iso7816.h (struct pininfo_s): Remove MODE and add FIXEDLEN. * scd/app-dinsig.c (verify_pin): Initialize FIXEDLEN to unknown. * scd/app-nks.c (verify_pin): Likewise. * scd/app-openpgp.c (verify_a_chv, verify_chv3, do_change_pin): Likewise. * scd/apdu.c (check_pcsc_keypad): Add comment. (pcsc_keypad_verify, pcsc_keypad_modify): PC/SC driver only support readers with the feature of variable length input (yet). (apdu_check_keypad): Set FIXEDLEN. * scd/ccid-driver.c (ccid_transceive_secure): Add GEMPC_PINPAD specific settings. Support fixed length PIN input for keypad.
This commit is contained in:
parent
4fe024cf33
commit
15200f7001
@ -2016,7 +2016,7 @@ check_pcsc_keypad (int slot, int command, pininfo_t *pininfo)
|
|||||||
size_t len = 256;
|
size_t len = 256;
|
||||||
int sw;
|
int sw;
|
||||||
|
|
||||||
(void)pininfo;
|
(void)pininfo; /* XXX: Identify reader and set pininfo->fixedlen. */
|
||||||
|
|
||||||
check_again:
|
check_again:
|
||||||
if (command == ISO7816_VERIFY)
|
if (command == ISO7816_VERIFY)
|
||||||
@ -2080,7 +2080,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
|
|||||||
&& (sw = reset_pcsc_reader (slot)))
|
&& (sw = reset_pcsc_reader (slot)))
|
||||||
return sw;
|
return sw;
|
||||||
|
|
||||||
if (pininfo->mode != 1)
|
if (pininfo->fixedlen != 0)
|
||||||
return SW_NOT_SUPPORTED;
|
return SW_NOT_SUPPORTED;
|
||||||
|
|
||||||
if (!pininfo->minlen)
|
if (!pininfo->minlen)
|
||||||
@ -2159,7 +2159,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
|
|||||||
&& (sw = reset_pcsc_reader (slot)))
|
&& (sw = reset_pcsc_reader (slot)))
|
||||||
return sw;
|
return sw;
|
||||||
|
|
||||||
if (pininfo->mode != 1)
|
if (pininfo->fixedlen != 0)
|
||||||
return SW_NOT_SUPPORTED;
|
return SW_NOT_SUPPORTED;
|
||||||
|
|
||||||
if (!pininfo->minlen)
|
if (!pininfo->minlen)
|
||||||
@ -3292,7 +3292,7 @@ apdu_check_keypad (int slot, int command, pininfo_t *pininfo)
|
|||||||
return SW_HOST_NO_DRIVER;
|
return SW_HOST_NO_DRIVER;
|
||||||
|
|
||||||
if (opt.enable_keypad_varlen)
|
if (opt.enable_keypad_varlen)
|
||||||
pininfo->mode = 0;
|
pininfo->fixedlen = 0;
|
||||||
|
|
||||||
if (reader_table[slot].check_keypad)
|
if (reader_table[slot].check_keypad)
|
||||||
{
|
{
|
||||||
|
@ -288,7 +288,7 @@ verify_pin (app_t app,
|
|||||||
return 0; /* No need to verify it again. */
|
return 0; /* No need to verify it again. */
|
||||||
|
|
||||||
memset (&pininfo, 0, sizeof pininfo);
|
memset (&pininfo, 0, sizeof pininfo);
|
||||||
pininfo.mode = 1;
|
pininfo.fixedlen = -1;
|
||||||
pininfo.minlen = 6;
|
pininfo.minlen = 6;
|
||||||
pininfo.maxlen = 8;
|
pininfo.maxlen = 8;
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ verify_pin (app_t app, int pwid, const char *desc,
|
|||||||
desc = "PIN";
|
desc = "PIN";
|
||||||
|
|
||||||
memset (&pininfo, 0, sizeof pininfo);
|
memset (&pininfo, 0, sizeof pininfo);
|
||||||
pininfo.mode = 1;
|
pininfo.fixedlen = -1;
|
||||||
pininfo.minlen = 6;
|
pininfo.minlen = 6;
|
||||||
pininfo.maxlen = 16;
|
pininfo.maxlen = 16;
|
||||||
|
|
||||||
|
@ -1516,7 +1516,7 @@ verify_a_chv (app_t app,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset (&pininfo, 0, sizeof pininfo);
|
memset (&pininfo, 0, sizeof pininfo);
|
||||||
pininfo.mode = 1;
|
pininfo.fixedlen = -1;
|
||||||
pininfo.minlen = minlen;
|
pininfo.minlen = minlen;
|
||||||
|
|
||||||
|
|
||||||
@ -1712,7 +1712,7 @@ verify_chv3 (app_t app,
|
|||||||
char *prompt;
|
char *prompt;
|
||||||
|
|
||||||
memset (&pininfo, 0, sizeof pininfo);
|
memset (&pininfo, 0, sizeof pininfo);
|
||||||
pininfo.mode = 1;
|
pininfo.fixedlen = -1;
|
||||||
pininfo.minlen = minlen;
|
pininfo.minlen = minlen;
|
||||||
|
|
||||||
rc = build_enter_admin_pin_prompt (app, &prompt);
|
rc = build_enter_admin_pin_prompt (app, &prompt);
|
||||||
@ -1923,7 +1923,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
|
|||||||
|
|
||||||
(void)ctrl;
|
(void)ctrl;
|
||||||
memset (&pininfo, 0, sizeof pininfo);
|
memset (&pininfo, 0, sizeof pininfo);
|
||||||
pininfo.mode = 1;
|
pininfo.fixedlen = -1;
|
||||||
pininfo.minlen = minlen;
|
pininfo.minlen = minlen;
|
||||||
|
|
||||||
if (reset_mode && chvno == 3)
|
if (reset_mode && chvno == 3)
|
||||||
|
@ -3362,23 +3362,27 @@ ccid_transceive_secure (ccid_driver_t handle,
|
|||||||
cherry_mode = 1;
|
cherry_mode = 1;
|
||||||
break;
|
break;
|
||||||
case VENDOR_GEMPC:
|
case VENDOR_GEMPC:
|
||||||
enable_varlen = 0;
|
|
||||||
if (handle->id_product == GEMPC_PINPAD)
|
if (handle->id_product == GEMPC_PINPAD)
|
||||||
|
{
|
||||||
|
enable_varlen = 0;
|
||||||
|
pininfo->minlen = 4;
|
||||||
|
pininfo->maxlen = 8;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable_varlen)
|
if (enable_varlen)
|
||||||
pininfo->mode = 0;
|
pininfo->fixedlen = 0;
|
||||||
|
|
||||||
if (pininfo->mode != 0 && pininfo->mode != 1)
|
|
||||||
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
if (testmode)
|
if (testmode)
|
||||||
return 0; /* Success */
|
return 0; /* Success */
|
||||||
|
|
||||||
|
if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
|
||||||
|
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
||||||
|
|
||||||
msg = send_buffer;
|
msg = send_buffer;
|
||||||
if (handle->id_vendor == VENDOR_SCM)
|
if (handle->id_vendor == VENDOR_SCM)
|
||||||
{
|
{
|
||||||
@ -3408,9 +3412,14 @@ ccid_transceive_secure (ccid_driver_t handle,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (pininfo->fixedlen == 0)
|
||||||
msg[13] = 0x00; /* bmPINBlockString:
|
msg[13] = 0x00; /* bmPINBlockString:
|
||||||
0 bits of pin length to insert.
|
0 bits of pin length to insert.
|
||||||
0 bytes of PIN block size. */
|
0 bytes of PIN block size. */
|
||||||
|
else
|
||||||
|
msg[13] = pininfo->fixedlen; /* bmPINBlockString:
|
||||||
|
0 bits of pin length to insert.
|
||||||
|
PIN block size by fixedlen. */
|
||||||
msg[14] = 0x00; /* bmPINLengthFormat:
|
msg[14] = 0x00; /* bmPINLengthFormat:
|
||||||
Units are bytes, position is 0. */
|
Units are bytes, position is 0. */
|
||||||
}
|
}
|
||||||
@ -3419,7 +3428,10 @@ ccid_transceive_secure (ccid_driver_t handle,
|
|||||||
if (apdu_buf[1] == 0x24)
|
if (apdu_buf[1] == 0x24)
|
||||||
{
|
{
|
||||||
msg[msglen++] = 0; /* bInsertionOffsetOld */
|
msg[msglen++] = 0; /* bInsertionOffsetOld */
|
||||||
|
if (pininfo->fixedlen == 0)
|
||||||
msg[msglen++] = 0; /* bInsertionOffsetNew */
|
msg[msglen++] = 0; /* bInsertionOffsetNew */
|
||||||
|
else
|
||||||
|
msg[msglen++] = pininfo->fixedlen; /* bInsertionOffsetNew */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following is a little endian word. */
|
/* The following is a little endian word. */
|
||||||
@ -3458,9 +3470,17 @@ ccid_transceive_secure (ccid_driver_t handle,
|
|||||||
msg[msglen++] = 2; /* bMsgIndex3. */
|
msg[msglen++] = 2; /* bMsgIndex3. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate Lc. */
|
||||||
|
n = pininfo->fixedlen;
|
||||||
|
if (apdu_buf[1] == 0x24)
|
||||||
|
n += pininfo->fixedlen;
|
||||||
|
|
||||||
/* bTeoProlog follows: */
|
/* bTeoProlog follows: */
|
||||||
msg[msglen++] = handle->nonnull_nad? ((1 << 4) | 0): 0;
|
msg[msglen++] = handle->nonnull_nad? ((1 << 4) | 0): 0;
|
||||||
msg[msglen++] = ((handle->t1_ns & 1) << 6); /* I-block */
|
msg[msglen++] = ((handle->t1_ns & 1) << 6); /* I-block */
|
||||||
|
if (n)
|
||||||
|
msg[msglen++] = n + 5; /* apdulen should be filled for fixed length. */
|
||||||
|
else
|
||||||
msg[msglen++] = 0; /* The apdulen will be filled in by the reader. */
|
msg[msglen++] = 0; /* The apdulen will be filled in by the reader. */
|
||||||
/* APDU follows: */
|
/* APDU follows: */
|
||||||
msg[msglen++] = apdu_buf[0]; /* CLA */
|
msg[msglen++] = apdu_buf[0]; /* CLA */
|
||||||
@ -3469,6 +3489,12 @@ ccid_transceive_secure (ccid_driver_t handle,
|
|||||||
msg[msglen++] = apdu_buf[3]; /* P2 */
|
msg[msglen++] = apdu_buf[3]; /* P2 */
|
||||||
if (cherry_mode)
|
if (cherry_mode)
|
||||||
msg[msglen++] = 0;
|
msg[msglen++] = 0;
|
||||||
|
else if (pininfo->fixedlen != 0)
|
||||||
|
{
|
||||||
|
msg[msglen++] = n;
|
||||||
|
memset (&msg[msglen], 0xff, n);
|
||||||
|
msglen += n;
|
||||||
|
}
|
||||||
/* An EDC is not required. */
|
/* An EDC is not required. */
|
||||||
set_msg_len (msg, msglen - 10);
|
set_msg_len (msg, msglen - 10);
|
||||||
|
|
||||||
|
@ -34,7 +34,12 @@
|
|||||||
ccid-driver.c for details. */
|
ccid-driver.c for details. */
|
||||||
struct pininfo_s
|
struct pininfo_s
|
||||||
{
|
{
|
||||||
int mode; /* 0: Use variable length input. 1: Use fixed length input. */
|
int fixedlen; /*
|
||||||
|
* -1: Variable length input is not supported,
|
||||||
|
* no information of fixed length yet.
|
||||||
|
* 0: Use variable length input.
|
||||||
|
* >0: Fixed length of PIN.
|
||||||
|
*/
|
||||||
int minlen;
|
int minlen;
|
||||||
int maxlen;
|
int maxlen;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user