1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-23 15:07:03 +01:00

* cardglue.c (open_card): Use shutdown code if possible.

(check_card_serialno): Ditto.

* ccid-driver.c (do_close_reader): Factored some code out from ...
(ccid_close_reader): ..here.
(ccid_shutdown_reader): New.

* apdu.c (apdu_shutdown_reader): New.
(shutdown_ccid_reader): New.
This commit is contained in:
Werner Koch 2004-09-20 13:15:37 +00:00
parent ca26884b3a
commit 5576f6ef6c
6 changed files with 179 additions and 43 deletions

View File

@ -1,3 +1,15 @@
2004-09-20 Werner Koch <wk@g10code.com>
* cardglue.c (open_card): Use shutdown code if possible.
(check_card_serialno): Ditto.
* ccid-driver.c (do_close_reader): Factored some code out from ...
(ccid_close_reader): ..here.
(ccid_shutdown_reader): New.
* apdu.c (apdu_shutdown_reader): New.
(shutdown_ccid_reader): New.
2004-09-17 Werner Koch <wk@g10code.com> 2004-09-17 Werner Koch <wk@g10code.com>
* g10.c (list_config): New config option ccid-reader-id. * g10.c (list_config): New config option ccid-reader-id.

View File

@ -92,6 +92,7 @@ struct reader_table_s {
/* Function pointers intialized to the various backends. */ /* Function pointers intialized to the various backends. */
int (*close_reader)(int); int (*close_reader)(int);
int (*shutdown_reader)(int);
int (*reset_reader)(int); int (*reset_reader)(int);
int (*get_status_reader)(int, unsigned int *); int (*get_status_reader)(int, unsigned int *);
int (*send_apdu_reader)(int,unsigned char *,size_t, int (*send_apdu_reader)(int,unsigned char *,size_t,
@ -244,6 +245,7 @@ new_reader_slot (void)
} }
#endif /*USE_GNU_PTH*/ #endif /*USE_GNU_PTH*/
reader_table[reader].close_reader = NULL; reader_table[reader].close_reader = NULL;
reader_table[reader].shutdown_reader = NULL;
reader_table[reader].reset_reader = NULL; reader_table[reader].reset_reader = NULL;
reader_table[reader].get_status_reader = NULL; reader_table[reader].get_status_reader = NULL;
reader_table[reader].send_apdu_reader = NULL; reader_table[reader].send_apdu_reader = NULL;
@ -1201,6 +1203,14 @@ close_ccid_reader (int slot)
} }
static int
shutdown_ccid_reader (int slot)
{
ccid_shutdown_reader (reader_table[slot].ccid.handle);
return 0;
}
static int static int
reset_ccid_reader (int slot) reset_ccid_reader (int slot)
{ {
@ -1300,6 +1310,7 @@ open_ccid_reader (const char *portstr)
} }
reader_table[slot].close_reader = close_ccid_reader; reader_table[slot].close_reader = close_ccid_reader;
reader_table[slot].shutdown_reader = shutdown_ccid_reader;
reader_table[slot].reset_reader = reset_ccid_reader; reader_table[slot].reset_reader = reset_ccid_reader;
reader_table[slot].get_status_reader = get_status_ccid; reader_table[slot].get_status_reader = get_status_ccid;
reader_table[slot].send_apdu_reader = send_apdu_ccid; reader_table[slot].send_apdu_reader = send_apdu_ccid;
@ -2051,6 +2062,19 @@ apdu_close_reader (int slot)
return SW_HOST_NOT_SUPPORTED; return SW_HOST_NOT_SUPPORTED;
} }
/* Shutdown a reader; that is basically the same as a close but keeps
the handle ready for later use. A apdu_reset_header should be used
to get it active again. */
int
apdu_shutdown_reader (int slot)
{
if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
return SW_HOST_NO_DRIVER;
if (reader_table[slot].shutdown_reader)
return reader_table[slot].shutdown_reader (slot);
return SW_HOST_NOT_SUPPORTED;
}
/* Enumerate all readers and return information on whether this reader /* Enumerate all readers and return information on whether this reader
is in use. The caller should start with SLOT set to 0 and is in use. The caller should start with SLOT set to 0 and
increment it with each call until an error is returned. */ increment it with each call until an error is returned. */

View File

@ -76,6 +76,7 @@ int apdu_open_remote_reader (const char *portstr,
void *writefnc_value, void *writefnc_value,
void (*closefnc) (void *opaque), void (*closefnc) (void *opaque),
void *closefnc_value); void *closefnc_value);
int apdu_shutdown_reader (int slot);
int apdu_close_reader (int slot); int apdu_close_reader (int slot);
int apdu_enum_reader (int slot, int *used); int apdu_enum_reader (int slot, int *used);
unsigned char *apdu_get_atr (int slot, size_t *atrlen); unsigned char *apdu_get_atr (int slot, size_t *atrlen);

View File

@ -54,7 +54,6 @@ static APP current_app;
/* Create a serialno/fpr string from the serial number and the secret /* Create a serialno/fpr string from the serial number and the secret
key. caller must free the returned string. There is no error key. caller must free the returned string. There is no error
return. [Taken from 1.9's keyid.c]*/ return. [Taken from 1.9's keyid.c]*/
@ -247,18 +246,25 @@ agent_release_card_info (struct agent_card_info_s *info)
static APP static APP
open_card (void) open_card (void)
{ {
int slot; int slot = -1;
int rc; int rc;
APP app; APP app;
int did_shutdown = 0;
card_close (); card_close ();
retry: retry:
slot = apdu_open_reader (default_reader_port); if (did_shutdown)
if (slot == -1) apdu_reset (slot);
else
{ {
log_error ("card reader not available\n"); slot = apdu_open_reader (default_reader_port);
return NULL; if (slot == -1)
{
log_error ("card reader not available\n");
return NULL;
}
} }
app = xcalloc (1, sizeof *app); app = xcalloc (1, sizeof *app);
@ -268,11 +274,14 @@ open_card (void)
{ {
write_status_text (STATUS_CARDCTRL, "1"); write_status_text (STATUS_CARDCTRL, "1");
did_shutdown = !!apdu_shutdown_reader (slot);
if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay", if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay",
_("Please insert the card and hit return or enter 'c' to cancel: "), _("Please insert the card and hit return or enter 'c' to cancel: "),
1) ) 1) )
{ {
apdu_close_reader (slot); if (!did_shutdown)
apdu_close_reader (slot);
xfree (app); xfree (app);
goto retry; goto retry;
} }
@ -323,7 +332,7 @@ card_close (void)
function return 0 is the present card is okay, -1 if the user function return 0 is the present card is okay, -1 if the user
selected to insert a new card or an error value. Note that the selected to insert a new card or an error value. Note that the
card context will be closed in all cases except for 0 as return card context will be closed in all cases except for 0 as return
value. */ value and if it was possible to merely shutdown the reader. */
static int static int
check_card_serialno (APP app, const char *serialno) check_card_serialno (APP app, const char *serialno)
{ {
@ -346,8 +355,12 @@ check_card_serialno (APP app, const char *serialno)
if (ask) if (ask)
{ {
char buf[5+32+1]; char buf[5+32+1];
int did_shutdown = 0;
card_close (); if (current_app && !apdu_shutdown_reader (current_app->slot))
did_shutdown = 1;
else
card_close ();
tty_printf (_("Please remove the current card and " tty_printf (_("Please remove the current card and "
"insert the one with the serial number:\n" "insert the one with the serial number:\n"
" %.*s\n"), 32, serialno); " %.*s\n"), 32, serialno);
@ -359,7 +372,14 @@ check_card_serialno (APP app, const char *serialno)
_("Hit return when ready " _("Hit return when ready "
"or enter 'c' to cancel: "), "or enter 'c' to cancel: "),
1) ) 1) )
return -1; {
card_close ();
return -1;
}
if (did_shutdown)
apdu_reset (current_app->slot);
else
card_close ();
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
} }
return 0; return 0;

View File

@ -196,6 +196,7 @@ struct ccid_driver_s
int auto_ifsd; int auto_ifsd;
int max_ifsd; int max_ifsd;
int ifsd; int ifsd;
int powered_off;
int has_pinpad; int has_pinpad;
}; };
@ -863,6 +864,102 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid)
} }
static void
do_close_reader (ccid_driver_t handle)
{
int rc;
unsigned char msg[100];
size_t msglen;
unsigned char seqno;
if (!handle->powered_off)
{
msg[0] = PC_to_RDR_IccPowerOff;
msg[5] = 0; /* slot */
msg[6] = seqno = handle->seqno++;
msg[7] = 0; /* RFU */
msg[8] = 0; /* RFU */
msg[9] = 0; /* RFU */
set_msg_len (msg, 0);
msglen = 10;
rc = bulk_out (handle, msg, msglen);
if (!rc)
bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus,seqno);
handle->powered_off = 1;
}
if (handle->idev)
{
usb_release_interface (handle->idev, 0);
usb_close (handle->idev);
handle->idev = NULL;
}
}
/* Reset a reader on HANDLE. This is useful in case a reader has been
plugged of and inserted at a different port. By resetting the
handle, the same reader will be get used. Note, that on error the
handle won't get released.
This does not return an ATR, so ccid_get_atr should be called right
after this one.
*/
int
ccid_shutdown_reader (ccid_driver_t handle)
{
int rc = 0;
struct usb_device *dev = NULL;
usb_dev_handle *idev = NULL;
unsigned char *ifcdesc_extra = NULL;
size_t ifcdesc_extra_len;
if (!handle || !handle->rid)
return CCID_DRIVER_ERR_INV_VALUE;
do_close_reader (handle);
idev = scan_or_find_devices (-1, handle->rid, NULL, &dev,
&ifcdesc_extra, &ifcdesc_extra_len);
if (!idev)
{
DEBUGOUT_1 ("no CCID reader with ID %s\n", handle->rid);
return CCID_DRIVER_ERR_NO_READER;
}
handle->idev = idev;
if (parse_ccid_descriptor (handle, ifcdesc_extra, ifcdesc_extra_len))
{
DEBUGOUT ("device not supported\n");
rc = CCID_DRIVER_ERR_NO_READER;
goto leave;
}
/* fixme: Do we need to claim and set the interface as
determined above? */
rc = usb_claim_interface (idev, 0);
if (rc)
{
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
goto leave;
}
leave:
free (ifcdesc_extra);
if (rc)
{
usb_close (handle->idev);
handle->idev = NULL;
}
return rc;
}
/* Close the reader HANDLE. */ /* Close the reader HANDLE. */
int int
ccid_close_reader (ccid_driver_t handle) ccid_close_reader (ccid_driver_t handle)
@ -870,34 +967,13 @@ ccid_close_reader (ccid_driver_t handle)
if (!handle || !handle->idev) if (!handle || !handle->idev)
return 0; return 0;
{ do_close_reader (handle);
int rc;
unsigned char msg[100];
size_t msglen;
unsigned char seqno;
msg[0] = PC_to_RDR_IccPowerOff;
msg[5] = 0; /* slot */
msg[6] = seqno = handle->seqno++;
msg[7] = 0; /* RFU */
msg[8] = 0; /* RFU */
msg[9] = 0; /* RFU */
set_msg_len (msg, 0);
msglen = 10;
rc = bulk_out (handle, msg, msglen);
if (!rc)
bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno);
}
usb_release_interface (handle->idev, 0);
usb_close (handle->idev);
handle->idev = NULL;
free (handle->rid); free (handle->rid);
free (handle); free (handle);
return 0; return 0;
} }
/* Return False if a card is present and powered. */ /* Return False if a card is present and powered. */
int int
ccid_check_card_presence (ccid_driver_t handle) ccid_check_card_presence (ccid_driver_t handle)
@ -1120,6 +1196,8 @@ ccid_get_atr (ccid_driver_t handle,
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, seqno); rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, seqno);
if (rc) if (rc)
return rc; return rc;
handle->powered_off = 0;
if (atr) if (atr)
{ {
@ -1680,16 +1758,16 @@ main (int argc, char **argv)
ccid_poll (ccid); ccid_poll (ccid);
/* if (!ccid->has_pinpad) */ /* if (!ccid->has_pinpad) */
{ /* { */
fputs ("verifying that CHV1 is 123456....\n", stderr); /* fputs ("verifying that CHV1 is 123456....\n", stderr); */
{ /* { */
static unsigned char apdu[] = {0, 0x20, 0, 0x81, /* static unsigned char apdu[] = {0, 0x20, 0, 0x81, */
6, '1','2','3','4','5','6'}; /* 6, '1','2','3','4','5','6'}; */
rc = ccid_transceive (ccid, apdu, sizeof apdu, /* rc = ccid_transceive (ccid, apdu, sizeof apdu, */
result, sizeof result, &resultlen); /* result, sizeof result, &resultlen); */
print_result (rc, result, resultlen); /* print_result (rc, result, resultlen); */
} /* } */
} /* } */
/* else */ /* else */
/* { */ /* { */
/* fputs ("verifying CHV1 using the PINPad ....\n", stderr); */ /* fputs ("verifying CHV1 using the PINPad ....\n", stderr); */

View File

@ -78,6 +78,7 @@ typedef struct ccid_driver_s *ccid_driver_t;
int ccid_set_debug_level (int level); int ccid_set_debug_level (int level);
char *ccid_get_reader_list (void); char *ccid_get_reader_list (void);
int ccid_open_reader (ccid_driver_t *handle, const char *readerid); int ccid_open_reader (ccid_driver_t *handle, const char *readerid);
int ccid_shutdown_reader (ccid_driver_t handle);
int ccid_close_reader (ccid_driver_t handle); int ccid_close_reader (ccid_driver_t handle);
int ccid_get_atr (ccid_driver_t handle, int ccid_get_atr (ccid_driver_t handle,
unsigned char *atr, size_t maxatrlen, size_t *atrlen); unsigned char *atr, size_t maxatrlen, size_t *atrlen);