Fix for card keys > 2048 bit.
authorWerner Koch <wk@gnupg.org>
Fri, 10 Jul 2009 10:15:33 +0000 (10:15 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 10 Jul 2009 10:15:33 +0000 (10:15 +0000)
scd/ChangeLog
scd/app-dinsig.c
scd/app-nks.c
scd/app-openpgp.c
scd/app-p15.c
scd/iso7816.c
scd/iso7816.h

index 94e1ebd..2745311 100644 (file)
@@ -1,3 +1,12 @@
+2009-07-10  Werner Koch  <wk@g10code.com>
+
+       * iso7816.c (iso7816_compute_ds): Add args EXTENDED_MODE and LE.
+       Change all callers to use 0.
+       (iso7816_internal_authenticate): Add args EXTENDED_MODE and LE.
+       * app-openpgp.c (do_sign): Take exmode and Le from card
+       capabilities and pass them to iso7816_compute_ds.
+       (do_auth): Ditto for iso7816_internal_authenticate.
+
 2009-07-09  Werner Koch  <wk@g10code.com>
 
        * app-openpgp.c (change_keyattr): New.
index f0655bb..46e9a6a 100644 (file)
@@ -483,7 +483,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 
   rc = verify_pin (app, pincb, pincb_arg);
   if (!rc)
-    rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen);
+    rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0, 
+                             outdata, outdatalen);
   return rc;
 }
 
index 53435c3..1f3aad2 100644 (file)
@@ -969,7 +969,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
     rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
   /* Compute the signature.  */
   if (!rc)
-    rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen);
+    rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0,
+                             outdata, outdatalen);
   return rc;
 }
 
index 9620d5b..134679b 100644 (file)
@@ -3008,6 +3008,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   const char *fpr = NULL;
   unsigned long sigcount;
   int use_auth = 0;
+  int exmode, le_value;
 
   if (!keyidstr || !*keyidstr)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -3148,7 +3149,19 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       xfree (pinvalue);
     }
 
-  rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen);
+
+  if (app->app_local->cardcap.ext_lc_le)
+    {
+      exmode = 1;    /* Use extended length.  */
+      le_value = app->app_local->extcap.max_rsp_data;
+    }
+  else
+    {
+      exmode = 0;
+      le_value = 0; 
+    }
+  rc = iso7816_compute_ds (app->slot, exmode, data, datalen, le_value,
+                           outdata, outdatalen);
   return rc;
 }
 
@@ -3219,8 +3232,23 @@ do_auth (app_t app, const char *keyidstr,
 
   rc = verify_chv2 (app, pincb, pincb_arg);
   if (!rc)
-    rc = iso7816_internal_authenticate (app->slot, indata, indatalen,
-                                        outdata, outdatalen);
+    {
+      int exmode, le_value;
+
+      if (app->app_local->cardcap.ext_lc_le)
+        {
+          exmode = 1;    /* Use extended length.  */
+          le_value = app->app_local->extcap.max_rsp_data;
+        }
+      else
+        {
+          exmode = 0;
+          le_value = 0; 
+        }
+      rc = iso7816_internal_authenticate (app->slot, exmode,
+                                          indata, indatalen, le_value,
+                                          outdata, outdatalen);
+    }
   return rc;
 }
 
index 62404be..7d83293 100644 (file)
@@ -3180,11 +3180,11 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
     }
 
   if (hashalgo == MD_USER_TLS_MD5SHA1)
-    err = iso7816_compute_ds (app->slot, data, 36, outdata, outdatalen);
+    err = iso7816_compute_ds (app->slot, 0, data, 36, 0, outdata, outdatalen);
   else if (no_data_padding)
-    err = iso7816_compute_ds (app->slot, data+15, 20, outdata, outdatalen);
+    err = iso7816_compute_ds (app->slot, 0, data+15, 20, 0,outdata,outdatalen);
   else
-    err = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
+    err = iso7816_compute_ds (app->slot, 0, data, 35, 0, outdata, outdatalen);
   return err;
 }
 
index 3fea6c7..f1ee0da 100644 (file)
@@ -505,9 +505,10 @@ iso7816_manage_security_env (int slot, int p1, int p2,
 /* Perform the security operation COMPUTE DIGITAL SIGANTURE.  On
    success 0 is returned and the data is availavle in a newly
    allocated buffer stored at RESULT with its length stored at
-   RESULTLEN. */
+   RESULTLEN.  For LE see do_generate_keypair. */
 gpg_error_t
-iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen,
+iso7816_compute_ds (int slot, int extended_mode,
+                    const unsigned char *data, size_t datalen, int le,
                     unsigned char **result, size_t *resultlen)
 {
   int sw;
@@ -517,9 +518,16 @@ iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen,
   *result = NULL;
   *resultlen = 0;
 
-  sw = apdu_send (slot, 0, 
-                  0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data,
-                  result, resultlen);
+  if (!extended_mode)
+    le = 256;  /* Ignore provided Le and use what apdu_send uses. */
+  else if (le >= 0 && le < 256)
+    le = 256;
+
+  sw = apdu_send_le (slot, extended_mode, 
+                     0x00, CMD_PSO, 0x9E, 0x9A,
+                     datalen, (const char*)data,
+                     le,
+                     result, resultlen);
   if (sw != SW_SUCCESS)
     {
       /* Make sure that pending buffers are released. */
@@ -586,9 +594,11 @@ iso7816_decipher (int slot, int extended_mode,
 }
 
 
+/*  For LE see do_generate_keypair.  */
 gpg_error_t
-iso7816_internal_authenticate (int slot,
+iso7816_internal_authenticate (int slot, int extended_mode,
                                const unsigned char *data, size_t datalen,
+                               int le,
                                unsigned char **result, size_t *resultlen)
 {
   int sw;
@@ -598,8 +608,16 @@ iso7816_internal_authenticate (int slot,
   *result = NULL;
   *resultlen = 0;
 
-  sw = apdu_send (slot, 0, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
-                  datalen, (const char*)data,  result, resultlen);
+  if (!extended_mode)
+    le = 256;  /* Ignore provided Le and use what apdu_send uses. */
+  else if (le >= 0 && le < 256)
+    le = 256;
+
+  sw = apdu_send_le (slot, extended_mode,
+                     0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
+                     datalen, (const char*)data,
+                     le,
+                     result, resultlen);
   if (sw != SW_SUCCESS)
     {
       /* Make sure that pending buffers are released. */
index d3deda1..4e7a344 100644 (file)
@@ -93,15 +93,17 @@ gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag,
 gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2,
                                          const unsigned char *data,
                                          size_t datalen);
-gpg_error_t iso7816_compute_ds (int slot,
+gpg_error_t iso7816_compute_ds (int slot, int extended_mode,
                                 const unsigned char *data, size_t datalen,
+                                int le,
                                 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,
                               unsigned char **result, size_t *resultlen);
-gpg_error_t iso7816_internal_authenticate (int slot,
+gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode,
                                    const unsigned char *data, size_t datalen,
+                                   int le,
                                    unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_generate_keypair (int slot, int extended_mode,
                                     const unsigned char *data, size_t datalen,