c96f948630454cd7ad45ce47c34650e4a77d52cc
[librfid] / utils / librfid-tool.c
1 /* librfid-tool - a small command-line tool for librfid testing
2  *
3  * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License version 2 
7  *  as published by the Free Software Foundation
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24
25 #define _GNU_SOURCE
26 #include <getopt.h>
27
28 #include <librfid/rfid.h>
29 #include <librfid/rfid_scan.h>
30 #include <librfid/rfid_reader.h>
31 #include <librfid/rfid_layer2.h>
32 #include <librfid/rfid_protocol.h>
33
34 #include <librfid/rfid_protocol_mifare_classic.h>
35 #include <librfid/rfid_protocol_mifare_ul.h>
36
37 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
38
39 static const char *
40 hexdump(const void *data, unsigned int len)
41 {
42         static char string[1024];
43         unsigned char *d = (unsigned char *) data;
44         unsigned int i, left;
45
46         string[0] = '\0';
47         left = sizeof(string);
48         for (i = 0; len--; i += 3) {
49                 if (i >= sizeof(string) -4)
50                         break;
51                 snprintf(string+i, 4, " %02x", *d++);
52         }
53         return string;
54 }
55
56 static struct rfid_reader_handle *rh;
57 static struct rfid_layer2_handle *l2h;
58 static struct rfid_protocol_handle *ph;
59
60 static int reader() {
61         printf("opening reader handle\n");
62         rh = rfid_reader_open(NULL, RFID_READER_CM5121);
63         if (!rh) {
64                 fprintf(stderr, "No Omnikey Cardman 5121 found\n");
65                 rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
66                 if (!rh) {
67                         fprintf(stderr, "No OpenPCD found either\n");
68                         return -1;
69                 }
70         }
71         return 0;
72 }
73 static int init(int layer2)
74 {
75         unsigned char buf[0x3f];
76         int rc;
77
78
79         printf("opening layer2 handle\n");
80         l2h = rfid_layer2_init(rh, layer2);
81         if (!l2h) {
82                 fprintf(stderr, "error during iso14443a_init\n");
83                 return -1;
84         }
85
86         //rc632_register_dump(rh->ah, buf);
87
88         printf("running layer2 anticol\n");
89         rc = rfid_layer2_open(l2h);
90         if (rc < 0) {
91                 fprintf(stderr, "error during layer2_open\n");
92                 return rc;
93         }
94
95         return 0;
96 }
97
98 static int l3(int protocol)
99 {
100         printf("running layer3 (ats)\n");
101         ph = rfid_protocol_init(l2h, protocol);
102         if (!ph) {
103                 fprintf(stderr, "error during protocol_init\n");
104                 return -1;
105         }
106         if (rfid_protocol_open(ph) < 0) {
107                 fprintf(stderr, "error during protocol_open\n");
108                 return -1;
109         }
110
111         printf("we now have layer3 up and running\n");
112
113         return 0;
114 }
115
116 static int select_mf(void)
117 {
118         unsigned char cmd[] = { 0x00, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00 };
119         unsigned char ret[256];
120         unsigned int rlen = sizeof(ret);
121
122         int rv;
123
124         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
125         if (rv < 0)
126                 return rv;
127
128         printf("%d: [%s]\n", rlen, hexdump(ret, rlen));
129
130         return 0;
131 }
132
133
134 static int iso7816_get_challenge(unsigned char len)
135 {
136         unsigned char cmd[] = { 0x00, 0x84, 0x00, 0x00, 0x08 };
137         unsigned char ret[256];
138         unsigned int rlen = sizeof(ret);
139
140         cmd[4] = len;
141
142         int rv;
143
144         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
145         if (rv < 0)
146                 return rv;
147
148         printf("%d: [%s]\n", rlen, hexdump(ret, rlen));
149
150         return 0;
151 }
152
153 int
154 iso7816_select_application(void)
155 {
156         unsigned char cmd[] = { 0x00, 0xa4, 0x04, 0x0c, 0x07,
157                        0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
158         unsigned char resp[7];
159         unsigned int rlen = sizeof(resp);
160
161         int rv;
162
163         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
164         if (rv < 0)
165                 return rv;
166
167         /* FIXME: parse response */
168         printf("%s\n", hexdump(resp, rlen));
169
170         return 0;
171 }
172
173 int
174 iso7816_select_ef(u_int16_t fid)
175 {
176         unsigned char cmd[7] = { 0x00, 0xa4, 0x02, 0x0c, 0x02, 0x00, 0x00 };
177         unsigned char resp[7];
178         unsigned int rlen = sizeof(resp);
179
180         int rv;
181
182         cmd[5] = (fid >> 8) & 0xff;
183         cmd[6] = fid & 0xff;
184
185         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
186         if (rv < 0)
187                 return rv;
188
189         /* FIXME: parse response */
190         printf("%s\n", hexdump(resp, rlen));
191
192         return 0;
193 }
194
195 int
196 iso7816_read_binary(unsigned char *buf, unsigned int *len)
197 {
198         unsigned char cmd[] = { 0x00, 0xb0, 0x00, 0x00, 0x00 };
199         unsigned char resp[256];
200         unsigned int rlen = sizeof(resp);
201         
202         int rv;
203
204         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
205         if (rv < 0)
206                 return rv;
207
208         printf("%s\n", hexdump(resp, rlen));
209
210         /* FIXME: parse response, determine whether we need additional reads */
211
212         /* FIXME: copy 'len' number of response bytes to 'buf' */
213         return 0;
214 }
215
216 /* wrapper function around SELECT EF and READ BINARY */
217 int
218 iso7816_read_ef(u_int16_t fid, unsigned char *buf, unsigned int *len)
219 {
220         int rv;
221
222         rv = iso7816_select_ef(fid);
223         if (rv < 0)
224                 return rv;
225
226         return iso7816_read_binary(buf, len);
227 }
228
229 /* mifare ultralight helpers */
230 int
231 mifare_ulight_write(struct rfid_protocol_handle *ph)
232 {
233         unsigned char buf[4] = { 0xa1, 0xa2, 0xa3, 0xa4 };
234
235         return rfid_protocol_write(ph, 10, buf, 4);
236 }
237
238 int
239 mifare_ulight_blank(struct rfid_protocol_handle *ph)
240 {
241         unsigned char buf[4] = { 0x00, 0x00, 0x00, 0x00 };
242         int i, ret;
243
244         for (i = 4; i <= MIFARE_UL_PAGE_MAX; i++) {
245                 ret = rfid_protocol_write(ph, i, buf, 4);
246                 if (ret < 0)
247                         return ret;
248         }
249         return 0;
250 }
251
252 static int
253 mifare_ulight_read(struct rfid_protocol_handle *ph)
254 {
255         unsigned char buf[20];
256         unsigned int len = sizeof(buf);
257         int ret;
258         int i;
259
260         for (i = 0; i <= MIFARE_UL_PAGE_MAX; i++) {
261                 ret = rfid_protocol_read(ph, i, buf, &len);
262                 if (ret < 0)
263                         return ret;
264
265                 printf("Page 0x%x: %s\n", i, hexdump(buf, 4));
266         }
267         return 0;
268 }
269
270 /* mifare classic helpers */
271 static int
272 mifare_classic_read_sector(struct rfid_protocol_handle *ph, int sector)
273 {
274         unsigned char buf[20];
275         unsigned int len = sizeof(buf);
276         int ret;
277         int block;
278
279         /* FIXME: make this work for sectors > 31 */
280         printf("reading sector %u\n", sector);
281
282         for (block = sector*4; block < sector*4+4; block++) {
283                 printf("reading block %u\n", block);
284                 ret = rfid_protocol_read(ph, block, buf, &len);
285                 if(ret == -ETIMEDOUT)
286                         fprintf(stderr, "TIMEOUT\n");
287                 if (ret < 0)
288                         return ret;
289
290                 printf("Page 0x%x: %s\n", block, hexdump(buf, len));
291         }
292         return 0;
293 }
294
295 static char *proto_names[] = {
296         [RFID_PROTOCOL_TCL] = "tcl",
297         [RFID_PROTOCOL_MIFARE_UL] = "mifare-ultralight",
298         [RFID_PROTOCOL_MIFARE_CLASSIC] = "mifare-classic",
299 };
300
301 static int proto_by_name(const char *name)
302 {
303         int i;
304
305         for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
306                 if (proto_names[i] == NULL)
307                         continue;
308                 if (!strcasecmp(name, proto_names[i]))
309                         return i;
310         }
311         return -1;
312 }
313
314 static char *l2_names[] = {
315         [RFID_LAYER2_ISO14443A] = "iso14443a",
316         [RFID_LAYER2_ISO14443B] = "iso14443b",
317         [RFID_LAYER2_ISO15693] = "iso15693",
318 };
319
320 static int l2_by_name(const char *name)
321 {
322         int i;
323
324         for (i = 0; i < ARRAY_SIZE(l2_names); i++) {
325                 if (l2_names[i] == NULL)
326                         continue;
327                 if (!strcasecmp(name, l2_names[i]))
328                         return i;
329         }
330         return -1;
331 }
332
333 static void help(void)
334 {
335         printf( " -s    --scan\n"
336                 " -p    --protocol {tcl,mifare-ultralight,mifare-classic}\n"
337                 " -l    --layer2   {iso14443a,iso14443b,iso15693}\n"
338                 " -h    --help\n");
339 }
340
341 static struct option opts[] = {
342         { "help", 0, 0, 'h' },
343         { "layer2", 1, 0, 'l' },
344         { "protocol", 1, 0, 'p' },
345         {0, 0, 0, 0}
346 };
347
348 int main(int argc, char **argv)
349 {
350         int rc;
351         char buf[0x40];
352         int i, protocol = -1, layer2 = -1;
353         
354         printf("librfid_tool - (C) 2006 by Harald Welte\n"
355                "This program is Free Software and has "
356                "ABSOLUTELY NO WARRANTY\n\n");
357
358         printf("initializing librfid\n");
359         rfid_init();
360
361         while (1) {
362                 int c, option_index = 0;
363                 c = getopt_long(argc, argv, "hp:l:s", opts, &option_index);
364                 if (c == -1)
365                         break;
366
367                 switch (c) {
368                 case 's':
369                         if (reader() < 0)
370                                 exit(1);
371                         printf("scanning for RFID token...\n");
372                         i = rfid_scan(rh, &l2h, &ph);
373                         exit(0);
374                         break;
375                 case 'p':
376                         protocol = proto_by_name(optarg);
377                         if (protocol < 0) {
378                                 fprintf(stderr, "unknown protocol `%s'\n", 
379                                         optarg);
380                                 exit(2);
381                         }
382                         break;
383                 case 'l':
384                         layer2 = l2_by_name(optarg);
385                         if (layer2 < 0) {
386                                 fprintf(stderr, "unknown layer2 `%s'\n",
387                                         optarg);
388                                 exit(2);
389                         }
390                         break;
391                 case 'h':
392                         help();
393                         exit(0);
394                         break;
395                 }
396         }
397
398         switch (protocol) {
399         case RFID_PROTOCOL_MIFARE_UL:
400         case RFID_PROTOCOL_MIFARE_CLASSIC:
401                 layer2 = RFID_LAYER2_ISO14443A;
402                 break;
403         case -1:
404                 fprintf(stderr, "you have to specify --protocol\n");
405                 exit(2);
406         }
407
408         if (layer2 < 0) {
409                 fprintf(stderr, "you have to specify --layer2\n");
410                 exit(2);
411         }
412         
413         if (reader() < 0)
414                 exit(1);
415
416         if (init(layer2) < 0)
417                 exit(1);
418
419         if (l3(protocol) < 0)
420                 exit(1);
421
422         switch (protocol) {
423                 char buf[32000];
424                 int len = 200;
425
426         case RFID_PROTOCOL_TCL:
427                 printf("Protocol T=CL\n");
428                 /* we've established T=CL at this point */
429                 printf("selecting Master File\n");
430                 rc = select_mf();
431                 if (rc < 0) {
432                         printf("error selecting MF\n");
433                         break;
434                 }
435
436                 printf("Getting random challenge, length 255\n");
437                 rc = iso7816_get_challenge(0xff);
438                 if (rc < 0) {
439                         printf("error getting random challenge\n");
440                         break;
441                 }
442
443                 printf("selecting Passport application\n");
444                 rc = iso7816_select_application();
445                 if (rc < 0) {
446                         printf("error selecting passport application\n");
447                         break;
448                 }
449
450                 printf("selecting EF 0x1e\n");
451                 rc = iso7816_select_ef(0x011e);
452                 if (rc < 0) {
453                         printf("error selecting EF 0x1e\n");
454                         break;
455                 }
456
457                 printf("selecting EF 0x01\n");
458                 rc = iso7816_select_ef(0x0101);
459                 if (rc < 0) {
460                         printf("error selecting EF 0x01\n");
461                         break;
462                 }
463
464                 while (1) {
465                         printf("reading EF1\n");
466                         len = 200;
467                         printf("reading ef\n");
468                         rc = iso7816_read_binary(buf, &len);
469                         if (rc < 0) {
470                                 printf("error reading EF\n");
471                                 break;
472                         }
473                 }
474 #if 0
475                 for (i = 0; i < 4; i++)
476                         iso7816_get_challenge(0xff);
477 #endif
478                 break;
479         case RFID_PROTOCOL_MIFARE_UL:
480                 printf("Protocol Mifare Ultralight\n");
481                 mifare_ulight_read(ph);
482 #if 0
483                 mifare_ulight_blank(ph);
484                 mifare_ulight_write(ph);
485                 mifare_ulight_read(ph);
486 #endif
487                 break;
488         case RFID_PROTOCOL_MIFARE_CLASSIC:
489                 printf("Protocol Mifare Classic\n");
490                 {
491                         int sector;
492                         for (sector = 1; sector < 31; sector++) {
493                                 rc = mfcl_set_key(ph, MIFARE_CL_KEYA_DEFAULT_INFINEON);
494                                 if (rc < 0) {
495                                         printf("key format error\n");
496                                         exit(1);
497                                 }
498                                 rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, sector*4);
499                                 if (rc < 0) {
500                                         printf("mifare auth error\n");
501                                         exit(1);
502                                 } else 
503                                         printf("mifare authe succeeded!\n");
504
505                                 mifare_classic_read_sector(ph, sector);
506                         }
507                 }
508                 break;
509         default:
510                 printf("unknown protocol\n");
511                 exit(1);
512                 break;
513         }
514
515         rfid_reader_close(rh);
516         
517         exit(0);
518 }