From 6332016b46fb63365c50ddba874cfce8787efc7b Mon Sep 17 00:00:00 2001 From: frankmorgner Date: Mon, 3 May 2010 19:52:41 +0000 Subject: [PATCH] put static pace functionality into the new program pace-tool git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@86 96b47cad-a561-4643-ad3b-153ac7d7599c --- ccid/Makefile | 13 +++- ccid/pace-tool.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++ ccid/usb.c | 132 +++++--------------------------------- ccid/util.c | 69 ++++++++++++++++++++ ccid/util.h | 29 +++++++++ 5 files changed, 288 insertions(+), 118 deletions(-) create mode 100644 ccid/pace-tool.c create mode 100644 ccid/util.c create mode 100644 ccid/util.h diff --git a/ccid/Makefile b/ccid/Makefile index 09a0461..50ef05f 100644 --- a/ccid/Makefile +++ b/ccid/Makefile @@ -13,17 +13,20 @@ CFLAGS = -Wall -g OPENSSL_CFLAGS = `pkg-config --cflags --libs libssl` OPENSC_CFLAGS = `pkg-config --cflags --libs libopensc` PTHREAD_CFLAGS = -pthread -a_flags = $(CFLAGS) $(OPENSC_CFLAGS) $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) +a_flags = $(CFLAGS) $(OPENSC_CFLAGS) $(PTHREAD_CFLAGS) INSTALL = install INSTALL_PROGRAM = $(INSTALL) TARGETS = ccid -CCID_OBJ = ccid.o sm.o usbstring.o usb.o +CCID_OBJ = ccid.o sm.o usbstring.o usb.o util.o +PTOOL_OBJ = ccid.o sm.o pace-tool.o util.o pace.o pace_lib.o ifdef PACE CCID_OBJ += pace.o pace_lib.o + TARGETS += pace-tool + a_flags += $(OPENSSL_CFLAGS) else a_flags += -DNO_PACE endif @@ -34,6 +37,8 @@ all: $(TARGETS) ccid: $(CCID_OBJ) $(CC) $^ -o $@ $(a_flags) +pace-tool: $(PTOOL_OBJ) + $(CC) $^ -o $@ $(a_flags) %.o: %.c %.h $(CC) $< -o $@ -c $(a_flags) %.o: %.c @@ -42,6 +47,7 @@ ccid: $(CCID_OBJ) install: $(TARGETS) installdirs $(INSTALL_PROGRAM) ccid $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) pace-tool $(DESTDIR)$(bindir) .PHONY: installdirs installdirs: @@ -54,7 +60,8 @@ install-strip: .PHONY: uninstall uninstall: rm -f $(DESTDIR)$(bindir)/ccid + rm -f $(DESTDIR)$(bindir)/pace-tool .PHONY: clean clean: - rm -f $(TARGETS) $(CCID_OBJ) + rm -f $(TARGETS) $(CCID_OBJ) $(PTOOL_OBJ) diff --git a/ccid/pace-tool.c b/ccid/pace-tool.c new file mode 100644 index 0000000..70ecb81 --- /dev/null +++ b/ccid/pace-tool.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2009 Frank Morgner + * + * This file is part of ccid. + * + * ccid is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * ccid is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * ccid. If not, see . + */ +#include "ccid.h" +#include "util.h" +#include +#include + +static int verbose = 0; +static int doinfo = 0; +static u8 dopacetest = 0; +static u8 dochangepin = 0; +static const char *newpin = NULL; +static int usb_reader_num = -1; +static const char *pin = NULL; +static const char *cdriver = NULL; + +#define OPT_HELP 'h' +#define OPT_READER 'r' +#define OPT_PIN 'i' +#define OPT_PUK 'u' +#define OPT_CAN 'a' +#define OPT_MRZ 'z' +#define OPT_CHANGE_PIN 'I' +#define OPT_CHANGE_CAN 'A' +#define OPT_VERBOSE 'v' +#define OPT_INFO 'o' +#define OPT_CARD 'c' + +static const struct option options[] = { + { "help", no_argument, NULL, OPT_HELP }, + { "reader", required_argument, NULL, OPT_READER }, + { "card-driver", required_argument, NULL, OPT_CARD }, + { "test-pin", optional_argument, NULL, OPT_PIN }, + { "test-puk", optional_argument, NULL, OPT_PUK }, + { "test-can", optional_argument, NULL, OPT_CAN }, + { "test-mrz", optional_argument, NULL, OPT_MRZ }, + { "new-pin", optional_argument, NULL, OPT_CHANGE_PIN }, + { "new-can", optional_argument, NULL, OPT_CHANGE_CAN }, + { "verbose", no_argument, NULL, OPT_VERBOSE }, + { "info", no_argument, NULL, OPT_INFO }, + { NULL, 0, NULL, 0 } +}; +static const char *option_help[] = { + "Print help and exit", + "Number of reader to use (default: auto-detect)", + "Which card driver to use (default: auto-detect)", + "Run PACE with PIN", + "Run PACE with PUK", + "Run PACE with CAN", + "Run PACE with MRZ", + "Change PIN when PACE is finished", + "Change CAN when PACE is finished", + "Use (several times) to be more verbose", + "Print version, available readers and drivers.", +}; + +int +main (int argc, char **argv) +{ + int i, oindex = 0; + + while (1) { + i = getopt_long(argc, argv, "hr:i::u::a::z::I::A::voc:", options, &oindex); + if (i == -1) + break; + switch (i) { + case OPT_HELP: + print_usage(argv[0] , options, option_help); + exit(0); + break; + case OPT_READER: + if (sscanf(optarg, "%d", &usb_reader_num) != 1) { + parse_error(argv[0], options, option_help, optarg, oindex); + exit(2); + } + break; + case OPT_CARD: + cdriver = optarg; + break; + case OPT_VERBOSE: + verbose++; + break; + case OPT_INFO: + doinfo++; + break; + case OPT_PUK: + /* PACE_PIN from openssl/pace.h */ + dopacetest = 4; + pin = optarg; + break; + case OPT_PIN: + /* PACE_PIN from openssl/pace.h */ + dopacetest = 3; + pin = optarg; + break; + case OPT_CAN: + /* PACE_PIN from openssl/pace.h */ + dopacetest = 2; + pin = optarg; + break; + case OPT_MRZ: + /* PACE_MRZ from openssl/pace.h */ + dopacetest = 1; + pin = optarg; + break; + case OPT_CHANGE_CAN: + dochangepin = 2; + newpin = optarg; + break; + case OPT_CHANGE_PIN: + dochangepin = 3; + newpin = optarg; + break; + case '?': + /* fall through */ + default: + exit(1); + break; + } + } + + if (optind < argc) { + fprintf (stderr, "Unknown argument%s:", optind+1 == argc ? "" : "s"); + while (optind < argc) { + fprintf(stderr, " \"%s\"", argv[optind++]); + fprintf(stderr, "%c", optind == argc ? '\n' : ','); + } + exit(1); + } + + + if (doinfo) { + fprintf(stderr, "%s 0.9 written by Frank Morgner.\n\n" , + argv[0]); + return ccid_print_avail(verbose); + } + + if (ccid_initialize(usb_reader_num, cdriver, verbose) < 0) { + perror("Can't initialize ccid"); + return 1; + } + + i = ccid_testpace(dopacetest, pin, !pin ? 0 : strlen(pin), + dochangepin, newpin, !newpin ? 0 : strlen(newpin)); + ccid_shutdown(); + return i; +} diff --git a/ccid/usb.c b/ccid/usb.c index d2291c7..9db95f2 100644 --- a/ccid/usb.c +++ b/ccid/usb.c @@ -35,7 +35,6 @@ #include #include #include -#include //#include // #include @@ -47,6 +46,7 @@ #include "usbstring.h" #include "ccid.h" +#include "util.h" #define DRIVER_VENDOR_NUM 0x0D46 /* KOBIL Systems */ #define DRIVER_PRODUCT_NUM 0x3010 /* KOBIL Class 3 Reader */ @@ -57,23 +57,13 @@ static int debug = 0; static int dohid = 0; static int doint = 0; static int doinfo = 0; -static u8 dopacetest = 0; -static u8 dochangepin = 0; -static const char *newpin = NULL; static int usb_reader_num = -1; -static const char *pin = NULL; static const char *cdriver = NULL; #define OPT_HELP 'h' #define OPT_INTERRUPT 'n' #define OPT_READER 'r' #define OPT_SERIAL 's' -#define OPT_PIN 'i' -#define OPT_PUK 'u' -#define OPT_CAN 'a' -#define OPT_MRZ 'z' -#define OPT_CHANGE_PIN 'I' -#define OPT_CHANGE_CAN 'A' #define OPT_PRODUCT 'p' #define OPT_VENDOR 'e' #define OPT_VERBOSE 'v' @@ -85,12 +75,6 @@ static const struct option options[] = { { "help", no_argument, NULL, OPT_HELP }, { "reader", required_argument, NULL, OPT_READER }, { "card-driver", required_argument, NULL, OPT_CARD }, - { "test-pin", optional_argument, NULL, OPT_PIN }, - { "test-puk", optional_argument, NULL, OPT_PUK }, - { "test-can", optional_argument, NULL, OPT_CAN }, - { "test-mrz", optional_argument, NULL, OPT_MRZ }, - { "new-pin", optional_argument, NULL, OPT_CHANGE_PIN }, - { "new-can", optional_argument, NULL, OPT_CHANGE_CAN }, { "serial", required_argument, NULL, OPT_SERIAL }, { "product", required_argument, NULL, OPT_PRODUCT }, { "vendor", required_argument, NULL, OPT_VENDOR }, @@ -104,12 +88,6 @@ static const char *option_help[] = { "Print help and exit", "Number of reader to use (default: auto-detect)", "Which card driver to use (default: auto-detect)", - "Run PACE with PIN", - "Run PACE with PUK", - "Run PACE with CAN", - "Run PACE with MRZ", - "Change PIN when PACE is finished", - "Change CAN when PACE is finished", "USB serial number (default: random)", "USB product ID (default: 0x3010)", "USB vendor ID (default: 0x0D46)", @@ -1716,55 +1694,6 @@ done: return 0; } -/*-------------------------------------------------------------------------*/ -void print_usage(const char *app_name, const struct option options[], - const char *option_help[]) -{ - int i = 0; - printf("Usage: %s [OPTIONS]\nOptions:\n", app_name); - - while (options[i].name) { - char buf[40], tmp[5]; - const char *arg_str; - - /* Skip "hidden" options */ - if (option_help[i] == NULL) { - i++; - continue; - } - - if (options[i].val > 0 && options[i].val < 128) - sprintf(tmp, "-%c", options[i].val); - else - tmp[0] = 0; - switch (options[i].has_arg) { - case 1: - arg_str = " "; - break; - case 2: - arg_str = " [arg]"; - break; - default: - arg_str = ""; - break; - } - sprintf(buf, "--%-13s%s%s", options[i].name, tmp, arg_str); - if (strlen(buf) > 24) { - printf(" %s\n", buf); - buf[0] = '\0'; - } - printf(" %-24s %s\n", buf, option_help[i]); - i++; - } -} - -void parse_error(const char *app_name, const char *optarg, int opt_ind) -{ - printf("Could not parse %s ('%s').\n", options[opt_ind].name, optarg); - print_usage(app_name , options, option_help); - exit(2); -} - int main (int argc, char **argv) { @@ -1789,20 +1718,28 @@ main (int argc, char **argv) exit(0); break; case OPT_READER: - if (sscanf(optarg, "%d", &usb_reader_num) != 1) - parse_error(argv[0], optarg, oindex); + if (sscanf(optarg, "%d", &usb_reader_num) != 1) { + parse_error(argv[0], options, option_help, optarg, oindex); + exit(2); + } break; case OPT_SERIAL: - if (sscanf(optarg, "%56s", serial) != 1) - parse_error(argv[0], optarg, oindex); + if (sscanf(optarg, "%56s", serial) != 1) { + parse_error(argv[0], options, option_help, optarg, oindex); + exit(2); + } break; case OPT_PRODUCT: - if (sscanf(optarg, "%x", &productid) != 1) - parse_error(argv[0], optarg, oindex); + if (sscanf(optarg, "%x", &productid) != 1) { + parse_error(argv[0], options, option_help, optarg, oindex); + exit(2); + } break; case OPT_VENDOR: - if (sscanf(optarg, "%x", &vendorid) != 1) - parse_error(argv[0], optarg, oindex); + if (sscanf(optarg, "%x", &vendorid) != 1) { + parse_error(argv[0], options, option_help, optarg, oindex); + exit(2); + } break; case OPT_CARD: cdriver = optarg; @@ -1813,34 +1750,6 @@ main (int argc, char **argv) case OPT_INFO: doinfo++; break; - case OPT_PUK: - /* PACE_PIN from openssl/pace.h */ - dopacetest = 4; - pin = optarg; - break; - case OPT_PIN: - /* PACE_PIN from openssl/pace.h */ - dopacetest = 3; - pin = optarg; - break; - case OPT_CAN: - /* PACE_PIN from openssl/pace.h */ - dopacetest = 2; - pin = optarg; - break; - case OPT_MRZ: - /* PACE_MRZ from openssl/pace.h */ - dopacetest = 1; - pin = optarg; - break; - case OPT_CHANGE_CAN: - dochangepin = 2; - newpin = optarg; - break; - case OPT_CHANGE_PIN: - dochangepin = 3; - newpin = optarg; - break; case '?': /* fall through */ default: @@ -1870,13 +1779,6 @@ main (int argc, char **argv) return 1; } - if (dopacetest) { - i = ccid_testpace(dopacetest, pin, !pin ? 0 : strlen(pin), - dochangepin, newpin, !newpin ? 0 : strlen(newpin)); - ccid_shutdown(); - return i; - } - if (verbose) fprintf (stderr, "serial=\"%s\"\n", serial); diff --git a/ccid/util.c b/ccid/util.c new file mode 100644 index 0000000..e7f704f --- /dev/null +++ b/ccid/util.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009 Frank Morgner + * + * This file is part of ccid. + * + * ccid is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * ccid is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * ccid. If not, see . + */ +#include "util.h" +#include +#include + +void print_usage(const char *app_name, const struct option options[], + const char *option_help[]) +{ + int i = 0; + printf("Usage: %s [OPTIONS]\nOptions:\n", app_name); + + while (options[i].name) { + char buf[40], tmp[5]; + const char *arg_str; + + /* Skip "hidden" options */ + if (option_help[i] == NULL) { + i++; + continue; + } + + if (options[i].val > 0 && options[i].val < 128) + sprintf(tmp, "-%c", options[i].val); + else + tmp[0] = 0; + switch (options[i].has_arg) { + case 1: + arg_str = " "; + break; + case 2: + arg_str = " [arg]"; + break; + default: + arg_str = ""; + break; + } + sprintf(buf, "--%-13s%s%s", options[i].name, tmp, arg_str); + if (strlen(buf) > 24) { + printf(" %s\n", buf); + buf[0] = '\0'; + } + printf(" %-24s %s\n", buf, option_help[i]); + i++; + } +} + +void parse_error(const char *app_name, const struct option options[], + const char *option_help[], const char *optarg, int opt_ind) +{ + printf("Could not parse %s ('%s').\n", options[opt_ind].name, optarg); + print_usage(app_name , options, option_help); +} diff --git a/ccid/util.h b/ccid/util.h new file mode 100644 index 0000000..bf5665d --- /dev/null +++ b/ccid/util.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009 Frank Morgner + * + * This file is part of ccid. + * + * ccid is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * ccid is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * ccid. If not, see . + */ +#ifndef _CCID_UTIL_H +#define _CCID_UTIL_H + +#include + +void print_usage(const char *app_name, const struct option options[], + const char *option_help[]); +void parse_error(const char *app_name, const struct option options[], + const char *option_help[], const char *optarg, int opt_ind); + +#endif