mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd: Add option --all to the SERIALNO command.
* scd/command.c (cmd_serialno): Add option --all. (open_card_with_request): Implement that option. * scd/app.c (select_all_additional_applications_internal): New. (select_additional_application): Add mode to call new function. -- This option is currently only useful for Yubikeys and basically ignored with other cards. Its use is SERIALNO --all LEARN --force --multi which will then print keypairinfo and other stuff for the OpenPGP and PIV application of a Yubikey. Scute is going to use this to allow using certificates from OpenPGP and PIV at the same time. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
fa25837942
commit
9a0d8f2d89
98
scd/app.c
98
scd/app.c
@ -753,6 +753,78 @@ select_additional_application_internal (card_t card, apptype_t req_apptype)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Add all possible additional applications to the card context but do
|
||||
* not change the current one. This current works only for Yubikeys. */
|
||||
static gpg_error_t
|
||||
select_all_additional_applications_internal (card_t card)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
apptype_t candidates[3];
|
||||
int i, j;
|
||||
|
||||
if (card->cardtype == CARDTYPE_YUBIKEY)
|
||||
{
|
||||
candidates[0] = APPTYPE_OPENPGP;
|
||||
candidates[1] = APPTYPE_PIV;
|
||||
candidates[2] = APPTYPE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
candidates[0] = APPTYPE_NONE;
|
||||
}
|
||||
|
||||
/* Find the app and run the select. */
|
||||
for (i=0; app_priority_list[i].apptype; i++)
|
||||
{
|
||||
app_t app, app_r, app_prev;
|
||||
|
||||
for (j=0; candidates[j]; j++)
|
||||
if (candidates[j] == app_priority_list[i].apptype
|
||||
&& is_app_allowed (app_priority_list[i].name))
|
||||
break;
|
||||
if (!candidates[j])
|
||||
continue;
|
||||
|
||||
for (app = card->app; app; app = app->next)
|
||||
if (app->apptype == candidates[j])
|
||||
break;
|
||||
if (app)
|
||||
continue; /* Already on the list of apps. */
|
||||
|
||||
app = xtrycalloc (1, sizeof *app);
|
||||
if (!app)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_info ("error allocating app context: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
app->card = card;
|
||||
err = app_priority_list[i].select_func (app);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error selecting additional app '%s': %s - skipped\n",
|
||||
strapptype (candidates[j]), gpg_strerror (err));
|
||||
err = 0;
|
||||
xfree (app);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Append to the list of apps. */
|
||||
app_prev = card->app;
|
||||
for (app_r=app_prev->next; app_r; app_prev=app_r, app_r=app_r->next)
|
||||
;
|
||||
app_prev->next = app;
|
||||
log_info ("added app '%s' to the card context\n",
|
||||
strapptype (app->apptype));
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* This function needs to be called with the NAME of the new
|
||||
* application to be selected on CARD. On success the application is
|
||||
* added to the list of the card's active applications as currently
|
||||
@ -765,9 +837,14 @@ select_additional_application (ctrl_t ctrl, const char *name)
|
||||
apptype_t req_apptype;
|
||||
card_t card;
|
||||
|
||||
req_apptype = apptype_from_name (name);
|
||||
if (!req_apptype)
|
||||
return gpg_error (GPG_ERR_NOT_FOUND);
|
||||
if (!name)
|
||||
req_apptype = 0;
|
||||
else
|
||||
{
|
||||
req_apptype = apptype_from_name (name);
|
||||
if (!req_apptype)
|
||||
return gpg_error (GPG_ERR_NOT_FOUND);
|
||||
}
|
||||
|
||||
card = ctrl->card_ctx;
|
||||
if (!card)
|
||||
@ -777,11 +854,18 @@ select_additional_application (ctrl_t ctrl, const char *name)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = select_additional_application_internal (card, req_apptype);
|
||||
if (!err)
|
||||
if (req_apptype)
|
||||
{
|
||||
ctrl->current_apptype = req_apptype;
|
||||
log_debug ("current_apptype is set to %s\n", name);
|
||||
err = select_additional_application_internal (card, req_apptype);
|
||||
if (!err)
|
||||
{
|
||||
ctrl->current_apptype = req_apptype;
|
||||
log_debug ("current_apptype is set to %s\n", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = select_all_additional_applications_internal (card);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
|
@ -218,10 +218,12 @@ open_card (ctrl_t ctrl)
|
||||
return select_application (ctrl, NULL, &ctrl->card_ctx, 0, NULL, 0);
|
||||
}
|
||||
|
||||
/* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */
|
||||
/* Explicitly open a card for a specific use of APPTYPE or SERIALNO.
|
||||
* If OPT_ALL ist set also add all possible additional apps. */
|
||||
static gpg_error_t
|
||||
open_card_with_request (ctrl_t ctrl,
|
||||
const char *apptypestr, const char *serialno)
|
||||
const char *apptypestr, const char *serialno,
|
||||
int opt_all)
|
||||
{
|
||||
gpg_error_t err;
|
||||
unsigned char *serialno_bin = NULL;
|
||||
@ -254,6 +256,8 @@ open_card_with_request (ctrl_t ctrl,
|
||||
|
||||
err = select_application (ctrl, apptypestr, &ctrl->card_ctx, 1,
|
||||
serialno_bin, serialno_bin_len);
|
||||
if (!err && opt_all)
|
||||
err = select_additional_application (ctrl, APPTYPE_NONE);
|
||||
|
||||
leave:
|
||||
xfree (serialno_bin);
|
||||
@ -262,7 +266,7 @@ open_card_with_request (ctrl_t ctrl,
|
||||
|
||||
|
||||
static const char hlp_serialno[] =
|
||||
"SERIALNO [--demand=<serialno>] [<apptype>]\n"
|
||||
"SERIALNO [--demand=<serialno>] [--all] [<apptype>]\n"
|
||||
"\n"
|
||||
"Return the serial number of the card using a status response. This\n"
|
||||
"function should be used to check for the presence of a card.\n"
|
||||
@ -270,6 +274,9 @@ static const char hlp_serialno[] =
|
||||
"If --demand is given, an application on the card with SERIALNO is\n"
|
||||
"selected and an error is returned if no such card available.\n"
|
||||
"\n"
|
||||
"If --all is given, all possible other applications of the card are\n"
|
||||
"will also be selected for on-the-fly swicthing.\n"
|
||||
"\n"
|
||||
"If APPTYPE is given, an application of that type is selected and an\n"
|
||||
"error is returned if the application is not supported or available.\n"
|
||||
"The default is to auto-select the application using a hardwired\n"
|
||||
@ -291,6 +298,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
|
||||
int rc = 0;
|
||||
char *serial;
|
||||
const char *demand;
|
||||
int opt_all = has_option (line, "--all");
|
||||
|
||||
if ( IS_LOCKED (ctrl) )
|
||||
return gpg_error (GPG_ERR_LOCKED);
|
||||
@ -308,11 +316,13 @@ cmd_serialno (assuan_context_t ctx, char *line)
|
||||
else
|
||||
demand = NULL;
|
||||
|
||||
line = skip_options (line);
|
||||
|
||||
/* Clear the remove flag so that the open_card is able to reread it. */
|
||||
if (ctrl->server_local->card_removed)
|
||||
ctrl->server_local->card_removed = 0;
|
||||
|
||||
if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand)))
|
||||
if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand, opt_all)))
|
||||
{
|
||||
ctrl->server_local->card_removed = 1;
|
||||
return rc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user