1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

PC/SC pinpad support.

Before this change, it is layered like following:

	iso7816_verify
        iso7816_verify_kp
	apdu_send_simple, apdu_send_simple_kp
	...

After this change, it will be layered like:

	iso7816_verify      iso7816_verify_kp
        apdu_send_simple    apdu_keypad_verify
	...

and apdu_send_simple_kp will be deprecated.

For PC/SC API, we use:
  SCardControl API to compose CCID PC_to_RDR_Secure message
  SCardTransmit API to compose CCID PC_to_RDR_XfrBlock message

Considering the support of PC/SC, we have nothing to share between _kp
version of iso7816_* and no _kp version.
This commit is contained in:
NIIBE Yutaka 2011-11-28 16:16:38 +09:00
parent 0689f0fc32
commit 26b4a012e3
9 changed files with 460 additions and 25 deletions

View file

@ -178,6 +178,13 @@ long (* pcsc_transmit) (unsigned long card,
unsigned long *recv_len);
long (* pcsc_set_timeout) (unsigned long context,
unsigned long timeout);
long (* pcsc_control) (unsigned long card,
unsigned long control_code,
const void *send_buffer,
unsigned long send_len,
void *recv_buffer,
unsigned long recv_len,
unsigned long *bytes_returned);
@ -335,6 +342,7 @@ load_pcsc_driver (const char *libname)
pcsc_end_transaction = dlsym (handle, "SCardEndTransaction");
pcsc_transmit = dlsym (handle, "SCardTransmit");
pcsc_set_timeout = dlsym (handle, "SCardSetTimeout");
pcsc_control = dlsym (handle, "SCardControl");
if (!pcsc_establish_context
|| !pcsc_release_context
@ -347,13 +355,14 @@ load_pcsc_driver (const char *libname)
|| !pcsc_begin_transaction
|| !pcsc_end_transaction
|| !pcsc_transmit
|| !pcsc_control
/* || !pcsc_set_timeout */)
{
/* Note that set_timeout is currently not used and also not
available under Windows. */
fprintf (stderr,
"apdu_open_reader: invalid PC/SC driver "
"(%d%d%d%d%d%d%d%d%d%d%d%d)\n",
"(%d%d%d%d%d%d%d%d%d%d%d%d%d)\n",
!!pcsc_establish_context,
!!pcsc_release_context,
!!pcsc_list_readers,
@ -365,7 +374,8 @@ load_pcsc_driver (const char *libname)
!!pcsc_begin_transaction,
!!pcsc_end_transaction,
!!pcsc_transmit,
!!pcsc_set_timeout );
!!pcsc_set_timeout,
!!pcsc_control );
dlclose (handle);
exit (1);
}
@ -720,6 +730,38 @@ handle_transmit (unsigned char *argbuf, size_t arglen)
}
/* Handle a control request. The argument is expected to be a buffer
which contains CONTROL_CODE (4-byte) and INPUT_BYTES.
*/
static void
handle_control (unsigned char *argbuf, size_t arglen)
{
long err;
unsigned long ioctl_code;
unsigned long recv_len = 1024;
unsigned char buffer[1024];
if (arglen < 4)
bad_request ("CONTROL");
ioctl_code = (argbuf[0] << 24) | (argbuf[1] << 16) | (argbuf[2] << 8) | argbuf[3];
argbuf += 4;
arglen -= 4;
recv_len = sizeof (buffer);
err = pcsc_control (pcsc_card, ioctl_code, argbuf, arglen,
buffer, recv_len, &recv_len);
if (err)
{
if (verbose)
fprintf (stderr, PGM": pcsc_control failed: %s (0x%lx)\n",
pcsc_error_string (err), err);
request_failed (err);
return;
}
request_succeeded (buffer, recv_len);
}
static void
print_version (int with_help)
@ -831,6 +873,10 @@ main (int argc, char **argv)
handle_reset (argbuffer, arglen);
break;
case 6:
handle_control (argbuffer, arglen);
break;
default:
fprintf (stderr, PGM ": invalid request 0x%02X\n", c);
exit (1);