mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd: Detect external interference when PCSC_SHARED.
* scd/app-common.h (check_aid): New method. * scd/app-openpgp.c (do_check_aid): New. * scd/app-piv.c (do_check_aid): New. * scd/app.c (check_external_interference): New. (maybe_switch_app): Check interference to determine switching is needed. -- GnuPG-bug-id: 5484 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
5f78ae696c
commit
044e5a3c38
@ -194,6 +194,8 @@ struct app_ctx_s {
|
|||||||
void *pincb_arg);
|
void *pincb_arg);
|
||||||
gpg_error_t (*with_keygrip) (app_t app, ctrl_t ctrl, int action,
|
gpg_error_t (*with_keygrip) (app_t app, ctrl_t ctrl, int action,
|
||||||
const char *keygrip_str, int capability);
|
const char *keygrip_str, int capability);
|
||||||
|
gpg_error_t (*check_aid) (app_t app, ctrl_t ctrl,
|
||||||
|
const unsigned char *aid, size_t aidlen);
|
||||||
} fnc;
|
} fnc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6134,6 +6134,18 @@ do_reselect (app_t app, ctrl_t ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if AID is the correct one. */
|
||||||
|
static gpg_error_t
|
||||||
|
do_check_aid (app_t app, ctrl_t ctrl, const unsigned char *aid, size_t aidlen)
|
||||||
|
{
|
||||||
|
if (aidlen >= sizeof openpgp_aid
|
||||||
|
&& memcmp (aid, openpgp_aid, sizeof openpgp_aid) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return gpg_error (GPG_ERR_WRONG_CARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Select the OpenPGP application on the card in SLOT. This function
|
/* Select the OpenPGP application on the card in SLOT. This function
|
||||||
must be used before any other OpenPGP application functions. */
|
must be used before any other OpenPGP application functions. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
@ -6322,6 +6334,7 @@ app_select_openpgp (app_t app)
|
|||||||
app->fnc.change_pin = do_change_pin;
|
app->fnc.change_pin = do_change_pin;
|
||||||
app->fnc.check_pin = do_check_pin;
|
app->fnc.check_pin = do_check_pin;
|
||||||
app->fnc.with_keygrip = do_with_keygrip;
|
app->fnc.with_keygrip = do_with_keygrip;
|
||||||
|
app->fnc.check_aid = do_check_aid;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
@ -3609,6 +3609,18 @@ do_reselect (app_t app, ctrl_t ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if AID is the correct one. */
|
||||||
|
static gpg_error_t
|
||||||
|
do_check_aid (app_t app, ctrl_t ctrl, const unsigned char *aid, size_t aidlen)
|
||||||
|
{
|
||||||
|
if (aidlen >= sizeof piv_aid
|
||||||
|
&& memcmp (aid, piv_aid, sizeof piv_aid) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return gpg_error (GPG_ERR_WRONG_CARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Select the PIV application on the card in SLOT. This function must
|
/* Select the PIV application on the card in SLOT. This function must
|
||||||
* be used before any other PIV application functions. */
|
* be used before any other PIV application functions. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
@ -3713,6 +3725,7 @@ app_select_piv (app_t app)
|
|||||||
app->fnc.change_pin = do_change_chv;
|
app->fnc.change_pin = do_change_chv;
|
||||||
app->fnc.check_pin = do_check_chv;
|
app->fnc.check_pin = do_check_chv;
|
||||||
app->fnc.with_keygrip = do_with_keygrip;
|
app->fnc.with_keygrip = do_with_keygrip;
|
||||||
|
app->fnc.check_aid = do_check_aid;
|
||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
46
scd/app.c
46
scd/app.c
@ -1435,6 +1435,46 @@ run_reselect (ctrl_t ctrl, card_t c, app_t a, app_t a_prev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check external interference before each use of the application on
|
||||||
|
* card. Returns -1 when detecting some external interference.
|
||||||
|
* Returns 0 if not.
|
||||||
|
*
|
||||||
|
* Note: This kind of detection can't be perfect. At most, it may be
|
||||||
|
* possibly useful kludge, in some limited situations.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
check_external_interference (app_t app, ctrl_t ctrl)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Only when a user is using Yubikey with pcsc-shared configuration,
|
||||||
|
* we need this detection. Otherwise, the card/token is under full
|
||||||
|
* control of scdaemon, there's no problem at all.
|
||||||
|
*/
|
||||||
|
if (!opt.pcsc_shared || app->card->cardtype != CARDTYPE_YUBIKEY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (app->fnc.check_aid)
|
||||||
|
{
|
||||||
|
unsigned char *aid;
|
||||||
|
size_t aidlen;
|
||||||
|
gpg_error_t err;
|
||||||
|
int slot = app_get_slot (app);
|
||||||
|
|
||||||
|
err = iso7816_get_data (slot, 0, 0x004F, &aid, &aidlen);
|
||||||
|
if (err)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
err = app->fnc.check_aid (app, ctrl, aid, aidlen);
|
||||||
|
xfree (aid);
|
||||||
|
if (err)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check that the card has been initialized and whether we need to
|
/* Check that the card has been initialized and whether we need to
|
||||||
* switch to another application on the same card. Switching means
|
* switch to another application on the same card. Switching means
|
||||||
* that the new active app will be moved to the head of the list at
|
* that the new active app will be moved to the head of the list at
|
||||||
@ -1490,7 +1530,8 @@ maybe_switch_app (ctrl_t ctrl, card_t card, const char *keyref)
|
|||||||
if (app->apptype == apptype)
|
if (app->apptype == apptype)
|
||||||
break;
|
break;
|
||||||
if (!app_prev && ctrl->current_apptype == card->app->apptype)
|
if (!app_prev && ctrl->current_apptype == card->app->apptype)
|
||||||
return 0; /* Already the first app - no need to switch. */
|
if (check_external_interference (app, ctrl) == 0)
|
||||||
|
return 0; /* Already the first app - no need to switch. */
|
||||||
}
|
}
|
||||||
else if (strlen (keyref) == 40)
|
else if (strlen (keyref) == 40)
|
||||||
{
|
{
|
||||||
@ -1503,7 +1544,8 @@ maybe_switch_app (ctrl_t ctrl, card_t card, const char *keyref)
|
|||||||
KEYGRIP_ACTION_LOOKUP, keyref, 0))
|
KEYGRIP_ACTION_LOOKUP, keyref, 0))
|
||||||
break;
|
break;
|
||||||
if (!app_prev && ctrl->current_apptype == card->app->apptype)
|
if (!app_prev && ctrl->current_apptype == card->app->apptype)
|
||||||
return 0; /* Already the first app - no need to switch. */
|
if (check_external_interference (app, ctrl) == 0)
|
||||||
|
return 0; /* Already the first app - no need to switch. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user