1
0
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:
Werner Koch 2019-09-04 12:08:07 +02:00
parent 2cdea776cd
commit 5cf5a04bae
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 61 additions and 19 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
} }