gpg: When comparing keyids, use the keyid, not the fingerprint's suffix.
[gnupg.git] / g10 / call-agent.c
index dc9d157..8eb16e4 100644 (file)
 #include "call-agent.h"
 #include "status.h"
 #include "../common/shareddefs.h"
-
-#ifndef DBG_ASSUAN
-# define DBG_ASSUAN 1
-#endif
+#include "host2net.h"
 
 #define CONTROL_D ('D' - 'A' + 1)
 
@@ -180,11 +177,15 @@ default_inq_cb (void *opaque, const char *line)
       else
         {
           char *pw;
+          char buf[32];
 
           if (parm->keyinfo.keyid)
             emit_status_need_passphrase (parm->keyinfo.keyid,
                                          parm->keyinfo.mainkeyid,
                                          parm->keyinfo.pubkey_algo);
+
+          snprintf (buf, sizeof (buf), "%u", 100);
+          write_status_text (STATUS_INQUIRE_MAXLEN, buf);
           pw = cpr_get_hidden ("passphrase.enter", _("Enter passphrase: "));
           cpr_kill_prompt ();
           if (*pw == CONTROL_D && !pw[1])
@@ -285,7 +286,7 @@ start_agent (ctrl_t ctrl, int for_card)
                                 opt.agent_program,
                                 opt.lc_ctype, opt.lc_messages,
                                 opt.session_env,
-                                opt.autostart, opt.verbose, DBG_ASSUAN,
+                                opt.autostart, opt.verbose, DBG_IPC,
                                 NULL, NULL);
       if (!opt.autostart && gpg_err_code (rc) == GPG_ERR_NO_AGENT)
         {
@@ -317,9 +318,12 @@ start_agent (ctrl_t ctrl, int for_card)
                                NULL, NULL, NULL, NULL, NULL, NULL);
               xfree (tmp);
               if (rc)
-                log_error ("setting pinentry mode '%s' failed: %s\n",
-                           str_pinentry_mode (opt.pinentry_mode),
-                           gpg_strerror (rc));
+                {
+                  log_error ("setting pinentry mode '%s' failed: %s\n",
+                             str_pinentry_mode (opt.pinentry_mode),
+                             gpg_strerror (rc));
+                  write_status_error ("set_pinentry_mode", rc);
+                }
             }
 
           check_hijacking (agent_ctx);
@@ -476,6 +480,7 @@ agent_release_card_info (struct agent_card_info_s *info)
   if (!info)
     return;
 
+  xfree (info->reader); info->reader = NULL;
   xfree (info->serialno); info->serialno = NULL;
   xfree (info->apptype); info->apptype = NULL;
   xfree (info->disp_name); info->disp_name = NULL;
@@ -505,7 +510,12 @@ learn_status_cb (void *opaque, const char *line)
   while (spacep (line))
     line++;
 
-  if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
+  if (keywordlen == 6 && !memcmp (keyword, "READER", keywordlen))
+    {
+      xfree (parm->reader);
+      parm->reader = unescape_status_string (line);
+    }
+  else if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
     {
       xfree (parm->serialno);
       parm->serialno = store_serialno (line);
@@ -648,14 +658,32 @@ learn_status_cb (void *opaque, const char *line)
     }
   else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
     {
-      int keyno, algo, nbits;
+      int keyno = 0;
+      int algo = PUBKEY_ALGO_RSA;
+      int n = 0;
 
-      sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
+      sscanf (line, "%d %d %n", &keyno, &algo, &n);
       keyno--;
-      if (keyno >= 0 && keyno < DIM (parm->key_attr))
+      if (keyno < 0 || keyno >= DIM (parm->key_attr))
+        return 0;
+
+      parm->key_attr[keyno].algo = algo;
+      if (algo == PUBKEY_ALGO_RSA)
+        parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
+      else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
+               || algo == PUBKEY_ALGO_EDDSA)
         {
-          parm->key_attr[keyno].algo = algo;
-          parm->key_attr[keyno].nbits = nbits;
+          const char *curve;
+
+          i = 0;
+          do
+            {
+              curve = openpgp_enum_curves (&i);
+              if (!strcmp (curve, line+n))
+                break;
+            }
+          while (curve != NULL);
+          parm->key_attr[keyno].curve = curve;
         }
     }
   else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
@@ -672,7 +700,7 @@ learn_status_cb (void *opaque, const char *line)
 
 /* Call the scdaemon to learn about a smartcard */
 int
-agent_scd_learn (struct agent_card_info_s *info)
+agent_scd_learn (struct agent_card_info_s *info, int force)
 {
   int rc;
   struct default_inq_parm_s parm;
@@ -700,7 +728,8 @@ agent_scd_learn (struct agent_card_info_s *info)
     return rc;
 
   parm.ctx = agent_ctx;
-  rc = assuan_transact (agent_ctx, "LEARN --sendinfo",
+  rc = assuan_transact (agent_ctx,
+                        force ? "LEARN --sendinfo --force" : "LEARN --sendinfo",
                         dummy_data_cb, NULL, default_inq_cb, &parm,
                         learn_status_cb, info);
   /* Also try to get the key attributes.  */
@@ -761,7 +790,7 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
             err = gpg_error (GPG_ERR_CARD);
           else
             {
-              *r_sw = (data[datalen-2] << 8) | data[datalen-1];
+              *r_sw = buf16_to_uint (data+datalen-2);
             }
           xfree (data);
         }
@@ -1628,7 +1657,7 @@ keyinfo_status_cb (void *opaque, const char *line)
   char **serialno = opaque;
   const char *s, *s2;
 
-  if ((s = has_leading_keyword (line, "KEYINFO ")) && !*serialno)
+  if ((s = has_leading_keyword (line, "KEYINFO")) && !*serialno)
     {
       s = strchr (s, ' ');
       if (s && s[1] == 'T' && s[2] == ' ' && s[3])