pinpad support change
This commit is contained in:
18
ChangeLog
18
ChangeLog
@@ -1,3 +1,21 @@
|
||||
2011-12-01 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.h (EV_PINPAD_INPUT_DONE, EV_NOP, EV_CMD_AVAILABLE)
|
||||
(EV_VERIFY_CMD_AVAILABLE, EV_MODIFY_CMD_AVAILABLE): New.
|
||||
* src/usb-icc.c (icc_power_off, icc_handle_data): Use EV_NOP,
|
||||
EV_CMD_AVAILABLE, EV_VERIFY_CMD_AVAILABLE, and EV_MODIFY_CMD_AVAILABLE.
|
||||
* src/pin-cir.c (cir_timer_interrupt): Use EV_PINPAD_INPUT_DONE.
|
||||
* src/pin-dial.c (dial_sw_interrupt, pinpad_getline): Ditto.
|
||||
(EV_SW_PUSH): Remove.
|
||||
|
||||
* src/openpgp.h (GPG_FUNCTION_NOT_SUPPORTED): New.
|
||||
(GPG_CONDITION_NOT_SATISFIED): New.
|
||||
* src/openpgp.c (cmd_change_password): Use GPG_FUNCTION_NOT_SUPPORTED.
|
||||
|
||||
* src/openpgp.c (cmd_verify, cmd_change_password)
|
||||
(cmd_reset_user_password, cmd_put_data): Remove pinpad handling...
|
||||
(GPGthread): ... and implement pinpad handling here.
|
||||
|
||||
2011-11-29 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_put_data) [PINPAD_SUPPORT]: Support pinpad
|
||||
|
||||
@@ -24,6 +24,13 @@ extern void *memmove(void *dest, const void *src, size_t n);
|
||||
|
||||
#define EV_EXEC_FINISHED ((eventmask_t)2) /* GPG Execution finished */
|
||||
|
||||
/* GPG thread */
|
||||
#define EV_PINPAD_INPUT_DONE ((eventmask_t)1)
|
||||
#define EV_NOP ((eventmask_t)2)
|
||||
#define EV_CMD_AVAILABLE ((eventmask_t)4)
|
||||
#define EV_VERIFY_CMD_AVAILABLE ((eventmask_t)8)
|
||||
#define EV_MODIFY_CMD_AVAILABLE ((eventmask_t)16)
|
||||
|
||||
/* maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_SIZE (7+282) /* header + data */
|
||||
/* maximum res apdu data is public key 5+9+256+2 (gpg_do_public_key) */
|
||||
|
||||
262
src/openpgp.c
262
src/openpgp.c
@@ -125,32 +125,14 @@ cmd_verify (void)
|
||||
DEBUG_INFO (" - VERIFY\r\n");
|
||||
DEBUG_BYTE (p2);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
if (cmd_APDU_size == 4)
|
||||
/* Verification with pinpad */
|
||||
len = cmd_APDU[4];
|
||||
if (len == 0) /* extended length */
|
||||
{
|
||||
len = get_pinpad_input (PIN_INPUT_CURRENT);
|
||||
if (len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
pw = pin_input_buffer;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
len = cmd_APDU[4];
|
||||
if (len == 0) /* extended length */
|
||||
{
|
||||
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||
data_start = 7;
|
||||
}
|
||||
|
||||
pw = &cmd_APDU[data_start];
|
||||
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||
data_start = 7;
|
||||
}
|
||||
|
||||
pw = &cmd_APDU[data_start];
|
||||
|
||||
if (p2 == 0x81)
|
||||
r = verify_pso_cds (pw, len);
|
||||
@@ -231,6 +213,7 @@ cmd_change_password (void)
|
||||
uint8_t old_ks[KEYSTRING_MD_SIZE];
|
||||
uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
|
||||
uint8_t *new_ks = &new_ks0[1];
|
||||
uint8_t p1 = cmd_APDU[2]; /* 0: change (old+new), 1: exchange (new) */
|
||||
uint8_t p2 = cmd_APDU[3];
|
||||
int len;
|
||||
const uint8_t *pw;
|
||||
@@ -242,55 +225,18 @@ cmd_change_password (void)
|
||||
DEBUG_INFO ("Change PW\r\n");
|
||||
DEBUG_BYTE (who);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
if (cmd_APDU_size == 4)
|
||||
/* Modification with pinpad */
|
||||
len = cmd_APDU[4];
|
||||
pw = &cmd_APDU[5];
|
||||
if (len == 0) /* extended length */
|
||||
{
|
||||
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
|
||||
if (pw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
pw = &cmd_APDU[5];
|
||||
memcpy (&cmd_APDU[5], pin_input_buffer, pw_len);
|
||||
newpw = pw + pw_len;
|
||||
|
||||
newpw_len = get_pinpad_input (PIN_INPUT_NEW);
|
||||
if (newpw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (&cmd_APDU[5]+pw_len, pin_input_buffer, newpw_len);
|
||||
|
||||
len = get_pinpad_input (PIN_INPUT_CONFIRM);
|
||||
if (len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (len != newpw_len || memcmp (newpw, pin_input_buffer, len) != 0)
|
||||
{
|
||||
GPG_SECURITY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
len = cmd_APDU[4] = pw_len + newpw_len;
|
||||
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||
pw += 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (p1 != 0)
|
||||
{
|
||||
len = cmd_APDU[4];
|
||||
pw = &cmd_APDU[5];
|
||||
if (len == 0) /* extended length */
|
||||
{
|
||||
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||
pw += 2;
|
||||
}
|
||||
GPG_FUNCTION_NOT_SUPPORTED();
|
||||
return;
|
||||
}
|
||||
|
||||
if (who == BY_USER) /* PW1 */
|
||||
@@ -395,60 +341,12 @@ cmd_reset_user_password (void)
|
||||
DEBUG_INFO ("Reset PW1\r\n");
|
||||
DEBUG_BYTE (p1);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
if (cmd_APDU_size == 4)
|
||||
/* Modification with pinpad */
|
||||
len = cmd_APDU[4];
|
||||
pw = &cmd_APDU[5];
|
||||
if (len == 0) /* extended length */
|
||||
{
|
||||
if (p1 == 0x00) /* by User with Reseting Code */
|
||||
{
|
||||
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
|
||||
if (pw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (&cmd_APDU[5], pin_input_buffer, pw_len);
|
||||
}
|
||||
else
|
||||
pw_len = 0;
|
||||
|
||||
pw = &cmd_APDU[5];
|
||||
newpw = pw + pw_len;
|
||||
newpw_len = get_pinpad_input (PIN_INPUT_NEW);
|
||||
if (newpw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (&cmd_APDU[5]+pw_len, pin_input_buffer, newpw_len);
|
||||
|
||||
len = get_pinpad_input (PIN_INPUT_CONFIRM);
|
||||
if (len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (len != newpw_len || memcmp (newpw, pin_input_buffer, len) != 0)
|
||||
{
|
||||
GPG_SECURITY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
len = cmd_APDU[4] = pw_len + newpw_len;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
len = cmd_APDU[4];
|
||||
pw = &cmd_APDU[5];
|
||||
if (len == 0) /* extended length */
|
||||
{
|
||||
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||
pw += 2;
|
||||
}
|
||||
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||
pw += 2;
|
||||
}
|
||||
|
||||
if (p1 == 0x00) /* by User with Reseting Code */
|
||||
@@ -574,42 +472,12 @@ cmd_put_data (void)
|
||||
tag = ((cmd_APDU[2]<<8) | cmd_APDU[3]);
|
||||
data = &cmd_APDU[5];
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
if (cmd_APDU_size == 4) /* For 0xD3: reset code */
|
||||
len = cmd_APDU_size - 5;
|
||||
if (len >= 256)
|
||||
/* extended Lc */
|
||||
{
|
||||
len = get_pinpad_input (PIN_INPUT_NEW);
|
||||
if (len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_APDU[4] = len;
|
||||
memcpy (data, pin_input_buffer, len);
|
||||
|
||||
len = get_pinpad_input (PIN_INPUT_CONFIRM);
|
||||
if (len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (len != cmd_APDU[4] || memcmp (data, pin_input_buffer, len) !=0)
|
||||
{
|
||||
GPG_SECURITY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
len = cmd_APDU_size - 5;
|
||||
if (len >= 256)
|
||||
/* extended Lc */
|
||||
{
|
||||
data += 2;
|
||||
len -= 2;
|
||||
}
|
||||
data += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
gpg_do_put_data (tag, data, len);
|
||||
@@ -1057,15 +925,91 @@ GPGthread (void *arg)
|
||||
|
||||
while (!chThdShouldTerminate ())
|
||||
{
|
||||
chEvtWaitOne (ALL_EVENTS);
|
||||
eventmask_t m = chEvtWaitOne (ALL_EVENTS);
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
int len, pw_len, newpw_len;
|
||||
#endif
|
||||
|
||||
DEBUG_INFO ("GPG!: ");
|
||||
|
||||
res_APDU_pointer = NULL; /* default */
|
||||
res_APDU_pointer = NULL;
|
||||
|
||||
if (m == EV_VERIFY_CMD_AVAILABLE)
|
||||
{
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
if (cmd_APDU[1] != INS_VERIFY)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
goto done;
|
||||
}
|
||||
|
||||
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
|
||||
if (pw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
goto done;
|
||||
}
|
||||
memcpy (&cmd_APDU[5], pin_input_buffer, pw_len);
|
||||
cmd_APDU[4] = pw_len;
|
||||
icc_data_size = 5 + pw_len;
|
||||
#else
|
||||
GPG_ERROR ();
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
else if (m == EV_MODIFY_CMD_AVAILABLE)
|
||||
{
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
if (cmd_APDU[1] != INS_CHANGE_REFERENCE_DATA)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
goto done;
|
||||
}
|
||||
|
||||
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
|
||||
if (pw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
goto done;
|
||||
}
|
||||
memcpy (&cmd_APDU[5], pin_input_buffer, pw_len);
|
||||
|
||||
newpw_len = get_pinpad_input (PIN_INPUT_NEW);
|
||||
if (newpw_len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
goto done;
|
||||
}
|
||||
memcpy (&cmd_APDU[5]+pw_len, pin_input_buffer, newpw_len);
|
||||
|
||||
len = get_pinpad_input (PIN_INPUT_CONFIRM);
|
||||
if (len < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (len != newpw_len
|
||||
|| memcmp (&cmd_APDU[5]+pw_len, pin_input_buffer, len) != 0)
|
||||
{
|
||||
GPG_SECURITY_FAILURE ();
|
||||
goto done;
|
||||
}
|
||||
|
||||
len = cmd_APDU[4] = pw_len + newpw_len;
|
||||
icc_data_size = 5 + len;
|
||||
#else
|
||||
GPG_ERROR ();
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
else if (m == EV_NOP)
|
||||
continue;
|
||||
|
||||
if (icc_data_size != 0)
|
||||
{
|
||||
process_command_apdu ();
|
||||
done:
|
||||
chEvtSignal (icc_thread, EV_EXEC_FINISHED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#define GPG_MEMORY_FAILURE() set_res_apdu (0x65, 0x81)
|
||||
#define GPG_SECURITY_FAILURE() set_res_apdu (0x69, 0x82)
|
||||
#define GPG_SECURITY_AUTH_BLOCKED() set_res_apdu (0x69, 0x83)
|
||||
#define GPG_CONDITION_NOT_SATISFIED() set_res_apdu (0x69, 0x85)
|
||||
#define GPG_COMMAND_NOT_ALLOWED() set_res_apdu (0x69, 0x86)
|
||||
#define GPG_FUNCTION_NOT_SUPPORTED() set_res_apdu (0x6a, 0x81)
|
||||
#define GPG_NO_FILE() set_res_apdu (0x6a, 0x82)
|
||||
#define GPG_NO_RECORD() set_res_apdu (0x6a, 0x88)
|
||||
#define GPG_BAD_P0_P1() set_res_apdu (0x6b, 0x00)
|
||||
|
||||
@@ -910,7 +910,7 @@ cir_timer_interrupt (void)
|
||||
cir_input_last = now;
|
||||
/* Notify thread */
|
||||
if (pin_thread)
|
||||
chEvtSignalI (pin_thread, (eventmask_t)1);
|
||||
chEvtSignalI (pin_thread, EV_PINPAD_INPUT_DONE);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_CIR)
|
||||
|
||||
@@ -117,13 +117,12 @@ blink_dp (void)
|
||||
}
|
||||
|
||||
static Thread *pin_thread;
|
||||
#define EV_SW_PUSH (eventmask_t)1
|
||||
|
||||
void
|
||||
dial_sw_interrupt (void)
|
||||
{
|
||||
dial_sw_disable ();
|
||||
chEvtSignalI (pin_thread, EV_SW_PUSH);
|
||||
chEvtSignalI (pin_thread, EV_PINPAD_INPUT_DONE);
|
||||
palClearPad (IOPORT1, GPIOA_LED2);
|
||||
}
|
||||
|
||||
@@ -157,7 +156,7 @@ pinpad_getline (int msg_code, systime_t timeout)
|
||||
dial_sw_enable ();
|
||||
m = chEvtWaitOneTimeout (ALL_EVENTS, LED_DISP_BLINK_INTERVAL0);
|
||||
|
||||
if (m == EV_SW_PUSH || sw_push_count)
|
||||
if (m == EV_PINPAD_INPUT_DONE || sw_push_count)
|
||||
{
|
||||
if (palReadPad (IOPORT2, GPIOB_BUTTON) == 0)
|
||||
sw_push_count++;
|
||||
|
||||
@@ -374,7 +374,7 @@ icc_power_off (void)
|
||||
if (gpg_thread)
|
||||
{
|
||||
chThdTerminate (gpg_thread);
|
||||
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||
chEvtSignal (gpg_thread, EV_NOP);
|
||||
chThdWait (gpg_thread);
|
||||
gpg_thread = NULL;
|
||||
}
|
||||
@@ -497,7 +497,7 @@ icc_handle_data (void)
|
||||
{
|
||||
if (icc_header->param == 0)
|
||||
{ /* Give this message to GPG thread */
|
||||
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||
chEvtSignal (gpg_thread, EV_CMD_AVAILABLE);
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
}
|
||||
else if (icc_header->param == 1)
|
||||
@@ -524,7 +524,7 @@ icc_handle_data (void)
|
||||
cmd_APDU[2] = icc_buffer[27];
|
||||
cmd_APDU[3] = icc_buffer[28];
|
||||
icc_data_size = 4;
|
||||
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||
chEvtSignal (gpg_thread, EV_VERIFY_CMD_AVAILABLE);
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
}
|
||||
else if (icc_buffer[10] == 0x01) /* PIN Modification */
|
||||
@@ -540,7 +540,7 @@ icc_handle_data (void)
|
||||
cmd_APDU[2] = icc_buffer[29 + num_msgs];
|
||||
cmd_APDU[3] = icc_buffer[30 + num_msgs];
|
||||
icc_data_size = 4;
|
||||
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||
chEvtSignal (gpg_thread, EV_MODIFY_CMD_AVAILABLE);
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
}
|
||||
else
|
||||
@@ -572,7 +572,7 @@ icc_handle_data (void)
|
||||
icc_data_size = icc_next_p - icc_buffer - ICC_MSG_HEADER_SIZE;
|
||||
icc_chain_p = NULL;
|
||||
next_state = ICC_STATE_EXECUTE;
|
||||
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||
chEvtSignal (gpg_thread, EV_CMD_AVAILABLE);
|
||||
}
|
||||
else /* icc_header->param == 3 is not supported. */
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user