support PIN modification

This commit is contained in:
NIIBE Yutaka
2011-01-17 17:32:31 +09:00
parent 182660c391
commit 18b2b94acd
4 changed files with 89 additions and 17 deletions

View File

@@ -1,5 +1,14 @@
2011-01-17 NIIBE Yutaka <gniibe@fsij.org> 2011-01-17 NIIBE Yutaka <gniibe@fsij.org>
* src/gnuk.h (PIN_INPUT_CURRENT, PIN_INPUT_NEW)
(PIN_INPUT_CONFIRM): New.
* src/pin-cir.c (pin_main): New argument MSG_CODE.
* src/openpgp.c (get_pinpad_input): New.
(cmd_verify): Use get_pinpad_input.
(cmd_change_password): Added PINPAD_SUPPORT.
* src/openpgp.c (cmd_nop): Removed. * src/openpgp.c (cmd_nop): Removed.
* src/config.h.in: ifdef-out (not for ASSEMBLER). * src/config.h.in: ifdef-out (not for ASSEMBLER).

View File

@@ -319,5 +319,8 @@ extern void cir_ext_enable (void);
extern uint8_t pin_input_buffer[MAX_PIN_CHARS]; extern uint8_t pin_input_buffer[MAX_PIN_CHARS];
extern uint8_t pin_input_len; extern uint8_t pin_input_len;
#define PIN_INPUT_CURRENT 1
#define PIN_INPUT_NEW 2
#define PIN_INPUT_CONFIRM 3
extern msg_t pin_main (void *arg); extern msg_t pin_main (void *arg);
#endif #endif

View File

@@ -94,6 +94,27 @@ gpg_fini (void)
ac_fini (); ac_fini ();
} }
/*
* Invoke the thread PIN_MAIN, and let user input PIN string.
* Return length of the string.
* The string itself is in PIN_INPUT_BUFFER.
*/
static int
get_pinpad_input (int msg_code)
{
Thread *t;
t = chThdCreateFromHeap (NULL, THD_WA_SIZE (128),
NORMALPRIO, pin_main, (void *)msg_code);
if (t == NULL)
return -1;
else
{
chThdWait (t);
return pin_input_len;
}
}
static void static void
cmd_verify (void) cmd_verify (void)
{ {
@@ -108,23 +129,16 @@ cmd_verify (void)
#if defined(PINPAD_SUPPORT) #if defined(PINPAD_SUPPORT)
if (cmd_APDU_size == 4) if (cmd_APDU_size == 4)
/* Verify with pinpad */ /* Verification with pinpad */
{ {
Thread *t; len = get_pinpad_input (PIN_INPUT_CURRENT);
if (len < 0)
t = chThdCreateFromHeap (NULL, THD_WA_SIZE (128),
NORMALPRIO, pin_main, NULL);
if (t == NULL)
{ {
GPG_ERROR (); GPG_ERROR ();
return; return;
} }
else else
{ pw = pin_input_buffer;
chThdWait (t);
pw = pin_input_buffer;
len = pin_input_len;
}
} }
else else
#endif #endif
@@ -220,8 +234,8 @@ cmd_change_password (void)
uint8_t new_ks0[KEYSTRING_MD_SIZE+1]; uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
uint8_t *new_ks = &new_ks0[1]; uint8_t *new_ks = &new_ks0[1];
uint8_t p2 = cmd_APDU[3]; uint8_t p2 = cmd_APDU[3];
int len = cmd_APDU[4]; int len;
const uint8_t *pw = &cmd_APDU[5]; const uint8_t *pw;
const uint8_t *newpw; const uint8_t *newpw;
int pw_len, newpw_len; int pw_len, newpw_len;
int who = p2 - 0x80; int who = p2 - 0x80;
@@ -230,10 +244,55 @@ cmd_change_password (void)
DEBUG_INFO ("Change PW\r\n"); DEBUG_INFO ("Change PW\r\n");
DEBUG_BYTE (who); DEBUG_BYTE (who);
if (len == 0) /* extended length */ #if defined(PINPAD_SUPPORT)
if (cmd_APDU_size == 4)
/* Modification with pinpad */
{ {
len = (cmd_APDU[5]<<8) | cmd_APDU[6]; pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
pw += 2; 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;
}
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;
}
} }
if (who == BY_USER) /* PW1 */ if (who == BY_USER) /* PW1 */

View File

@@ -240,8 +240,9 @@ msg_t
pin_main (void *arg) pin_main (void *arg)
{ {
uint8_t s = 0; uint8_t s = 0;
int msg_code = (int)arg;
(void)arg; (void)msg_code;
pin_thread = chThdSelf (); pin_thread = chThdSelf ();
#if defined(DEBUG_CIR) #if defined(DEBUG_CIR)