|
From 6d138f0199575516bfaad18cbbafcfa2ee61e58f 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/26] OpenPGP: Support erasing (reset) card.
|
|
|
|
Command: openpgp-tool --erase
|
|
---
|
|
src/libopensc/card-openpgp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
|
|
src/tools/openpgp-tool.c | 22 ++++++++++++++-
|
|
2 files changed, 85 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
|
|
index 1cc3923..7349876 100644
|
|
--- a/src/libopensc/card-openpgp.c
|
|
+++ b/src/libopensc/card-openpgp.c
|
|
@@ -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);
|
|
diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
|
|
index a24a395..de1c9d4 100644
|
|
--- a/src/tools/openpgp-tool.c
|
|
+++ b/src/tools/openpgp-tool.c
|
|
@@ -78,6 +78,7 @@ static int opt_pin = 0;
|
|
static char *pin = NULL;
|
|
static int opt_dump_do = 0;
|
|
static u8 do_dump_idx;
|
|
+static int opt_erase = 0;
|
|
|
|
static const char *app_name = "openpgp-tool";
|
|
|
|
@@ -94,6 +95,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 },
|
|
{ "do", required_argument, NULL, 'd' },
|
|
@@ -113,6 +115,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",
|
|
/* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)"
|
|
@@ -232,7 +235,7 @@ static int decode_options(int argc, char **argv)
|
|
{
|
|
int c;
|
|
|
|
- while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:", options, (int *) 0)) != EOF) {
|
|
+ while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:E", options, (int *) 0)) != EOF) {
|
|
switch (c) {
|
|
case 'r':
|
|
opt_reader = optarg;
|
|
@@ -296,6 +299,8 @@ static int decode_options(int argc, char **argv)
|
|
do_dump_idx = optarg[0] - '0';
|
|
opt_dump_do++;
|
|
actions++;
|
|
+ case 'E':
|
|
+ opt_erase++;
|
|
break;
|
|
default:
|
|
util_print_usage_and_die(app_name, options, option_help, NULL);
|
|
@@ -452,6 +457,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;
|
|
@@ -531,6 +548,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);
|
|
--
|
|
2.1.3
|
|
|