[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