scd: better handling of extended APDU.
[gnupg.git] / scd / app-p15.c
index f11de59..8322617 100644 (file)
@@ -5,7 +5,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,
@@ -14,9 +14,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/>.
  */
 
 /* Information pertaining to the BELPIC developer card samples:
@@ -692,7 +690,8 @@ read_ef_odf (app_t app, unsigned short odf_fid)
     }
 
   if (buflen)
-    log_info ("warning: %u bytes of garbage detected at end of ODF\n", buflen);
+    log_info ("warning: %u bytes of garbage detected at end of ODF\n",
+              (unsigned int)buflen);
 
   xfree (buffer);
   return 0;
@@ -2364,7 +2363,6 @@ send_certinfo (app_t app, ctrl_t ctrl, const char *certtype,
   for (; certinfo; certinfo = certinfo->next)
     {
       char *buf, *p;
-      int i;
 
       buf = xtrymalloc (9 + certinfo->objidlen*2 + 1);
       if (!buf)
@@ -2376,11 +2374,7 @@ send_certinfo (app_t app, ctrl_t ctrl, const char *certtype,
           p += 5;
         }
       p = stpcpy (p, ".");
-      for (i=0; i < certinfo->objidlen; i++)
-        {
-          sprintf (p, "%02X", certinfo->objid[i]);
-          p += 2;
-        }
+      bin2hex (certinfo->objid, certinfo->objidlen, p);
 
       send_status_info (ctrl, "CERTINFO",
                         certtype, strlen (certtype),
@@ -2459,7 +2453,7 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
     {
       char gripstr[40+1];
       char *buf, *p;
-      int i, j;
+      int j;
 
       buf = xtrymalloc (9 + keyinfo->objidlen*2 + 1);
       if (!buf)
@@ -2471,11 +2465,7 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
           p += 5;
         }
       p = stpcpy (p, ".");
-      for (i=0; i < keyinfo->objidlen; i++)
-        {
-          sprintf (p, "%02X", keyinfo->objid[i]);
-          p += 2;
-        }
+      bin2hex (keyinfo->objid, keyinfo->objidlen, p);
 
       err = keygripstr_from_prkdf (app, keyinfo, gripstr);
       if (err)
@@ -2502,17 +2492,23 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t keyinfo)
 
 /* This is the handler for the LEARN command.  */
 static gpg_error_t 
-do_learn_status (app_t app, ctrl_t ctrl)
+do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 {
   gpg_error_t err;
 
-  err = send_certinfo (app, ctrl, "100", app->app_local->certificate_info);
-  if (!err)
-    err = send_certinfo (app, ctrl, "101",
-                         app->app_local->trusted_certificate_info);
-  if (!err)
-    err = send_certinfo (app, ctrl, "102",
-                         app->app_local->useful_certificate_info);
+  if ((flags & 1))
+    err = 0;
+  else
+    {
+      err = send_certinfo (app, ctrl, "100", app->app_local->certificate_info);
+      if (!err)
+        err = send_certinfo (app, ctrl, "101",
+                             app->app_local->trusted_certificate_info);
+      if (!err)
+        err = send_certinfo (app, ctrl, "102",
+                             app->app_local->useful_certificate_info);
+    }
+
   if (!err)
     err = send_keypairinfo (app, ctrl, app->app_local->private_key_info);
 
@@ -2670,7 +2666,6 @@ static gpg_error_t
 do_getattr (app_t app, ctrl_t ctrl, const char *name)
 {
   gpg_error_t err;
-  int i;
 
   if (!strcmp (name, "$AUTHKEYID"))
     {
@@ -2695,11 +2690,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
               p += 5;
             }
           p = stpcpy (p, ".");
-          for (i=0; i < prkdf->objidlen; i++)
-            {
-              sprintf (p, "%02X", prkdf->objid[i]);
-              p += 2;
-            }
+          bin2hex (prkdf->objid, prkdf->objidlen, p);
 
           send_status_info (ctrl, name, buf, strlen (buf), NULL, 0);
           xfree (buf);
@@ -2918,7 +2909,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (aodf->pinflags.integrity_protected
       || aodf->pinflags.confidentiality_protected)
     {
-      log_error ("PIN verification requires unsupported protecion method\n");
+      log_error ("PIN verification requires unsupported protection method\n");
       return gpg_error (GPG_ERR_BAD_PIN_METHOD);
     }
   if (!aodf->stored_length && aodf->pinflags.needs_padding)
@@ -2949,7 +2940,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       
       mse[0] = 4;    /* Length of the template. */
       mse[1] = 0x80; /* Algorithm reference tag. */
-      if (hashalgo == GCRY_MD_USER_TLS_MD5SHA1)
+      if (hashalgo == MD_USER_TLS_MD5SHA1)
         mse[2] = 0x01; /* Let card do pkcs#1 0xFF padding. */
       else
         mse[2] = 0x02; /* RSASSA-PKCS1-v1.5 using SHA1. */
@@ -3125,7 +3116,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (indatalen == 36)
     {
       /* No ASN.1 container used. */
-      if (hashalgo != GCRY_MD_USER_TLS_MD5SHA1)
+      if (hashalgo != MD_USER_TLS_MD5SHA1)
         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
       memcpy (data, indata, indatalen);
     }
@@ -3188,12 +3179,12 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       return err;
     }
 
-  if (hashalgo == GCRY_MD_USER_TLS_MD5SHA1)
-    err = iso7816_compute_ds (app->slot, data, 36, outdata, outdatalen);
+  if (hashalgo == MD_USER_TLS_MD5SHA1)
+    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;
 }
 
@@ -3227,7 +3218,7 @@ do_auth (app_t app, const char *keyidstr,
       return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
     }
 
-  algo = indatalen == 36? GCRY_MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1;
+  algo = indatalen == 36? MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1;
   return do_sign (app, keyidstr, algo, pincb, pincb_arg, 
                   indata, indatalen, outdata, outdatalen);
 }