7085fc7593c183d6c7ccea6a901a204648cb115e
[librfid] / openct-escape.c
1
2 /*
3  *  This program is free software; you can redistribute it and/or modify
4  *  it under the terms of the GNU General Public License version 2 
5  *  as published by the Free Software Foundation
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <openct/openct.h>
22
23 #include <rfid/rfid.h>
24 #include <rfid/rfid_reader.h>
25 #include <rfid/rfid_layer2.h>
26 #include <rfid/rfid_protocol.h>
27 #include <rfid/rfid_reader_cm5121.h>
28
29 static int slot = 1;
30 static ct_handle *h;
31 static ct_lock_handle lock;
32
33 static struct rfid_reader_handle *rh;
34 static struct rfid_layer2_handle *l2h;
35 static struct rfid_protocol_handle *ph;
36
37
38 /* this is the sole function required by rfid_reader_cm5121.c */
39 int 
40 PC_to_RDR_Escape(void *handle, 
41                  const unsigned char *tx_buf, unsigned int tx_len,
42                  unsigned char *rx_buf, unsigned int *rx_len)
43 {
44         ct_handle *h = (ct_handle *) handle;
45         int rc;
46
47         rc = ct_card_transact(h, 1, tx_buf, tx_len, rx_buf, *rx_len);
48         if (rc >= 0) {
49                 *rx_len = rc;
50                 return 0;
51         }
52
53         return rc;
54 }
55
56
57
58 static int init()
59 {
60         unsigned char buf[0x3f];
61         unsigned char atr[64];
62         int rc;
63
64         h = ct_reader_connect(0);
65         if (!h)
66                 return -1;
67
68         printf("acquiring card lock\n");
69         rc = ct_card_lock(h, slot, IFD_LOCK_EXCLUSIVE, &lock);
70         if (rc < 0) {
71                 fprintf(stderr, "error, no card lock\n");
72                 return -1;
73         }
74
75         rc = ct_card_reset(h, slot, atr, sizeof(atr));
76         if (rc < 0) {
77                 fprintf(stderr, "error, can't reset virtual card\n");
78                 return -1;
79         }
80
81         printf("initializing librfid\n");
82         rfid_init();
83
84         printf("opening reader handle\n");
85         rh = rfid_reader_open(h, RFID_READER_CM5121);
86         if (!rh) {
87                 fprintf(stderr, "error, no cm5121 handle\n");
88                 return -1;
89         }
90
91         sleep(2);
92
93         printf("opening layer2 handle\n");
94         l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A);
95         //l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443B);
96         if (!l2h) {
97                 fprintf(stderr, "error during iso14443a_init\n");
98                 return -1;
99         }
100
101         //rc632_register_dump(rh->ah, buf);
102
103         printf("running layer2 anticol\n");
104         rc = rfid_layer2_open(l2h);
105         if (rc < 0) {
106                 fprintf(stderr, "error during layer2_open\n");
107                 return rc;
108         }
109
110         return 0;
111 }
112
113 static int l3(int protocol)
114 {
115         printf("running layer3 (ats)\n");
116         ph = rfid_protocol_init(l2h, protocol);
117         if (!ph) {
118                 fprintf(stderr, "error during protocol_init\n");
119                 return -1;
120         }
121         if (rfid_protocol_open(ph) < 0) {
122                 fprintf(stderr, "error during protocol_open\n");
123                 return -1;
124         }
125
126         printf("we now have layer3 up and running\n");
127
128         return 0;
129 }
130
131 static int select_mf(void)
132 {
133         unsigned char cmd[] = { 0x00, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00 };
134         unsigned char ret[256];
135         unsigned int rlen = sizeof(ret);
136
137         int rv;
138
139         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
140         if (rv < 0)
141                 return rv;
142
143         printf("%s\n", rfid_hexdump(ret, rlen));
144
145         return 0;
146 }
147
148
149 static int get_challenge(unsigned char len)
150 {
151         unsigned char cmd[] = { 0x00, 0x84, 0x00, 0x00, 0x08 };
152         unsigned char ret[256];
153         unsigned int rlen = sizeof(ret);
154
155         cmd[4] = len;
156
157         int rv;
158
159         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
160         if (rv < 0)
161                 return rv;
162
163         //printf("%s\n", rfid_hexdump(ret, rlen));
164
165         return 0;
166 }
167
168 int
169 iso7816_select_application(void)
170 {
171         char cmd[] = { 0x00, 0xa4, 0x04, 0x0c, 0x07,
172                        0x0a, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
173         char resp[7];
174         unsigned int rlen = sizeof(resp);
175
176         int rv;
177
178         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
179         if (rv < 0)
180                 return rv;
181
182         /* FIXME: parse response */
183         return 0;
184 }
185
186 int
187 iso7816_select_ef(u_int16_t fid)
188 {
189         unsigned char cmd[7] = { 0x00, 0xa4, 0x02, 0x0c, 0x02, 0x00, 0x00 };
190         unsigned char resp[7];
191         unsigned int rlen = sizeof(resp);
192
193         int rv;
194
195         cmd[5] = (fid >> 8) & 0xff;
196         cmd[6] = fid & 0xff;
197
198         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
199         if (rv < 0)
200                 return rv;
201
202         /* FIXME: parse response */
203
204         return 0;
205 }
206
207 int
208 iso7816_read_binary(unsigned char *buf, unsigned int *len)
209 {
210         unsigned char cmd[] = { 0x00, 0xb0, 0x00, 0x00, 0x00 };
211         unsigned char resp[256];
212         unsigned int rlen = sizeof(resp);
213         
214         int rv;
215
216         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
217         if (rv < 0)
218                 return rv;
219
220         /* FIXME: parse response, determine whether we need additional reads */
221
222         /* FIXME: copy 'len' number of response bytes to 'buf' */
223         return 0;
224 }
225
226 /* wrapper function around SELECT EF and READ BINARY */
227 int
228 iso7816_read_ef(u_int16_t fid, unsigned char *buf, unsigned int *len)
229 {
230         int rv;
231
232         rv = iso7816_select_ef(fid);
233         if (rv < 0)
234                 return rv;
235
236         return iso7816_read_binary(buf, len);
237 }
238
239 int
240 mifare_ulight_write(struct rfid_protocol_handle *ph)
241 {
242         unsigned char buf[4] = { 0xa1, 0xa2, 0xa3, 0xa4 };
243
244         return rfid_protocol_write(ph, 20, buf, 4);
245 }
246
247 int
248 mifare_ulight_blank(struct rfid_protocol_handle *ph)
249 {
250         unsigned char buf[4] = { 0x00, 0x00, 0x00, 0x00 };
251         int i, ret;
252
253         for (i = 4; i <= MIFARE_UL_PAGE_MAX; i++) {
254                 ret = rfid_protocol_write(ph, i, buf, 4);
255                 if (ret < 0)
256                         return ret;
257         }
258         return 0;
259 }
260
261 int
262 mifare_ulight_read(struct rfid_protocol_handle *ph)
263 {
264         unsigned char buf[20];
265         unsigned int len = sizeof(buf);
266         int ret;
267         int i;
268
269         for (i = 0; i <= MIFARE_UL_PAGE_MAX; i++) {
270                 ret = rfid_protocol_read(ph, i, buf, &len);
271                 if (ret < 0)
272                         return ret;
273
274                 rfid_hexdump(buf, 4);
275         }
276         return 0;
277 }
278
279 int main(int argc, char **argv)
280 {
281         int rc;
282         char buf[0x40];
283         int i, protocol;
284
285         if (init() < 0)
286                 exit(1);
287
288         protocol = RFID_PROTOCOL_MIFARE_UL;
289 //      protocol = RFID_PROTOCOL_TCL;
290
291         if (l3(protocol) < 0)
292                 exit(1);
293
294         switch (protocol) {
295         case RFID_PROTOCOL_TCL:
296                 /* we've established T=CL at this point */
297                 select_mf();
298
299                 rc632_register_dump(rh->ah, buf);
300                 select_mf();
301
302                 iso7816_select_application();
303                 iso7816_select_ef(0x011e);
304                 iso7816_select_ef(0x0101);
305 #if 0
306                 for (i = 0; i < 4; i++)
307                         get_challenge(0x60);
308 #endif
309                 break;
310         case RFID_PROTOCOL_MIFARE_UL:
311                 mifare_ulight_read(ph);
312                 //mifare_ulight_blank(ph);
313                 mifare_ulight_write(ph);
314                 mifare_ulight_read(ph);
315                 break;
316         }
317
318
319         rfid_reader_close(rh);
320         
321         exit(0);
322 }