Make most of the selftests work.
[gnupg.git] / agent / learncard.c
index 8b2c7ad..77f2bb0 100644 (file)
@@ -1,11 +1,11 @@
 /* learncard.c - Handle the LEARN command
- *     Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  * 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/>.
  */
 
 #include <config.h>
@@ -34,7 +32,8 @@
 
 /* Structures used by the callback mechanism to convey information
    pertaining to key pairs.  */
-struct keypair_info_s {
+struct keypair_info_s 
+{
   struct keypair_info_s *next;
   int no_cert;
   char *id;          /* points into grip */
@@ -45,13 +44,14 @@ struct keypair_info_s {
 };
 typedef struct keypair_info_s *KEYPAIR_INFO;
 
-struct kpinfo_cb_parm_s {
+struct kpinfo_cb_parm_s 
+{
+  ctrl_t ctrl;
   int error;
   KEYPAIR_INFO info;
 };
 
 
-
 /* Structures used by the callback mechanism to convey information
    pertaining to certificates.  */
 struct certinfo_s {
@@ -62,7 +62,9 @@ struct certinfo_s {
 };
 typedef struct certinfo_s *CERTINFO;
 
-struct certinfo_cb_parm_s {
+struct certinfo_cb_parm_s 
+{
+  ctrl_t ctrl;
   int error;
   CERTINFO info;
 };
@@ -78,7 +80,7 @@ struct sinfo_s {
 typedef struct sinfo_s *SINFO;  
 
 struct sinfo_cb_parm_s {
-  int error;;
+  int error;
   SINFO info;
 };
 
@@ -132,6 +134,11 @@ kpinfo_cb (void *opaque, const char *line)
 
   if (parm->error)
     return; /* no need to gather data after an error coccured */
+
+  if ((parm->error = agent_write_status (parm->ctrl, "PROGRESS",
+                                         "learncard", "k", "0", "0", NULL)))
+    return;
+
   item = xtrycalloc (1, sizeof *item + strlen (line));
   if (!item)
     {
@@ -185,6 +192,10 @@ certinfo_cb (void *opaque, const char *line)
   if (parm->error)
     return; /* no need to gather data after an error coccured */
 
+  if ((parm->error = agent_write_status (parm->ctrl, "PROGRESS",
+                                         "learncard", "c", "0", "0", NULL)))
+    return;
+
   type = strtol (line, &p, 10);
   while (spacep (p))
     p++;
@@ -251,9 +262,23 @@ send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context)
   rc = agent_card_readcert (ctrl, id, &derbuf, &derbuflen);
   if (rc)
     {
-      log_error ("error reading certificate: %s\n",
-                 gpg_strerror (rc));
-      return rc;
+      const char *action;
+
+      switch (gpg_err_code (rc))
+        {
+        case GPG_ERR_INV_ID:
+        case GPG_ERR_NOT_FOUND:
+          action = " - ignored";
+          break;
+        default:
+          action = "";
+          break;
+        }
+      if (opt.verbose || !*action)
+        log_info ("error reading certificate `%s': %s%s\n",
+                  id? id:"?", gpg_strerror (rc), action);
+
+      return *action? 0 : rc;
     }
 
   rc = assuan_send_data (assuan_context, derbuf, derbuflen);
@@ -277,6 +302,7 @@ int
 agent_handle_learn (ctrl_t ctrl, void *assuan_context)
 {
   int rc;
+
   struct kpinfo_cb_parm_s parm;
   struct certinfo_cb_parm_s cparm;
   struct sinfo_cb_parm_s sparm;
@@ -287,10 +313,12 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
   char *p;
   int i;
   static int certtype_list[] = { 
+    111, /* Root CA */
     101, /* trusted */
     102, /* useful */
     100, /* regular */
-    /* We don't include 110 here because gpgsm can't handle it. */
+    /* We don't include 110 here because gpgsm can't handle that
+       special root CA format. */
     -1 /* end of list */
   };
 
@@ -298,6 +326,8 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
   memset (&parm, 0, sizeof parm);
   memset (&cparm, 0, sizeof cparm);
   memset (&sparm, 0, sizeof sparm);
+  parm.ctrl = ctrl;
+  cparm.ctrl = ctrl;
 
   /* Check whether a card is present and get the serial number */
   rc = agent_card_serialno (ctrl, &serialno);
@@ -360,6 +390,12 @@ agent_handle_learn (ctrl_t ctrl, void *assuan_context)
       if (item->no_cert)
         continue; /* No public key yet available. */
 
+      if (assuan_context)
+        {
+          agent_write_status (ctrl, "KEYPAIRINFO",
+                              item->hexgrip, item->id, NULL);
+        }
+
       for (p=item->hexgrip, i=0; i < 20; p += 2, i++)
         grip[i] = xtoi_2 (p);