You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

173 lines
4.9 KiB

From 4cdc5f3102f5ad93d263eea2f8206bb5e9fffc6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
<ng.hong.quan@gmail.com>
Date: Mon, 4 Mar 2013 11:28:08 +0700
Subject: [PATCH 05/18] OpenPGP: Support erasing (reset) card.
Command: openpgp-tool --erase
---
src/libopensc/card-openpgp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
src/tools/openpgp-tool.c | 23 +++++++++++++++-
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
index ead07ae..42a9684 100644
--- a/src/libopensc/card-openpgp.c
+++ b/src/libopensc/card-openpgp.c
@@ -2197,6 +2197,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)
{
@@ -2221,6 +2281,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);
diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
index 8b5e327..0d360a3 100644
--- a/src/tools/openpgp-tool.c
+++ b/src/tools/openpgp-tool.c
@@ -76,6 +76,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";
@@ -92,6 +93,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 }
@@ -110,6 +112,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"
};
@@ -228,7 +231,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;
@@ -288,6 +291,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);
}
@@ -446,6 +452,18 @@ int do_verify(sc_card_t *card, u8 *type, u8* 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;
@@ -521,6 +539,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);
--
1.9.3