mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
(reader_table_s): Add function pointers for the backends.
(apdu_close_reader, apdu_get_status, apdu_activate) (send_apdu): Make use of them. (new_reader_slot): Intialize them to NULL. (dump_ccid_reader_status, ct_dump_reader_status): New. (dump_pcsc_reader_status): New. (open_ct_reader, open_pcsc_reader, open_ccid_reader) (open_osc_reader, open_rapdu_reader): Intialize function pointers. (ct_activate_card, ct_send_apdu, pcsc_send_apdu, osc_send_apdu) (error_string): Removed. Replaced by apdu_strerror. (get_ccid_error_string): Removed. (ct_activate_card): Remove the unused loop. (reset_ct_reader): Implemented. (ct_send_apdu): Activate the card if not yet done. (pcsc_send_apdu): Ditto.
This commit is contained in:
parent
c4e52b1531
commit
8add759d64
@ -1,3 +1,46 @@
|
||||
2004-07-16 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* apdu.c (reader_table_s): Add function pointers for the backends.
|
||||
(apdu_close_reader, apdu_get_status, apdu_activate)
|
||||
(send_apdu): Make use of them.
|
||||
(new_reader_slot): Intialize them to NULL.
|
||||
(dump_ccid_reader_status, ct_dump_reader_status): New.
|
||||
(dump_pcsc_reader_status): New.
|
||||
(open_ct_reader, open_pcsc_reader, open_ccid_reader)
|
||||
(open_osc_reader, open_rapdu_reader): Intialize function pointers.
|
||||
(ct_activate_card, ct_send_apdu, pcsc_send_apdu, osc_send_apdu)
|
||||
(error_string): Removed. Replaced by apdu_strerror.
|
||||
(get_ccid_error_string): Removed.
|
||||
(ct_activate_card): Remove the unused loop.
|
||||
(reset_ct_reader): Implemented.
|
||||
(ct_send_apdu): Activate the card if not yet done.
|
||||
(pcsc_send_apdu): Ditto.
|
||||
|
||||
2004-07-15 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* ccid-driver.h: Add error codes.
|
||||
* ccid-driver.c: Implement more or less proper error codes all
|
||||
over the place.
|
||||
|
||||
* apdu.c (apdu_send_direct): New.
|
||||
(get_ccid_error_string): Add some error code mappings.
|
||||
(send_apdu): Pass error codes along for drivers already supporting
|
||||
them.
|
||||
(host_sw_string): New.
|
||||
(get_ccid_error_string): Use above.
|
||||
(send_apdu_ccid): Reset the reader if it has not yet been done.
|
||||
(open_ccid_reader): Don't care if the ATR can't be read.
|
||||
(apdu_activate_card): New.
|
||||
(apdu_strerror): New.
|
||||
(dump_reader_status): Only enable it with opt.VERBOSE.
|
||||
* iso7816.c (map_sw): Add mappings for the new error codes.
|
||||
|
||||
2004-07-02 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* apdu.c (open_ct_reader, open_pcsc_reader, open_ccid_reader)
|
||||
(reset_ccid_reader, open_osc_reader): Call dump_reader_status only
|
||||
in verbose mode.
|
||||
|
||||
2004-07-01 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* sc-investigate.c: Initialize Pth which is now required.
|
||||
|
1707
scd/apdu.c
1707
scd/apdu.c
File diff suppressed because it is too large
Load Diff
27
scd/apdu.h
27
scd/apdu.h
@ -53,19 +53,38 @@ enum {
|
||||
SW_HOST_NO_DRIVER = 0x10004,
|
||||
SW_HOST_NOT_SUPPORTED = 0x10005,
|
||||
SW_HOST_LOCKING_FAILED= 0x10006,
|
||||
SW_HOST_BUSY = 0x10007
|
||||
SW_HOST_BUSY = 0x10007,
|
||||
SW_HOST_NO_CARD = 0x10008,
|
||||
SW_HOST_CARD_INACTIVE = 0x10009,
|
||||
SW_HOST_CARD_IO_ERROR = 0x1000a,
|
||||
SW_HOST_GENERAL_ERROR = 0x1000b,
|
||||
SW_HOST_NO_READER = 0x1000c
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Note , that apdu_open_reader returns no status word but -1 on error. */
|
||||
int apdu_open_reader (const char *portstr);
|
||||
int apdu_open_remote_reader (const char *portstr,
|
||||
const unsigned char *cookie, size_t length,
|
||||
int (*readfnc) (void *opaque,
|
||||
void *buffer, size_t size),
|
||||
void *readfnc_value,
|
||||
int (*writefnc) (void *opaque,
|
||||
const void *buffer, size_t size),
|
||||
void *writefnc_value,
|
||||
void (*closefnc) (void *opaque),
|
||||
void *closefnc_value);
|
||||
int apdu_close_reader (int slot);
|
||||
int apdu_enum_reader (int slot, int *used);
|
||||
unsigned char *apdu_get_atr (int slot, size_t *atrlen);
|
||||
|
||||
const char *apdu_strerror (int rc);
|
||||
|
||||
/* The apdu send functions do return status words. */
|
||||
|
||||
/* These apdu functions do return status words. */
|
||||
|
||||
int apdu_activate (int slot);
|
||||
int apdu_reset (int slot);
|
||||
int apdu_get_status (int slot, int hang,
|
||||
unsigned int *status, unsigned int *changed);
|
||||
@ -77,6 +96,10 @@ int apdu_send (int slot, int class, int ins, int p0, int p1,
|
||||
int apdu_send_le (int slot, int class, int ins, int p0, int p1,
|
||||
int lc, const char *data, int le,
|
||||
unsigned char **retbuf, size_t *retbuflen);
|
||||
int apdu_send_direct (int slot,
|
||||
const unsigned char *apdudata, size_t apdudatalen,
|
||||
int handle_more,
|
||||
unsigned char **retbuf, size_t *retbuflen);
|
||||
|
||||
|
||||
#endif /*APDU_H*/
|
||||
|
@ -442,11 +442,11 @@ read_device_info (ccid_driver_t handle, struct usb_device *dev)
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; /* No suitable device found. */
|
||||
return CCID_DRIVER_ERR_NO_READER; /* No suitable device found. */
|
||||
}
|
||||
|
||||
|
||||
/* Open the reader with the internal number READERNO and return a a
|
||||
/* Open the reader with the internal number READERNO and return a
|
||||
pointer to be used as handle in HANDLE. Returns 0 on success. */
|
||||
int
|
||||
ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
@ -469,7 +469,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
if (rc)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_create_match failed: %d\n", rc);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_NO_READER;
|
||||
}
|
||||
|
||||
while (usb_find_device(match, dev, &dev) >= 0)
|
||||
@ -482,7 +482,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
if (!*handle)
|
||||
{
|
||||
DEBUGOUT ("out of memory\n");
|
||||
rc = -1;
|
||||
rc = CCID_DRIVER_ERR_OUT_OF_CORE;
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
goto leave;
|
||||
@ -503,6 +503,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
DEBUGOUT_1 ("usb_open failed: %d\n", rc);
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -515,6 +516,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -605,7 +607,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen)
|
||||
DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno));
|
||||
else
|
||||
DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -631,7 +633,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
||||
if (rc < 0)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno));
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
|
||||
*nread = msglen = rc;
|
||||
@ -639,23 +641,23 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
||||
if (msglen < 10)
|
||||
{
|
||||
DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
if (buffer[0] != expected_type)
|
||||
{
|
||||
DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
if (buffer[5] != 0)
|
||||
{
|
||||
DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
if (buffer[6] != seqno)
|
||||
{
|
||||
DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n",
|
||||
seqno, buffer[6]);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80)
|
||||
@ -672,6 +674,13 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
||||
DEBUGOUT_CONT_1 (" %02X", buffer[i]);
|
||||
DEBUGOUT_LF ();
|
||||
|
||||
switch ((buffer[7] & 0x03))
|
||||
{
|
||||
case 0: /* no error */ break;
|
||||
case 1: return CCID_DRIVER_ERR_CARD_INACTIVE;
|
||||
case 2: return CCID_DRIVER_ERR_NO_CARD;
|
||||
case 3: /* RFU */ break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -695,7 +704,7 @@ ccid_poll (ccid_driver_t handle)
|
||||
if (rc < 0)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno));
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
|
||||
msglen = rc;
|
||||
@ -704,7 +713,7 @@ ccid_poll (ccid_driver_t handle)
|
||||
if (msglen < 1)
|
||||
{
|
||||
DEBUGOUT ("intr-in msg too short\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
if (msg[0] == RDR_to_PC_NotifySlotChange)
|
||||
@ -731,7 +740,8 @@ ccid_poll (ccid_driver_t handle)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Note that this fucntion won't return the error codes NO_CARD or
|
||||
CARD_INACTIVE */
|
||||
int
|
||||
ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
||||
{
|
||||
@ -752,7 +762,8 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno);
|
||||
if (rc)
|
||||
if (rc && rc != CCID_DRIVER_ERR_NO_CARD
|
||||
&& rc != CCID_DRIVER_ERR_CARD_INACTIVE)
|
||||
return rc;
|
||||
*statusbits = (msg[7] & 3);
|
||||
|
||||
@ -1018,7 +1029,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
|
||||
/* Construct an I-Block. */
|
||||
if (apdulen > 254)
|
||||
return -1; /* Invalid length. */
|
||||
return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
|
||||
|
||||
tpdu = msg+10;
|
||||
/* NAD: DAD=1, SAD=0 */
|
||||
@ -1082,7 +1093,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
if (tpdulen < 4)
|
||||
{
|
||||
DEBUGOUT ("cannot yet handle short blocks!\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_T1
|
||||
@ -1132,7 +1143,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
DEBUGOUT_2 ("provided buffer too short for received data "
|
||||
"(%u/%u)\n",
|
||||
(unsigned int)n, (unsigned int)maxresplen);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
memcpy (resp, p, n);
|
||||
@ -1163,7 +1174,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
if (++retries > 3)
|
||||
{
|
||||
DEBUGOUT ("3 failed retries\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
msg = send_buffer;
|
||||
tpdulen = last_tpdulen;
|
||||
@ -1171,7 +1182,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns)
|
||||
{ /* Reponse does not match our sequence number. */
|
||||
DEBUGOUT ("R-block with wrong seqno received on more bit\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
else if (sending)
|
||||
{ /* Send next chunk. */
|
||||
@ -1183,7 +1194,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
else
|
||||
{
|
||||
DEBUGOUT ("unexpected ACK R-block received\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1210,7 +1221,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
DEBUGOUT_1 ("T1 waittime extension of bwi=%d\n", bwi);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
} /* end T=1 protocol loop. */
|
||||
|
||||
|
@ -55,6 +55,22 @@
|
||||
#ifndef CCID_DRIVER_H
|
||||
#define CCID_DRIVER_H
|
||||
|
||||
/* The CID driver returns the same error codes as the statsu words
|
||||
used by GnuPG's apdu.h. For ease of maintenance they should always
|
||||
match. */
|
||||
#define CCID_DRIVER_ERR_OUT_OF_CORE 0x10001
|
||||
#define CCID_DRIVER_ERR_INV_VALUE 0x10002
|
||||
#define CCID_DRIVER_ERR_INCOMPLETE_CARD_RESPONSE = 0x10003
|
||||
#define CCID_DRIVER_ERR_NO_DRIVER 0x10004
|
||||
#define CCID_DRIVER_ERR_NOT_SUPPORTED 0x10005
|
||||
#define CCID_DRIVER_ERR_LOCKING_FAILED 0x10006
|
||||
#define CCID_DRIVER_ERR_BUSY 0x10007
|
||||
#define CCID_DRIVER_ERR_NO_CARD 0x10008
|
||||
#define CCID_DRIVER_ERR_CARD_INACTIVE 0x10009
|
||||
#define CCID_DRIVER_ERR_CARD_IO_ERROR 0x1000a
|
||||
#define CCID_DRIVER_ERR_GENERAL_ERROR 0x1000b
|
||||
#define CCID_DRIVER_ERR_NO_READER 0x1000c
|
||||
|
||||
|
||||
struct ccid_driver_s;
|
||||
typedef struct ccid_driver_s *ccid_driver_t;
|
||||
|
@ -85,6 +85,12 @@ map_sw (int sw)
|
||||
case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break;
|
||||
case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break;
|
||||
case SW_HOST_BUSY: ec = GPG_ERR_EBUSY; break;
|
||||
case SW_HOST_NO_CARD: ec = GPG_ERR_CARD_NOT_PRESENT; break;
|
||||
case SW_HOST_CARD_INACTIVE: ec = GPG_ERR_CARD_RESET; break;
|
||||
case SW_HOST_CARD_IO_ERROR: ec = GPG_ERR_EIO; break;
|
||||
case SW_HOST_GENERAL_ERROR: ec = GPG_ERR_GENERAL; break;
|
||||
case SW_HOST_NO_READER: ec = GPG_ERR_ENODEV; break;
|
||||
|
||||
default:
|
||||
if ((sw & 0x010000))
|
||||
ec = GPG_ERR_GENERAL; /* Should not happen. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user