1
0
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:
NIIBE Yutaka 2013-01-09 16:23:55 +09:00
parent 4fe024cf33
commit 15200f7001
6 changed files with 53 additions and 22 deletions

View File

@ -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)
{ {

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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)
break; {
enable_varlen = 0;
pininfo->minlen = 4;
pininfo->maxlen = 8;
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
{ {
msg[13] = 0x00; /* bmPINBlockString: if (pininfo->fixedlen == 0)
0 bits of pin length to insert. msg[13] = 0x00; /* bmPINBlockString:
0 bytes of PIN block size. */ 0 bits of pin length to insert.
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 */
msg[msglen++] = 0; /* bInsertionOffsetNew */ if (pininfo->fixedlen == 0)
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,10 +3470,18 @@ 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 */
msg[msglen++] = 0; /* The apdulen will be filled in by the reader. */ 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. */
/* APDU follows: */ /* APDU follows: */
msg[msglen++] = apdu_buf[0]; /* CLA */ msg[msglen++] = apdu_buf[0]; /* CLA */
msg[msglen++] = apdu_buf[1]; /* INS */ msg[msglen++] = apdu_buf[1]; /* INS */
@ -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);

View File

@ -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;
}; };