From 5264d3f58e8a8362900c3518bdd683ff9a23cccc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 26 May 2022 12:01:16 +0900 Subject: [PATCH] scd: Return USAGE information for KEYINFO command. * scd/command.c (hlp_keyinfo): Update. (send_keyinfo): Add a USAGE argument. * scd/scdaemon.h (send_keyinfo): Add a USAGE argument. * scd/app-nks.c (set_usage_string): New. (do_learn_status_core, do_readkey): Use set_usage_string. (do_with_keygrip): Add USAGE to call send_keyinfo, using set_usage_string. * scd/app-openpgp.c (get_usage_string): New. (send_keypair_info): Use get_usage_string. (send_keyinfo_if_available): Add USAGE to call send_keyinfo, using get_usage_string. * scd/app-p15.c (set_usage_string): New. (send_keypairinfo): Use set_usage_string. (do_with_keygrip): Add USAGE to call send_keyinfo, using set_usage_string. * scd/app-piv.c (do_with_keygrip): Add USAGE to call send_keyinfo. -- Signed-off-by: NIIBE Yutaka --- scd/app-nks.c | 41 ++++++++++++------------ scd/app-openpgp.c | 26 ++++++++++----- scd/app-p15.c | 82 ++++++++++++++++++++++++++--------------------- scd/app-piv.c | 9 +++++- scd/command.c | 13 +++++--- scd/scdaemon.h | 3 +- 6 files changed, 103 insertions(+), 71 deletions(-) diff --git a/scd/app-nks.c b/scd/app-nks.c index 31b91ac93..8b962722e 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -814,6 +814,21 @@ get_nks_tag (app_t app, int nks_app_id) return tag; } +static void +set_usage_string (char usagebuf[5], int i) +{ + int usageidx = 0; + if (filelist[i].issignkey) + usagebuf[usageidx++] = 's'; + if (filelist[i].isauthkey) + usagebuf[usageidx++] = 'a'; + if (filelist[i].isencrkey) + usagebuf[usageidx++] = 'e'; + if (!usageidx) + usagebuf[usageidx++] = '-'; + usagebuf[usageidx] = 0; +} + static void do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, int nks_app_id) @@ -856,7 +871,6 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, { char gripstr[40+1]; char usagebuf[5]; - int usageidx = 0; char *algostr = NULL; err = keygripstr_from_pk_file (app, filelist[i].fid, @@ -869,15 +883,7 @@ do_learn_status_core (app_t app, ctrl_t ctrl, unsigned int flags, { snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X", tag, filelist[i].fid); - if (filelist[i].issignkey) - usagebuf[usageidx++] = 's'; - if (filelist[i].isauthkey) - usagebuf[usageidx++] = 'a'; - if (filelist[i].isencrkey) - usagebuf[usageidx++] = 'e'; - if (!usageidx) - usagebuf[usageidx++] = '-'; - usagebuf[usageidx] = 0; + set_usage_string (usagebuf, i); send_status_info (ctrl, "KEYPAIRINFO", gripstr, 40, id_buf, strlen (id_buf), @@ -1280,7 +1286,6 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags, { char *algostr; char usagebuf[5]; - int usageidx = 0; char id_buf[100]; if (app_help_get_keygrip_string_pk (*pk, *pklen, NULL, NULL, NULL, @@ -1290,15 +1295,7 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyid, unsigned int flags, snprintf (id_buf, sizeof id_buf, "NKS-%s.%04X", get_nks_tag (app, filelist[i].nks_app_id), filelist[i].fid); - if (filelist[i].issignkey) - usagebuf[usageidx++] = 's'; - if (filelist[i].isauthkey) - usagebuf[usageidx++] = 'a'; - if (filelist[i].isencrkey) - usagebuf[usageidx++] = 'e'; - if (!usageidx) - usagebuf[usageidx++] = '-'; - usagebuf[usageidx] = 0; + set_usage_string (usagebuf, i); send_status_info (ctrl, "KEYPAIRINFO", keygripstr, strlen (keygripstr), id_buf, strlen (id_buf), @@ -2334,6 +2331,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, { char idbuf[20]; const char *tagstr; + char usagebuf[5]; if (app->app_local->active_nks_app == NKS_APP_ESIGN) tagstr = "ESIGN"; @@ -2348,7 +2346,8 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, snprintf (idbuf, sizeof idbuf, "NKS-%s.%04X", tagstr, filelist[idx].fid); - send_keyinfo (ctrl, data, keygripstr, serialno, idbuf); + set_usage_string (usagebuf, idx); + send_keyinfo (ctrl, data, keygripstr, serialno, idbuf, usagebuf); } } diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 08c9d71ac..3affda583 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2043,6 +2043,21 @@ get_public_key (app_t app, int keyno) } +static const char * +get_usage_string (int keyno) +{ + const char *usage; + switch (keyno) + { + case 0: usage = "sc"; break; + case 1: usage = "e"; break; + case 2: usage = "sa"; break; + default: usage = "-"; break; + } + return usage; +} + + /* Send the KEYPAIRINFO back. KEY needs to be in the range [1,3]. This is used by the LEARN command. */ static gpg_error_t @@ -2062,13 +2077,7 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key) if (!app->app_local->pk[keyno].key) goto leave; /* No such key - ignore. */ - switch (keyno) - { - case 0: usage = "sc"; break; - case 1: usage = "e"; break; - case 2: usage = "sa"; break; - default: usage = "-"; break; - } + usage = get_usage_string (keyno); if (retrieve_fprtime_from_card (app, keyno, &fprtime)) fprtime = 0; @@ -5920,12 +5929,13 @@ send_keyinfo_if_available (app_t app, ctrl_t ctrl, char *serial, int data, int i) { char idbuf[50]; + const char *usage = get_usage_string (i); if (app->app_local->pk[i].read_done) { sprintf (idbuf, "OPENPGP.%d", i+1); send_keyinfo (ctrl, data, - app->app_local->pk[i].keygrip_str, serial, idbuf); + app->app_local->pk[i].keygrip_str, serial, idbuf, usage); } } diff --git a/scd/app-p15.c b/scd/app-p15.c index ac6b875b8..5310af84d 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -4110,6 +4110,47 @@ keyref_from_prkdf (app_t app, prkdf_object_t prkdf) } +static void +set_usage_string (char usage[5], prkdf_object_t prkdf) +{ + size_t usagelen = 0; + if (prkdf->gpgusage.any) + { + if (prkdf->gpgusage.sign) + usage[usagelen++] = 's'; + if (prkdf->gpgusage.cert) + usage[usagelen++] = 'c'; + if (prkdf->gpgusage.encr) + usage[usagelen++] = 'e'; + if (prkdf->gpgusage.auth) + usage[usagelen++] = 'a'; + } + else + { + if ((prkdf->usageflags.sign + || prkdf->usageflags.sign_recover + || prkdf->usageflags.non_repudiation) + && (!prkdf->extusage.valid + || prkdf->extusage.sign)) + usage[usagelen++] = 's'; + if ((prkdf->usageflags.sign + || prkdf->usageflags.sign_recover) + && (!prkdf->extusage.valid || prkdf->extusage.sign)) + usage[usagelen++] = 'c'; + if ((prkdf->usageflags.decrypt + || prkdf->usageflags.unwrap) + && (!prkdf->extusage.valid || prkdf->extusage.encr)) + usage[usagelen++] = 'e'; + if ((prkdf->usageflags.sign + || prkdf->usageflags.sign_recover) + && (!prkdf->extusage.valid || prkdf->extusage.auth)) + usage[usagelen++] = 'a'; + } + if (!usagelen) + usage[usagelen++] = '-'; + usage[usagelen++] = 0; +} + /* Helper to do_learn_status: Send information about all known keypairs back. FIXME: much code duplication from send_certinfo(). */ @@ -4140,40 +4181,6 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t prkdf) char usage[5]; char keytime[20]; const char *algostr; - size_t usagelen = 0; - - if (prkdf->gpgusage.any) - { - if (prkdf->gpgusage.sign) - usage[usagelen++] = 's'; - if (prkdf->gpgusage.cert) - usage[usagelen++] = 'c'; - if (prkdf->gpgusage.encr) - usage[usagelen++] = 'e'; - if (prkdf->gpgusage.auth) - usage[usagelen++] = 'a'; - } - else - { - if ((prkdf->usageflags.sign - || prkdf->usageflags.sign_recover - || prkdf->usageflags.non_repudiation) - && (!prkdf->extusage.valid - || prkdf->extusage.sign)) - usage[usagelen++] = 's'; - if ((prkdf->usageflags.sign - || prkdf->usageflags.sign_recover) - && (!prkdf->extusage.valid || prkdf->extusage.sign)) - usage[usagelen++] = 'c'; - if ((prkdf->usageflags.decrypt - || prkdf->usageflags.unwrap) - && (!prkdf->extusage.valid || prkdf->extusage.encr)) - usage[usagelen++] = 'e'; - if ((prkdf->usageflags.sign - || prkdf->usageflags.sign_recover) - && (!prkdf->extusage.valid || prkdf->extusage.auth)) - usage[usagelen++] = 'a'; - } log_assert (strlen (prkdf->keygrip) == 40); if (prkdf->keytime && prkdf->have_keytime) @@ -4184,10 +4191,11 @@ send_keypairinfo (app_t app, ctrl_t ctrl, prkdf_object_t prkdf) algostr = prkdf->keyalgostr; + set_usage_string (usage, prkdf); send_status_info (ctrl, "KEYPAIRINFO", prkdf->keygrip, 2*KEYGRIP_LEN, buf, strlen (buf), - usage, usagelen, + usage, strlen (usage), keytime, strlen (keytime), algostr, strlen (algostr?algostr:""), NULL, (size_t)0); @@ -6017,6 +6025,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, else if (!want_keygripstr || !strcmp (prkdf->keygrip, want_keygripstr)) { char *keyref; + char usage[5]; if (capability == GCRY_PK_USAGE_SIGN) { @@ -6042,7 +6051,8 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, goto leave; } - send_keyinfo (ctrl, as_data, prkdf->keygrip, serialno, keyref); + set_usage_string (usage, prkdf); + send_keyinfo (ctrl, as_data, prkdf->keygrip, serialno, keyref, usage); xfree (keyref); if (want_keygripstr) { diff --git a/scd/app-piv.c b/scd/app-piv.c index 23b50bf99..a51ac31ec 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -3529,6 +3529,13 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, } else if (!want_keygripstr || !strcmp (keygripstr, want_keygripstr)) { + const char *usage; + + if (data_objects[i].usage) + usage = data_objects[i].usage; + else + usage = "-"; + if (capability == GCRY_PK_USAGE_SIGN) { if (strcmp (data_objects[i].keyref, "9C")) @@ -3546,7 +3553,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, } snprintf (idbuf, sizeof idbuf, "PIV.%s", data_objects[i].keyref); - send_keyinfo (ctrl, data, keygripstr, serialno, idbuf); + send_keyinfo (ctrl, data, keygripstr, serialno, idbuf, usage); if (want_keygripstr) { err = 0; /* Found */ diff --git a/scd/command.c b/scd/command.c index 28fdfcb62..b9303b546 100644 --- a/scd/command.c +++ b/scd/command.c @@ -2235,7 +2235,7 @@ static const char hlp_keyinfo[] = "Unless --data is given, the\n" "information is returned as a status line using the format:\n" "\n" - " KEYINFO T \n" + " KEYINFO T \n" "\n" "KEYGRIP is the keygrip.\n" "\n" @@ -2243,9 +2243,13 @@ static const char hlp_keyinfo[] = " smartcard. If the serial number is not known a single\n" " dash '-' is used instead.\n" "\n" - "IDSTR is the IDSTR used to distinguish keys on a smartcard. If it\n" + "IDSTR is a string used to distinguish keys on a smartcard. If it\n" " is not known a dash is used instead.\n" "\n" + "USAGE is a string of capabilities of the key, 's' for sign, \n" + "'e' for encryption, 'a' for auth, and 'c' for cert. If it is not\n" + "known a dash is used instead.\n" + "\n" "More information may be added in the future."; static gpg_error_t cmd_keyinfo (assuan_context_t ctx, char *line) @@ -2290,14 +2294,15 @@ cmd_keyinfo (assuan_context_t ctx, char *line) * line. */ void send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str, - const char *serialno, const char *idstr) + const char *serialno, const char *idstr, const char *usage) { char *string; assuan_context_t ctx = ctrl->server_local->assuan_ctx; - string = xtryasprintf ("%s T %s %s%s", keygrip_str, + string = xtryasprintf ("%s T %s %s %s%s", keygrip_str, serialno? serialno : "-", idstr? idstr : "-", + usage? usage : "-", data? "\n" : ""); if (!string) diff --git a/scd/scdaemon.h b/scd/scdaemon.h index b2a1d2fcc..68136b886 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -140,7 +140,8 @@ gpg_error_t send_status_direct (ctrl_t ctrl, gpg_error_t send_status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...) GPGRT_ATTR_PRINTF(3,4); void send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str, - const char *serialno, const char *idstr); + const char *serialno, const char *idstr, + const char *usage); void pincache_put (ctrl_t ctrl, int slot, const char *appname, const char *pinref, const char *pin, unsigned int pinlen);