aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/card-call-scd.c39
-rw-r--r--tools/card-tool-misc.c58
-rw-r--r--tools/card-tool.h2
-rw-r--r--tools/gpg-card-tool.c9
4 files changed, 108 insertions, 0 deletions
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index 7add56daf..0d6dabf1b 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -1299,6 +1299,45 @@ scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen)
+/* 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;
+}
+
+
+
/* Callback function for card_cardlist. */
static gpg_error_t
card_cardlist_cb (void *opaque, const char *line)
diff --git a/tools/card-tool-misc.c b/tools/card-tool-misc.c
index 06fcb6705..5e0461cb8 100644
--- a/tools/card-tool-misc.c
+++ b/tools/card-tool-misc.c
@@ -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;
+}
diff --git a/tools/card-tool.h b/tools/card-tool.h
index 2707b3e8f..c121e88ef 100644
--- a/tools/card-tool.h
+++ b/tools/card-tool.h
@@ -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);
diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c
index 0dbf2b224..71ce13f1b 100644
--- a/tools/gpg-card-tool.c
+++ b/tools/gpg-card-tool.c
@@ -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)
{