diff options
-rw-r--r-- | scd/app-common.h | 5 | ||||
-rw-r--r-- | scd/app-openpgp.c | 42 | ||||
-rw-r--r-- | scd/app-piv.c | 18 | ||||
-rw-r--r-- | scd/app.c | 13 | ||||
-rw-r--r-- | scd/command.c | 36 |
5 files changed, 79 insertions, 35 deletions
diff --git a/scd/app-common.h b/scd/app-common.h index 87f63bb7e..99331b04e 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -188,7 +188,7 @@ struct app_ctx_s { gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t (*with_keygrip) (app_t app, ctrl_t ctrl, int action, - const char *keygrip_str); + const char *keygrip_str, int capability); } fnc; }; @@ -301,7 +301,8 @@ gpg_error_t app_change_pin (card_t card, ctrl_t ctrl, gpg_error_t app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); -card_t app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str); +card_t app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str, + int capability); /*-- app-openpgp.c --*/ diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 4f76caac3..cdd16fab2 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -4929,8 +4929,23 @@ do_check_pin (app_t app, const char *keyidstr, return verify_chv2 (app, pincb, pincb_arg); } +static void +send_keyinfo_if_available (app_t app, ctrl_t ctrl, char *serial, + int data, int i) +{ + char idbuf[50]; + + 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); + } +} + static gpg_error_t -do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str) +do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str, + int capability) { int i; @@ -4950,7 +4965,6 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str) } else { - char idbuf[50]; char buf[65]; int data = (action == KEYGRIP_ACTION_SEND_DATA); @@ -4961,13 +4975,17 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str) if (keygrip_str == NULL) { - for (i = 0; i < 3; 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,buf, idbuf); - } + if (capability == 0) + { + for (i = 0; i < 3; i++) + send_keyinfo_if_available (app, ctrl, buf, data, i); + } + else + { + i = capability - 1; + send_keyinfo_if_available (app, ctrl, buf, data, i); + } + /* Return an error so that the dispatcher keeps on looping * over the other applications. Only for clarity we use a * different error code than for the not_found case. */ @@ -4976,11 +4994,9 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str) else { for (i = 0; i < 3; i++) - if (app->app_local->pk[i].read_done - && !strcmp (keygrip_str, app->app_local->pk[i].keygrip_str)) + if (!strcmp (keygrip_str, app->app_local->pk[i].keygrip_str)) { - sprintf (idbuf, "OPENPGP.%d", i+1); - send_keyinfo (ctrl, data, keygrip_str, buf, idbuf); + send_keyinfo_if_available (app, ctrl, buf, data, i); return 0; } } diff --git a/scd/app-piv.c b/scd/app-piv.c index 3cc7754df..0b1cb8208 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -3330,7 +3330,7 @@ do_writecert (app_t app, ctrl_t ctrl, /* Process the various keygrip based info requests. */ static gpg_error_t do_with_keygrip (app_t app, ctrl_t ctrl, int action, - const char *want_keygripstr) + const char *want_keygripstr, int capability) { gpg_error_t err; char *keygripstr = NULL; @@ -3389,6 +3389,22 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, } else if (!want_keygripstr || !strcmp (keygripstr, want_keygripstr)) { + if (capability == 1) + { + if (strcmp (data_objects[i].keyref, "9C")) + continue; + } + if (capability == 2) + { + if (strcmp (data_objects[i].keyref, "9D")) + continue; + } + if (capability == 3) + { + if (strcmp (data_objects[i].keyref, "9A")) + continue; + } + snprintf (idbuf, sizeof idbuf, "PIV.%s", data_objects[i].keyref); send_keyinfo (ctrl, data, keygripstr, serialno, idbuf); if (want_keygripstr) @@ -1138,7 +1138,7 @@ maybe_switch_app (ctrl_t ctrl, card_t card, const char *keyref) for (app = card->app; app; app_prev = app, app = app->next) if (app->fnc.with_keygrip && !app->fnc.with_keygrip (app, ctrl, - KEYGRIP_ACTION_LOOKUP, keyref)) + KEYGRIP_ACTION_LOOKUP, keyref, 0)) break; if (!app_prev && ctrl->current_apptype == card->app->apptype) return 0; /* Already the first app - no need to switch. */ @@ -1969,7 +1969,8 @@ app_send_card_list (ctrl_t ctrl) * <keygrip> T <serialno> <idstr> * If a match was found a pointer to the matching application is * returned. With the KEYGRIP_STR given as NULL, lines for all - * keys will be send and the return value is NULL. + * keys (with CAPABILITY) will be send and the return value is + * GPG_ERR_TRUE. * * - KEYGRIP_ACTION_WRITE_STATUS * @@ -1980,10 +1981,12 @@ app_send_card_list (ctrl_t ctrl) * * Returns a pointer to the application matching KEYGRIP_STR but * does not emit any status or data lines. If no key with that - * keygrip is available or KEYGRIP_STR is NULL, NULL is returned. + * keygrip is available or KEYGRIP_STR is NULL, GPG_ERR_NOT_FOUND + * is returned. */ card_t -app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str) +app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str, + int capability) { int locked = 0; card_t c; @@ -2005,7 +2008,7 @@ app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str) if (DBG_APP) log_debug ("slot %d app %s: calling with_keygrip(action=%d)\n", c->slot, xstrapptype (a), action); - if (!a->fnc.with_keygrip (a, ctrl, action, keygrip_str)) + if (!a->fnc.with_keygrip (a, ctrl, action, keygrip_str, capability)) goto leave_the_loop; } unlock_card (c); diff --git a/scd/command.c b/scd/command.c index 73a524b49..e5cf98fcb 100644 --- a/scd/command.c +++ b/scd/command.c @@ -830,7 +830,7 @@ cmd_pksign (assuan_context_t ctx, char *line) ctrl->card_ctx. */ if (strlen (keyidstr) == 40) { - card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr); + card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr, 0); direct = 1; } else @@ -898,7 +898,7 @@ cmd_pkauth (assuan_context_t ctx, char *line) ctrl->card_ctx. */ if (strlen (keyidstr) == 40) { - card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr); + card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr, 0); direct = 1; } else @@ -959,7 +959,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) ctrl->card_ctx. */ if (strlen (keyidstr) == 40) { - card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr); + card = app_do_with_keygrip (ctrl, KEYGRIP_ACTION_LOOKUP, keyidstr, 0); direct = 1; } else @@ -1893,12 +1893,13 @@ cmd_killscd (assuan_context_t ctx, char *line) static const char hlp_keyinfo[] = - "KEYINFO [--list] [--data] <keygrip>\n" + "KEYINFO [--list[=auth|encr|sign]] [--data] <keygrip>\n" "\n" "Return information about the key specified by the KEYGRIP. If the\n" "key is not available GPG_ERR_NOT_FOUND is returned. If the option\n" "--list is given the keygrip is ignored and information about all\n" - "available keys are returned. Unless --data is given, the\n" + "available keys are returned. Capability may limit the listing.\n" + "Unless --data is given, the\n" "information is returned as a status line using the format:\n" "\n" " KEYINFO <keygrip> T <serialno> <idstr>\n" @@ -1916,30 +1917,37 @@ static const char hlp_keyinfo[] = static gpg_error_t cmd_keyinfo (assuan_context_t ctx, char *line) { - int list_mode; + int cap; int opt_data; int action; char *keygrip_str; ctrl_t ctrl = assuan_get_pointer (ctx); card_t card; - list_mode = has_option (line, "--list"); - opt_data = has_option (line, "--data"); - line = skip_options (line); - - if (list_mode) - keygrip_str = NULL; + cap = 0; + keygrip_str = NULL; + if (has_option (line, "--list")) + cap = 0; + else if (has_option (line, "--list=sign")) + cap = 1; + else if (has_option (line, "--list=encr")) + cap = 2; + else if (has_option (line, "--list=auth")) + cap = 3; else keygrip_str = line; + opt_data = has_option (line, "--data"); + line = skip_options (line); + if (opt_data) action = KEYGRIP_ACTION_SEND_DATA; else action = KEYGRIP_ACTION_WRITE_STATUS; - card = app_do_with_keygrip (ctrl, action, keygrip_str); + card = app_do_with_keygrip (ctrl, action, keygrip_str, cap); - if (!list_mode && !card) + if (keygrip_str && !card) return gpg_error (GPG_ERR_NOT_FOUND); return 0; } |