source: trunk/src/tools/openct-tool.c @ 963

Revision 963, 7.2 KB checked in by aj, 5 years ago (diff)

indent changes only.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * openct-tool
3 *
4 * Copyright (C) 2003 Olaf Kirch <okir@suse.de>
5 */
6
7#ifdef HAVE_CONFIG_H
8#include <config.h>
9#endif
10#ifdef HAVE_GETOPT_H
11#include <getopt.h>
12#endif
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17#include <ctype.h>
18#include <openct/openct.h>
19#include <openct/logging.h>
20#include <openct/error.h>
21
22static void usage(int exval);
23static void version(void);
24static int do_reset(ct_handle *, unsigned char *, size_t);
25static void do_select_mf(ct_handle * reader);
26static void do_read_memory(ct_handle *, unsigned int, unsigned int);
27static void print_reader(ct_handle * h);
28static void print_reader_info(ct_info_t * info);
29static void print_atr(ct_handle *, unsigned char *, size_t);
30static void dump(unsigned char *data, size_t len);
31
32static unsigned int opt_reader = 0;
33static unsigned int opt_slot = 0;
34static const char *opt_config = NULL;
35static int opt_debug = 0;
36static int opt_command = -1;
37
38enum {
39        CMD_LIST = 0,
40        CMD_WAIT,
41        CMD_RWAIT,
42        CMD_ATR,
43        CMD_MF,
44        CMD_READ,
45        CMD_VERSION
46};
47
48int main(int argc, char **argv)
49{
50        unsigned char atr[64];
51        const char *cmd;
52        ct_handle *h;
53        ct_lock_handle lock;
54        int c, rc;
55
56        while ((c = getopt(argc, argv, "df:r:s:hv")) != -1) {
57                switch (c) {
58                case 'd':
59                        opt_debug++;
60                        break;
61                case 'f':
62                        opt_config = optarg;
63                        break;
64                case 'v':
65                        version();
66                case 'h':
67                        usage(0);
68                case 'r':
69                        opt_reader = atoi(optarg);
70                        break;
71                case 's':
72                        opt_slot = atoi(optarg);
73                        break;
74                default:
75                        usage(1);
76                }
77        }
78
79        if (optind == argc)
80                usage(1);
81
82        cmd = argv[optind++];
83
84        if (!strcmp(cmd, "list"))
85                opt_command = CMD_LIST;
86        else if (!strcmp(cmd, "atr"))
87                opt_command = CMD_ATR;
88        else if (!strcmp(cmd, "rwait"))
89                opt_command = CMD_RWAIT;
90        else if (!strcmp(cmd, "wait"))
91                opt_command = CMD_WAIT;
92        else if (!strcmp(cmd, "mf"))
93                opt_command = CMD_MF;
94        else if (!strcmp(cmd, "read"))
95                opt_command = CMD_READ;
96        else {
97                fprintf(stderr, "Unknown command \"%s\"\n", cmd);
98                usage(1);
99        }
100
101        if (opt_command == CMD_LIST) {
102                int i;
103
104                for (i = 0; i < OPENCT_MAX_READERS; i++) {
105                        ct_info_t info;
106
107                        if (ct_reader_info(i, &info) < 0)
108                                continue;
109                        printf(" %2d ", i);
110                        print_reader_info(&info);
111                }
112
113                exit(0);
114        }
115
116        if (opt_command == CMD_RWAIT) {
117                while (1) {
118                        h = ct_reader_connect(opt_reader);
119                        if (h) {
120                                free(h);
121                                break;
122                        }
123                        sleep(1);
124                }
125                exit(0);
126        }
127
128        if (!(h = ct_reader_connect(opt_reader))) {
129                fprintf(stderr, "Unknown reader #%u\n", opt_reader);
130                return 1;
131        }
132
133        if (opt_command == CMD_WAIT) {
134                int status;
135
136                while (1) {
137                        if ((rc = ct_card_status(h, opt_slot, &status)) < 0) {
138                                fprintf(stderr,
139                                        "failed to get card status: %s\n",
140                                        ct_strerror(rc));
141                                return 1;
142                        }
143                        if (status)
144                                break;
145                        sleep(1);
146                }
147                printf("Card detected\n");
148                return 0;
149        }
150
151        printf("Detected ");
152        print_reader(h);
153
154        if ((rc = ct_card_lock(h, opt_slot, IFD_LOCK_SHARED, &lock)) < 0) {
155                fprintf(stderr, "ct_card_lock: err=%d\n", rc);
156                exit(1);
157        }
158
159        rc = do_reset(h, atr, sizeof(atr));
160
161        switch (opt_command) {
162        case CMD_ATR:
163                print_atr(h, atr, rc);
164                break;
165
166        case CMD_MF:
167                do_select_mf(h);
168                break;
169
170        case CMD_READ:{
171                        unsigned int address = 0, count = 1024;
172
173                        if (optind < argc)
174                                address = strtoul(argv[optind++], NULL, 0);
175                        if (optind < argc)
176                                count = strtoul(argv[optind++], NULL, 0);
177                        do_read_memory(h, address, count);
178                }
179                break;
180        }
181
182        ct_card_unlock(h, 0, lock);
183        sleep(1);
184        return 0;
185}
186
187static void version(void)
188{
189        fprintf(stdout, "OpenCT " VERSION "\n");
190        exit(0);
191}
192
193static void usage(int exval)
194{
195        fprintf(exval ? stderr : stdout,
196                "usage: openct-tool [-d] [-f configfile] [-r reader] command ...\n"
197                "  -d   enable debugging; repeat to increase verbosity\n"
198                "  -f   specify config file (default %s)\n"
199                "  -r   specify index of reader to use\n"
200                "  -s   specify slot of reader to use\n"
201                "  -h   display this message\n"
202                "  -v   display version and exit\n"
203                "\n"
204                "command: can be one of the following\n"
205                " list  list all readers found\n"
206                " atr   print ATR of card in selected reader\n"
207                " wait  wait for card to be inserted\n"
208                " rwait wait for reader to be attached\n"
209                " mf    try to select main folder of card\n"
210                " read  dump memory of synchronous card\n", OPENCT_CONF_PATH);
211        exit(exval);
212}
213
214static int do_reset(ct_handle * h, unsigned char *atr, size_t atr_len)
215{
216        int rc, n, status;
217
218        if ((rc = ct_card_status(h, opt_slot, &status)) < 0) {
219                fprintf(stderr, "ct_card_status: err=%d\n", rc);
220                exit(1);
221        }
222
223        printf("Card %spresent%s\n",
224               (status & IFD_CARD_PRESENT) ? "" : "not ",
225               (status & IFD_CARD_STATUS_CHANGED) ? ", status changed" : "");
226
227        if (status & IFD_CARD_PRESENT) {
228                n = ct_card_reset(h, opt_slot, atr, atr_len);
229        } else {
230                n = ct_card_request(h, opt_slot, 5, "Please insert card",
231                                    atr, atr_len);
232        }
233
234        if (n < 0) {
235                fprintf(stderr, "failed to reset card\n");
236                exit(1);
237        }
238
239        return n;
240}
241
242static void do_select_mf(ct_handle * h)
243{
244        unsigned char cmd[] =
245            { 0x00, 0xA4, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00 };
246        unsigned char res[256];
247        ct_lock_handle lock;
248        int rc;
249
250        if ((rc = ct_card_lock(h, opt_slot, IFD_LOCK_EXCLUSIVE, &lock)) < 0) {
251                fprintf(stderr, "ct_card_lock: err=%d\n", rc);
252                exit(1);
253        }
254
255      again:
256        rc = ct_card_transact(h, opt_slot, cmd, sizeof(cmd), res, sizeof(res));
257        if (rc < 0) {
258                fprintf(stderr, "card communication failure, err=%d\n", rc);
259                return;
260        }
261
262        if (rc == 2 && res[0] == 0x6A && res[1] == 0x86) {
263                /* FIXME - Cryptoflex needs class byte 0xC0 :-( */
264                if (cmd[0] == 0x00) {
265                        cmd[0] = 0xC0;
266                        goto again;
267                }
268        }
269
270        printf("Selected MF, response:\n");
271        dump(res, rc);
272}
273
274static void do_read_memory(ct_handle * h, unsigned int address,
275                           unsigned int count)
276{
277        unsigned char buffer[8192];
278        int rc;
279
280        if (count > sizeof(buffer))
281                count = sizeof(buffer);
282
283        rc = ct_card_read_memory(h, opt_slot, address, buffer, count);
284        if (rc < 0) {
285                fprintf(stderr,
286                        "failed to read memory card: %s\n", ct_strerror(rc));
287                exit(1);
288        }
289
290        printf("Read %u bytes at address 0x%04x\n", rc, address);
291        dump(buffer, rc);
292}
293
294static void print_reader(ct_handle * h)
295{
296        ct_info_t info;
297        int rc;
298
299        if ((rc = ct_reader_status(h, &info)) < 0) {
300                printf("ct_reader_status: err=%d\n", rc);
301        } else {
302                print_reader_info(&info);
303        }
304}
305
306static void print_reader_info(ct_info_t * info)
307{
308        const char *sepa;
309
310        printf("%s", info->ct_name);
311
312        sepa = " (";
313        if (info->ct_slots != 1) {
314                printf("%s%d slots", sepa, info->ct_slots);
315                sepa = ", ";
316        }
317        if (info->ct_display) {
318                printf("%sdisplay", sepa);
319                sepa = ", ";
320        }
321        if (info->ct_keypad) {
322                printf("%skeypad", sepa);
323                sepa = ", ";
324        }
325        if (sepa[0] != ' ')
326                printf(")");
327        printf("\n");
328}
329
330static void print_atr(ct_handle * h, unsigned char *atr, size_t len)
331{
332        unsigned int m;
333
334        printf("ATR:");
335        if (len == 0) {
336                printf("<empty>");
337        } else {
338                for (m = 0; m < len; m++)
339                        printf(" %02x", atr[m]);
340        }
341        printf("\n");
342}
343
344static void dump(unsigned char *data, size_t len)
345{
346        unsigned int offset = 0;
347
348        do {
349                unsigned int i;
350
351                printf("%04x:", offset);
352                for (i = 0; i < 16; i++) {
353                        if (offset + i < len)
354                                printf(" %02x", data[offset + i]);
355                        else
356                                printf("   ");
357                }
358                printf("   ");
359                for (i = 0; i < 16 && offset + i < len; i++) {
360                        int c = data[offset + i];
361
362                        if (!isprint(c) || (isspace(c) && c != ' '))
363                                c = '.';
364                        printf("%c", c);
365                }
366                offset += 16;
367                printf("\n");
368        } while (offset < len);
369}
Note: See TracBrowser for help on using the repository browser.