mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
card: Run factory-reset in locked stated also in gpg-card.
* tools/card-call-scd.c (scd_apdu): Add more pseudo APDUs. * tools/card-misc.c (send_apdu): Handle them. * tools/gpg-card.c (cmd_factoryreset): Use lock commands. -- This is port of the code used with gpg-card-edit. Note that the command "apdu" now also understands some extra keywords. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
8fb0d5e3c7
commit
12fd10791f
@ -974,8 +974,9 @@ agent_scd_keypairinfo (ctrl_t ctrl, const char *keyref, keypair_info_t *r_list)
|
|||||||
|
|
||||||
|
|
||||||
/* Send an APDU to the current card. On success the status word is
|
/* Send an APDU to the current card. On success the status word is
|
||||||
* stored at R_SW. With HEXAPDU being NULL only a RESET command is
|
* stored at R_SW unless R_SQ is NULL. With HEXAPDU being NULL only a
|
||||||
* send to scd. HEXAPDU may also be one of these special strings:
|
* RESET command is send to scd. HEXAPDU may also be one of theseo
|
||||||
|
* special strings:
|
||||||
*
|
*
|
||||||
* "undefined" :: Send the command "SCD SERIALNO undefined"
|
* "undefined" :: Send the command "SCD SERIALNO undefined"
|
||||||
* "lock" :: Send the command "SCD LOCK --wait"
|
* "lock" :: Send the command "SCD LOCK --wait"
|
||||||
|
@ -421,9 +421,16 @@ store_serialno (const char *line)
|
|||||||
|
|
||||||
/* Send an APDU to the current card. On success the status word is
|
/* Send an APDU to the current card. On success the status word is
|
||||||
* stored at R_SW inless R_SW is NULL. With HEXAPDU being NULL only a
|
* stored at R_SW inless R_SW is NULL. With HEXAPDU being NULL only a
|
||||||
* RESET command is send to scd. With HEXAPDU being the string
|
* RESET command is send to scd. HEXAPDU may also be one of theseo
|
||||||
* "undefined" the command "SERIALNO undefined" is send to scd. If
|
* special strings:
|
||||||
* R_DATA is not NULL the data without the status code is stored
|
*
|
||||||
|
* "undefined" :: Send the command "SCD SERIALNO undefined"
|
||||||
|
* "lock" :: Send the command "SCD LOCK --wait"
|
||||||
|
* "trylock" :: Send the command "SCD LOCK"
|
||||||
|
* "unlock" :: Send the command "SCD UNLOCK"
|
||||||
|
* "reset-keep-lock" :: Send the command "SCD RESET --keep-lock"
|
||||||
|
*
|
||||||
|
* If R_DATA is not NULL the data without the status code is stored
|
||||||
* there. Caller must release it. If OPTIONS is not NULL, this will
|
* there. Caller must release it. If OPTIONS is not NULL, this will
|
||||||
* be passed verbatim to the SCDaemon's APDU command. */
|
* be passed verbatim to the SCDaemon's APDU command. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
@ -447,6 +454,26 @@ scd_apdu (const char *hexapdu, const char *options, unsigned int *r_sw,
|
|||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (hexapdu, "reset-keep-lock"))
|
||||||
|
{
|
||||||
|
err = assuan_transact (agent_ctx, "SCD RESET --keep-lock",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
else if (!strcmp (hexapdu, "lock"))
|
||||||
|
{
|
||||||
|
err = assuan_transact (agent_ctx, "SCD LOCK --wait",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
else if (!strcmp (hexapdu, "trylock"))
|
||||||
|
{
|
||||||
|
err = assuan_transact (agent_ctx, "SCD LOCK",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
else if (!strcmp (hexapdu, "unlock"))
|
||||||
|
{
|
||||||
|
err = assuan_transact (agent_ctx, "SCD UNLOCK",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
else if (!strcmp (hexapdu, "undefined"))
|
else if (!strcmp (hexapdu, "undefined"))
|
||||||
{
|
{
|
||||||
err = assuan_transact (agent_ctx, "SCD SERIALNO undefined",
|
err = assuan_transact (agent_ctx, "SCD SERIALNO undefined",
|
||||||
|
@ -92,8 +92,13 @@ send_apdu (const char *hexapdu, const char *desc, unsigned int ignore,
|
|||||||
if (err)
|
if (err)
|
||||||
log_error ("sending card command %s failed: %s\n", desc,
|
log_error ("sending card command %s failed: %s\n", desc,
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
else if (!hexapdu || !strcmp (hexapdu, "undefined"))
|
else if (!hexapdu
|
||||||
;
|
|| !strcmp (hexapdu, "undefined")
|
||||||
|
|| !strcmp (hexapdu, "reset-keep-lock")
|
||||||
|
|| !strcmp (hexapdu, "lock")
|
||||||
|
|| !strcmp (hexapdu, "trylock")
|
||||||
|
|| !strcmp (hexapdu, "unlock"))
|
||||||
|
; /* Ignore pseudo APDUs. */
|
||||||
else if (ignore == 0xffff)
|
else if (ignore == 0xffff)
|
||||||
; /* Ignore all status words. */
|
; /* Ignore all status words. */
|
||||||
else if (sw != 0x9000)
|
else if (sw != 0x9000)
|
||||||
|
@ -2922,6 +2922,7 @@ cmd_factoryreset (card_info_t info)
|
|||||||
int termstate = 0;
|
int termstate = 0;
|
||||||
int any_apdu = 0;
|
int any_apdu = 0;
|
||||||
int is_yubikey = 0;
|
int is_yubikey = 0;
|
||||||
|
int locked = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
@ -3026,7 +3027,7 @@ cmd_factoryreset (card_info_t info)
|
|||||||
|
|
||||||
if (is_yubikey)
|
if (is_yubikey)
|
||||||
{
|
{
|
||||||
/* The PIV application si already selected, we only need to
|
/* If the PIV application is already selected, we only need to
|
||||||
* send the special reset APDU after having blocked PIN and
|
* send the special reset APDU after having blocked PIN and
|
||||||
* PUK. Note that blocking the PUK is done using the
|
* PUK. Note that blocking the PUK is done using the
|
||||||
* unblock PIN command. */
|
* unblock PIN command. */
|
||||||
@ -3044,9 +3045,15 @@ cmd_factoryreset (card_info_t info)
|
|||||||
else /* OpenPGP card. */
|
else /* OpenPGP card. */
|
||||||
{
|
{
|
||||||
any_apdu = 1;
|
any_apdu = 1;
|
||||||
/* We need to select a card application before we can send APDUs
|
/* We need to select a card application before we can send
|
||||||
* to the card without scdaemon doing anything on its own. */
|
* APDUs to the card without scdaemon doing anything on its
|
||||||
err = send_apdu (NULL, "RESET", 0, NULL, NULL);
|
* own. We then lock the connection so that other tools
|
||||||
|
* (e.g. Kleopatra) don't try a new select. */
|
||||||
|
err = send_apdu ("lock", "locking connection ", 0, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
locked = 1;
|
||||||
|
err = send_apdu ("reset-keep-lock", "reset", 0, NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
err = send_apdu ("undefined", "dummy select ", 0, NULL, NULL);
|
err = send_apdu ("undefined", "dummy select ", 0, NULL, NULL);
|
||||||
@ -3095,6 +3102,9 @@ cmd_factoryreset (card_info_t info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Finally we reset the card reader once more. */
|
/* Finally we reset the card reader once more. */
|
||||||
|
if (locked)
|
||||||
|
err = send_apdu ("reset-keep-lock", "reset", 0, NULL, NULL);
|
||||||
|
else
|
||||||
err = send_apdu (NULL, "RESET", 0, NULL, NULL);
|
err = send_apdu (NULL, "RESET", 0, NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -3123,6 +3133,8 @@ cmd_factoryreset (card_info_t info)
|
|||||||
* scd serialno openpgp
|
* scd serialno openpgp
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
if (locked)
|
||||||
|
send_apdu ("unlock", "unlocking connection ", 0, NULL, NULL);
|
||||||
xfree (answer);
|
xfree (answer);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user