mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-20 10:50:09 +00:00
implement downloading program
This commit is contained in:
parent
e2e2e1a045
commit
ce338a9727
22
ChangeLog
22
ChangeLog
@ -1,8 +1,25 @@
|
|||||||
2012-05-17 Niibe Yutaka <gniibe@fsij.org>
|
2012-05-17 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* tool/gnuk_upgrade.py: New tool.
|
||||||
|
|
||||||
|
* src/gnuk.h (ICC_STATE_EXITED, ICC_STATE_EXEC_REQUESTED): New.
|
||||||
|
|
||||||
|
* src/openpgp.c (INS_EXTERNAL_AUTHENTICATE)
|
||||||
|
(cmd_external_authenticate): New.
|
||||||
|
(INS_GET_CHALLENGE, cmd_get_challenge): New.
|
||||||
|
|
||||||
|
* src/usb-icc.c (USBthread): Finish the thread with
|
||||||
|
ICC_STATE_EXITED, after EXTERNAL_AUTHENTICATE.
|
||||||
|
|
||||||
* src/usb_prop.c (gnuk_setup_endpoints_for_interface): Add STOP
|
* src/usb_prop.c (gnuk_setup_endpoints_for_interface): Add STOP
|
||||||
argument.
|
argument.
|
||||||
(gnuk_usb_event): Disable all endpoints when configure(0).
|
(gnuk_usb_event): Disable all endpoints when configure(0).
|
||||||
|
(vcom_port_data_setup): Check direction and support
|
||||||
|
USB_CDC_REQ_SET_LINE_CODING.
|
||||||
|
(vcom_port_setup_with_nodata): Check direction.
|
||||||
|
(gnuk_setup_with_data): Check direction and add FSIJ_GNUK device
|
||||||
|
requests.
|
||||||
|
(gnuk_setup_with_nodata): Likewise.
|
||||||
|
|
||||||
* src/usb_lld.c (LAST_OUT_DATA): Remove.
|
* src/usb_lld.c (LAST_OUT_DATA): Remove.
|
||||||
(handle_datastage_out): Cleanup and call st103_ep_set_rxtx_status.
|
(handle_datastage_out): Cleanup and call st103_ep_set_rxtx_status.
|
||||||
@ -10,6 +27,11 @@
|
|||||||
st103_ep_set_tx_status.
|
st103_ep_set_tx_status.
|
||||||
(handle_setup0): Likewise.
|
(handle_setup0): Likewise.
|
||||||
(handle_out0): Remove LAST_OUT_DATA.
|
(handle_out0): Remove LAST_OUT_DATA.
|
||||||
|
(std_none, std_get_status, std_clear_feature, std_set_feature)
|
||||||
|
(std_set_address, std_get_descriptor, std_get_configuration)
|
||||||
|
(std_set_configuration, std_get_interface, std_set_interface):
|
||||||
|
Check direction.
|
||||||
|
(handle_setup0): Add length for setup_with_data
|
||||||
|
|
||||||
2012-05-16 Niibe Yutaka <gniibe@fsij.org>
|
2012-05-16 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
@ -76,6 +76,9 @@ enum icc_state
|
|||||||
ICC_STATE_EXECUTE, /* Busy4 */
|
ICC_STATE_EXECUTE, /* Busy4 */
|
||||||
ICC_STATE_RECEIVE, /* APDU Received Partially */
|
ICC_STATE_RECEIVE, /* APDU Received Partially */
|
||||||
ICC_STATE_SEND, /* APDU Sent Partially */
|
ICC_STATE_SEND, /* APDU Sent Partially */
|
||||||
|
|
||||||
|
ICC_STATE_EXITED, /* ICC Thread Terminated */
|
||||||
|
ICC_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum icc_state *icc_state_p;
|
extern enum icc_state *icc_state_p;
|
||||||
@ -385,3 +388,5 @@ extern uint8_t pin_input_len;
|
|||||||
extern int pinpad_getline (int msg_code, systime_t timeout);
|
extern int pinpad_getline (int msg_code, systime_t timeout);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern uint8_t __heap_base__, __heap_end__;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* openpgp.c -- OpenPGP card protocol support
|
* openpgp.c -- OpenPGP card protocol support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011 Free Software Initiative of Japan
|
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@ -39,6 +39,8 @@
|
|||||||
#define INS_PSO 0x2a
|
#define INS_PSO 0x2a
|
||||||
#define INS_RESET_RETRY_COUNTER 0x2c
|
#define INS_RESET_RETRY_COUNTER 0x2c
|
||||||
#define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47
|
#define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47
|
||||||
|
#define INS_EXTERNAL_AUTHENTICATE 0x82
|
||||||
|
#define INS_GET_CHALLENGE 0x84
|
||||||
#define INS_INTERNAL_AUTHENTICATE 0x88
|
#define INS_INTERNAL_AUTHENTICATE 0x88
|
||||||
#define INS_SELECT_FILE 0xa4
|
#define INS_SELECT_FILE 0xa4
|
||||||
#define INS_READ_BINARY 0xb0
|
#define INS_READ_BINARY 0xb0
|
||||||
@ -821,6 +823,43 @@ cmd_write_binary (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_external_authenticate (void)
|
||||||
|
{
|
||||||
|
DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
|
||||||
|
|
||||||
|
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
|
||||||
|
{
|
||||||
|
GPG_SECURITY_FAILURE ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chThdTerminate (chThdSelf ());
|
||||||
|
set_res_sw (0xff, 0xff);
|
||||||
|
DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_get_challenge (void)
|
||||||
|
{
|
||||||
|
const uint8_t *rand;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DEBUG_INFO (" - GET CHALLENGE\r\n");
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
rand = random_bytes_get ();
|
||||||
|
memcpy (res_APDU + i * 16, rand, 16);
|
||||||
|
random_bytes_free (rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
res_APDU_size = 96;
|
||||||
|
GPG_SUCCESS ();
|
||||||
|
DEBUG_INFO ("GET CHALLENGE done.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct command
|
struct command
|
||||||
{
|
{
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
@ -833,11 +872,14 @@ const struct command cmds[] = {
|
|||||||
{ INS_PSO, cmd_pso },
|
{ INS_PSO, cmd_pso },
|
||||||
{ INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
|
{ INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
|
||||||
{ INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
|
{ INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
|
||||||
|
{ INS_EXTERNAL_AUTHENTICATE, /* Not in OpenPGP card protocol */
|
||||||
|
cmd_external_authenticate },
|
||||||
|
{ INS_GET_CHALLENGE, cmd_get_challenge }, /* Not in OpenPGP card protocol */
|
||||||
{ INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
|
{ INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
|
||||||
{ INS_SELECT_FILE, cmd_select_file },
|
{ INS_SELECT_FILE, cmd_select_file },
|
||||||
{ INS_READ_BINARY, cmd_read_binary },
|
{ INS_READ_BINARY, cmd_read_binary },
|
||||||
{ INS_GET_DATA, cmd_get_data },
|
{ INS_GET_DATA, cmd_get_data },
|
||||||
{ INS_WRITE_BINARY, cmd_write_binary}, /* Not in OpenPGP card protocol */
|
{ INS_WRITE_BINARY, cmd_write_binary}, /* Not in OpenPGP card protocol */
|
||||||
#if defined(CERTDO_SUPPORT)
|
#if defined(CERTDO_SUPPORT)
|
||||||
{ INS_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
|
{ INS_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1273,6 +1273,7 @@ icc_handle_timeout (struct ccid *c)
|
|||||||
|
|
||||||
static struct ccid ccid;
|
static struct ccid ccid;
|
||||||
|
|
||||||
|
#define GPG_THREAD_TERMINATED 0xffff
|
||||||
|
|
||||||
msg_t
|
msg_t
|
||||||
USBthread (void *arg)
|
USBthread (void *arg)
|
||||||
@ -1303,6 +1304,16 @@ USBthread (void *arg)
|
|||||||
else if (m == EV_EXEC_FINISHED)
|
else if (m == EV_EXEC_FINISHED)
|
||||||
if (c->icc_state == ICC_STATE_EXECUTE)
|
if (c->icc_state == ICC_STATE_EXECUTE)
|
||||||
{
|
{
|
||||||
|
if (c->a->sw == GPG_THREAD_TERMINATED)
|
||||||
|
{
|
||||||
|
c->sw1sw2[0] = 0x90;
|
||||||
|
c->sw1sw2[1] = 0x00;
|
||||||
|
c->state = APDU_STATE_RESULT;
|
||||||
|
icc_send_data_block (c, 0);
|
||||||
|
c->icc_state = ICC_STATE_EXITED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
c->a->cmd_apdu_data_len = 0;
|
c->a->cmd_apdu_data_len = 0;
|
||||||
c->sw1sw2[0] = c->a->sw >> 8;
|
c->sw1sw2[0] = c->a->sw >> 8;
|
||||||
c->sw1sw2[1] = c->a->sw & 0xff;
|
c->sw1sw2[1] = c->a->sw & 0xff;
|
||||||
|
104
src/usb_lld.c
104
src/usb_lld.c
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#define USB_MAX_PACKET_SIZE 64 /* For FS device */
|
#define USB_MAX_PACKET_SIZE 64 /* For FS device */
|
||||||
|
|
||||||
#define RECIPIENT 0x1F /* Mask to get recipient */
|
|
||||||
|
|
||||||
enum STANDARD_REQUESTS
|
enum STANDARD_REQUESTS
|
||||||
{
|
{
|
||||||
GET_STATUS = 0,
|
GET_STATUS = 0,
|
||||||
@ -450,25 +448,27 @@ static void handle_datastage_in (void)
|
|||||||
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*HANDLER) (uint8_t rcp,
|
typedef int (*HANDLER) (uint8_t req,
|
||||||
uint16_t value, uint16_t index, uint16_t length);
|
uint16_t value, uint16_t index, uint16_t length);
|
||||||
|
|
||||||
static int std_none (uint8_t rcp,
|
static int std_none (uint8_t req,
|
||||||
uint16_t value, uint16_t index, uint16_t length)
|
uint16_t value, uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
(void)rcp; (void)value; (void)index; (void)length;
|
(void)req; (void)value; (void)index; (void)length;
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_status (uint8_t rcp,
|
static int std_get_status (uint8_t req,
|
||||||
uint16_t value, uint16_t index, uint16_t length)
|
uint16_t value, uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
static uint16_t status_info;
|
static uint16_t status_info;
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
status_info = 0; /* Reset Status Information */
|
status_info = 0; /* Reset Status Information */
|
||||||
data_p->addr = (uint8_t *)&status_info;
|
data_p->addr = (uint8_t *)&status_info;
|
||||||
|
|
||||||
if (value != 0 || length != 2 || (index >> 8) != 0)
|
if (value != 0 || length != 2 || (index >> 8) != 0
|
||||||
|
|| (req & REQUEST_DIR) == 0)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
@ -540,9 +540,14 @@ static int std_get_status (uint8_t rcp,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_clear_feature (uint8_t rcp, uint16_t value,
|
static int std_clear_feature (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 1)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (length != 0 || index != 0)
|
if (length != 0 || index != 0)
|
||||||
@ -598,9 +603,14 @@ static int std_clear_feature (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_feature (uint8_t rcp, uint16_t value,
|
static int std_set_feature (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 1)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (length != 0 || index != 0)
|
if (length != 0 || index != 0)
|
||||||
@ -646,9 +656,14 @@ static int std_set_feature (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_address (uint8_t rcp, uint16_t value,
|
static int std_set_address (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 1)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (length == 0 && value <= 127 && index == 0
|
if (length == 0 && value <= 127 && index == 0
|
||||||
@ -659,9 +674,14 @@ static int std_set_address (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_descriptor (uint8_t rcp, uint16_t value,
|
static int std_get_descriptor (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 0)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
(void)length;
|
(void)length;
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
return (*method_p->get_descriptor) ((value >> 8), index, value);
|
return (*method_p->get_descriptor) ((value >> 8), index, value);
|
||||||
@ -669,9 +689,14 @@ static int std_get_descriptor (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_configuration (uint8_t rcp, uint16_t value,
|
static int std_get_configuration (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 0)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
(void)value; (void)index; (void)length;
|
(void)value; (void)index; (void)length;
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
@ -683,9 +708,14 @@ static int std_get_configuration (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_configuration (uint8_t rcp, uint16_t value,
|
static int std_set_configuration (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 1)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT && index == 0 && length == 0)
|
if (rcp == DEVICE_RECIPIENT && index == 0 && length == 0)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@ -698,9 +728,14 @@ static int std_set_configuration (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_get_interface (uint8_t rcp, uint16_t value,
|
static int std_get_interface (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 0)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == INTERFACE_RECIPIENT)
|
if (rcp == INTERFACE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (value != 0 || (index >> 8) != 0 || length != 1)
|
if (value != 0 || (index >> 8) != 0 || length != 1)
|
||||||
@ -715,9 +750,14 @@ static int std_get_interface (uint8_t rcp, uint16_t value,
|
|||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int std_set_interface (uint8_t rcp, uint16_t value,
|
static int std_set_interface (uint8_t req, uint16_t value,
|
||||||
uint16_t index, uint16_t length)
|
uint16_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
|
uint8_t rcp = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 1)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
if (rcp == INTERFACE_RECIPIENT)
|
if (rcp == INTERFACE_RECIPIENT)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@ -759,7 +799,6 @@ static void handle_setup0 (void)
|
|||||||
uint8_t req;
|
uint8_t req;
|
||||||
int r = USB_UNSUPPORT;
|
int r = USB_UNSUPPORT;
|
||||||
HANDLER handler;
|
HANDLER handler;
|
||||||
uint8_t type_rcp;
|
|
||||||
|
|
||||||
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2));
|
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2));
|
||||||
w = *pw++;
|
w = *pw++;
|
||||||
@ -776,34 +815,35 @@ static void handle_setup0 (void)
|
|||||||
data_p->len = 0;
|
data_p->len = 0;
|
||||||
data_p->offset = 0;
|
data_p->offset = 0;
|
||||||
|
|
||||||
type_rcp = (ctrl_p->bmRequestType & (REQUEST_TYPE | RECIPIENT));
|
if ((ctrl_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
|
||||||
if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) /* Interface */
|
|
||||||
|| (ctrl_p->bmRequestType & REQUEST_TYPE) == VENDOR_REQUEST)
|
|
||||||
{
|
|
||||||
if (ctrl_p->wLength == 0)
|
|
||||||
r = (*method_p->setup_with_nodata) (type_rcp, req, ctrl_p->wIndex);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(*method_p->setup_with_data) (type_rcp, req, ctrl_p->wIndex);
|
|
||||||
if (data_p->len != 0)
|
|
||||||
r = USB_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((ctrl_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
|
|
||||||
{
|
{
|
||||||
if (req < TOTAL_REQUEST)
|
if (req < TOTAL_REQUEST)
|
||||||
{
|
{
|
||||||
handler = std_request_handler[req];
|
handler = std_request_handler[req];
|
||||||
r = (*handler) (ctrl_p->bmRequestType & RECIPIENT,
|
r = (*handler) (ctrl_p->bmRequestType,
|
||||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ctrl_p->wLength == 0)
|
||||||
|
r = (*method_p->setup_with_nodata) (ctrl_p->bmRequestType,
|
||||||
|
req, ctrl_p->wIndex);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*method_p->setup_with_data) (ctrl_p->bmRequestType, req,
|
||||||
|
ctrl_p->wIndex, ctrl_p->wLength);
|
||||||
|
if (data_p->len != 0)
|
||||||
|
r = USB_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (r != USB_SUCCESS)
|
if (r != USB_SUCCESS)
|
||||||
dev_p->state = STALLED;
|
dev_p->state = STALLED;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ctrl_p->bmRequestType & 0x80)
|
if (ctrl_p->bmRequestType & REQUEST_DIR)
|
||||||
{
|
{
|
||||||
uint32_t len = ctrl_p->wLength;
|
uint32_t len = ctrl_p->wLength;
|
||||||
|
|
||||||
|
@ -39,10 +39,12 @@ enum DESCRIPTOR_TYPE
|
|||||||
ENDPOINT_DESCRIPTOR
|
ENDPOINT_DESCRIPTOR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define REQUEST_DIR 0x80 /* Mask to get request dir */
|
||||||
#define REQUEST_TYPE 0x60 /* Mask to get request type */
|
#define REQUEST_TYPE 0x60 /* Mask to get request type */
|
||||||
#define STANDARD_REQUEST 0x00 /* Standard request */
|
#define STANDARD_REQUEST 0x00 /* Standard request */
|
||||||
#define CLASS_REQUEST 0x20 /* Class request */
|
#define CLASS_REQUEST 0x20 /* Class request */
|
||||||
#define VENDOR_REQUEST 0x40 /* Vendor request */
|
#define VENDOR_REQUEST 0x40 /* Vendor request */
|
||||||
|
#define RECIPIENT 0x1F /* Mask to get recipient */
|
||||||
|
|
||||||
struct Descriptor
|
struct Descriptor
|
||||||
{
|
{
|
||||||
@ -60,7 +62,8 @@ struct usb_device_method
|
|||||||
{
|
{
|
||||||
void (*init) (void);
|
void (*init) (void);
|
||||||
void (*reset) (void);
|
void (*reset) (void);
|
||||||
void (*setup_with_data) (uint8_t rcp, uint8_t req_no, uint16_t index);
|
void (*setup_with_data) (uint8_t rcp, uint8_t req_no, uint16_t index,
|
||||||
|
uint16_t len);
|
||||||
int (*setup_with_nodata) (uint8_t rcp, uint8_t req_no, uint16_t index);
|
int (*setup_with_nodata) (uint8_t rcp, uint8_t req_no, uint16_t index);
|
||||||
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value);
|
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value);
|
||||||
int (*event) (uint8_t event_type, uint16_t value);
|
int (*event) (uint8_t event_type, uint16_t value);
|
||||||
@ -141,3 +144,8 @@ extern uint8_t usb_lld_current_configuration (void);
|
|||||||
extern void usb_lld_set_feature (uint8_t feature);
|
extern void usb_lld_set_feature (uint8_t feature);
|
||||||
|
|
||||||
extern void usb_lld_set_data_to_send (const void *p, size_t len);
|
extern void usb_lld_set_data_to_send (const void *p, size_t len);
|
||||||
|
|
||||||
|
extern inline void usb_lld_set_data_to_recv (void *p, size_t len)
|
||||||
|
{
|
||||||
|
usb_lld_set_data_to_send ((const void *)p, len);
|
||||||
|
}
|
||||||
|
100
src/usb_prop.c
100
src/usb_prop.c
@ -28,6 +28,7 @@
|
|||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
#include "usb_conf.h"
|
#include "usb_conf.h"
|
||||||
|
#include "gnuk.h"
|
||||||
|
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
#include "usb-cdc.h"
|
#include "usb-cdc.h"
|
||||||
@ -40,7 +41,7 @@ struct line_coding
|
|||||||
uint8_t datatype;
|
uint8_t datatype;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct line_coding line_coding = {
|
static struct line_coding line_coding = {
|
||||||
115200, /* baud rate: 115200 */
|
115200, /* baud rate: 115200 */
|
||||||
0x00, /* stop bits: 1 */
|
0x00, /* stop bits: 1 */
|
||||||
0x00, /* parity: none */
|
0x00, /* parity: none */
|
||||||
@ -48,20 +49,19 @@ static const struct line_coding line_coding = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vcom_port_data_setup (uint8_t RequestNo)
|
vcom_port_data_setup (uint8_t req, uint8_t req_no)
|
||||||
{
|
{
|
||||||
if (RequestNo != USB_CDC_REQ_GET_LINE_CODING)
|
if ((req & REQUEST_DIR) == 1 && req_no == USB_CDC_REQ_GET_LINE_CODING)
|
||||||
return;
|
usb_lld_set_data_to_send (&line_coding, sizeof(line_coding));
|
||||||
|
|
||||||
/* RequestNo == USB_CDC_REQ_SET_LINE_CODING is not supported */
|
if ((req & REQUEST_DIR) == 0 && req_no == USB_CDC_REQ_SET_LINE_CODING)
|
||||||
|
usb_lld_set_data_to_recv (&line_coding, sizeof(line_coding));
|
||||||
usb_lld_set_data_to_send (&line_coding, sizeof(line_coding));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vcom_port_setup_with_nodata (uint8_t RequestNo)
|
vcom_port_setup_with_nodata (uint8_t req, uint8_t req_no)
|
||||||
{
|
{
|
||||||
if (RequestNo == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
if ((req & REQUEST_DIR) == 0 && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||||
/* Do nothing and success */
|
/* Do nothing and success */
|
||||||
return USB_SUCCESS;
|
return USB_SUCCESS;
|
||||||
|
|
||||||
@ -183,26 +183,54 @@ static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
|
|||||||
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
|
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const uint8_t *mem_info[] = { &__heap_base__, &__heap_end__, };
|
||||||
|
|
||||||
|
#define USB_FSIJ_GNUK_MEMINFO 0
|
||||||
|
#define USB_FSIJ_GNUK_DOWNLOAD 1
|
||||||
|
#define USB_FSIJ_GNUK_EXEC 2
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnuk_setup_with_data (uint8_t recipient, uint8_t RequestNo, uint16_t index)
|
gnuk_setup_with_data (uint8_t req, uint8_t req_no, uint16_t index,
|
||||||
|
uint16_t len)
|
||||||
{
|
{
|
||||||
if (recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) /* Interface */
|
uint8_t recipient = req & RECIPIENT;
|
||||||
|
|
||||||
|
if (recipient == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||||
|
{
|
||||||
|
if ((req & REQUEST_DIR) == 1 && req_no == USB_FSIJ_GNUK_MEMINFO)
|
||||||
|
usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
|
||||||
|
else if ((req & REQUEST_DIR) == 0 && req_no == USB_FSIJ_GNUK_DOWNLOAD)
|
||||||
|
{
|
||||||
|
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((uint32_t)(index * 0x100) < (uint32_t)&__heap_base__
|
||||||
|
|| (uint32_t)((index * 0x100) + len) > (uint32_t)&__heap_end__)
|
||||||
|
return;
|
||||||
|
|
||||||
|
usb_lld_set_data_to_recv ((void *)0x20000000 + index*0x100, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if (RequestNo == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
if ((req & REQUEST_DIR) == 1
|
||||||
|
&& req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||||
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
|
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
|
||||||
else if (RequestNo == USB_CCID_REQ_GET_DATA_RATES)
|
else if ((req & REQUEST_DIR) == 1
|
||||||
usb_lld_set_data_to_send (data_rate_table, sizeof (data_rate_table));
|
&& req_no == USB_CCID_REQ_GET_DATA_RATES)
|
||||||
|
usb_lld_set_data_to_send (data_rate_table,
|
||||||
|
sizeof (data_rate_table));
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
else if (index == 1)
|
else if (index == 1)
|
||||||
vcom_port_data_setup (RequestNo);
|
vcom_port_data_setup (req, req_no);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PINPAD_DND_SUPPORT
|
#ifdef PINPAD_DND_SUPPORT
|
||||||
else if (index == MSC_INTERFACE_NO)
|
else if (index == MSC_INTERFACE_NO)
|
||||||
{
|
{
|
||||||
if (RequestNo == MSC_GET_MAX_LUN_COMMAND)
|
if ((req & REQUEST_DIR) == 1 && req_no == MSC_GET_MAX_LUN_COMMAND)
|
||||||
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
|
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -211,12 +239,28 @@ gnuk_setup_with_data (uint8_t recipient, uint8_t RequestNo, uint16_t index)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gnuk_setup_with_nodata (uint8_t recipient, uint8_t RequestNo, uint16_t index)
|
gnuk_setup_with_nodata (uint8_t req, uint8_t req_no, uint16_t index)
|
||||||
{
|
{
|
||||||
if (recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) /* Interface */
|
uint8_t recipient = req & RECIPIENT;
|
||||||
|
|
||||||
|
if ((req & REQUEST_DIR) == 1)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
|
if (recipient == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||||
|
{
|
||||||
|
if (req_no == USB_FSIJ_GNUK_EXEC)
|
||||||
|
{
|
||||||
|
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||||
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
|
*icc_state_p = ICC_STATE_EXEC_REQUESTED;
|
||||||
|
return USB_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if (RequestNo == USB_CCID_REQ_ABORT)
|
if (req_no == USB_CCID_REQ_ABORT)
|
||||||
/* wValue: bSeq, bSlot */
|
/* wValue: bSeq, bSlot */
|
||||||
/* Abortion is not supported in Gnuk */
|
/* Abortion is not supported in Gnuk */
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
@ -225,24 +269,20 @@ gnuk_setup_with_nodata (uint8_t recipient, uint8_t RequestNo, uint16_t index)
|
|||||||
}
|
}
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
else if (index == 1)
|
else if (index == 1)
|
||||||
return vcom_port_setup_with_nodata (RequestNo);
|
return vcom_port_setup_with_nodata (req, req_no);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PINPAD_DND_SUPPORT
|
#ifdef PINPAD_DND_SUPPORT
|
||||||
else if (index == MSC_INTERFACE_NO)
|
else if (index == MSC_INTERFACE_NO)
|
||||||
{
|
{
|
||||||
if (RequestNo == MSC_MASS_STORAGE_RESET_COMMAND)
|
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||||
{
|
{
|
||||||
/* Should call resetting MSC thread, something like msc_reset() */
|
/* Should call resetting MSC thread, something like msc_reset() */
|
||||||
return USB_SUCCESS;
|
return USB_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
else
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -278,6 +318,8 @@ gnuk_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
|
|||||||
|
|
||||||
static int gnuk_usb_event (uint8_t event_type, uint16_t value)
|
static int gnuk_usb_event (uint8_t event_type, uint16_t value)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
switch (event_type)
|
switch (event_type)
|
||||||
{
|
{
|
||||||
case USB_EVENT_RESET:
|
case USB_EVENT_RESET:
|
||||||
@ -288,10 +330,6 @@ static int gnuk_usb_event (uint8_t event_type, uint16_t value)
|
|||||||
case USB_EVENT_CONFIG:
|
case USB_EVENT_CONFIG:
|
||||||
if (usb_lld_current_configuration () == 0)
|
if (usb_lld_current_configuration () == 0)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
extern void *main_thread;
|
|
||||||
#define LED_STATUS_MODE (8)
|
|
||||||
|
|
||||||
if (value != 1)
|
if (value != 1)
|
||||||
return USB_UNSUPPORT;
|
return USB_UNSUPPORT;
|
||||||
|
|
||||||
|
239
tool/gnuk_upgrade.py
Executable file
239
tool/gnuk_upgrade.py
Executable file
@ -0,0 +1,239 @@
|
|||||||
|
#! /usr/bin/python
|
||||||
|
|
||||||
|
"""
|
||||||
|
gnuk_upgrade.py - a tool to upgrade firmware of Gnuk Token
|
||||||
|
|
||||||
|
Copyright (C) 2012 Free Software Initiative of Japan
|
||||||
|
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
|
|
||||||
|
Gnuk is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Gnuk is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from intel_hex import *
|
||||||
|
from struct import *
|
||||||
|
import sys, time, os, binascii, string
|
||||||
|
|
||||||
|
# INPUT: binary file
|
||||||
|
|
||||||
|
# Assume only single CCID device is attached to computer, and it's Gnuk Token
|
||||||
|
|
||||||
|
import usb
|
||||||
|
|
||||||
|
# USB class, subclass, protocol
|
||||||
|
CCID_CLASS = 0x0B
|
||||||
|
CCID_SUBCLASS = 0x00
|
||||||
|
CCID_PROTOCOL_0 = 0x00
|
||||||
|
|
||||||
|
def icc_compose(msg_type, data_len, slot, seq, param, data):
|
||||||
|
return pack('<BiBBBH', msg_type, data_len, slot, seq, 0, param) + data
|
||||||
|
|
||||||
|
def iso7816_compose(ins, p1, p2, data):
|
||||||
|
cls = 0x00
|
||||||
|
data_len = len(data)
|
||||||
|
if data_len == 0:
|
||||||
|
return pack('>BBBB', cls, ins, p1, p2)
|
||||||
|
else:
|
||||||
|
return pack('>BBBBBh', cls, ins, p1, p2, 0, data_len) + data
|
||||||
|
|
||||||
|
# This class only supports Gnuk (for now)
|
||||||
|
class gnuk_token:
|
||||||
|
def __init__(self, device, configuration, interface):
|
||||||
|
"""
|
||||||
|
__init__(device, configuration, interface) -> None
|
||||||
|
Initialize the device.
|
||||||
|
device: usb.Device object.
|
||||||
|
configuration: configuration number.
|
||||||
|
interface: usb.Interface object representing the interface and altenate setting.
|
||||||
|
"""
|
||||||
|
if interface.interfaceClass != CCID_CLASS:
|
||||||
|
raise ValueError, "Wrong interface class"
|
||||||
|
if interface.interfaceSubClass != CCID_SUBCLASS:
|
||||||
|
raise ValueError, "Wrong interface sub class"
|
||||||
|
self.__devhandle = device.open()
|
||||||
|
try:
|
||||||
|
self.__devhandle.setConfiguration(configuration)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.__devhandle.claimInterface(interface)
|
||||||
|
self.__devhandle.setAltInterface(interface)
|
||||||
|
|
||||||
|
self.__intf = interface.interfaceNumber
|
||||||
|
self.__alt = interface.alternateSetting
|
||||||
|
self.__conf = configuration
|
||||||
|
|
||||||
|
self.__bulkout = 2
|
||||||
|
self.__bulkin = 0x81
|
||||||
|
|
||||||
|
self.__timeout = 10000
|
||||||
|
self.__seq = 0
|
||||||
|
|
||||||
|
def icc_get_result(self):
|
||||||
|
msg = self.__devhandle.bulkRead(self.__bulkin, 1024, self.__timeout)
|
||||||
|
if len(msg) < 10:
|
||||||
|
print msg
|
||||||
|
raise ValueError, "icc_get_result"
|
||||||
|
msg_type = msg[0]
|
||||||
|
data_len = msg[1] + (msg[2]<<8) + (msg[3]<<16) + (msg[4]<<24)
|
||||||
|
slot = msg[5]
|
||||||
|
seq = msg[6]
|
||||||
|
status = msg[7]
|
||||||
|
error = msg[8]
|
||||||
|
chain = msg[9]
|
||||||
|
data = msg[10:]
|
||||||
|
# XXX: check msg_type, data_len, slot, seq, error
|
||||||
|
return (status, chain, data)
|
||||||
|
|
||||||
|
def icc_get_status(self):
|
||||||
|
msg = icc_compose(0x65, 0, 0, self.__seq, 0, "")
|
||||||
|
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||||
|
self.__seq += 1
|
||||||
|
status, chain, data = self.icc_get_result()
|
||||||
|
# XXX: check chain, data
|
||||||
|
return status
|
||||||
|
|
||||||
|
def icc_power_on(self):
|
||||||
|
msg = icc_compose(0x62, 0, 0, self.__seq, 0, "")
|
||||||
|
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||||
|
self.__seq += 1
|
||||||
|
status, chain, data = self.icc_get_result()
|
||||||
|
# XXX: check status, chain
|
||||||
|
return data # ATR
|
||||||
|
|
||||||
|
def icc_power_off(self):
|
||||||
|
msg = icc_compose(0x63, 0, 0, self.__seq, 0, "")
|
||||||
|
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||||
|
self.__seq += 1
|
||||||
|
status, chain, data = self.icc_get_result()
|
||||||
|
# XXX: check chain, data
|
||||||
|
return status
|
||||||
|
|
||||||
|
def icc_send_data_block(self, data):
|
||||||
|
msg = icc_compose(0x6f, len(data), 0, self.__seq, 0, data)
|
||||||
|
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||||
|
self.__seq += 1
|
||||||
|
return self.icc_get_result()
|
||||||
|
|
||||||
|
def icc_send_cmd(self, data):
|
||||||
|
status, chain, data_rcv = self.icc_send_data_block(data)
|
||||||
|
if chain == 0:
|
||||||
|
return data_rcv
|
||||||
|
elif chain == 1:
|
||||||
|
d = data_rcv
|
||||||
|
while True:
|
||||||
|
msg = icc_compose(0x6f, 0, 0, self.__seq, 0x10, "")
|
||||||
|
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||||
|
self.__seq += 1
|
||||||
|
status, chain, data_rcv = self.icc_get_result()
|
||||||
|
# XXX: check status
|
||||||
|
d += data_rcv
|
||||||
|
if chain == 2:
|
||||||
|
break
|
||||||
|
elif chain == 3:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
raise ValueError, "icc_send_cmd chain"
|
||||||
|
return d
|
||||||
|
else:
|
||||||
|
raise ValueError, "icc_send_cmd"
|
||||||
|
|
||||||
|
def cmd_get_response(self, expected_len):
|
||||||
|
cmd_data = iso7816_compose(0xc0, 0x00, 0x00, [expected_len])
|
||||||
|
response = self.icc_send_cmd(cmd_data)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def cmd_verify(self, who, passwd):
|
||||||
|
cmd_data = iso7816_compose(0x20, 0x00, 0x80+who, passwd)
|
||||||
|
sw = self.icc_send_cmd(cmd_data)
|
||||||
|
if len(sw) != 2:
|
||||||
|
raise ValueError, "cmd_verify"
|
||||||
|
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||||
|
raise ValueError, "cmd_verify"
|
||||||
|
|
||||||
|
def cmd_select_openpgp(self):
|
||||||
|
cmd_data = iso7816_compose(0xa4, 0x04, 0x0c, "\xD2\x76\x00\x01\x24\x01")
|
||||||
|
sw = self.icc_send_cmd(cmd_data)
|
||||||
|
if len(sw) != 2:
|
||||||
|
raise ValueError, "cmd_select_openpgp"
|
||||||
|
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||||
|
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
|
||||||
|
|
||||||
|
def cmd_external_authenticate(self, who, signed):
|
||||||
|
cmd_data = iso7816_compose(0x82, 0x00, 0x00, signed)
|
||||||
|
sw = self.icc_send_cmd(cmd_data)
|
||||||
|
if len(sw) != 2:
|
||||||
|
raise ValueError, "cmd_external_authenticate"
|
||||||
|
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||||
|
raise ValueError, "cmd_external_authenticate"
|
||||||
|
|
||||||
|
def compare(data_original, data_in_device):
|
||||||
|
i = 0
|
||||||
|
for d in data_original:
|
||||||
|
if ord(d) != data_in_device[i]:
|
||||||
|
raise ValueError, "verify failed at %08x" % i
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
def get_device():
|
||||||
|
busses = usb.busses()
|
||||||
|
for bus in busses:
|
||||||
|
devices = bus.devices
|
||||||
|
for dev in devices:
|
||||||
|
for config in dev.configurations:
|
||||||
|
for intf in config.interfaces:
|
||||||
|
for alt in intf:
|
||||||
|
if alt.interfaceClass == CCID_CLASS and \
|
||||||
|
alt.interfaceSubClass == CCID_SUBCLASS and \
|
||||||
|
alt.interfaceProtocol == CCID_PROTOCOL_0:
|
||||||
|
return dev, config, alt
|
||||||
|
raise ValueError, "Device not found"
|
||||||
|
|
||||||
|
def main(passwd, data):
|
||||||
|
dev, config, intf = get_device()
|
||||||
|
print "Device: ", dev.filename
|
||||||
|
print "Configuration: ", config.value
|
||||||
|
print "Interface: ", intf.interfaceNumber
|
||||||
|
icc = gnuk_token(dev, config, intf)
|
||||||
|
if icc.icc_get_status() == 2:
|
||||||
|
raise ValueError, "No ICC present"
|
||||||
|
elif icc.icc_get_status() == 1:
|
||||||
|
icc.icc_power_on()
|
||||||
|
icc.cmd_verify(3, passwd)
|
||||||
|
icc.cmd_select_openpgp()
|
||||||
|
challenge = icc.cmd_get_challenge()
|
||||||
|
signed = challenge
|
||||||
|
icc.cmd_external_authenticate(signed)
|
||||||
|
# set_configure(0) to disable all interfaces but control pipe
|
||||||
|
# check mem_info
|
||||||
|
# download flash install program
|
||||||
|
# exec
|
||||||
|
# ...
|
||||||
|
# Then, send upgrade program...
|
||||||
|
return 0
|
||||||
|
|
||||||
|
DEFAULT_PW3 = "12345678"
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
passwd = DEFAULT_PW3
|
||||||
|
if sys.argv[1] == '-p':
|
||||||
|
from getpass import getpass
|
||||||
|
passwd = getpass("Admin password: ")
|
||||||
|
sys.argv.pop(1)
|
||||||
|
filename = sys.argv[1]
|
||||||
|
f = open(filename)
|
||||||
|
data = f.read()
|
||||||
|
f.close()
|
||||||
|
print "%s: %d" % (filename, len(data))
|
||||||
|
print "Downloading flash upgrade program"
|
||||||
|
main(passwd, data)
|
Loading…
Reference in New Issue
Block a user