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.

172 lines
5.0 KiB

  1. From 6d138f0199575516bfaad18cbbafcfa2ee61e58f Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  3. <ng.hong.quan@gmail.com>
  4. Date: Mon, 4 Mar 2013 11:28:08 +0700
  5. Subject: [PATCH 05/26] OpenPGP: Support erasing (reset) card.
  6. Command: openpgp-tool --erase
  7. ---
  8. src/libopensc/card-openpgp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
  9. src/tools/openpgp-tool.c | 22 ++++++++++++++-
  10. 2 files changed, 85 insertions(+), 1 deletion(-)
  11. diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
  12. index 1cc3923..7349876 100644
  13. --- a/src/libopensc/card-openpgp.c
  14. +++ b/src/libopensc/card-openpgp.c
  15. @@ -2195,6 +2195,66 @@ out:
  16. #endif /* ENABLE_OPENSSL */
  17. +/**
  18. + * Erase card
  19. + **/
  20. +static int pgp_erase_card(sc_card_t *card)
  21. +{
  22. + sc_context_t *ctx = card->ctx;
  23. + u8 *apdustring[10] = {
  24. + "00:20:00:81:08:40:40:40:40:40:40:40:40",
  25. + "00:20:00:81:08:40:40:40:40:40:40:40:40",
  26. + "00:20:00:81:08:40:40:40:40:40:40:40:40",
  27. + "00:20:00:81:08:40:40:40:40:40:40:40:40",
  28. + "00:20:00:83:08:40:40:40:40:40:40:40:40",
  29. + "00:20:00:83:08:40:40:40:40:40:40:40:40",
  30. + "00:20:00:83:08:40:40:40:40:40:40:40:40",
  31. + "00:20:00:83:08:40:40:40:40:40:40:40:40",
  32. + "00:e6:00:00",
  33. + "00:44:00:00"
  34. + };
  35. + u8 buf[SC_MAX_APDU_BUFFER_SIZE];
  36. + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
  37. + sc_apdu_t apdu;
  38. + size_t len0;
  39. + int commandsnum = 10;
  40. + int i, r;
  41. +
  42. + LOG_FUNC_CALLED(ctx);
  43. +
  44. + /* Check card version */
  45. + if (card->type != SC_CARD_TYPE_OPENPGP_V2) {
  46. + sc_log(ctx, "Card is not OpenPGP v2");
  47. + LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT);
  48. + }
  49. + sc_log(ctx, "Card is OpenPGP v2. Erase card.");
  50. +
  51. + /* Iterate over 10 commands above */
  52. + for (i = 0; i < commandsnum; i++) {
  53. + /* Convert the string to binary array */
  54. + len0 = sizeof(buf);
  55. + sc_hex_to_bin(apdustring[i], buf, &len0);
  56. + printf("Sending: ");
  57. + for (r = 0; r < len0; r++)
  58. + printf("%02X ", buf[r]);
  59. + printf("\n");
  60. +
  61. + /* Build APDU from binary array */
  62. + r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
  63. + if (r) {
  64. + sc_log(ctx, "Failed to build APDU");
  65. + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
  66. + }
  67. + apdu.resp = rbuf;
  68. + apdu.resplen = sizeof(rbuf);
  69. +
  70. + /* Send APDU to card */
  71. + r = sc_transmit_apdu(card, &apdu);
  72. + LOG_TEST_RET(ctx, r, "Transmiting APDU failed");
  73. + }
  74. + LOG_FUNC_RETURN(ctx, r);
  75. +}
  76. +
  77. /* ABI: card ctl: perform special card-specific operations */
  78. static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
  79. {
  80. @@ -2219,6 +2279,10 @@ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
  81. LOG_FUNC_RETURN(card->ctx, r);
  82. break;
  83. #endif /* ENABLE_OPENSSL */
  84. + case SC_CARDCTL_ERASE_CARD:
  85. + r = pgp_erase_card(card);
  86. + LOG_FUNC_RETURN(card->ctx, r);
  87. + break;
  88. }
  89. LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
  90. diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
  91. index a24a395..de1c9d4 100644
  92. --- a/src/tools/openpgp-tool.c
  93. +++ b/src/tools/openpgp-tool.c
  94. @@ -78,6 +78,7 @@ static int opt_pin = 0;
  95. static char *pin = NULL;
  96. static int opt_dump_do = 0;
  97. static u8 do_dump_idx;
  98. +static int opt_erase = 0;
  99. static const char *app_name = "openpgp-tool";
  100. @@ -94,6 +95,7 @@ static const struct option options[] = {
  101. { "help", no_argument, NULL, 'h' },
  102. { "verbose", no_argument, NULL, 'v' },
  103. { "version", no_argument, NULL, 'V' },
  104. + { "erase", no_argument, NULL, 'E' },
  105. { "verify", required_argument, NULL, OPT_VERIFY },
  106. { "pin", required_argument, NULL, OPT_PIN },
  107. { "do", required_argument, NULL, 'd' },
  108. @@ -113,6 +115,7 @@ static const char *option_help[] = {
  109. /* h */ "Print this help message",
  110. /* v */ "Verbose operation. Use several times to enable debug output.",
  111. /* V */ "Show version number",
  112. +/* E */ "Erase (reset) the card",
  113. "Verify PIN (CHV1, CHV2, CHV3...)",
  114. "PIN string",
  115. /* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)"
  116. @@ -232,7 +235,7 @@ static int decode_options(int argc, char **argv)
  117. {
  118. int c;
  119. - while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:", options, (int *) 0)) != EOF) {
  120. + while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:E", options, (int *) 0)) != EOF) {
  121. switch (c) {
  122. case 'r':
  123. opt_reader = optarg;
  124. @@ -296,6 +299,8 @@ static int decode_options(int argc, char **argv)
  125. do_dump_idx = optarg[0] - '0';
  126. opt_dump_do++;
  127. actions++;
  128. + case 'E':
  129. + opt_erase++;
  130. break;
  131. default:
  132. util_print_usage_and_die(app_name, options, option_help, NULL);
  133. @@ -452,6 +457,18 @@ int do_verify(sc_card_t *card, char *type, char *pin)
  134. return r;
  135. }
  136. +int do_erase(sc_card_t *card)
  137. +{
  138. + int r;
  139. + /* Check card version */
  140. + if (card->type != SC_CARD_TYPE_OPENPGP_V2) {
  141. + printf("Do not erase card which is not OpenPGP v2\n");
  142. + }
  143. + printf("Erase card\n");
  144. + r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL);
  145. + return r;
  146. +}
  147. +
  148. int main(int argc, char **argv)
  149. {
  150. sc_context_t *ctx = NULL;
  151. @@ -531,6 +548,9 @@ int main(int argc, char **argv)
  152. exit(EXIT_FAILURE);
  153. }
  154. + if (opt_erase)
  155. + exit_status != do_erase(card);
  156. +
  157. out:
  158. sc_unlock(card);
  159. sc_disconnect_card(card);
  160. --
  161. 2.1.3