mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
scd: Add option --multi to the LEARN command.
* scd/app-common.h (APP_LEARN_FLAG_MULTI): New. * scd/command.c (cmd_learn): Add option --multi. * scd/app.c (app_write_learn_status): Factor some code out to ... (write_learn_status_core): new. (app_write_learn_status): Implement flag --multi. -- This new option is intended to return information about all active applications of the current card. Thus if a "SERIALNO openpgp" and a "SERIALNO piv" has been done in a session the command "LEARN --force --multi" returns information about both applications. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
2cdea776cd
commit
5cf5a04bae
@ -44,6 +44,8 @@
|
|||||||
|
|
||||||
/* Flags used by the app_write_learn_status. */
|
/* Flags used by the app_write_learn_status. */
|
||||||
#define APP_LEARN_FLAG_KEYPAIRINFO 1 /* Return only keypair infos. */
|
#define APP_LEARN_FLAG_KEYPAIRINFO 1 /* Return only keypair infos. */
|
||||||
|
#define APP_LEARN_FLAG_MULTI 2 /* Return info for all apps. */
|
||||||
|
|
||||||
|
|
||||||
/* List of supported card types. Generic is the usual ISO7817-4
|
/* List of supported card types. Generic is the usual ISO7817-4
|
||||||
* compliant card. More specific card or token versions can be given
|
* compliant card. More specific card or token versions can be given
|
||||||
|
69
scd/app.c
69
scd/app.c
@ -1030,13 +1030,36 @@ maybe_switch_app (ctrl_t ctrl, card_t card)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper for app_write_learn_status. */
|
||||||
|
static gpg_error_t
|
||||||
|
write_learn_status_core (card_t card, app_t app, ctrl_t ctrl,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
/* We do not send CARD and APPTYPE if only keypairinfo is requested. */
|
||||||
|
if (!(flags & APP_LEARN_FLAG_KEYPAIRINFO))
|
||||||
|
{
|
||||||
|
if (card && card->cardtype)
|
||||||
|
send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype));
|
||||||
|
if (card && card->cardversion)
|
||||||
|
send_status_printf (ctrl, "CARDVERSION", "%X", card->cardversion);
|
||||||
|
if (app->apptype)
|
||||||
|
send_status_direct (ctrl, "APPTYPE", strapptype (app->apptype));
|
||||||
|
if (app->appversion)
|
||||||
|
send_status_printf (ctrl, "APPVERSION", "%X", app->appversion);
|
||||||
|
}
|
||||||
|
|
||||||
|
return app->fnc.learn_status (app, ctrl, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write out the application specific status lines for the LEARN
|
/* Write out the application specific status lines for the LEARN
|
||||||
command. */
|
command. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
app_write_learn_status (card_t card, ctrl_t ctrl, unsigned int flags)
|
app_write_learn_status (card_t card, ctrl_t ctrl, unsigned int flags)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err, err2;
|
||||||
app_t app;
|
app_t app;
|
||||||
|
int any_reselect = 0;
|
||||||
|
|
||||||
if (!card)
|
if (!card)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
@ -1045,29 +1068,43 @@ app_write_learn_status (card_t card, ctrl_t ctrl, unsigned int flags)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
/* Always make sure that the current app for this connection has
|
||||||
|
* been selected and is at the top of the list. */
|
||||||
if ((err = maybe_switch_app (ctrl, card)))
|
if ((err = maybe_switch_app (ctrl, card)))
|
||||||
;
|
;
|
||||||
else if (!card->app->fnc.learn_status)
|
else if (!card->app->fnc.learn_status)
|
||||||
err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
|
err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
app = card->app;
|
err = write_learn_status_core (card, card->app, ctrl, flags);
|
||||||
|
if (!err && card->app->fnc.reselect && (flags & APP_LEARN_FLAG_MULTI))
|
||||||
/* We do not send CARD and APPTYPE if only keypairinfo is requested. */
|
|
||||||
if (!(flags & APP_LEARN_FLAG_KEYPAIRINFO))
|
|
||||||
{
|
{
|
||||||
if (card->cardtype)
|
/* The current app has the reselect feature so that we can
|
||||||
send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype));
|
* loop over all other apps which are capable of a reselect
|
||||||
if (card->cardversion)
|
* and finally reselect the first app again. Note that we
|
||||||
send_status_printf (ctrl, "CARDVERSION", "%X", card->cardversion);
|
* did the learn for the currently selected card above. */
|
||||||
if (app->apptype)
|
app = card->app;
|
||||||
send_status_direct (ctrl, "APPTYPE", strapptype (app->apptype));
|
for (app = app->next; app && !err; app = app->next)
|
||||||
if (app->appversion)
|
if (app->fnc.reselect)
|
||||||
send_status_printf (ctrl, "APPVERSION", "%X", app->appversion);
|
{
|
||||||
/* FIXME: Send info for the other active apps of the card? */
|
any_reselect = 1;
|
||||||
|
err = app->fnc.reselect (app, ctrl);
|
||||||
|
if (!err)
|
||||||
|
err = write_learn_status_core (NULL, app, ctrl, flags);
|
||||||
|
}
|
||||||
|
app = card->app;
|
||||||
|
if (any_reselect)
|
||||||
|
{
|
||||||
|
err2 = app->fnc.reselect (app, ctrl);
|
||||||
|
if (err2)
|
||||||
|
{
|
||||||
|
log_error ("error re-selecting '%s': %s\n",
|
||||||
|
strapptype(app->apptype), gpg_strerror (err2));
|
||||||
|
if (!err)
|
||||||
|
err = err2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = app->fnc.learn_status (app, ctrl, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_card (card);
|
unlock_card (card);
|
||||||
|
@ -338,7 +338,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_learn[] =
|
static const char hlp_learn[] =
|
||||||
"LEARN [--force] [--keypairinfo]\n"
|
"LEARN [--force] [--keypairinfo] [--multi]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Learn all useful information of the currently inserted card. When\n"
|
"Learn all useful information of the currently inserted card. When\n"
|
||||||
"used without the force options, the command might do an INQUIRE\n"
|
"used without the force options, the command might do an INQUIRE\n"
|
||||||
@ -366,7 +366,8 @@ static const char hlp_learn[] =
|
|||||||
" PIV = PIV card\n"
|
" PIV = PIV card\n"
|
||||||
" NKS = NetKey card\n"
|
" NKS = NetKey card\n"
|
||||||
"\n"
|
"\n"
|
||||||
"are implemented. These strings are aliases for the AID\n"
|
"are implemented. These strings are aliases for the AID. With option\n"
|
||||||
|
"--multi information for all switchable apps are returned.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id> [<usage>]\n"
|
" S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id> [<usage>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -413,6 +414,7 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int only_keypairinfo = has_option (line, "--keypairinfo");
|
int only_keypairinfo = has_option (line, "--keypairinfo");
|
||||||
|
int opt_multi = has_option (line, "--multi");
|
||||||
|
|
||||||
if ((rc = open_card (ctrl)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
@ -477,7 +479,8 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
if (!rc)
|
if (!rc)
|
||||||
rc = app_write_learn_status
|
rc = app_write_learn_status
|
||||||
(ctrl->card_ctx, ctrl,
|
(ctrl->card_ctx, ctrl,
|
||||||
(only_keypairinfo? APP_LEARN_FLAG_KEYPAIRINFO : 0));
|
( (only_keypairinfo? APP_LEARN_FLAG_KEYPAIRINFO : 0)
|
||||||
|
| (opt_multi? APP_LEARN_FLAG_MULTI : 0)) );
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user