SmartCrad.rar
上面为源代码有用者可下载
/*
2 * iso7816.c: Functions specified by the ISO 7816 standard
3 *
4 * Copyright (C) 2001, 2002 Juha Yrj鰈?
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "config.h"
22
23 #include
24 #include
25 #include
26 #include
27
28 #include "internal.h"
29 #include "asn1.h"
30 #include "iso7816.h"
31
32 static const struct sc_card_error iso7816_errors[] = {
33 { 0x6200, SC_ERROR_MEMORY_FAILURE, "State of non-volatile memory unchanged" },
34 { 0x6281, SC_ERROR_MEMORY_FAILURE, "Part of returned data may be corrupted" },
35 { 0x6282, SC_ERROR_CARD_CMD_FAILED, "End of file/record reached before reading Le bytes" },
36 { 0x6283, SC_ERROR_CARD_CMD_FAILED, "Selected file invalidated" },
37 { 0x6284, SC_ERROR_CARD_CMD_FAILED, "FCI not formatted according to ISO 7816-4" },
38
39 { 0x6300, SC_ERROR_MEMORY_FAILURE, "State of non-volatile memory changed" },
40 { 0x6381, SC_ERROR_CARD_CMD_FAILED, "File filled up by last write" },
41
42 { 0x6581, SC_ERROR_MEMORY_FAILURE, "Memory failure" },
43
44 { 0x6700, SC_ERROR_WRONG_LENGTH, "Wrong length" },
45
46 { 0x6800, SC_ERROR_NO_CARD_SUPPORT, "Functions in CLA not supported" },
47 { 0x6881, SC_ERROR_NO_CARD_SUPPORT, "Logical channel not supported" },
48 { 0x6882, SC_ERROR_NO_CARD_SUPPORT, "Secure messaging not supported" },
49
50 { 0x6900, SC_ERROR_NOT_ALLOWED, "Command not allowed" },
51 { 0x6981, SC_ERROR_CARD_CMD_FAILED, "Command incompatible with file structure" },
52 { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" },
53 { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" },
54 { 0x6984, SC_ERROR_CARD_CMD_FAILED, "Referenced data invalidated" },
55 { 0x6985, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied" },
56 { 0x6986, SC_ERROR_NOT_ALLOWED, "Command not allowed (no current EF)" },
57 { 0x6987, SC_ERROR_INCORRECT_PARAMETERS,"Expected SM data objects missing" },
58 { 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"SM data objects incorrect" },
59
60 { 0x6A00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
61 { 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters in the data field" },
62 { 0x6A81, SC_ERROR_NO_CARD_SUPPORT, "Function not supported" },
63 { 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File not found" },
64 { 0x6A83, SC_ERROR_RECORD_NOT_FOUND, "Record not found" },
65 { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory space in the file" },
66 { 0x6A85, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with TLV structure" },
67 { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters P1-P2" },
68 { 0x6A87, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with P1-P2" },
69 { 0x6A88, SC_ERROR_DATA_OBJECT_NOT_FOUND,"Referenced data not found" },
70
71 { 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
72 { 0x6D00, SC_ERROR_INS_NOT_SUPPORTED, "Instruction code not supported or invalid" },
73 { 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },
74 { 0x6F00, SC_ERROR_CARD_CMD_FAILED, "No precise diagnosis" },
75
76 /* Possibly TCOS / Micardo specific errors */
77 { 0x6600, SC_ERROR_INCORRECT_PARAMETERS, "Error setting the security env"},
78 { 0x66F0, SC_ERROR_INCORRECT_PARAMETERS, "No space left for padding"},
79 { 0x69F0, SC_ERROR_NOT_ALLOWED, "Command not allowed"},
80 { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS, "Files exists"},
81 { 0x6A8A, SC_ERROR_FILE_ALREADY_EXISTS, "Application exists"},
82 };
83
84 static int iso7816_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
85 {
86 const int err_count = sizeof(iso7816_errors)/sizeof(iso7816_errors[0]);
87 int i;
88
89 /* Handle special cases here */
90 if (sw1 == 0x6C) {
91 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Wrong length; correct length is %d", sw2);
92 return SC_ERROR_WRONG_LENGTH;
93 }
94 if (sw1 == 0x90)
95 return SC_SUCCESS;
96 if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) {
97 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verification failed (remaining tries: %d)",
98 (sw2 & 0x0f));
99 return SC_ERROR_PIN_CODE_INCORRECT;
100 }
101 for (i = 0; i < err_count; i++)
102 if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) {
103 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s", iso7816_errors[i].errorstr);
104 return iso7816_errors[i].errorno;
105 }
106 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);
107 return SC_ERROR_CARD_CMD_FAILED;
108 }
109
110 static int iso7816_read_binary(sc_card_t *card,
111 unsigned int idx, u8 *buf, size_t count,
112 unsigned long flags)
113 {
114 sc_apdu_t apdu;
115 u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
116 int r;
117
118 if (idx > 0x7fff) {
119 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid EF offset: 0x%X > 0x7FFF", idx);
120 return SC_ERROR_OFFSET_TOO_LARGE;
121 }
122
123 assert(count <= (card->max_recv_size > 0 ? card->max_recv_size : 256));
124 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0,
125 (idx >> 8) & 0x7F, idx & 0xFF);
126 apdu.le = count;
127 apdu.resplen = count;
128 apdu.resp = recvbuf;
129
130 r = sc_transmit_apdu(card, &apdu);
131 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
132 if (apdu.resplen == 0)
133 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
134 memcpy(buf, recvbuf, apdu.resplen);
135
136 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);
137 }
138
139 static int iso7816_read_record(sc_card_t *card,
140 unsigned int rec_nr, u8 *buf, size_t count,
141 unsigned long flags)
142 {
143 sc_apdu_t apdu;
144 u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
145 int r;
146
147 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, rec_nr, 0);
148 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
149 if (flags & SC_RECORD_BY_REC_NR)
150 apdu.p2 |= 0x04;
151
152 apdu.le = count;
153 apdu.resplen = count;
154 apdu.resp = recvbuf;
155
156 r = sc_transmit_apdu(card, &apdu);
157 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
158 if (apdu.resplen == 0)
159 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
160 memcpy(buf, recvbuf, apdu.resplen);
161
162 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);
163 }
164
165 static int iso7816_write_record(sc_card_t *card, unsigned int rec_nr,
166 const u8 *buf, size_t count,
167 unsigned long flags)
168 {
169 sc_apdu_t apdu;
170 int r;
171
172 if (count > 256) {
173 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Trying to send too many bytes");
174 return SC_ERROR_INVALID_ARGUMENTS;
175 }
176 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD2, rec_nr, 0);
177 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
178 if (flags & SC_RECORD_BY_REC_NR)
179 apdu.p2 |= 0x04;
180
181 apdu.lc = count;
182 apdu.datalen = count;
183 apdu.data = buf;
184
185 r = sc_transmit_apdu(card, &apdu);
186 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
187 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),
188 "Card returned error");
189 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count);
190 }
191
192 static int iso7816_append_record(sc_card_t *card,
193 const u8 *buf, size_t count,
194 unsigned long flags)
195 {
196 sc_apdu_t apdu;
197 int r;
198
199 if (count > 256) {
200 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Trying to send too many bytes");
201 return SC_ERROR_INVALID_ARGUMENTS;
202 }
203 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE2, 0, 0);
204 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
205
206 apdu.lc = count;
207 apdu.datalen = count;
208 apdu.data = buf;
209
210 r = sc_transmit_apdu(card, &apdu);
211 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
212 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),
213 "Card returned error");
214 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count);
215 }
216
217 static int iso7816_update_record(sc_card_t *card, unsigned int rec_nr,
218 const u8 *buf, size_t count,
219 unsigned long flags)
220 {
221 sc_apdu_t apdu;
222 int r;
223
224 if (count > 256) {
225 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Trying to send too many bytes");
226 return SC_ERROR_INVALID_ARGUMENTS;
227 }
228 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0);
229 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
230 if (flags & SC_RECORD_BY_REC_NR)
231 apdu.p2 |= 0x04;
232
233 apdu.lc = count;
234 apdu.datalen = count;
235 apdu.data = buf;
236
237 r = sc_transmit_apdu(card, &apdu);
238 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
239 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),
240 "Card returned error");
241 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count);
242 }
243
244 static int iso7816_write_binary(sc_card_t *card,
245 unsigned int idx, const u8 *buf,
246 size_t count, unsigned long flags)
247 {
248 sc_apdu_t apdu;
249 int r;
250
251 assert(count <= (card->max_send_size > 0 ? card->max_send_size : 255));
252
253 if (idx > 0x7fff) {
254 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid EF offset: 0x%X > 0x7FFF", idx);
255 return SC_ERROR_OFFSET_TOO_LARGE;
256 }
257
258 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD0,
259 (idx >> 8) & 0x7F, idx & 0xFF);
260 apdu.lc = count;
261 apdu.datalen = count;
262 apdu.data = buf;
263
264 r = sc_transmit_apdu(card, &apdu);
265 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
266 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),
267 "Card returned error");
268 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count);
269 }
270
271 static int iso7816_update_binary(sc_card_t *card,
272 unsigned int idx, const u8 *buf,
273 size_t count, unsigned long flags)
274 {
275 sc_apdu_t apdu;
276 int r;
277
278 assert(count <= (card->max_send_size > 0 ? card->max_send_size : 255));
279
280 if (idx > 0x7fff) {
281 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid EF offset: 0x%X > 0x7FFF", idx);
282 return SC_ERROR_OFFSET_TOO_LARGE;
283 }
284
285 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6,
286 (idx >> 8) & 0x7F, idx & 0xFF);
287 apdu.lc = count;
288 apdu.datalen = count;
289 apdu.data = buf;
290
291 r = sc_transmit_apdu(card, &apdu);
292 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
293 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),
294 "Card returned error");
295 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count);
296 }
297
298 static int iso7816_process_fci(sc_card_t *card, sc_file_t *file,
299 const u8 *buf, size_t buflen)
300 {
301 sc_context_t *ctx = card->ctx;
302 size_t taglen, len = buflen;
303 const u8 *tag = NULL, *p = buf;
304
305 sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "processing FCI bytes");
306 tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
307 if (tag != NULL && taglen == 2) {
308 file->id = (tag[0] << 8) | tag[1];
309 sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
310 " file identifier: 0x%02X%02X", tag[0], tag[1]);
311 }
312 tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
313 if (tag != NULL && taglen > 0 && taglen < 3) {
314 file->size = tag[0];
315 if (taglen == 2)
316 file->size = (file->size << 8) + tag[1];
317 sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " bytes in file: %d", file->size);
318 }
319 if (tag == NULL) {
320 tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
321 if (tag != NULL && taglen >= 2) {
322 int bytes = (tag[0] << 8) + tag[1];
323 sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
324 " bytes in file: %d", bytes);
325 file->size = bytes;
326 }
327 }
328 tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
329 if (tag != NULL) {
330 if (taglen > 0) {
331 unsigned char byte = tag[0];
332 const char *type;
333
334 file->shareable = byte & 0x40 ? 1 : 0;
335 sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " shareable: %s",
336 (byte & 0x40) ? "yes" : "no");
337 file->ef_structure = byte & 0x07;
338 switch ((byte >> 3) & 7) {
339 case 0:
340 type = "working EF";
341 file->type = SC_FILE_TYPE_WORKING_EF;
342 break;
343 case 1:
344 type = "internal EF";
345 file->type = SC_FILE_TYPE_INTERNAL_EF;
346 break;
347 case 7:
348 type = "DF";
349 file->type = SC_FILE_TYPE_DF;
350 break;
351 default:
352 type = "unknown";
353 break;
354 }
355 sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
356 " type: %s", type);
357 sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
358 " EF structure: %d", byte & 0x07);
359 }
360 }
361 tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
362 if (tag != NULL && taglen > 0 && taglen <= 16) {
363 char tbuf[128];
364 memcpy(file->name, tag, taglen);
365 file->namelen = taglen;
366
367 sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
368 file->name, file->namelen, tbuf, sizeof(tbuf));
369 sc_debug(ctx, SC_LOG_DEBUG_NORMAL, " File name: %s", tbuf);
370 if (!file->type)
371 file->type = SC_FILE_TYPE_DF;
372 }
373 tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
374 if (tag != NULL && taglen) {
375 sc_file_set_prop_attr(file, tag, taglen);
376 } else
377 file->prop_attr_len = 0;
378 tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
379 if (tag != NULL && taglen) {
380 sc_file_set_prop_attr(file, tag, taglen);
381 }
382 tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
383 if (tag != NULL && taglen) {
384 sc_file_set_sec_attr(file, tag, taglen);
385 }
386 tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen);
387 if (tag != NULL && taglen==1) {
388 if (tag[0] == 0x01)
389 file->status = SC_FILE_STATUS_CREATION;
390 else if (tag[0] == 0x07 || tag[0] == 0x05)
391 file->status = SC_FILE_STATUS_ACTIVATED;
392 else if (tag[0] == 0x06 || tag[0] == 0x04)
393 file->status = SC_FILE_STATUS_INVALIDATED;
394 }
395 file->magic = SC_FILE_MAGIC;
396
397 return 0;
398 }
399
400 static int iso7816_select_file(sc_card_t *card,
401 const sc_path_t *in_path,
402 sc_file_t **file_out)
403 {
404 sc_context_t *ctx;
405 sc_apdu_t apdu;
406 u8 buf[SC_MAX_APDU_BUFFER_SIZE];
407 u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
408 int r, pathlen;
409 sc_file_t *file = NULL;
410
411 assert(card != NULL && in_path != NULL);
412 ctx = card->ctx;
413 memcpy(path, in_path->value, in_path->len);
414 pathlen = in_path->len;
415
416 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
417
418 switch (in_path->type) {
419 case SC_PATH_TYPE_FILE_ID:
420 apdu.p1 = 0;
421 if (pathlen != 2)
422 return SC_ERROR_INVALID_ARGUMENTS;
423 break;
424 case SC_PATH_TYPE_DF_NAME:
425 apdu.p1 = 4;
426 break;
427 case SC_PATH_TYPE_PATH:
428 apdu.p1 = 8;
429 if (pathlen >= 2 && memcmp(path, "\x3F\x00", 2) == 0) {
430 if (pathlen == 2) { /* only 3F00 supplied */
431 apdu.p1 = 0;
432 break;
433 }
434 path += 2;
435 pathlen -= 2;
436 }
437 break;
438 case SC_PATH_TYPE_FROM_CURRENT:
439 apdu.p1 = 9;
440 break;
441 case SC_PATH_TYPE_PARENT:
442 apdu.p1 = 3;
443 pathlen = 0;
444 apdu.cse = SC_APDU_CASE_2_SHORT;
445 break;
446 default:
447 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
448 }
449 apdu.p2 = 0; /* first record, return FCI */
450 apdu.lc = pathlen;
451 apdu.data = path;
452 apdu.datalen = pathlen;
453
454 if (file_out != NULL) {
455 apdu.resp = buf;
456 apdu.resplen = sizeof(buf);
457 apdu.le = card->max_recv_size > 0 ? card->max_recv_size : 256;
458 } else
459 apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
460
461 r = sc_transmit_apdu(card, &apdu);
462 SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
463 if (file_out == NULL) {
464 if (apdu.sw1 == 0x61)
465 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, 0);
466 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
467 }
468
469 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
470 if (r)
471 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
472
473 if (apdu.resplen < 2)
474 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
475 switch (apdu.resp[0]) {
476 case ISO7816_TAG_FCI:
477 case ISO7816_TAG_FCP:
478 file = sc_file_new();
479 if (file == NULL)
480 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
481 file->path = *in_path;
482 if (card->ops->process_fci == NULL) {
483 sc_file_free(file);
484 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
485 }
486 if ((size_t)apdu.resp[1] + 2 <= apdu.resplen)
487 card->ops->process_fci(card, file, apdu.resp+2, apdu.resp[1]);
488 *file_out = file;
489 break;
490 case 0x00: /* proprietary coding */
491 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
492 default:
493 SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
494 }
495 return SC_SUCCESS;
496 }
497
498 static int iso7816_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
499 {
500 int r;
501 sc_apdu_t apdu;
502 u8 buf[10];
503
504 if (!rnd)
505 return SC_ERROR_INVALID_ARGUMENTS;
506
507 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT,
508 0x84, 0x00, 0x00);
509 apdu.le = 8;
510 apdu.resp = buf;
511 apdu.resplen = 8; /* include SW's */
512
513 while (len > 0) {
514 size_t n = len > 8 ? 8 : len;
515
516 r = sc_transmit_apdu(card, &apdu);
517 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
518 if (apdu.resplen != 8)
519 return sc_check_sw(card, apdu.sw1, apdu.sw2);
520 memcpy(rnd, apdu.resp, n);
521 len -= n;
522 rnd += n;
523 }
524 return 0;
525 }
526
527 static int iso7816_construct_fci(sc_card_t *card, const sc_file_t *file,
528 u8 *out, size_t *outlen)
529 {
530 u8 *p = out;
531 u8 buf[64];
532
533 if (*outlen < 2)
534 return SC_ERROR_BUFFER_TOO_SMALL;
535 *p++ = 0x6F;
536 p++;
537
538 buf[0] = (file->size >> 8) & 0xFF;
539 buf[1] = file->size & 0xFF;
540 sc_asn1_put_tag(0x81, buf, 2, p, *outlen - (p - out), &p);
541
542 if (file->type_attr_len) {
543 assert(sizeof(buf) >= file->type_attr_len);
544 memcpy(buf, file->type_attr, file->type_attr_len);
545 sc_asn1_put_tag(0x82, buf, file->type_attr_len,
546 p, *outlen - (p - out), &p);
547 } else {
548 buf[0] = file->shareable ? 0x40 : 0;
549 switch (file->type) {
550 case SC_FILE_TYPE_INTERNAL_EF:
551 buf[0] |= 0x08;
552 case SC_FILE_TYPE_WORKING_EF:
553 buf[0] |= file->ef_structure & 7;
554 break;
555 case SC_FILE_TYPE_DF:
556 buf[0] |= 0x38;
557 break;
558 default:
559 return SC_ERROR_NOT_SUPPORTED;
560 }
561 sc_asn1_put_tag(0x82, buf, 1, p, *outlen - (p - out), &p);
562 }
563 buf[0] = (file->id >> 8) & 0xFF;
564 buf[1] = file->id & 0xFF;
565 sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p);
566 /* 0x84 = DF name */
567 if (file->prop_attr_len) {
568 assert(sizeof(buf) >= file->prop_attr_len);
569 memcpy(buf, file->prop_attr, file->prop_attr_len);
570 sc_asn1_put_tag(0x85, buf, file->prop_attr_len,
571 p, *outlen - (p - out), &p);
572 }
573 if (file->sec_attr_len) {
574 assert(sizeof(buf) >= file->prop_attr_len);
575 memcpy(buf, file->sec_attr, file->sec_attr_len);
576 sc_asn1_put_tag(0x86, buf, file->sec_attr_len,
577 p, *outlen - (p - out), &p);
578 }
579 out[1] = p - out - 2;
580
581 *outlen = p - out;
582 return 0;
583 }
584
585 static int iso7816_create_file(sc_card_t *card, sc_file_t *file)
586 {
587 int r;
588 size_t len;
589 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
590 sc_apdu_t apdu;
591
592 len = SC_MAX_APDU_BUFFER_SIZE;
593
594 if (card->ops->construct_fci == NULL)
595 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
596 r = card->ops->construct_fci(card, file, sbuf, &len);
597 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "construct_fci() failed");
598
599 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
600 apdu.lc = len;
601 apdu.datalen = len;
602 apdu.data = sbuf;
603
604 r = sc_transmit_apdu(card, &apdu);
605 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
606 return sc_check_sw(card, apdu.sw1, apdu.sw2);
607 }
608
609 static int iso7816_get_response(sc_card_t *card, size_t *count, u8 *buf)
610 {
611 sc_apdu_t apdu;
612 int r;
613 size_t rlen;
614
615 /* request at most max_recv_size bytes */
616 if (card->max_recv_size > 0 && *count > card->max_recv_size)
617 rlen = card->max_recv_size;
618 else
619 rlen = *count;
620
621 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xC0, 0x00, 0x00);
622 apdu.le = rlen;
623 apdu.resplen = rlen;
624 apdu.resp = buf;
625 /* don't call GET RESPONSE recursively */
626 apdu.flags |= SC_APDU_FLAGS_NO_GET_RESP;
627
628 r = sc_transmit_apdu(card, &apdu);
629 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
630 if (apdu.resplen == 0)
631 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
632
633 *count = apdu.resplen;
634
635 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
636 r = 0; /* no more data to read */
637 else if (apdu.sw1 == 0x61)
638 r = apdu.sw2 == 0 ? 256 : apdu.sw2; /* more data to read */
639 else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82)
640 r = 0; /* Le not reached but file/record ended */
641 else
642 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
643
644 return r;
645 }
646
647 static int iso7816_delete_file(sc_card_t *card, const sc_path_t *path)
648 {
649 int r;
650 u8 sbuf[2];
651 sc_apdu_t apdu;
652
653 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
654 if (path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) {
655 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID");
656 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS);
657 }
658
659 if (path->len == 2) {
660 sbuf[0] = path->value[0];
661 sbuf[1] = path->value[1];
662 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
663 apdu.lc = 2;
664 apdu.datalen = 2;
665 }
666 else /* No file ID given: means currently selected file */
667 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00);
668 apdu.data = sbuf;
669
670 r = sc_transmit_apdu(card, &apdu);
671 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
672 return sc_check_sw(card, apdu.sw1, apdu.sw2);
673 }
674
675 static int iso7816_set_security_env(sc_card_t *card,
676 const sc_security_env_t *env,
677 int se_num)
678 {
679 sc_apdu_t apdu;
680 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
681 u8 *p;
682 int r, locked = 0;
683
684 assert(card != NULL && env != NULL);
685 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
686 switch (env->operation) {
687 case SC_SEC_OPERATION_DECIPHER:
688 apdu.p2 = 0xB8;
689 break;
690 case SC_SEC_OPERATION_SIGN:
691 apdu.p2 = 0xB6;
692 break;
693 default:
694 return SC_ERROR_INVALID_ARGUMENTS;
695 }
696 p = sbuf;
697 if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
698 *p++ = 0x80; /* algorithm reference */
699 *p++ = 0x01;
700 *p++ = env->algorithm_ref & 0xFF;
701 }
702 if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) {
703 *p++ = 0x81;
704 *p++ = env->file_ref.len;
705 assert(sizeof(sbuf) - (p - sbuf) >= env->file_ref.len);
706 memcpy(p, env->file_ref.value, env->file_ref.len);
707 p += env->file_ref.len;
708 }
709 if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
710 if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC)
711 *p++ = 0x83;
712 else
713 *p++ = 0x84;
714 *p++ = env->key_ref_len;
715 assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len);
716 memcpy(p, env->key_ref, env->key_ref_len);
717 p += env->key_ref_len;
718 }
719 r = p - sbuf;
720 apdu.lc = r;
721 apdu.datalen = r;
722 apdu.data = sbuf;
723 if (se_num > 0) {
724 r = sc_lock(card);
725 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
726 locked = 1;
727 }
728 if (apdu.datalen != 0) {
729 r = sc_transmit_apdu(card, &apdu);
730 if (r) {
731 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
732 "%s: APDU transmit failed", sc_strerror(r));
733 goto err;
734 }
735 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
736 if (r) {
737 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
738 "%s: Card returned error", sc_strerror(r));
739 goto err;
740 }
741 }
742 if (se_num <= 0)
743 return 0;
744 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num);
745 r = sc_transmit_apdu(card, &apdu);
746 sc_unlock(card);
747 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
748 return sc_check_sw(card, apdu.sw1, apdu.sw2);
749 err:
750 if (locked)
751 sc_unlock(card);
752 return r;
753 }
754
755 static int iso7816_restore_security_env(sc_card_t *card, int se_num)
756 {
757 sc_apdu_t apdu;
758 int r;
759 u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
760
761 assert(card != NULL);
762
763 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, se_num);
764 apdu.resplen = sizeof(rbuf) > 250 ? 250 : sizeof(rbuf);
765 apdu.resp = rbuf;
766 r = sc_transmit_apdu(card, &apdu);
767 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
768 return sc_check_sw(card, apdu.sw1, apdu.sw2);
769 }
770
771 static int iso7816_compute_signature(sc_card_t *card,
772 const u8 * data, size_t datalen,
773 u8 * out, size_t outlen)
774 {
775 int r;
776 sc_apdu_t apdu;
777 u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
778 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
779
780 assert(card != NULL && data != NULL && out != NULL);
781 if (datalen > 255)
782 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
783
784 /* INS: 0x2A PERFORM SECURITY OPERATION
785 * P1: 0x9E Resp: Digital Signature
786 * P2: 0x9A Cmd: Input for Digital Signature */
787 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E,
788 0x9A);
789 apdu.resp = rbuf;
790 apdu.resplen = sizeof(rbuf); /* FIXME */
791 apdu.le = 256;
792
793 memcpy(sbuf, data, datalen);
794 apdu.data = sbuf;
795 apdu.lc = datalen;
796 apdu.datalen = datalen;
797 r = sc_transmit_apdu(card, &apdu);
798 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
799 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
800 size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
801
802 memcpy(out, apdu.resp, len);
803 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len);
804 }
805 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
806 }
807
808 static int iso7816_decipher(sc_card_t *card,
809 const u8 * crgram, size_t crgram_len,
810 u8 * out, size_t outlen)
811 {
812 int r;
813 sc_apdu_t apdu;
814 u8 *sbuf = NULL;
815
816 assert(card != NULL && crgram != NULL && out != NULL);
817 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL);
818
819 sbuf = malloc(crgram_len + 1);
820 if (sbuf == NULL)
821 return SC_ERROR_OUT_OF_MEMORY;
822
823 /* INS: 0x2A PERFORM SECURITY OPERATION
824 * P1: 0x80 Resp: Plain value
825 * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */
826 sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86);
827 apdu.resp = out;
828 apdu.resplen = outlen;
829 /* if less than 256 bytes are expected than set Le to 0x00
830 * to tell the card the we want everything available (note: we
831 * always have Le <= crgram_len) */
832 apdu.le = (outlen >= 256 && crgram_len < 256) ? 256 : outlen;
833 /* Use APDU chaining with 2048bit RSA keys if the card does not do extended APDU-s */
834 if ((crgram_len+1 > 255) && !(card->caps & SC_CARD_CAP_APDU_EXT))
835 apdu.flags |= SC_APDU_FLAGS_CHAINING;
836
837 sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
838 memcpy(sbuf + 1, crgram, crgram_len);
839 apdu.data = sbuf;
840 apdu.lc = crgram_len + 1;
841 apdu.datalen = crgram_len + 1;
842 r = sc_transmit_apdu(card, &apdu);
843 sc_mem_clear(sbuf, crgram_len + 1);
844 free(sbuf);
845 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
846 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
847 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);
848 else
849 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
850 }
851
852 static int iso7816_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu,
853 struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len)
854 {
855 int r, len = 0, pad = 0, use_pin_pad = 0, ins, p1 = 0;
856
857 switch (data->pin_type) {
858 case SC_AC_CHV:
859 break;
860 default:
861 return SC_ERROR_INVALID_ARGUMENTS;
862 }
863
864 if (data->flags & SC_PIN_CMD_NEED_PADDING)
865 pad = 1;
866 if (data->flags & SC_PIN_CMD_USE_PINPAD)
867 use_pin_pad = 1;
868
869 data->pin1.offset = 5;
870
871 switch (data->cmd) {
872 case SC_PIN_CMD_VERIFY:
873 ins = 0x20;
874 if ((r = sc_build_pin(buf, buf_len, &data->pin1, pad)) < 0)
875 return r;
876 len = r;
877 break;
878 case SC_PIN_CMD_CHANGE:
879 ins = 0x24;
880 if (data->pin1.len != 0 || use_pin_pad) {
881 if ((r = sc_build_pin(buf, buf_len, &data->pin1, pad)) < 0)
882 return r;
883 len += r;
884 } else {
885 /* implicit test */
886 p1 = 1;
887 }
888
889 data->pin2.offset = data->pin1.offset + len;
890 if ((r = sc_build_pin(buf+len, buf_len-len, &data->pin2, pad)) < 0)
891 return r;
892 len += r;
893 break;
894 case SC_PIN_CMD_UNBLOCK:
895 ins = 0x2C;
896 if (data->pin1.len != 0 || use_pin_pad) {
897 if ((r = sc_build_pin(buf, buf_len, &data->pin1, pad)) < 0)
898 return r;
899 len += r;
900 } else {
901 p1 |= 0x02;
902 }
903
904 if (data->pin2.len != 0 || use_pin_pad) {
905 data->pin2.offset = data->pin1.offset + len;
906 if ((r = sc_build_pin(buf+len, buf_len-len, &data->pin2, pad)) < 0)
907 return r;
908 len += r;
909 } else {
910 p1 |= 0x01;
911 }
912 break;
913 default:
914 return SC_ERROR_NOT_SUPPORTED;
915 }
916
917 sc_format_apdu(card, apdu, SC_APDU_CASE_3_SHORT,
918 ins, p1, data->pin_reference);
919
920 apdu->lc = len;
921 apdu->datalen = len;
922 apdu->data = buf;
923 apdu->resplen = 0;
924
925 return 0;
926 }
927
928 static int iso7816_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
929 int *tries_left)
930 {
931 sc_apdu_t local_apdu, *apdu;
932 int r;
933 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
934
935 if (tries_left)
936 *tries_left = -1;
937
938 /* See if we've been called from another card driver, which is
939 * passing an APDU to us (this allows to write card drivers
940 * whose PIN functions behave "mostly like ISO" except in some
941 * special circumstances.
942 */
943 if (data->apdu == NULL) {
944 r = iso7816_build_pin_apdu(card, &local_apdu, data, sbuf, sizeof(sbuf));
945 if (r < 0)
946 return r;
947 data->apdu = &local_apdu;
948 }
949 apdu = data->apdu;
950
951 if (!(data->flags & SC_PIN_CMD_USE_PINPAD)) {
952 /* Transmit the APDU to the card */
953 r = sc_transmit_apdu(card, apdu);
954
955 /* Clear the buffer - it may contain pins */
956 sc_mem_clear(sbuf, sizeof(sbuf));
957 } else {
958 /* Call the reader driver to collect
959 * the PIN and pass on the APDU to the card */
960 if (data->pin1.offset == 0) {
961 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
962 "Card driver didn't set PIN offset");
963 return SC_ERROR_INVALID_ARGUMENTS;
964 }
965 if (card->reader
966 && card->reader->ops
967 && card->reader->ops->perform_verify) {
968 r = card->reader->ops->perform_verify(card->reader, data);
969 /* sw1/sw2 filled in by reader driver */
970 } else {
971 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
972 "Card reader driver does not support "
973 "PIN entry through reader key pad");
974 r = SC_ERROR_NOT_SUPPORTED;
975 }
976 }
977
978 /* Don't pass references to local variables up to the caller. */
979 if (data->apdu == &local_apdu)
980 data->apdu = NULL;
981
982 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
983 if (apdu->sw1 == 0x63) {
984 if ((apdu->sw2 & 0xF0) == 0xC0 && tries_left != NULL)
985 *tries_left = apdu->sw2 & 0x0F;
986 return SC_ERROR_PIN_CODE_INCORRECT;
987 }
988 return sc_check_sw(card, apdu->sw1, apdu->sw2);
989 }
990
991 static int no_match(sc_card_t *card)
992 {
993 return 0;
994 }
995
996 static struct sc_card_operations iso_ops = {
997 no_match,
998 NULL, /* init */
999 NULL, /* finish */
1000 iso7816_read_binary,
1001 iso7816_write_binary,
1002 iso7816_update_binary,
1003 NULL, /* erase_binary */
1004 iso7816_read_record,
1005 iso7816_write_record,
1006 iso7816_append_record,
1007 iso7816_update_record,
1008 iso7816_select_file,
1009 iso7816_get_response,
1010 iso7816_get_challenge,
1011 NULL, /* verify */
1012 NULL, /* logout */
1013 iso7816_restore_security_env,
1014 iso7816_set_security_env,
1015 iso7816_decipher,
1016 iso7816_compute_signature,
1017 NULL, /* change_reference_data */
1018 NULL, /* reset_retry_counter */
1019 iso7816_create_file,
1020 iso7816_delete_file,
1021 NULL, /* list_files */
1022 iso7816_check_sw,
1023 NULL, /* card_ctl */
1024 iso7816_process_fci,
1025 iso7816_construct_fci,
1026 iso7816_pin_cmd,
1027 NULL, /* get_data */
1028 NULL, /* put_data */
1029 NULL /* delete_record */
1030 };
1031
1032 static struct sc_card_driver iso_driver = {
1033 "ISO 7816 reference driver",
1034 "iso7816",
1035 &iso_ops,
1036 NULL, 0, NULL
1037 };
1038
1039 struct sc_card_driver * sc_get_iso7816_driver(void)
1040 {
1041 return &iso_driver;
1042 }
阅读(7103) | 评论(4) | 转发(1) |