mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
scd: Add an re-select mechanism to switch apps.
* scd/app-common.h (struct app_ctx_s): Add func ptr 'reselect'. * scd/app-piv.c (do_reselect): New. (app_select_piv): Move AID constant to file scope. * scd/app-openpgp.c (do_reselect): New. (app_select_openpgp): Move AID constant to file scope. * scd/app.c (apptype_from_name): New. (check_application_conflict): Check against all apps of the card. Always set current_apptype. (select_additional_application): New. (maybe_switch_app): New. (app_write_learn_status, app_readcert, app_readkey, app_getattr) (app_setattr, app_sign, app_auth, app_decipher, app_writecert) (app_writekey, app_genkey, app_change_pin, app_check_pin): Use it here. (app_do_with_keygrip): Force reselect on success. (app_new_register): Move setting of CURRENT_APPTYPE to ... (select_application): here so that it will be set to the requested card. * scd/command.c (open_card_with_request): Select additional application if possible. -- Noet that we will likely need to rework this even more so to get well defined semantics for card access. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
d7d1ff4557
commit
d803b3bb3c
11 changed files with 274 additions and 49 deletions
|
@ -81,6 +81,10 @@
|
|||
#define PIV_ALGORITHM_ECC_P384 0x14
|
||||
|
||||
|
||||
/* The AID for PIV. */
|
||||
static char const piv_aid[] = { 0xA0, 0x00, 0x00, 0x03, 0x08, /* RID=NIST */
|
||||
0x00, 0x00, 0x10, 0x00 /* PIX=PIV */ };
|
||||
|
||||
|
||||
/* A table describing the DOs of a PIV card. */
|
||||
struct data_object_s
|
||||
|
@ -3390,13 +3394,32 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
|
|||
}
|
||||
|
||||
|
||||
/* Reselect the application. This is used by cards which support
|
||||
* on-the-fly switching between applications. */
|
||||
static gpg_error_t
|
||||
do_reselect (app_t app, ctrl_t ctrl)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
(void)ctrl;
|
||||
|
||||
/* An extra check which should not be necessary because the caller
|
||||
* should have made sure that a re-select is only called for
|
||||
* approriate cards. */
|
||||
if (!app->app_local->flags.yubikey)
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
||||
err = iso7816_select_application (app_get_slot (app),
|
||||
piv_aid, sizeof piv_aid, 0x0001);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Select the PIV application on the card in SLOT. This function must
|
||||
* be used before any other PIV application functions. */
|
||||
gpg_error_t
|
||||
app_select_piv (app_t app)
|
||||
{
|
||||
static char const aid[] = { 0xA0, 0x00, 0x00, 0x03, 0x08, /* RID=NIST */
|
||||
0x00, 0x00, 0x10, 0x00 /* PIX=PIV */ };
|
||||
int slot = app_get_slot (app);
|
||||
gpg_error_t err;
|
||||
unsigned char *apt = NULL;
|
||||
|
@ -3407,7 +3430,7 @@ app_select_piv (app_t app)
|
|||
/* Note that we select using the AID without the 2 octet version
|
||||
* number. This allows for better reporting of future specs. We
|
||||
* need to use the use-zero-for-P2-flag. */
|
||||
err = iso7816_select_application_ext (slot, aid, sizeof aid, 0x0001,
|
||||
err = iso7816_select_application_ext (slot, piv_aid, sizeof piv_aid, 0x0001,
|
||||
&apt, &aptlen);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
@ -3427,7 +3450,7 @@ app_select_piv (app_t app)
|
|||
}
|
||||
|
||||
s = find_tlv (apt, aptlen, 0x4F, &n);
|
||||
if (!s || n != 6 || memcmp (s, aid+5, 4))
|
||||
if (!s || n != 6 || memcmp (s, piv_aid+5, 4))
|
||||
{
|
||||
/* The PIX does not match. */
|
||||
log_error ("piv: missing or invalid DO 0x4F in APT\n");
|
||||
|
@ -3450,7 +3473,7 @@ app_select_piv (app_t app)
|
|||
goto leave;
|
||||
}
|
||||
s = find_tlv (s, n, 0x4F, &n);
|
||||
if (!s || n != 5 || memcmp (s, aid, 5))
|
||||
if (!s || n != 5 || memcmp (s, piv_aid, 5))
|
||||
{
|
||||
/* The RID does not match. */
|
||||
log_error ("piv: missing or invalid DO 0x79.4F in APT\n");
|
||||
|
@ -3475,6 +3498,7 @@ app_select_piv (app_t app)
|
|||
dump_all_do (slot);
|
||||
|
||||
app->fnc.deinit = do_deinit;
|
||||
app->fnc.reselect = do_reselect;
|
||||
app->fnc.learn_status = do_learn_status;
|
||||
app->fnc.readcert = do_readcert;
|
||||
app->fnc.readkey = do_readkey;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue