mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-08 12:44:23 +01:00
scd: Enhance KEYINFO command to limit listing with capability.
* scd/app-common.h: Add CAPABILITY argument to the WITH_KEYGRIP. (app_do_with_keygrip): Likewise. * scd/app-openpgp.c (send_keyinfo_if_available): New. (do_with_keygrip): Support listing with CAPABILITY. * scd/app-piv.c (do_with_keygrip): Likewise. * scd/app.c (maybe_switch_app): Supply the argument. (app_do_with_keygrip): Add CAPABILITY argument. * scd/command.c (cmd_pksign, cmd_pkauth): Supply the argument. (cmd_pkdecrypt): Likewise. (cmd_keyinfo): Support listing with CAPABILITY. -- GnuPG-bug-id: 4784 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
70cb02c059
commit
b2a2df174b
@ -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 --*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
13
scd/app.c
13
scd/app.c
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user