card: Print the used algorithm of all keys.
authorWerner Koch <wk@gnupg.org>
Thu, 7 Feb 2019 19:28:43 +0000 (20:28 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 7 Feb 2019 19:28:43 +0000 (20:28 +0100)
* tools/card-call-scd.c (scd_readkey): New.
* tools/card-tool-misc.c (pubkey_algo_string): New.
* tools/gpg-card-tool.c (list_one_kinfo): Print the algo.
--

It is convenient to see the actual algorithm of keys even if no
certificate has yet been created.

Signed-off-by: Werner Koch <wk@gnupg.org>
tools/card-call-scd.c
tools/card-tool-misc.c
tools/card-tool.h
tools/gpg-card-tool.c

index 7add56d..0d6dabf 100644 (file)
@@ -1299,6 +1299,45 @@ scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen)
 
 
 \f
+/* Send a READKEY command to the SCdaemon.  On success a new
+ * s-expression is stored at R_RESULT.  */
+gpg_error_t
+scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  membuf_t data;
+  unsigned char *buf;
+  size_t len, buflen;
+
+  *r_result = NULL;
+  err = start_agent (0);
+  if (err)
+    return err;
+
+  init_membuf (&data, 1024);
+  snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr);
+  err = assuan_transact (agent_ctx, line,
+                         put_membuf_cb, &data,
+                         NULL, NULL,
+                         NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  buf = get_membuf (&data, &buflen);
+  if (!buf)
+    return gpg_error_from_syserror ();
+
+  err = gcry_sexp_new (r_result, buf, buflen, 0);
+  xfree (buf);
+
+  return err;
+}
+
+
+\f
 /* Callback function for card_cardlist.  */
 static gpg_error_t
 card_cardlist_cb (void *opaque, const char *line)
index 06fcb67..5e0461c 100644 (file)
@@ -77,3 +77,61 @@ hex_to_buffer (const char *string, size_t *r_length)
   *r_length = n;
   return buffer;
 }
+
+
+
+/* Given the public key S_PKEY, return a new buffer with a descriptive
+ * string for its algorithm.  This function always returns a string. */
+char *
+pubkey_algo_string (gcry_sexp_t s_pkey)
+{
+  const char *prefix;
+  gcry_sexp_t l1;
+  char *algoname;
+  int algo;
+  char *result;
+
+  l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
+  if (!l1)
+    return xstrdup ("E_no_key");
+  {
+    gcry_sexp_t l_tmp = gcry_sexp_cadr (l1);
+    gcry_sexp_release (l1);
+    l1 = l_tmp;
+  }
+  algoname = gcry_sexp_nth_string (l1, 0);
+  gcry_sexp_release (l1);
+  if (!algoname)
+    return xstrdup ("E_no_algo");
+
+  algo = gcry_pk_map_name (algoname);
+  switch (algo)
+    {
+    case GCRY_PK_RSA: prefix = "rsa"; break;
+    case GCRY_PK_ELG: prefix = "elg"; break;
+    case GCRY_PK_DSA: prefix = "dsa"; break;
+    case GCRY_PK_ECC: prefix = "";  break;
+    default:          prefix = NULL; break;
+    }
+
+  if (prefix && *prefix)
+    result = xasprintf ("%s%u", prefix, gcry_pk_get_nbits (s_pkey));
+  else if (prefix)
+    {
+      const char *curve = gcry_pk_get_curve (s_pkey, 0, NULL);
+      const char *name = openpgp_oid_to_curve
+        (openpgp_curve_to_oid (curve, NULL), 0);
+
+      if (name)
+        result = xstrdup (name);
+      else if (curve)
+        result = xasprintf ("X_%s", curve);
+      else
+        result = xstrdup ("E_unknown");
+    }
+  else
+    result = xasprintf ("X_algo_%d", algo);
+
+  xfree (algoname);
+  return result;
+}
index 2707b3e..c121e88 100644 (file)
@@ -192,6 +192,7 @@ gpg_error_t test_get_matching_keys (const char *hexgrip);
 /*-- card-tool-misc.c --*/
 key_info_t find_kinfo (card_info_t info, const char *keyref);
 void *hex_to_buffer (const char *string, size_t *r_length);
+char *pubkey_algo_string (gcry_sexp_t s_pkey);
 
 
 /*-- card-call-scd.c --*/
@@ -211,6 +212,7 @@ gpg_error_t scd_genkey (int keyno, int force, u32 *createtime);
 gpg_error_t scd_serialno (char **r_serialno, const char *demand);
 gpg_error_t scd_readcert (const char *certidstr,
                           void **r_buf, size_t *r_buflen);
+gpg_error_t scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result);
 gpg_error_t scd_cardlist (strlist_t *result);
 gpg_error_t scd_change_pin (const char *pinref, int reset_mode);
 gpg_error_t scd_checkpin (const char *serialno);
index 0dbf2b2..71ce13f 100644 (file)
@@ -620,6 +620,7 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp)
   userid_t uid;
   key_info_t ki;
   const char *s;
+  gcry_sexp_t s_pkey;
 
   if (firstkinfo && kinfo)
     {
@@ -630,6 +631,14 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp)
           goto leave;
         }
       print_keygrip (fp, kinfo->grip);
+      if (!scd_readkey (kinfo->keyref, &s_pkey))
+        {
+          char *tmp = pubkey_algo_string (s_pkey);
+          tty_fprintf (fp, "      algorithm ..: %s\n", tmp);
+          xfree (tmp);
+          gcry_sexp_release (s_pkey);
+          s_pkey = NULL;
+        }
 
       if (kinfo->fprlen && kinfo->created)
         {