OpenPGP: Support erasing (reset) card.

Command: openpgp-tool --erase
This commit is contained in:
Nguyễn Hồng Quân 2013-03-04 11:28:08 +07:00
parent 24e3bdb872
commit 3b8f77882b
2 changed files with 86 additions and 1 deletions

View File

@ -2195,6 +2195,66 @@ out:
#endif /* ENABLE_OPENSSL */
/**
* Erase card
**/
static int pgp_erase_card(sc_card_t *card)
{
sc_context_t *ctx = card->ctx;
u8 *apdustring[10] = {
"00:20:00:81:08:40:40:40:40:40:40:40:40",
"00:20:00:81:08:40:40:40:40:40:40:40:40",
"00:20:00:81:08:40:40:40:40:40:40:40:40",
"00:20:00:81:08:40:40:40:40:40:40:40:40",
"00:20:00:83:08:40:40:40:40:40:40:40:40",
"00:20:00:83:08:40:40:40:40:40:40:40:40",
"00:20:00:83:08:40:40:40:40:40:40:40:40",
"00:20:00:83:08:40:40:40:40:40:40:40:40",
"00:e6:00:00",
"00:44:00:00"
};
u8 buf[SC_MAX_APDU_BUFFER_SIZE];
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
sc_apdu_t apdu;
size_t len0;
int commandsnum = 10;
int i, r;
LOG_FUNC_CALLED(ctx);
/* Check card version */
if (card->type != SC_CARD_TYPE_OPENPGP_V2) {
sc_log(ctx, "Card is not OpenPGP v2");
LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT);
}
sc_log(ctx, "Card is OpenPGP v2. Erase card.");
/* Iterate over 10 commands above */
for (i = 0; i < commandsnum; i++) {
/* Convert the string to binary array */
len0 = sizeof(buf);
sc_hex_to_bin(apdustring[i], buf, &len0);
printf("Sending: ");
for (r = 0; r < len0; r++)
printf("%02X ", buf[r]);
printf("\n");
/* Build APDU from binary array */
r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
if (r) {
sc_log(ctx, "Failed to build APDU");
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
}
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
/* Send APDU to card */
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(ctx, r, "Transmiting APDU failed");
}
LOG_FUNC_RETURN(ctx, r);
}
/* ABI: card ctl: perform special card-specific operations */
static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
{
@ -2219,6 +2279,10 @@ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
LOG_FUNC_RETURN(card->ctx, r);
break;
#endif /* ENABLE_OPENSSL */
case SC_CARDCTL_ERASE_CARD:
r = pgp_erase_card(card);
LOG_FUNC_RETURN(card->ctx, r);
break;
}
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

View File

@ -75,6 +75,7 @@ static int opt_verify = 0;
static char *verifytype = NULL;
static int opt_pin = 0;
static char *pin = NULL;
static int opt_erase = 0;
static const char *app_name = "openpgp-tool";
@ -91,6 +92,7 @@ static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ "erase", no_argument, NULL, 'E' },
{ "verify", required_argument, NULL, OPT_VERIFY },
{ "pin", required_argument, NULL, OPT_PIN },
{ NULL, 0, NULL, 0 }
@ -109,6 +111,7 @@ static const char *option_help[] = {
/* h */ "Print this help message",
/* v */ "Verbose operation. Use several times to enable debug output.",
/* V */ "Show version number",
/* E */ "Erase (reset) the card",
"Verify PIN (CHV1, CHV2, CHV3...)",
"PIN string"
};
@ -227,7 +230,7 @@ static int decode_options(int argc, char **argv)
{
int c;
while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvV", options, (int *) 0)) != EOF) {
while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVE", options, (int *) 0)) != EOF) {
switch (c) {
case 'r':
opt_reader = optarg;
@ -287,6 +290,9 @@ static int decode_options(int argc, char **argv)
show_version();
exit(EXIT_SUCCESS);
break;
case 'E':
opt_erase++;
break;
default:
util_print_usage_and_die(app_name, options, option_help, NULL);
}
@ -406,6 +412,18 @@ int do_verify(sc_card_t *card, char *type, char *pin)
return r;
}
int do_erase(sc_card_t *card)
{
int r;
/* Check card version */
if (card->type != SC_CARD_TYPE_OPENPGP_V2) {
printf("Do not erase card which is not OpenPGP v2\n");
}
printf("Erase card\n");
r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL);
return r;
}
int main(int argc, char **argv)
{
sc_context_t *ctx = NULL;
@ -481,6 +499,9 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (opt_erase)
exit_status != do_erase(card);
out:
sc_unlock(card);
sc_disconnect_card(card);