Project

General

Profile

Download (10.2 KB) Statistics
| Branch: | Tag: | Revision:
1 13da9a6f (no author)
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <ctype.h>
5
#include <limits.h>
6
7
#include "zebvty/vty.h"
8
#include "zebvty/command.h"
9
10
#define MAX_BUFFER_SIZE		2048
11
#define MAX_LENC	MAX_BUFFER_SIZE
12
#define MAX_LENR	MAX_LENC
13
#define MAX_COMMAND_SIZE	2048
14
15
static void strcompact(char *str)
16
{
17
	int i, j = 0;
18
19
	for (i = 0; i < strlen(str); i++) {
20
		if (!isspace(str[i]))
21
			str[j++] = tolower(str[i]);
22
	}
23
	str[j] = 0;
24
}
25
26
static int strtobin(char *s, unsigned char *d, unsigned int *len)
27
{
28
	long l;
29
	int i, ret;
30
31
	if (*s == ':')
32
		s++;
33
34
	for (i = 0; i < (strlen(s) >> 1); i++) {
35
		if (i >= MAX_LENC || i >> *len)
36
			return 0;
37
		ret = sscanf(s + (i << 1), "%2lx", &l);
38
		if (ret != 1)
39
			return 0;
40
		d[i] = l & 0xff;
41
	}
42
	*len = i;
43
44
	return 1;
45
}
46
47
DEFUN(rc632_reg_read,
48
      rc632_reg_read_cmd, 
49
      "reg_read WORD", 
50
      "Read register of RC632\n")
51
{
52
#if 0
53
	if (send_hex_command(vty, argv[0]) < 0)
54
		return CMD_ERR_NO_MATCH;
55
#endif
56
	return CMD_SUCCESS;
57
}
58
59
60
#if 0
61
static int select_file(struct vty *v, int absolute, int path, 
62
			char *selector, unsigned int sellen, 
63
			unsigned char *rsp, unsigned int *rlen)
64
{
65
	unsigned char cmd[MAX_LENC];
66
67
	cmd[0] = 0x00;
68
	cmd[1] = 0xa4;
69
	if (absolute) {
70
		if (path)
71
			cmd[2] = 0x08;
72
		else
73
			cmd[2] = 0x00;
74
	} else {
75
		if (path)
76
			cmd[2] = 0x09;
77
		else
78
			cmd[2] = 0x02;
79
	}
80
	cmd[3] = 0x00; // FIXME: other templates
81
82
	cmd[4] = sellen & 0xff;
83
84
	memcpy(cmd[5], selector, sellen);
85
	cmd[5+sellen] = 0x00;
86
87
	send_apdu(hCard, v, cmd, 5+cmd[4], rsp, rlen);
88
	parse_selectfile_response(hCard, v, rsp, *rlen);
89
	return CMD_SUCCESS;
90
91
}
92
93
DEFUN(send_7816_select_file_absolute_fid,
94
	send_7816_select_file_absolute_fid_cmd,
95
	"select file absolute fid WORD",
96
	"Selects a file on the ICC\n")
97
{
98
	char *file = argv[0];
99
	unsigned char rsp[MAX_LENR];
100
	unsigned int lenr = MAX_LENR;
101
	unsigned char selector[255];
102
	unsigned int sellen = 255;
103
104
	if (strtobin(file, selector, &sellen) < 0)
105
		return CMD_ERR_NO_MATCH;
106
	
107
	return select_file(vty, 1, 0, selector, sellen, rsp, &lenr);
108
}
109
110
DEFUN(send_7816_select_file_absolute_path,
111
	send_7816_select_file_absolute_path_cmd,
112
	"select file absolute path WORD",
113
	"Selects a file on the ICC\n")
114
{
115
	char *file = argv[0];
116
	unsigned char rsp[MAX_LENR];
117
	unsigned int lenr = MAX_LENR;
118
	unsigned char selector[255];
119
	unsigned int sellen = 255;
120
121
	if (strtobin(file, selector, &sellen) < 0)
122
		return CMD_ERR_NO_MATCH;
123
	
124
125
	return select_file(vty, 1, 1, selector, sellen, rsp, &lenr);
126
}
127
128
DEFUN(send_7816_select_file_relative_fid,
129
	send_7816_select_file_relative_fid_cmd,
130
	"select file absolute fid WORD",
131
	"Selects a file on the ICC\n")
132
{
133
	char *file = argv[0];
134
	unsigned char rsp[MAX_LENR];
135
	unsigned int lenr = MAX_LENR;
136
	unsigned char selector[255];
137
	unsigned int sellen = 255;
138
139
	if (strtobin(file, selector, &sellen) < 0)
140
		return CMD_ERR_NO_MATCH;
141
	
142
143
	return select_file(vty, 0, 0, selector, sellen, rsp, &lenr);
144
}
145
146
147
DEFUN(send_7816_select_file_relative_path,
148
	send_7816_select_file_relative_path_cmd,
149
	"select file relative path WORD",
150
	"Selects a file on the ICC\n")
151
{
152
	char *file = argv[0];
153
	unsigned char rsp[MAX_LENR];
154
	unsigned int lenr = MAX_LENR;
155
	unsigned char selector[255];
156
	unsigned int sellen = 255;
157
158
	if (strtobin(file, selector, &sellen) < 0)
159
		return CMD_ERR_NO_MATCH;
160
	
161
162
	return select_file(vty, 0, 1, selector, sellen, rsp, &lenr);
163
}
164
165
DEFUN(send_7816_select_dir,
166
	send_7816_select_dir_cmd,
167
	"select directory (MF|PARENT|CHILD) (FID|AID)",
168
	"Selects a directory on the ICC\n")
169
{
170
	char *file = argv[1];
171
	char *type = argv[0];
172
	char cmd[22];
173
	char rsp[MAX_LENR];
174
	int len, lenr = MAX_LENR;
175
	int empty = 0;
176
177
	if (!type)
178
		return CMD_ERR_NO_MATCH;
179
180
	memset(cmd, 0, sizeof(cmd));
181
	cmd[1] = 0xa4;
182
183
	if (!strcmp(type, "MF")) {
184
		cmd[2] = 0x00;
185
		cmd[3] = 0x00;
186
		cmd[4] = 2;	/* length */
187
		cmd[5] = 0x3f;	/* 3ff0 */
188
		cmd[6] = 0xf0;
189
		empty = 1;
190
	} else if (!strcmp(type, "PARENT")) {
191
		cmd[2] = 0x03;
192
		cmd[3] = 0x00;
193
		cmd[4] = 0x00;
194
		empty = 1;
195
	} else if (!strcmp(file, "CHILD")) {
196
		cmd[2] = 0x01;
197
		cmd[3] = 0x00;
198
	} else {
199
		cmd[2] = 0x00;
200
		cmd[3] = 0x00;
201
	}
202
203
	if (!empty) {
204
		len = 16;
205
		/* convert hex string of identifier to bytecode */
206
		strtobin(file, &cmd[5], &len);
207
		cmd[4] = len & 0xff;
208
	}
209
	send_apdu(hCard, vty, cmd, 5+cmd[4], rsp, &lenr);
210
	parse_selectfile_response(hCard, vty, rsp, lenr);
211
	return CMD_SUCCESS;
212
}
213
214
DEFUN(send_7816_ls,
215
	send_7816_ls_cmd,
216
	"ls",
217
	"Tries to list all files on a 7816-4 compliant ICC\n")
218
{
219
	return CMD_SUCCESS;
220
}
221
222
DEFUN(send_7816_tree,
223
	send_7816_tree_cmd,
224
	"tree",
225
	"Tries to list a full DF hiararchy tree on a 7816-4 compliant ICC\n")
226
{
227
228
	return CMD_SUCCESS;
229
}
230
231
DEFUN(send_7816_read_binary,
232
	send_7816_read_binary_cmd,
233
	"read binary OFFSET LENGTH",
234
	"Read bytes form a previously selected EF\n")
235
{
236
	unsigned char cmd[] = { 0x00, 0xb0, 0x00, 0x00, 0x00 };
237
	unsigned char rsp[MAX_LENR]; // FIXME
238
	unsigned int lenr = MAX_LENR;
239
	
240
	unsigned long datalen;
241
	unsigned long offset;
242
243
	offset = strtoul(argv[0], NULL, 0);
244
	if (offset == ULONG_MAX || offset > 0xffff)
245
		return CMD_ERR_NO_MATCH;
246
247
	datalen = strtoul(argv[1], NULL, 0);
248
	if (datalen == ULONG_MAX || datalen > 0xff)
249
		return CMD_ERR_NO_MATCH;
250
251
	cmd[2] = (offset >> 8) & 0xff;
252
	cmd[3] = offset & 0xff;
253
	cmd[4] = datalen & 0xff;
254
255
	send_apdu(hCard, vty, cmd, 5+cmd[4], rsp, &lenr);
256
	if (lenr < 2)
257
		return CMD_SUCCESS; // FIXME
258
259
	parse_sw(vty, rsp[lenr-2], rsp[lenr-1]);
260
261
	return CMD_SUCCESS;
262
}
263
264
DEFUN(send_7816_write_binary,
265
	send_7816_write_binary_cmd,
266
	"write binary OFFSET LENGTH DATA",
267
	"Write bytes to a previously selected EF\n")
268
{
269
	unsigned char cmd[MAX_LENC];
270
	unsigned char rsp[MAX_LENR];
271
	unsigned int lenr;
272
273
	unsigned long datalen;
274
	unsigned long offset;
275
276
	offset = strtoul(argv[0], NULL, 0);
277
	if (offset == ULONG_MAX || offset > 0xffff)
278
		return CMD_ERR_NO_MATCH;
279
280
	datalen = strtoul(argv[1], NULL, 0);
281
	if (datalen == ULONG_MAX || datalen > 0xff)
282
		return CMD_ERR_NO_MATCH;
283
284
	memset(cmd, 0, sizeof(cmd));
285
286
	cmd[1] = 0xd0;
287
	cmd[2] = (offset >> 8) & 0xff;
288
	cmd[3] = offset & 0xff;
289
290
	if (!strtobin(argv[2], cmd+5, &datalen)) {
291
		vty_out(vty, "command decoding error%s", vty_newline(vty));
292
		return -1;
293
	}
294
295
	cmd[4] = datalen & 0xff;
296
297
	send_apdu(hCard, vty, cmd, 5+cmd[4], rsp, &lenr);
298
	if (lenr < 2)
299
		return CMD_SUCCESS; // FIXME
300
301
	parse_sw(vty, rsp[lenr-2], rsp[lenr-1]);
302
303
	return CMD_SUCCESS;
304
305
	return CMD_SUCCESS;
306
} 
307
308
DEFUN(send_7816_update_binary,
309
	send_7816_update_binary_cmd,
310
	"update binary OFFSET LENGTH DATA",
311
	"Update bytes of a previously selected EF\n")
312
{
313
	unsigned char cmd[MAX_LENC];
314
	unsigned char rsp[MAX_LENR];
315
	unsigned int lenr;
316
317
	unsigned long datalen;
318
	unsigned long offset;
319
320
	offset = strtoul(argv[0], NULL, 0);
321
	if (offset == ULONG_MAX || offset > 0xffff)
322
		return CMD_ERR_NO_MATCH;
323
324
	datalen = strtoul(argv[1], NULL, 0);
325
	if (datalen == ULONG_MAX || datalen > 0xff)
326
		return CMD_ERR_NO_MATCH;
327
328
	memset(cmd, 0, sizeof(cmd));
329
330
	cmd[1] = 0xd6;
331
	cmd[2] = (offset >> 8) & 0xff;
332
	cmd[3] = offset & 0xff;
333
334
	if (!strtobin(argv[2], cmd+5, &datalen)) {
335
		vty_out(vty, "command decoding error%s", vty_newline(vty));
336
		return -1;
337
	}
338
339
	cmd[4] = datalen & 0xff;
340
341
	send_apdu(hCard, vty, cmd, 5+cmd[4], rsp, &lenr);
342
	if (lenr < 2)
343
		return CMD_SUCCESS; // FIXME
344
345
	parse_sw(vty, rsp[lenr-2], rsp[lenr-1]);
346
347
	return CMD_SUCCESS;
348
} 
349
350
DEFUN(send_7816_erase_binary,
351
	send_7816_erase_binary_cmd,
352
	"erase binary OFFSET LENGTH",
353
	"Erase bytes of a previously selected EF\n")
354
{
355
	unsigned char cmd[8] = { 0x00, 0x0e, 0x00, 0x00,
356
				 0x00, 0x00, 0x00, 0x00 };
357
	unsigned char rsp[MAX_LENR];
358
	unsigned int lenr;
359
360
	unsigned long datalen;
361
	unsigned long offset;
362
363
	offset = strtoul(argv[0], NULL, 0);
364
	if (offset == ULONG_MAX || offset > 0xffff)
365
		return CMD_ERR_NO_MATCH;
366
367
	datalen = strtoul(argv[1], NULL, 0);
368
	if (datalen == ULONG_MAX || (offset+datalen > 0xffff))
369
		return CMD_ERR_NO_MATCH;
370
371
	cmd[2] = (offset >> 8) & 0xff;
372
	cmd[3] = offset & 0xff;
373
	cmd[4] = 0x02;
374
	cmd[5] = ((offset+datalen) >> 8) & 0xff;
375
	cmd[6] = (offset+datalen) & 0xff;
376
377
	send_apdu(hCard, vty, cmd, 5+cmd[4], rsp, &lenr);
378
	if (lenr < 2)
379
		return CMD_SUCCESS; // FIXME
380
381
	parse_sw(vty, rsp[lenr-2], rsp[lenr-1]);
382
383
	return CMD_SUCCESS;
384
}
385
386
DEFUN(send_7816_get_response,
387
	send_7816_get_response_cmd,
388
	"get response LENGTH",
389
	"Get more data from the ICC\n")
390
{
391
	unsigned char cmd[6] = { 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 };
392
	unsigned char rsp[MAX_LENR];
393
	unsigned int lenr = MAX_LENR;
394
395
	unsigned long length;
396
397
	length = strtoul(argv[0], NULL, 0);
398
	if (length == ULONG_MAX || length > 0xff)
399
		return CMD_ERR_NO_MATCH;
400
401
	cmd[5] = length & 0xff;
402
403
	send_apdu(hCard, vty, cmd, 6, rsp, &lenr);
404
	if (lenr < 2)
405
		return CMD_SUCCESS; // FIXME
406
407
	parse_sw(vty, rsp[lenr-2], rsp[lenr-1]);
408
409
	return CMD_SUCCESS;
410
411
}
412
#endif
413
 
414
DEFUN(rc632,
415
	rc632_cmd,
416
	"rc632", "Commands related to low-level RC632 access\n")
417
{
418
	vty->node = RC632_NODE;
419
	return CMD_SUCCESS;
420
}
421
422
/* dummy */
423
static int send_config_write(struct vty *v)
424
{
425
	return CMD_SUCCESS;
426
}
427
428
struct cmd_node rc632_node = {
429
	RC632_NODE,
430
	"%s(rc632)# ",
431
	1,
432
};
433
434
static int opcdshell_init()
435
{
436
	cmd_init(1);
437
	vty_init();
438
439
	install_node(&rc632_node, send_config_write);
440
441
	install_element(RC632_NODE, &rc632_reg_read_cmd);
442
443
#if 0
444
	install_element(RC632_NODE, &send_7816_select_file_absolute_fid_cmd);
445
	install_element(RC632_NODE, &send_7816_select_file_absolute_path_cmd);
446
	install_element(RC632_NODE, &send_7816_select_file_relative_fid_cmd);
447
	install_element(RC632_NODE, &send_7816_select_file_relative_path_cmd);
448
449
	install_element(RC632_NODE, &send_7816_select_dir_cmd);
450
	install_element(RC632_NODE, &send_7816_ls_cmd);
451
	install_element(RC632_NODE, &send_7816_tree_cmd);
452
453
	install_element(RC632_NODE, &send_7816_read_binary_cmd);
454
	install_element(RC632_NODE, &send_7816_write_binary_cmd);
455
	install_element(RC632_NODE, &send_7816_update_binary_cmd);
456
	install_element(RC632_NODE, &send_7816_erase_binary_cmd);
457
458
	install_element(RC632_NODE, &send_7816_get_response_cmd);
459
#endif
460
461
	install_default(RC632_NODE);
462
463
	install_element(VIEW_NODE, &rc632_cmd);
464
465
	return 0;
466
}
467
468
static int opcdshell(void)
469
{
470
	struct vty *v;
471
472
	v = vty_create(0);
473
	if (!v)
474
		return -1;
475
	while (1) {
476
		vty_read(v);
477
	}
478
	return 0;
479
}
480
481
482
/***********************************************************************
483
 * main program, copied from pcsc-lite 'testpcsc.c'
484
 ***********************************************************************/
485
486
int main(int argc, char **argv)
487
{
488
	opcdshell_init();
489
490
	printf("\nopcd_shell (C) 2006 Harald Welte <hwelte@hmw-consulting.de>\n\n");
491
492
	opcdshell();
493
494
	return 0;
495
}
Add picture from clipboard (Maximum size: 48.8 MB)