[PATCH] pcsc pinpad support (part 1)
NIIBE Yutaka
gniibe at fsij.org
Thu Jan 13 03:06:57 CET 2011
Hi,
I am submitting a series of patches for pcsc pinpad support.
While I am sure that I have done copyright paper work to FSF for
Emacs, GCC, etc., I am not sure that I have filed for GnuPG. Please
instruct me, if any paper work is required.
The first patch is adding pcsc_control handle and two fields to
reader_table_s structure; verify_ioctl and modify_ioctl which
correspond to the operations of PIN Verification and PIN Modification.
(In the forthcoming another patch,) the value of verify_ioctl and
modify_ioctl will be filled using pcsc_control. Since the value is in
the format of big-endian TLV (Tag-Length-Value), convert_be_u32 is
added.
This patch is generated by "git format-patch" command. No, it's not
attachment (sorry for my previous mail where I said "attach"), as I
think it would be better for git users.
Compilation tested on Debian GNU/Linux. I don't have development
environment on Windows.
Lastly, thanks to Nils Faerber for the encouragement.
2011-01-13 NIIBE Yutaka <gniibe at fsij.org>
* pcsc-wrapper.c (pcsc_control): New.
(load_pcsc_driver): Initialize pcsc_control.
* apdu.c (struct reader_table_s): Add fields verify_ioctl and
modify_ioctl in pcsc.
(new_reader_slot): Initialize them.
(convert_be_u32): New.
(pcsc_control): New.
(apdu_open_reader): Initialize pcsc_control.
---
scd/apdu.c | 26 ++++++++++++++++++++++++--
scd/pcsc-wrapper.c | 14 ++++++++++++--
3 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/scd/apdu.c b/scd/apdu.c
index 80c933e..cd8a192 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -117,6 +117,8 @@ struct reader_table_s {
unsigned long context;
unsigned long card;
unsigned long protocol;
+ unsigned long verify_ioctl;
+ unsigned long modify_ioctl;
#ifdef NEED_PCSC_WRAPPER
int req_fd;
int rsp_fd;
@@ -303,6 +305,13 @@ long (* DLSTDCALL pcsc_transmit) (unsigned long card,
unsigned long *recv_len);
long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
unsigned long timeout);
+long (* DLSTDCALL 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);
/* Prototypes. */
@@ -367,6 +376,8 @@ new_reader_slot (void)
reader_table[reader].pcsc.rsp_fd = -1;
reader_table[reader].pcsc.pid = (pid_t)(-1);
#endif
+ reader_table[slot].pcsc.verify_ioctl = 0;
+ reader_table[slot].pcsc.modify_ioctl = 0;
return reader;
}
@@ -1261,6 +1272,14 @@ close_pcsc_reader (int slot)
/* Connect a PC/SC card. */
#ifndef NEED_PCSC_WRAPPER
+/* Convert a big endian stored 4 byte value into an unsigned
+ integer. */
+static unsigned int
+convert_be_u32 (const unsigned char *buf)
+{
+ return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
+
static int
connect_pcsc_card (int slot)
{
@@ -2438,6 +2457,7 @@ apdu_open_reader (const char *portstr)
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
@@ -2450,12 +2470,13 @@ apdu_open_reader (const char *portstr)
|| !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. */
log_error ("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,
@@ -2467,7 +2488,8 @@ apdu_open_reader (const char *portstr)
!!pcsc_begin_transaction,
!!pcsc_end_transaction,
!!pcsc_transmit,
- !!pcsc_set_timeout );
+ !!pcsc_set_timeout,
+ !!pcsc_control );
dlclose (handle);
return -1;
}
diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c
index a7b2198..a61fde1 100644
--- a/scd/pcsc-wrapper.c
+++ b/scd/pcsc-wrapper.c
@@ -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);
}
--
1.7.2.3
More information about the Gnupg-devel
mailing list