Fixed the card removed with cached app bug. (Famous last fix).
[gnupg.git] / scd / ccid-driver.c
index 33de492..57e617a 100644 (file)
@@ -6,7 +6,7 @@
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  *
  * ALTERNATIVELY, this file may be distributed under the terms of the
  * following license, in which case the provisions of this license are
@@ -284,7 +282,7 @@ set_msg_len (unsigned char *msg, unsigned int length)
 
 
 /* Pint an error message for a failed CCID command including a textual
-   error code.  MSG is shall be the CCID message of at least 10 bytes. */
+   error code.  MSG shall be the CCID message at a minimum of 10 bytes. */
 static void
 print_command_failed (const unsigned char *msg)
 {
@@ -1355,7 +1353,7 @@ ccid_close_reader (ccid_driver_t handle)
 int
 ccid_check_card_presence (ccid_driver_t handle)
 {
-
+  (void)handle;  /* Not yet implemented.  */
   return -1;
 }
 
@@ -1709,6 +1707,8 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
 }
 
 
+/* Return the ATR of the card.  This is not a cached value and thus an
+   actual reset is done.  */
 int 
 ccid_get_atr (ccid_driver_t handle,
               unsigned char *atr, size_t maxatrlen, size_t *atrlen)
@@ -1732,7 +1732,6 @@ ccid_get_atr (ccid_driver_t handle,
   if (statusbits == 2)
     return CCID_DRIVER_ERR_NO_CARD;
 
-    
   /* For an inactive and also for an active card, issue the PowerOn
      command to get the ATR.  */
  again:
@@ -1959,7 +1958,7 @@ ccid_transceive_apdu_level (ccid_driver_t handle,
                             size_t *nresp)
 {
   int rc;
-  unsigned char send_buffer[10+259], recv_buffer[10+259];
+  unsigned char send_buffer[10+261], recv_buffer[10+261];
   const unsigned char *apdu;
   size_t apdulen;
   unsigned char *msg;
@@ -1973,7 +1972,10 @@ ccid_transceive_apdu_level (ccid_driver_t handle,
   apdulen = apdu_buflen;
   assert (apdulen);
 
-  if (apdulen > 254)
+  /* The maximum length for a short APDU T=1 block is 261.  For an
+     extended APDU T=1 block the maximum length 65544; however
+     extended APDU exchange levele is not yet supported.  */
+  if (apdulen > 261)
     return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
 
   msg[0] = PC_to_RDR_XfrBlock;
@@ -2119,7 +2121,11 @@ ccid_transceive (ccid_driver_t handle,
           assert (apdulen);
 
           /* Construct an I-Block. */
-          if (apdulen > 254)
+          /* Fixme: I am not sure whether limiting the length to 259
+             as per CCID spec is required.  The code blow chops the
+             APDU anyway into 128 byte blocks.  Needs to be addressed
+             when supporting extended length APDUs. */
+          if (apdulen > 259)
             return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
 
           tpdu = msg+10;