Fix for extended length Le in decipher
authorWerner Koch <wk@gnupg.org>
Thu, 3 Sep 2009 10:57:23 +0000 (10:57 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 3 Sep 2009 10:57:23 +0000 (10:57 +0000)
scd/ChangeLog
scd/apdu.c
scd/app-geldkarte.c
scd/app-nks.c
scd/app-openpgp.c
scd/iso7816.c
scd/iso7816.h

index e7bf653..3a421cc 100644 (file)
@@ -1,3 +1,12 @@
+2009-09-03  Werner Koch  <wk@g10code.com>
+
+       * app-openpgp.c (do_decipher): Compute required Le.
+       * iso7816.c (iso7816_decipher): Add new arg LE.
+       * app-nks.c (do_decipher): Adjust for change.
+
+       * iso7816.c (iso7816_put_data, iso7816_put_data_odd): Turn DATA
+       into a void ptr.
+
 2009-08-05  Werner Koch  <wk@g10code.com>
 
        * app-openpgp.c (change_keyattr_from_string): New.
        (iso7816_generate_keypair, iso7816_read_public_key): Ditto.
        Changed all callers.
        * apdu.c (send_le): Implement extended length return values.
-       
+
        * ccid-driver.c (bulk_in): Retry on EAGAIN.
        (abort_cmd): Change seqno handling.
 
index d114b6e..f382aea 100644 (file)
@@ -15,8 +15,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * $Id$
  */
 
 /* NOTE: This module is also used by other software, thus the use of
index 34ce08f..6e8d077 100644 (file)
@@ -274,7 +274,7 @@ bcd_to_int (const unsigned char *string, size_t length, int *result)
 gpg_error_t
 app_select_geldkarte (app_t app)
 {
-  static unsigned char const aid[] =
+  static char const aid[] =
     { 0xD2, 0x76, 0x00, 0x00, 0x25, 0x45, 0x50, 0x02, 0x00 };
   gpg_error_t err;
   int slot = app->slot;
index 1f3aad2..076b913 100644 (file)
@@ -271,7 +271,8 @@ get_chv_status (app_t app, int sigg, int pwid)
   command[2] = 0x00;
   command[3] = pwid;
 
-  if (apdu_send_direct (app->slot, 0, command, 4, 0, &result, &resultlen))
+  if (apdu_send_direct (app->slot, 0, (unsigned char *)command, 
+                        4, 0, &result, &resultlen))
     rc = -1; /* Error. */
   else if (resultlen < 2)
     rc = -1; /* Error. */
@@ -1055,7 +1056,7 @@ do_decipher (app_t app, const char *keyidstr,
      Command chaining does not work.  */
   if (!rc)
     rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0,
-                           indata, indatalen, 0x81,
+                           indata, indatalen, 0, 0x81,
                            outdata, outdatalen);
   return rc;
 }
index 2c10cd9..d468591 100644 (file)
@@ -16,8 +16,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * $Id$
  */
 
 /* Some notes:
@@ -3316,7 +3314,7 @@ do_decipher (app_t app, const char *keyidstr,
   const char *s;
   int n;
   const char *fpr = NULL;
-  int exmode;
+  int exmode, le_value;
 
   if (!keyidstr || !*keyidstr || !indatalen)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -3399,16 +3397,22 @@ do_decipher (app_t app, const char *keyidstr,
           indatalen = fixuplen + indatalen;
           padind = -1; /* Already padded.  */
         }
-      
+
       if (app->app_local->cardcap.ext_lc_le && indatalen > 254 )
-        exmode = 1;    /* Extended length w/o a limit.  */
+        {
+          exmode = 1;    /* Extended length w/o a limit.  */
+          le_value = app->app_local->extcap.max_rsp_data;
+        }
       else if (app->app_local->cardcap.cmd_chaining && indatalen > 254)
-        exmode = -254; /* Command chaining with max. 254 bytes.  */
+        {
+          exmode = -254; /* Command chaining with max. 254 bytes.  */
+          le_value = 0;
+        }
       else
-        exmode = 0;    
+        exmode = le_value = 0;    
 
       rc = iso7816_decipher (app->slot, exmode, 
-                             indata, indatalen, padind,
+                             indata, indatalen, le_value, padind,
                              outdata, outdatalen);
       xfree (fixbuf);
     }
index f1ee0da..e3f2c1b 100644 (file)
@@ -15,8 +15,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * $Id$
  */
 
 #include <config.h>
@@ -460,7 +458,7 @@ iso7816_get_data (int slot, int extended_mode, int tag,
    bytes. */
 gpg_error_t
 iso7816_put_data (int slot, int extended_mode, int tag,
-                  const unsigned char *data, size_t datalen)
+                  const void *data, size_t datalen)
 {
   int sw;
 
@@ -473,7 +471,7 @@ iso7816_put_data (int slot, int extended_mode, int tag,
 /* Same as iso7816_put_data but uses an odd instruction byte.  */
 gpg_error_t
 iso7816_put_data_odd (int slot, int extended_mode, int tag,
-                      const unsigned char *data, size_t datalen)
+                      const void *data, size_t datalen)
 {
   int sw;
 
@@ -545,10 +543,11 @@ iso7816_compute_ds (int slot, int extended_mode,
    indicator to be used.  It should be 0 if no padding is required, a
    value of -1 suppresses the padding byte.  On success 0 is returned
    and the plaintext is available in a newly allocated buffer stored
-   at RESULT with its length stored at RESULTLEN. */
+   at RESULT with its length stored at RESULTLEN.  For LE see
+   do_generate_keypair. */
 gpg_error_t
 iso7816_decipher (int slot, int extended_mode, 
-                  const unsigned char *data, size_t datalen,
+                  const unsigned char *data, size_t datalen, int le,
                   int padind, unsigned char **result, size_t *resultlen)
 {
   int sw;
@@ -559,6 +558,11 @@ iso7816_decipher (int slot, int extended_mode,
   *result = NULL;
   *resultlen = 0;
 
+  if (!extended_mode)
+    le = 256;  /* Ignore provided Le and use what apdu_send uses. */
+  else if (le >= 0 && le < 256)
+    le = 256;
+
   if (padind >= 0)
     {
       /* We need to prepend the padding indicator. */
@@ -568,18 +572,18 @@ iso7816_decipher (int slot, int extended_mode,
       
       *buf = padind; /* Padding indicator. */
       memcpy (buf+1, data, datalen);
-      sw = apdu_send (slot, extended_mode, 
-                      0x00, CMD_PSO, 0x80, 0x86,
-                      datalen+1, (char*)buf,
-                      result, resultlen);
+      sw = apdu_send_le (slot, extended_mode, 
+                         0x00, CMD_PSO, 0x80, 0x86,
+                         datalen+1, (char*)buf, le,
+                         result, resultlen);
       xfree (buf);
     }
   else
     {
-      sw = apdu_send (slot, extended_mode,
-                      0x00, CMD_PSO, 0x80, 0x86,
-                      datalen, (const char *)data,
-                      result, resultlen);
+      sw = apdu_send_le (slot, extended_mode,
+                         0x00, CMD_PSO, 0x80, 0x86,
+                         datalen, (const char *)data, le,
+                         result, resultlen);
     }
   if (sw != SW_SUCCESS)
     {
index 4e7a344..8519712 100644 (file)
@@ -15,8 +15,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * $Id$
  */
 
 #ifndef ISO7816_H
@@ -87,9 +85,9 @@ gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno,
 gpg_error_t iso7816_get_data (int slot, int extended_mode, int tag,
                               unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag,
-                              const unsigned char *data, size_t datalen);
+                              const void *data, size_t datalen);
 gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag,
-                                  const unsigned char *data, size_t datalen);
+                                  const void *data, size_t datalen);
 gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2,
                                          const unsigned char *data,
                                          size_t datalen);
@@ -99,7 +97,7 @@ gpg_error_t iso7816_compute_ds (int slot, int extended_mode,
                                 unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_decipher (int slot, int extended_mode,
                               const unsigned char *data, size_t datalen,
-                              int padind,
+                              int le, int padind,
                               unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode,
                                    const unsigned char *data, size_t datalen,