Add new option --with-keygrip
[gnupg.git] / sm / keylist.c
index c593ccc..4f876ff 100644 (file)
@@ -1,6 +1,6 @@
 /* keylist.c - Print certificates in various formats.
  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- *               2004, 2005, 2008 Free Software Foundation, Inc.
+ *               2004, 2005, 2008, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -229,6 +229,9 @@ print_key_data (ksba_cert_t cert, estream_t fp)
       putchar(':');
       putchar('\n');
     }
+#else
+  (void)cert;
+  (void)fp;
 #endif
 }
 
@@ -283,6 +286,8 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
     es_putc ('S', fp);
   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
     es_putc ('C', fp);
+
+  es_putc (':', fp);
 }
 
 
@@ -415,6 +420,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
         *truststring = 'e';
       else if (valerr)
         *truststring = 'i';
+      else if (ctrl->with_validation && !is_root)
+        *truststring = 'f';
     }
 
   /* If we have no truststring yet (i.e. the certificate might be
@@ -424,7 +431,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
     {
       struct rootca_flags_s dummy_flags;
 
-      rc = gpgsm_agent_istrusted (ctrl, cert, &dummy_flags);
+      rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
       if (!rc)
         *truststring = 'u';  /* Yes, we trust this one (ultimately). */
       else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
@@ -476,7 +483,24 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
   es_putc (':', fp);
   /* Field 12, capabilities: */ 
   print_capabilities (cert, fp);
+  /* Field 13, not used: */
   es_putc (':', fp);
+  if (have_secret)
+    {
+      char *cardsn;
+
+      p = gpgsm_get_keygrip_hexstring (cert);
+      if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
+        {
+          /* Field 14, not used: */
+          es_putc (':', fp);
+          /* Field 15:  Token serial number.  */
+          es_fputs (cardsn, fp);
+          es_putc (':', fp);
+        }
+      xfree (cardsn);
+      xfree (p);
+    }
   es_putc ('\n', fp);
 
   /* FPR record */
@@ -592,7 +616,7 @@ print_utf8_extn_raw (estream_t fp, int indent,
       es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
       return;
     }
-  es_fprintf (fp, "%*s(%.*s)\n", indent, "", objlen, der);
+  es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
 }
 
 
@@ -647,8 +671,10 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
   unsigned int reason;
   const unsigned char *cert_der = NULL;
 
+  (void)have_secret;
+
   es_fprintf (fp, "           ID: 0x%08lX\n",
-              gpgsm_get_short_fingerprint (cert));
+              gpgsm_get_short_fingerprint (cert, NULL));
 
   sexp = ksba_cert_get_serial (cert);
   es_fputs ("          S/N: ", fp);
@@ -982,7 +1008,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
     }
 
-  if (opt.with_ephemeral_keys && hd)
+  if (hd)
     {
       unsigned int blobflags;
 
@@ -1017,7 +1043,7 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
 
 
   es_fprintf (fp, "           ID: 0x%08lX\n",
-              gpgsm_get_short_fingerprint (cert));
+              gpgsm_get_short_fingerprint (cert, NULL));
 
   sexp = ksba_cert_get_serial (cert);
   es_fputs ("          S/N: ", fp);
@@ -1190,7 +1216,26 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
   es_fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
   xfree (dn);
 
+  if (opt.with_keygrip)
+    {
+      dn = gpgsm_get_keygrip_hexstring (cert);
+      if (dn)
+        {
+          es_fprintf (fp, "      keygrip: %s\n", dn);
+          xfree (dn);
+        }
+    }      
+
+  if (have_secret)
+    {
+      char *cardsn;
 
+      p = gpgsm_get_keygrip_hexstring (cert);
+      if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
+        es_fprintf (fp, "     card s/n: %s\n", cardsn);
+      xfree (cardsn);
+      xfree (p);
+    }
 
   if (with_validation)
     {
@@ -1267,6 +1312,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
   gpg_error_t rc = 0;
   const char *lastresname, *resname;
   int have_secret;
+  int want_ephemeral = ctrl->with_ephemeral_keys;
 
   hd = keydb_new (0);
   if (!hd)
@@ -1298,7 +1344,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
     {
       for (ndesc=0, sl=names; sl; sl = sl->next) 
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc);
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
@@ -1311,7 +1357,24 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
       
     }
 
-  if (opt.with_ephemeral_keys)
+  /* If all specifications are done by fingerprint or keygrip, we
+     switch to ephemeral mode so that _all_ currently available and
+     matching certificates are listed.  */
+  if (!want_ephemeral && names && ndesc)
+    {
+      int i;
+
+      for (i=0; (i < ndesc
+                 && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
+                     || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
+                     || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
+                     || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
+        ;
+      if (i == ndesc)
+        want_ephemeral = 1;
+    }
+
+  if (want_ephemeral)
     keydb_set_ephemeral (hd, 1);
 
   /* It would be nice to see which of the given users did actually
@@ -1348,6 +1411,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
       if (gpgsm_certs_identical_p (cert, lastcert))
        {
          ksba_cert_release (cert);
+          cert = NULL;
          continue;
        }
 
@@ -1374,7 +1438,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
           if (p)
             {
               rc = gpgsm_agent_havekey (ctrl, p); 
-             if (!rc)
+              if (!rc)
                 have_secret = 1;
               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
                 goto leave;