1 /*
2 * iso7816.c: Functions specified by the ISO 7816 standard
3 *
4 * Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
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 <assert.h>
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "internal.h"
29 #include "asn1.h"
30 #include "iso7816.h"
31 #include "sm/sm-iso.h"
32
33
fixup_transceive_length(const struct sc_card * card,struct sc_apdu * apdu)34 static void fixup_transceive_length(const struct sc_card *card,
35 struct sc_apdu *apdu)
36 {
37 if (card == NULL || apdu == NULL) {
38 return;
39 }
40
41 if (apdu->lc > sc_get_max_send_size(card)) {
42 /* The lower layers will automatically do chaining */
43 apdu->flags |= SC_APDU_FLAGS_CHAINING;
44 }
45
46 if (apdu->le > sc_get_max_recv_size(card)) {
47 /* The lower layers will automatically do a GET RESPONSE, if possible.
48 * All other workarounds must be carried out by the upper layers. */
49 apdu->le = sc_get_max_recv_size(card);
50 }
51 }
52
53
54 static const struct sc_card_error iso7816_errors[] = {
55 { 0x6200, SC_ERROR_CARD_CMD_FAILED, "Warning: no information given, non-volatile memory is unchanged" },
56 { 0x6281, SC_ERROR_CORRUPTED_DATA, "Part of returned data may be corrupted" },
57 { 0x6282, SC_ERROR_FILE_END_REACHED, "End of file/record reached before reading Le bytes" },
58 { 0x6283, SC_ERROR_CARD_CMD_FAILED, "Selected file invalidated" },
59 { 0x6284, SC_ERROR_CARD_CMD_FAILED, "FCI not formatted according to ISO 7816-4" },
60 { 0x6285, SC_ERROR_CARD_CMD_FAILED, "Selected file in termination state" },
61 { 0x6286, SC_ERROR_CARD_CMD_FAILED, "No input data available from a sensor on the card" },
62
63 { 0x6300, SC_ERROR_CARD_CMD_FAILED, "Warning: no information given, non-volatile memory has changed" },
64 { 0x6381, SC_ERROR_CARD_CMD_FAILED, "Warning: file filled up by last write" },
65
66 { 0x6400, SC_ERROR_CARD_CMD_FAILED, "Execution error" },
67 { 0x6401, SC_ERROR_CARD_CMD_FAILED, "Immediate response required by the card" },
68
69 { 0x6581, SC_ERROR_MEMORY_FAILURE, "Memory failure" },
70
71 { 0x6700, SC_ERROR_WRONG_LENGTH, "Wrong length" },
72
73 { 0x6800, SC_ERROR_NO_CARD_SUPPORT, "Functions in CLA not supported" },
74 { 0x6881, SC_ERROR_NO_CARD_SUPPORT, "Logical channel not supported" },
75 { 0x6882, SC_ERROR_NO_CARD_SUPPORT, "Secure messaging not supported" },
76 { 0x6883, SC_ERROR_CARD_CMD_FAILED, "Last command of the chain expected" },
77 { 0x6884, SC_ERROR_NO_CARD_SUPPORT, "Command chaining not supported" },
78
79 { 0x6900, SC_ERROR_NOT_ALLOWED, "Command not allowed" },
80 { 0x6981, SC_ERROR_CARD_CMD_FAILED, "Command incompatible with file structure" },
81 { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED,"Security status not satisfied" },
82 { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" },
83 { 0x6984, SC_ERROR_REF_DATA_NOT_USABLE, "Referenced data not usable" },
84 { 0x6985, SC_ERROR_NOT_ALLOWED, "Conditions of use not satisfied" },
85 { 0x6986, SC_ERROR_NOT_ALLOWED, "Command not allowed (no current EF)" },
86 { 0x6987, SC_ERROR_INCORRECT_PARAMETERS,"Expected SM data objects missing" },
87 { 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect SM data objects" },
88
89 { 0x6A00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
90 { 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters in the data field" },
91 { 0x6A81, SC_ERROR_NO_CARD_SUPPORT, "Function not supported" },
92 { 0x6A82, SC_ERROR_FILE_NOT_FOUND, "File or application not found" },
93 { 0x6A83, SC_ERROR_RECORD_NOT_FOUND, "Record not found" },
94 { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory space in the file" },
95 { 0x6A85, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with TLV structure" },
96 { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters P1-P2" },
97 { 0x6A87, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with P1-P2" },
98 { 0x6A88, SC_ERROR_DATA_OBJECT_NOT_FOUND,"Referenced data not found" },
99 { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS, "File already exists"},
100 { 0x6A8A, SC_ERROR_FILE_ALREADY_EXISTS, "DF name already exists"},
101
102 { 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
103 { 0x6D00, SC_ERROR_INS_NOT_SUPPORTED, "Instruction code not supported or invalid" },
104 { 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },
105 { 0x6F00, SC_ERROR_CARD_CMD_FAILED, "No precise diagnosis" },
106 };
107
108
109 static int
iso7816_check_sw(struct sc_card * card,unsigned int sw1,unsigned int sw2)110 iso7816_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
111 {
112 const int err_count = sizeof(iso7816_errors)/sizeof(iso7816_errors[0]);
113 int i;
114
115 /* Handle special cases here */
116 if (sw1 == 0x6C) {
117 sc_log(card->ctx, "Wrong length; correct length is %d", sw2);
118 return SC_ERROR_WRONG_LENGTH;
119 }
120 if (sw1 == 0x90)
121 return SC_SUCCESS;
122 if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) {
123 sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f));
124 return SC_ERROR_PIN_CODE_INCORRECT;
125 }
126 for (i = 0; i < err_count; i++) {
127 if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) {
128 sc_log(card->ctx, "%s", iso7816_errors[i].errorstr);
129 return iso7816_errors[i].errorno;
130 }
131 }
132
133 sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);
134 return SC_ERROR_CARD_CMD_FAILED;
135 }
136
137
138 static int
iso7816_read_binary(struct sc_card * card,unsigned int idx,u8 * buf,size_t count,unsigned long flags)139 iso7816_read_binary(struct sc_card *card, unsigned int idx, u8 *buf, size_t count, unsigned long flags)
140 {
141 struct sc_context *ctx = card->ctx;
142 struct sc_apdu apdu;
143 int r;
144
145 if (idx > 0x7FFF) {
146 sc_log(ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
147 return SC_ERROR_OFFSET_TOO_LARGE;
148 }
149
150 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB0, (idx >> 8) & 0x7F, idx & 0xFF);
151 apdu.le = count;
152 apdu.resplen = count;
153 apdu.resp = buf;
154
155 fixup_transceive_length(card, &apdu);
156 r = sc_transmit_apdu(card, &apdu);
157 LOG_TEST_RET(ctx, r, "APDU transmit failed");
158
159 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
160 if (r == SC_ERROR_FILE_END_REACHED)
161 LOG_FUNC_RETURN(ctx, apdu.resplen);
162 LOG_TEST_RET(ctx, r, "Check SW error");
163
164 LOG_FUNC_RETURN(ctx, apdu.resplen);
165 }
166
167
168 static int
iso7816_read_record(struct sc_card * card,unsigned int rec_nr,u8 * buf,size_t count,unsigned long flags)169 iso7816_read_record(struct sc_card *card,
170 unsigned int rec_nr, u8 *buf, size_t count, unsigned long flags)
171 {
172 struct sc_apdu apdu;
173 int r;
174
175 if (rec_nr > 0xFF)
176 LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
177
178 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB2, rec_nr, 0);
179 apdu.le = count;
180 apdu.resplen = count;
181 apdu.resp = buf;
182 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
183 if (flags & SC_RECORD_BY_REC_NR)
184 apdu.p2 |= 0x04;
185
186 fixup_transceive_length(card, &apdu);
187 r = sc_transmit_apdu(card, &apdu);
188 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
189 if (apdu.resplen == 0)
190 LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
191
192 LOG_FUNC_RETURN(card->ctx, apdu.resplen);
193 }
194
195
196 static int
iso7816_write_record(struct sc_card * card,unsigned int rec_nr,const u8 * buf,size_t count,unsigned long flags)197 iso7816_write_record(struct sc_card *card, unsigned int rec_nr,
198 const u8 *buf, size_t count, unsigned long flags)
199 {
200 struct sc_apdu apdu;
201 int r;
202
203 sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD2, rec_nr, 0);
204 apdu.lc = count;
205 apdu.datalen = count;
206 apdu.data = buf;
207 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
208 if (flags & SC_RECORD_BY_REC_NR)
209 apdu.p2 |= 0x04;
210
211 fixup_transceive_length(card, &apdu);
212 r = sc_transmit_apdu(card, &apdu);
213 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
214 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
215 LOG_TEST_RET(card->ctx, r, "Card returned error");
216
217 LOG_FUNC_RETURN(card->ctx, count);
218 }
219
220
221 static int
iso7816_append_record(struct sc_card * card,const u8 * buf,size_t count,unsigned long flags)222 iso7816_append_record(struct sc_card *card,
223 const u8 *buf, size_t count, unsigned long flags)
224 {
225 struct sc_apdu apdu;
226 int r;
227
228 sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xE2, 0, 0);
229 apdu.lc = count;
230 apdu.datalen = count;
231 apdu.data = buf;
232 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
233
234 fixup_transceive_length(card, &apdu);
235 r = sc_transmit_apdu(card, &apdu);
236 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
237 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
238 LOG_TEST_RET(card->ctx, r, "Card returned error");
239
240 LOG_FUNC_RETURN(card->ctx, count);
241 }
242
243
244 static int
iso7816_update_record(struct sc_card * card,unsigned int rec_nr,const u8 * buf,size_t count,unsigned long flags)245 iso7816_update_record(struct sc_card *card, unsigned int rec_nr,
246 const u8 *buf, size_t count, unsigned long flags)
247 {
248 struct sc_apdu apdu;
249 int r;
250
251 sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xDC, rec_nr, 0);
252 apdu.lc = count;
253 apdu.datalen = count;
254 apdu.data = buf;
255 apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
256 if (flags & SC_RECORD_BY_REC_NR)
257 apdu.p2 |= 0x04;
258
259 fixup_transceive_length(card, &apdu);
260 r = sc_transmit_apdu(card, &apdu);
261 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
262 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
263 LOG_TEST_RET(card->ctx, r, "Card returned error");
264
265 LOG_FUNC_RETURN(card->ctx, count);
266 }
267
268
269 static int
iso7816_write_binary(struct sc_card * card,unsigned int idx,const u8 * buf,size_t count,unsigned long flags)270 iso7816_write_binary(struct sc_card *card,
271 unsigned int idx, const u8 *buf, size_t count, unsigned long flags)
272 {
273 struct sc_apdu apdu;
274 int r;
275
276 if (idx > 0x7fff) {
277 sc_log(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
278 return SC_ERROR_OFFSET_TOO_LARGE;
279 }
280
281 sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD0,
282 (idx >> 8) & 0x7F, idx & 0xFF);
283 apdu.lc = count;
284 apdu.datalen = count;
285 apdu.data = buf;
286
287 fixup_transceive_length(card, &apdu);
288 r = sc_transmit_apdu(card, &apdu);
289 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
290 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
291 LOG_TEST_RET(card->ctx, r, "Card returned error");
292
293 LOG_FUNC_RETURN(card->ctx, count);
294 }
295
296
297 static int
iso7816_update_binary(struct sc_card * card,unsigned int idx,const u8 * buf,size_t count,unsigned long flags)298 iso7816_update_binary(struct sc_card *card,
299 unsigned int idx, const u8 *buf, size_t count, unsigned long flags)
300 {
301 struct sc_apdu apdu;
302 int r;
303
304 if (idx > 0x7fff) {
305 sc_log(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
306 return SC_ERROR_OFFSET_TOO_LARGE;
307 }
308
309 sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD6, (idx >> 8) & 0x7F, idx & 0xFF);
310 apdu.lc = count;
311 apdu.datalen = count;
312 apdu.data = buf;
313
314 fixup_transceive_length(card, &apdu);
315 r = sc_transmit_apdu(card, &apdu);
316 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
317 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
318 LOG_TEST_RET(card->ctx, r, "Card returned error");
319
320 LOG_FUNC_RETURN(card->ctx, count);
321 }
322
323
324 static int
iso7816_process_fci(struct sc_card * card,struct sc_file * file,const unsigned char * buf,size_t buflen)325 iso7816_process_fci(struct sc_card *card, struct sc_file *file,
326 const unsigned char *buf, size_t buflen)
327 {
328 struct sc_context *ctx = card->ctx;
329 const unsigned char *p, *end;
330 unsigned int cla = 0, tag = 0;
331 size_t length;
332 int size;
333
334 file->status = SC_FILE_STATUS_UNKNOWN;
335
336 for (p = buf, length = buflen, end = buf + buflen;
337 p < end;
338 p += length, length = end - p) {
339
340 if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length)
341 || p == NULL) {
342 break;
343 }
344 switch (cla | tag) {
345 case 0x81:
346 if (file->size != 0) {
347 /* don't overwrite existing file size excluding structural information */
348 break;
349 }
350 /* fall through */
351 case 0x80:
352 /* determine the file size */
353 if (sc_asn1_decode_integer(p, length, &size, 0) == 0 && size >= 0) {
354 file->size = size;
355 sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u",
356 file->size);
357 }
358 break;
359
360 case 0x82:
361 if (length > 0) {
362 unsigned char byte = p[0];
363 const char *type;
364
365 file->shareable = byte & 0x40 ? 1 : 0;
366 sc_log(ctx, " shareable: %s", (byte & 0x40) ? "yes" : "no");
367 file->ef_structure = byte & 0x07;
368 switch ((byte >> 3) & 7) {
369 case 0:
370 type = "working EF";
371 file->type = SC_FILE_TYPE_WORKING_EF;
372 break;
373 case 1:
374 type = "internal EF";
375 file->type = SC_FILE_TYPE_INTERNAL_EF;
376 break;
377 case 7:
378 type = "DF";
379 file->type = SC_FILE_TYPE_DF;
380 break;
381 default:
382 file->type = SC_FILE_TYPE_UNKNOWN;
383 type = "unknown";
384 break;
385 }
386 sc_log(ctx, " type: %s", type);
387 sc_log(ctx, " EF structure: %d", byte & 0x07);
388 sc_log(ctx, " tag 0x82: 0x%02x", byte);
389
390 /* if possible, get additional information for non-DFs */
391 if (file->type != SC_FILE_TYPE_DF) {
392 /* max. record length for fixed- & variable-sized records */
393 if (length > 2 && byte & 0x06) {
394 file->record_length = (length > 3)
395 ? bebytes2ushort(p+2)
396 : p[2];
397 sc_log(ctx, " record length: %"SC_FORMAT_LEN_SIZE_T"u",
398 file->record_length);
399 }
400
401 /* number of records */
402 if (length > 4) {
403 file->record_count = (length > 5)
404 ? bebytes2ushort(p+4)
405 : p[4];
406 sc_log(ctx, " records: %"SC_FORMAT_LEN_SIZE_T"u",
407 file->record_count);
408 }
409 }
410
411 if (SC_SUCCESS != sc_file_set_type_attr(file, p, length))
412 sc_log(ctx, "Warning: Could not set file attributes");
413 }
414 break;
415
416 case 0x83:
417 if (length == 2) {
418 file->id = (p[0] << 8) | p[1];
419 sc_log(ctx, " file identifier: 0x%02X%02X", p[0], p[1]);
420 }
421 break;
422
423 case 0x84:
424 if (length > 0 && length <= 16) {
425 memcpy(file->name, p, length);
426 file->namelen = length;
427
428 sc_log_hex(ctx, " File name:", file->name, file->namelen);
429 if (!file->type)
430 file->type = SC_FILE_TYPE_DF;
431 }
432 break;
433
434 case 0x85:
435 case 0xA5:
436 if (SC_SUCCESS != sc_file_set_prop_attr(file, p, length)) {
437 sc_log(ctx, "Warning: Could not set proprietary file properties");
438 }
439 break;
440
441 case 0x86:
442 if (SC_SUCCESS != sc_file_set_sec_attr(file, p, length)) {
443 sc_log(ctx, "Warning: Could not set file security properties");
444 }
445 break;
446
447 case 0x88:
448 if (length == 1) {
449 file->sid = *p;
450 sc_log(ctx, " short file identifier: 0x%02X", *p);
451 }
452 break;
453
454 case 0x8A:
455 if (length == 1) {
456 switch (p[0]) {
457 case 0:
458 file->status =SC_FILE_STATUS_NO_INFO;
459 break;
460 case 1:
461 file->status = SC_FILE_STATUS_CREATION;
462 break;
463 case 3:
464 file->status = SC_FILE_STATUS_INITIALISATION;
465 break;
466 case 4:
467 case 6:
468 file->status = SC_FILE_STATUS_INVALIDATED;
469 break;
470 case 5:
471 case 7:
472 file->status = SC_FILE_STATUS_ACTIVATED;
473 break;
474 case 12:
475 case 13:
476 case 14:
477 case 15:
478 file->status = SC_FILE_STATUS_TERMINATION;
479 break;
480 case 2:
481 file->status = SC_FILE_STATUS_RFU_2;
482 break;
483 case 8:
484 file->status = SC_FILE_STATUS_RFU_8;
485 break;
486 case 9:
487 file->status = SC_FILE_STATUS_RFU_9;
488 break;
489 case 10:
490 file->status = SC_FILE_STATUS_RFU_10;
491 break;
492 case 11:
493 file->status = SC_FILE_STATUS_RFU_11;
494 break;
495 default:
496 file->status = SC_FILE_STATUS_PROPRIETARY;
497 }
498 }
499 break;
500
501 case 0x62:
502 case 0x64:
503 case 0x6F:
504 /* allow nested FCP/FMD/FCI templates */
505 iso7816_process_fci(card, file, p, length);
506 }
507 }
508
509 file->magic = SC_FILE_MAGIC;
510
511 return SC_SUCCESS;
512 }
513
514
515 static int
iso7816_select_file(struct sc_card * card,const struct sc_path * in_path,struct sc_file ** file_out)516 iso7816_select_file(struct sc_card *card, const struct sc_path *in_path, struct sc_file **file_out)
517 {
518 struct sc_context *ctx;
519 struct sc_apdu apdu;
520 unsigned char buf[SC_MAX_APDU_BUFFER_SIZE];
521 unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
522 int r, pathlen, pathtype;
523 int select_mf = 0;
524 struct sc_file *file = NULL;
525 const u8 *buffer;
526 size_t buffer_len;
527 unsigned int cla, tag;
528
529 if (card == NULL || in_path == NULL) {
530 return SC_ERROR_INVALID_ARGUMENTS;
531 }
532 ctx = card->ctx;
533 memcpy(path, in_path->value, in_path->len);
534 pathlen = in_path->len;
535 pathtype = in_path->type;
536
537 if (in_path->aid.len) {
538 if (!pathlen) {
539 memcpy(path, in_path->aid.value, in_path->aid.len);
540 pathlen = in_path->aid.len;
541 pathtype = SC_PATH_TYPE_DF_NAME;
542 } else {
543 /* First, select the application */
544 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 4, 0);
545 apdu.data = in_path->aid.value;
546 apdu.datalen = in_path->aid.len;
547 apdu.lc = in_path->aid.len;
548
549 r = sc_transmit_apdu(card, &apdu);
550 LOG_TEST_RET(ctx, r, "APDU transmit failed");
551 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
552 if (r)
553 LOG_FUNC_RETURN(ctx, r);
554
555 if (pathtype == SC_PATH_TYPE_PATH
556 || pathtype == SC_PATH_TYPE_DF_NAME)
557 pathtype = SC_PATH_TYPE_FROM_CURRENT;
558 }
559 }
560
561 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
562
563 switch (pathtype) {
564 case SC_PATH_TYPE_FILE_ID:
565 apdu.p1 = 0;
566 if (pathlen != 2)
567 return SC_ERROR_INVALID_ARGUMENTS;
568 break;
569 case SC_PATH_TYPE_DF_NAME:
570 apdu.p1 = 4;
571 break;
572 case SC_PATH_TYPE_PATH:
573 apdu.p1 = 8;
574 if (pathlen >= 2 && memcmp(path, "\x3F\x00", 2) == 0) {
575 if (pathlen == 2) { /* only 3F00 supplied */
576 select_mf = 1;
577 apdu.p1 = 0;
578 break;
579 }
580 path += 2;
581 pathlen -= 2;
582 }
583 break;
584 case SC_PATH_TYPE_FROM_CURRENT:
585 apdu.p1 = 9;
586 break;
587 case SC_PATH_TYPE_PARENT:
588 apdu.p1 = 3;
589 pathlen = 0;
590 apdu.cse = SC_APDU_CASE_2_SHORT;
591 break;
592 default:
593 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
594 }
595 apdu.lc = pathlen;
596 apdu.data = path;
597 apdu.datalen = pathlen;
598
599 if (file_out != NULL) {
600 apdu.p2 = 0; /* first record, return FCI */
601 apdu.resp = buf;
602 apdu.resplen = sizeof(buf);
603 apdu.le = sc_get_max_recv_size(card) < 256 ? sc_get_max_recv_size(card) : 256;
604 }
605 else {
606 apdu.p2 = 0x0C; /* first record, return nothing */
607 apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
608 }
609
610 r = sc_transmit_apdu(card, &apdu);
611 LOG_TEST_RET(ctx, r, "APDU transmit failed");
612 if (file_out == NULL) {
613 /* For some cards 'SELECT' can be only with request to return FCI/FCP. */
614 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
615 if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86) {
616 apdu.p2 = 0x00;
617 if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS)
618 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
619 }
620 if (apdu.sw1 == 0x61)
621 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
622 LOG_FUNC_RETURN(ctx, r);
623 }
624
625 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
626 if (r)
627 LOG_FUNC_RETURN(ctx, r);
628
629 if (file_out && (apdu.resplen == 0)) {
630 /* For some cards 'SELECT' MF or DF_NAME do not return FCI. */
631 if (select_mf || pathtype == SC_PATH_TYPE_DF_NAME) {
632 file = sc_file_new();
633 if (file == NULL)
634 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
635 file->path = *in_path;
636
637 *file_out = file;
638 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
639 }
640 }
641
642 if (apdu.resplen < 2)
643 LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
644 switch (apdu.resp[0]) {
645 case ISO7816_TAG_FCI:
646 case ISO7816_TAG_FCP:
647 file = sc_file_new();
648 if (file == NULL)
649 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
650 file->path = *in_path;
651 if (card->ops->process_fci == NULL) {
652 sc_file_free(file);
653 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
654 }
655 buffer = apdu.resp;
656 r = sc_asn1_read_tag(&buffer, apdu.resplen, &cla, &tag, &buffer_len);
657 if (r == SC_SUCCESS)
658 card->ops->process_fci(card, file, buffer, buffer_len);
659 *file_out = file;
660 break;
661 case 0x00: /* proprietary coding */
662 LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
663 default:
664 LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
665 }
666
667 return SC_SUCCESS;
668 }
669
670
671 static int
iso7816_get_challenge(struct sc_card * card,u8 * rnd,size_t len)672 iso7816_get_challenge(struct sc_card *card, u8 *rnd, size_t len)
673 {
674 int r;
675 struct sc_apdu apdu;
676
677 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00);
678 apdu.le = len;
679 apdu.resp = rnd;
680 apdu.resplen = len;
681
682 r = sc_transmit_apdu(card, &apdu);
683 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
684
685 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
686 LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed");
687
688 if (len < apdu.resplen) {
689 return (int) len;
690 }
691
692 return (int) apdu.resplen;
693 }
694
695
696 static int
iso7816_construct_fci(struct sc_card * card,const sc_file_t * file,u8 * out,size_t * outlen)697 iso7816_construct_fci(struct sc_card *card, const sc_file_t *file,
698 u8 *out, size_t *outlen)
699 {
700 u8 *p = out;
701 u8 buf[64];
702
703 if (*outlen < 2)
704 return SC_ERROR_BUFFER_TOO_SMALL;
705 *p++ = 0x6F;
706 p++;
707
708 buf[0] = (file->size >> 8) & 0xFF;
709 buf[1] = file->size & 0xFF;
710 sc_asn1_put_tag(0x81, buf, 2, p, *outlen - (p - out), &p);
711
712 if (file->type_attr_len) {
713 assert(sizeof(buf) >= file->type_attr_len);
714 memcpy(buf, file->type_attr, file->type_attr_len);
715 sc_asn1_put_tag(0x82, buf, file->type_attr_len,
716 p, *outlen - (p - out), &p);
717 } else {
718 buf[0] = file->shareable ? 0x40 : 0;
719 switch (file->type) {
720 case SC_FILE_TYPE_INTERNAL_EF:
721 buf[0] |= 0x08;
722 /* fall through */
723 case SC_FILE_TYPE_WORKING_EF:
724 buf[0] |= file->ef_structure & 7;
725 break;
726 case SC_FILE_TYPE_DF:
727 buf[0] |= 0x38;
728 break;
729 default:
730 return SC_ERROR_NOT_SUPPORTED;
731 }
732 sc_asn1_put_tag(0x82, buf, 1, p, *outlen - (p - out), &p);
733 }
734 buf[0] = (file->id >> 8) & 0xFF;
735 buf[1] = file->id & 0xFF;
736 sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p);
737 /* 0x84 = DF name */
738 if (file->prop_attr_len) {
739 assert(sizeof(buf) >= file->prop_attr_len);
740 memcpy(buf, file->prop_attr, file->prop_attr_len);
741 sc_asn1_put_tag(0x85, buf, file->prop_attr_len,
742 p, *outlen - (p - out), &p);
743 }
744 if (file->sec_attr_len) {
745 assert(sizeof(buf) >= file->sec_attr_len);
746 memcpy(buf, file->sec_attr, file->sec_attr_len);
747 sc_asn1_put_tag(0x86, buf, file->sec_attr_len,
748 p, *outlen - (p - out), &p);
749 }
750 out[1] = p - out - 2;
751
752 *outlen = p - out;
753 return 0;
754 }
755
756
757 static int
iso7816_create_file(struct sc_card * card,sc_file_t * file)758 iso7816_create_file(struct sc_card *card, sc_file_t *file)
759 {
760 int r;
761 size_t len;
762 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
763 struct sc_apdu apdu;
764
765 len = SC_MAX_APDU_BUFFER_SIZE;
766
767 if (card->ops->construct_fci == NULL)
768 LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
769 r = card->ops->construct_fci(card, file, sbuf, &len);
770 LOG_TEST_RET(card->ctx, r, "construct_fci() failed");
771
772 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
773 apdu.lc = len;
774 apdu.datalen = len;
775 apdu.data = sbuf;
776
777 r = sc_transmit_apdu(card, &apdu);
778 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
779 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
780 LOG_TEST_RET(card->ctx, r, "Card returned error");
781
782 return r;
783 }
784
785
786 static int
iso7816_get_response(struct sc_card * card,size_t * count,u8 * buf)787 iso7816_get_response(struct sc_card *card, size_t *count, u8 *buf)
788 {
789 struct sc_apdu apdu;
790 int r;
791 size_t rlen;
792
793 /* request at most max_recv_size bytes */
794 if (*count > sc_get_max_recv_size(card))
795 rlen = sc_get_max_recv_size(card);
796 else
797 rlen = *count;
798
799 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xC0, 0x00, 0x00);
800 apdu.le = rlen;
801 apdu.resplen = rlen;
802 apdu.resp = buf;
803 /* don't call GET RESPONSE recursively */
804 apdu.flags |= SC_APDU_FLAGS_NO_GET_RESP;
805
806 r = sc_transmit_apdu(card, &apdu);
807 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
808 if (apdu.resplen == 0)
809 LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
810
811 *count = apdu.resplen;
812
813 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
814 r = 0; /* no more data to read */
815 else if (apdu.sw1 == 0x61)
816 r = apdu.sw2 == 0 ? 256 : apdu.sw2; /* more data to read */
817 else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x82)
818 r = 0; /* Le not reached but file/record ended */
819 else
820 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
821
822 return r;
823 }
824
825
826 static int
iso7816_delete_file(struct sc_card * card,const sc_path_t * path)827 iso7816_delete_file(struct sc_card *card, const sc_path_t *path)
828 {
829 int r;
830 u8 sbuf[2];
831 struct sc_apdu apdu;
832
833 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
834 if (path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) {
835 sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID");
836 LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
837 }
838
839 if (path->len == 2) {
840 sbuf[0] = path->value[0];
841 sbuf[1] = path->value[1];
842 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
843 apdu.lc = 2;
844 apdu.datalen = 2;
845 apdu.data = sbuf;
846 }
847 else {
848 /* No file ID given: means currently selected file */
849 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00);
850 }
851
852 r = sc_transmit_apdu(card, &apdu);
853 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
854 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
855 LOG_TEST_RET(card->ctx, r, "Card returned error");
856
857 return r;
858 }
859
860
861 static int
iso7816_set_security_env(struct sc_card * card,const struct sc_security_env * env,int se_num)862 iso7816_set_security_env(struct sc_card *card,
863 const struct sc_security_env *env, int se_num)
864 {
865 struct sc_apdu apdu;
866 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
867 u8 *p;
868 int r, locked = 0;
869
870 if (card == NULL || env == NULL) {
871 return SC_ERROR_INVALID_ARGUMENTS;
872 }
873 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
874 switch (env->operation) {
875 case SC_SEC_OPERATION_DECIPHER:
876 apdu.p2 = 0xB8;
877 break;
878 case SC_SEC_OPERATION_SIGN:
879 apdu.p2 = 0xB6;
880 break;
881 default:
882 return SC_ERROR_INVALID_ARGUMENTS;
883 }
884 p = sbuf;
885 if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
886 *p++ = 0x80; /* algorithm reference */
887 *p++ = 0x01;
888 *p++ = env->algorithm_ref & 0xFF;
889 }
890 if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) {
891 if (env->file_ref.len > 0xFF)
892 return SC_ERROR_INVALID_ARGUMENTS;
893 if (sizeof(sbuf) - (p - sbuf) < env->file_ref.len + 2)
894 return SC_ERROR_OFFSET_TOO_LARGE;
895
896 *p++ = 0x81;
897 *p++ = (u8) env->file_ref.len;
898 memcpy(p, env->file_ref.value, env->file_ref.len);
899 p += env->file_ref.len;
900 }
901 if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
902 if (sizeof(sbuf) - (p - sbuf) < env->key_ref_len + 2)
903 return SC_ERROR_OFFSET_TOO_LARGE;
904
905 if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC)
906 *p++ = 0x83;
907 else
908 *p++ = 0x84;
909 if (env->key_ref_len > 0xFF)
910 return SC_ERROR_INVALID_ARGUMENTS;
911 *p++ = env->key_ref_len & 0xFF;
912 memcpy(p, env->key_ref, env->key_ref_len);
913 p += env->key_ref_len;
914 }
915 r = p - sbuf;
916 apdu.lc = r;
917 apdu.datalen = r;
918 apdu.data = sbuf;
919 if (se_num > 0) {
920 r = sc_lock(card);
921 LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
922 locked = 1;
923 }
924 if (apdu.datalen != 0) {
925 r = sc_transmit_apdu(card, &apdu);
926 if (r) {
927 sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r));
928 goto err;
929 }
930 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
931 if (r) {
932 sc_log(card->ctx, "%s: Card returned error", sc_strerror(r));
933 goto err;
934 }
935 }
936 if (se_num <= 0)
937 return 0;
938 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num);
939 r = sc_transmit_apdu(card, &apdu);
940 sc_unlock(card);
941 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
942
943 return sc_check_sw(card, apdu.sw1, apdu.sw2);
944 err:
945 if (locked)
946 sc_unlock(card);
947 return r;
948 }
949
950
951 static int
iso7816_restore_security_env(struct sc_card * card,int se_num)952 iso7816_restore_security_env(struct sc_card *card, int se_num)
953 {
954 struct sc_apdu apdu;
955 int r;
956
957 if (card == NULL) {
958 return SC_ERROR_INVALID_ARGUMENTS;
959 }
960
961 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, se_num);
962
963 r = sc_transmit_apdu(card, &apdu);
964 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
965 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
966 LOG_TEST_RET(card->ctx, r, "Card returned error");
967
968 return r;
969 }
970
971
972 static int
iso7816_compute_signature(struct sc_card * card,const u8 * data,size_t datalen,u8 * out,size_t outlen)973 iso7816_compute_signature(struct sc_card *card,
974 const u8 * data, size_t datalen,
975 u8 * out, size_t outlen)
976 {
977 int r;
978 struct sc_apdu apdu;
979
980 if (card == NULL || data == NULL || out == NULL) {
981 return SC_ERROR_INVALID_ARGUMENTS;
982 }
983 LOG_FUNC_CALLED(card->ctx);
984 sc_log(card->ctx,
985 "ISO7816 compute signature: in-len %"SC_FORMAT_LEN_SIZE_T"u, out-len %"SC_FORMAT_LEN_SIZE_T"u",
986 datalen, outlen);
987
988 /* INS: 0x2A PERFORM SECURITY OPERATION
989 * P1: 0x9E Resp: Digital Signature
990 * P2: 0x9A Cmd: Input for Digital Signature */
991 sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x9E, 0x9A);
992 apdu.resp = out;
993 apdu.resplen = outlen;
994 apdu.le = outlen;
995
996 apdu.data = data;
997 apdu.lc = datalen;
998 apdu.datalen = datalen;
999
1000 fixup_transceive_length(card, &apdu);
1001 r = sc_transmit_apdu(card, &apdu);
1002 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1003 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
1004 LOG_FUNC_RETURN(card->ctx, apdu.resplen);
1005
1006 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1007 LOG_TEST_RET(card->ctx, r, "Card returned error");
1008
1009 LOG_FUNC_RETURN(card->ctx, r);
1010 }
1011
1012
1013 static int
iso7816_decipher(struct sc_card * card,const u8 * crgram,size_t crgram_len,u8 * out,size_t outlen)1014 iso7816_decipher(struct sc_card *card,
1015 const u8 * crgram, size_t crgram_len,
1016 u8 * out, size_t outlen)
1017 {
1018 int r;
1019 struct sc_apdu apdu;
1020 u8 *sbuf = NULL;
1021
1022 if (card == NULL || crgram == NULL || out == NULL) {
1023 return SC_ERROR_INVALID_ARGUMENTS;
1024 }
1025 LOG_FUNC_CALLED(card->ctx);
1026 sc_log(card->ctx,
1027 "ISO7816 decipher: in-len %"SC_FORMAT_LEN_SIZE_T"u, out-len %"SC_FORMAT_LEN_SIZE_T"u",
1028 crgram_len, outlen);
1029
1030 sbuf = malloc(crgram_len + 1);
1031 if (sbuf == NULL)
1032 return SC_ERROR_OUT_OF_MEMORY;
1033
1034 /* INS: 0x2A PERFORM SECURITY OPERATION
1035 * P1: 0x80 Resp: Plain value
1036 * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */
1037 sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86);
1038 apdu.resp = out;
1039 apdu.resplen = outlen;
1040 apdu.le = outlen;
1041
1042 sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
1043 memcpy(sbuf + 1, crgram, crgram_len);
1044 apdu.data = sbuf;
1045 apdu.lc = crgram_len + 1;
1046 apdu.datalen = crgram_len + 1;
1047
1048 fixup_transceive_length(card, &apdu);
1049 r = sc_transmit_apdu(card, &apdu);
1050 sc_mem_clear(sbuf, crgram_len + 1);
1051 free(sbuf);
1052 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1053
1054 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
1055 LOG_FUNC_RETURN(card->ctx, apdu.resplen);
1056 else
1057 LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1058 }
1059
1060
1061 int
iso7816_build_pin_apdu(struct sc_card * card,struct sc_apdu * apdu,struct sc_pin_cmd_data * data,u8 * buf,size_t buf_len)1062 iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
1063 struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len)
1064 {
1065 int r, len = 0, pad = 0, use_pin_pad = 0, ins, p1 = 0;
1066 int cse = SC_APDU_CASE_3_SHORT;
1067
1068 switch (data->pin_type) {
1069 case SC_AC_CHV:
1070 /* fall through */
1071 case SC_AC_SESSION:
1072 case SC_AC_CONTEXT_SPECIFIC:
1073 break;
1074 default:
1075 return SC_ERROR_INVALID_ARGUMENTS;
1076 }
1077
1078 if (data->flags & SC_PIN_CMD_NEED_PADDING)
1079 pad = 1;
1080 if (data->flags & SC_PIN_CMD_USE_PINPAD)
1081 use_pin_pad = 1;
1082
1083 data->pin1.offset = 5;
1084
1085 switch (data->cmd) {
1086 case SC_PIN_CMD_VERIFY:
1087 ins = 0x20;
1088 if ((r = sc_build_pin(buf, buf_len, &data->pin1, pad)) < 0)
1089 return r;
1090 len = r;
1091 break;
1092 case SC_PIN_CMD_CHANGE:
1093 ins = 0x24;
1094 if (data->pin1.len != 0 || (use_pin_pad && !( data->flags & SC_PIN_CMD_IMPLICIT_CHANGE))) {
1095 if ((r = sc_build_pin(buf, buf_len, &data->pin1, pad)) < 0)
1096 return r;
1097 len += r;
1098 }
1099 else {
1100 /* implicit test */
1101 p1 = 1;
1102 }
1103
1104 data->pin2.offset = data->pin1.offset + len;
1105 if ((r = sc_build_pin(buf+len, buf_len-len, &data->pin2, pad)) < 0)
1106 return r;
1107 /* Special case - where provided the old PIN on the command line
1108 * but expect the new one to be entered on the keypad.
1109 */
1110 if (data->pin1.len && data->pin2.len == 0) {
1111 sc_log(card->ctx, "Special case - initial pin provided - but new pin asked on keypad");
1112 data->flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
1113 };
1114 len += r;
1115 break;
1116 case SC_PIN_CMD_UNBLOCK:
1117 ins = 0x2C;
1118 if (data->pin1.len != 0 || (use_pin_pad && !( data->flags & SC_PIN_CMD_IMPLICIT_CHANGE))) {
1119 if ((r = sc_build_pin(buf, buf_len, &data->pin1, pad)) < 0)
1120 return r;
1121 len += r;
1122 } else {
1123 p1 |= 0x02;
1124 }
1125
1126 if (data->pin2.len != 0 || use_pin_pad) {
1127 data->pin2.offset = data->pin1.offset + len;
1128 if ((r = sc_build_pin(buf+len, buf_len-len, &data->pin2, pad)) < 0)
1129 return r;
1130 len += r;
1131 } else {
1132 p1 |= 0x01;
1133 }
1134 break;
1135 case SC_PIN_CMD_GET_INFO:
1136 ins = 0x20;
1137 /* No data to send or to receive */
1138 cse = SC_APDU_CASE_1;
1139 break;
1140 default:
1141 return SC_ERROR_NOT_SUPPORTED;
1142 }
1143
1144 sc_format_apdu(card, apdu, cse, ins, p1, data->pin_reference);
1145 apdu->lc = len;
1146 apdu->datalen = len;
1147 apdu->data = buf;
1148 apdu->resplen = 0;
1149
1150 return 0;
1151 }
1152
1153
1154 static int
iso7816_pin_cmd(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)1155 iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
1156 {
1157 struct sc_apdu local_apdu, *apdu;
1158 int r;
1159 u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
1160
1161 data->pin1.tries_left = -1;
1162 if (tries_left != NULL) {
1163 *tries_left = data->pin1.tries_left;
1164 }
1165
1166 /* Many cards do support PIN status queries, but some cards don't and
1167 * mistakenly count the command as a failed PIN attempt, so for now we
1168 * whitelist cards with this flag. In future this may be reduced to a
1169 * blacklist, subject to testing more cards. */
1170 if (data->cmd == SC_PIN_CMD_GET_INFO &&
1171 !(card->caps & SC_CARD_CAP_ISO7816_PIN_INFO)) {
1172 sc_log(card->ctx, "Card does not support PIN status queries");
1173 return SC_ERROR_NOT_SUPPORTED;
1174 }
1175
1176 /* See if we've been called from another card driver, which is
1177 * passing an APDU to us (this allows to write card drivers
1178 * whose PIN functions behave "mostly like ISO" except in some
1179 * special circumstances.
1180 */
1181 if (data->apdu == NULL) {
1182 r = iso7816_build_pin_apdu(card, &local_apdu, data, sbuf, sizeof(sbuf));
1183 if (r < 0)
1184 return r;
1185 data->apdu = &local_apdu;
1186 }
1187 apdu = data->apdu;
1188
1189 if (!(data->flags & SC_PIN_CMD_USE_PINPAD) || data->cmd == SC_PIN_CMD_GET_INFO) {
1190 /* Transmit the APDU to the card */
1191 r = sc_transmit_apdu(card, apdu);
1192
1193 /* Clear the buffer - it may contain pins */
1194 sc_mem_clear(sbuf, sizeof(sbuf));
1195 }
1196 else {
1197 /* Call the reader driver to collect
1198 * the PIN and pass on the APDU to the card */
1199 if (data->pin1.offset == 0) {
1200 sc_log(card->ctx, "Card driver didn't set PIN offset");
1201 return SC_ERROR_INVALID_ARGUMENTS;
1202 }
1203 if (card->reader && card->reader->ops && card->reader->ops->perform_verify) {
1204 r = card->reader->ops->perform_verify(card->reader, data);
1205 /* sw1/sw2 filled in by reader driver */
1206 }
1207 else {
1208 sc_log(card->ctx, "Card reader driver does not support "
1209 "PIN entry through reader key pad");
1210 r = SC_ERROR_NOT_SUPPORTED;
1211 }
1212 }
1213
1214 /* Don't pass references to local variables up to the caller. */
1215 if (data->apdu == &local_apdu)
1216 data->apdu = NULL;
1217
1218 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1219 r = sc_check_sw(card, apdu->sw1, apdu->sw2);
1220
1221 if (r == SC_SUCCESS) {
1222 data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
1223 } else if (r == SC_ERROR_PIN_CODE_INCORRECT) {
1224 data->pin1.tries_left = apdu->sw2 & 0xF;
1225 data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
1226 if (data->cmd == SC_PIN_CMD_GET_INFO)
1227 r = SC_SUCCESS;
1228 } else if (r == SC_ERROR_AUTH_METHOD_BLOCKED) {
1229 data->pin1.tries_left = 0;
1230 data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
1231 if (data->cmd == SC_PIN_CMD_GET_INFO)
1232 r = SC_SUCCESS;
1233 }
1234 if (tries_left != NULL) {
1235 *tries_left = data->pin1.tries_left;
1236 }
1237
1238 return r;
1239 }
1240
1241
iso7816_get_data(struct sc_card * card,unsigned int tag,u8 * buf,size_t len)1242 static int iso7816_get_data(struct sc_card *card, unsigned int tag, u8 *buf, size_t len)
1243 {
1244 int r, cse;
1245 struct sc_apdu apdu;
1246
1247 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1248
1249 if (buf && len)
1250 cse = SC_APDU_CASE_2;
1251 else
1252 cse = SC_APDU_CASE_1;
1253
1254 sc_format_apdu(card, &apdu, cse, 0xCA, (tag >> 8) & 0xff, tag & 0xff);
1255 apdu.le = len;
1256 apdu.resp = buf;
1257 apdu.resplen = len;
1258 r = sc_transmit_apdu(card, &apdu);
1259 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1260
1261 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1262 LOG_TEST_RET(card->ctx, r, "GET_DATA returned error");
1263
1264 if (apdu.resplen > len)
1265 r = SC_ERROR_WRONG_LENGTH;
1266 else
1267 r = apdu.resplen;
1268
1269 LOG_FUNC_RETURN(card->ctx, r);
1270 }
1271
1272
1273
1274 static int
iso7816_init(struct sc_card * card)1275 iso7816_init(struct sc_card *card)
1276 {
1277 #if ENABLE_SM
1278 memset(&card->sm_ctx, 0, sizeof card->sm_ctx);
1279 #endif
1280 return SC_SUCCESS;
1281 }
1282
1283
1284 static int
no_match(struct sc_card * card)1285 no_match(struct sc_card *card)
1286 {
1287 return 0;
1288 }
1289
1290 static struct sc_card_operations iso_ops = {
1291 no_match,
1292 iso7816_init, /* init */
1293 NULL, /* finish */
1294 iso7816_read_binary,
1295 iso7816_write_binary,
1296 iso7816_update_binary,
1297 NULL, /* erase_binary */
1298 iso7816_read_record,
1299 iso7816_write_record,
1300 iso7816_append_record,
1301 iso7816_update_record,
1302 iso7816_select_file,
1303 iso7816_get_response,
1304 iso7816_get_challenge,
1305 NULL, /* verify */
1306 NULL, /* logout */
1307 iso7816_restore_security_env,
1308 iso7816_set_security_env,
1309 iso7816_decipher,
1310 iso7816_compute_signature,
1311 NULL, /* change_reference_data */
1312 NULL, /* reset_retry_counter */
1313 iso7816_create_file,
1314 iso7816_delete_file,
1315 NULL, /* list_files */
1316 iso7816_check_sw,
1317 NULL, /* card_ctl */
1318 iso7816_process_fci,
1319 iso7816_construct_fci,
1320 iso7816_pin_cmd,
1321 iso7816_get_data,
1322 NULL, /* put_data */
1323 NULL, /* delete_record */
1324 NULL, /* read_public_key */
1325 NULL, /* card_reader_lock_obtained */
1326 NULL, /* wrap */
1327 NULL /* unwrap */
1328 };
1329
1330 static struct sc_card_driver iso_driver = {
1331 "ISO 7816 reference driver",
1332 "iso7816",
1333 &iso_ops,
1334 NULL, 0, NULL
1335 };
1336
sc_get_iso7816_driver(void)1337 struct sc_card_driver * sc_get_iso7816_driver(void)
1338 {
1339 return &iso_driver;
1340 }
1341
1342 #define ISO_READ_BINARY 0xB0
1343 #define ISO_P1_FLAG_SFID 0x80
iso7816_read_binary_sfid(sc_card_t * card,unsigned char sfid,u8 ** ef,size_t * ef_len)1344 int iso7816_read_binary_sfid(sc_card_t *card, unsigned char sfid,
1345 u8 **ef, size_t *ef_len)
1346 {
1347 int r;
1348 size_t read = MAX_SM_APDU_RESP_SIZE;
1349 sc_apdu_t apdu;
1350 u8 *p;
1351
1352 if (!card || !ef || !ef_len) {
1353 r = SC_ERROR_INVALID_ARGUMENTS;
1354 goto err;
1355 }
1356 *ef_len = 0;
1357
1358 #if MAX_SM_APDU_RESP_SIZE > (0xff+1)
1359 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT,
1360 ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
1361 #else
1362 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT,
1363 ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
1364 #endif
1365 p = realloc(*ef, read);
1366 if (!p) {
1367 r = SC_ERROR_OUT_OF_MEMORY;
1368 goto err;
1369 }
1370 *ef = p;
1371 apdu.resp = *ef;
1372 apdu.resplen = read;
1373 apdu.le = read;
1374
1375 r = sc_transmit_apdu(card, &apdu);
1376 if (r < 0)
1377 goto err;
1378 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1379 if (r < 0 && r != SC_ERROR_FILE_END_REACHED)
1380 goto err;
1381 /* emulate the behaviour of sc_read_binary */
1382 r = apdu.resplen;
1383
1384 while(1) {
1385 if (r >= 0 && ((size_t) r) != read) {
1386 *ef_len += r;
1387 break;
1388 }
1389 if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
1390 break;
1391 if (r < 0) {
1392 sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read EF.");
1393 goto err;
1394 }
1395 *ef_len += r;
1396
1397 p = realloc(*ef, *ef_len + read);
1398 if (!p) {
1399 r = SC_ERROR_OUT_OF_MEMORY;
1400 goto err;
1401 }
1402 *ef = p;
1403
1404 r = sc_read_binary(card, *ef_len,
1405 *ef + *ef_len, read, 0);
1406 }
1407
1408 r = *ef_len;
1409
1410 err:
1411 return r;
1412 }
1413
1414 #define ISO_WRITE_BINARY 0xD0
iso7816_write_binary_sfid(sc_card_t * card,unsigned char sfid,u8 * ef,size_t ef_len)1415 int iso7816_write_binary_sfid(sc_card_t *card, unsigned char sfid,
1416 u8 *ef, size_t ef_len)
1417 {
1418 int r;
1419 size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0;
1420 sc_apdu_t apdu;
1421 #ifdef ENABLE_SM
1422 struct iso_sm_ctx *iso_sm_ctx;
1423 #endif
1424
1425 if (!card) {
1426 r = SC_ERROR_INVALID_ARGUMENTS;
1427 goto err;
1428 }
1429
1430 #ifdef ENABLE_SM
1431 iso_sm_ctx = card->sm_ctx.info.cmd_data;
1432 if (write > SC_MAX_APDU_BUFFER_SIZE-2
1433 || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
1434 && write > (((SC_MAX_APDU_BUFFER_SIZE-2
1435 /* for encrypted APDUs we usually get authenticated status
1436 * bytes (4B), a MAC (11B) and a cryptogram with padding
1437 * indicator (3B without data). The cryptogram is always
1438 * padded to the block size. */
1439 -18) / iso_sm_ctx->block_length)
1440 * iso_sm_ctx->block_length - 1)))
1441 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT,
1442 ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
1443 else
1444 #endif
1445 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
1446 ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
1447
1448 if (write > ef_len) {
1449 apdu.datalen = ef_len;
1450 apdu.lc = ef_len;
1451 } else {
1452 apdu.datalen = write;
1453 apdu.lc = write;
1454 }
1455 apdu.data = ef;
1456
1457
1458 r = sc_transmit_apdu(card, &apdu);
1459 /* emulate the behaviour of sc_write_binary */
1460 if (r >= 0)
1461 r = apdu.datalen;
1462
1463 while (1) {
1464 if (r < 0 || ((size_t) r) > ef_len) {
1465 sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not write EF.");
1466 goto err;
1467 }
1468 if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
1469 break;
1470 wrote += r;
1471 apdu.data += r;
1472 if (wrote >= ef_len)
1473 break;
1474
1475 r = sc_write_binary(card, wrote, ef, write, 0);
1476 }
1477
1478 r = wrote;
1479
1480 err:
1481 return r;
1482 }
1483
1484 #define ISO_UPDATE_BINARY 0xD6
iso7816_update_binary_sfid(sc_card_t * card,unsigned char sfid,u8 * ef,size_t ef_len)1485 int iso7816_update_binary_sfid(sc_card_t *card, unsigned char sfid,
1486 u8 *ef, size_t ef_len)
1487 {
1488 int r;
1489 size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0;
1490 sc_apdu_t apdu;
1491 #ifdef ENABLE_SM
1492 struct iso_sm_ctx *iso_sm_ctx;
1493 #endif
1494
1495 if (!card) {
1496 r = SC_ERROR_INVALID_ARGUMENTS;
1497 goto err;
1498 }
1499
1500 #ifdef ENABLE_SM
1501 iso_sm_ctx = card->sm_ctx.info.cmd_data;
1502 if (write > SC_MAX_APDU_BUFFER_SIZE-2
1503 || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
1504 && write > (((SC_MAX_APDU_BUFFER_SIZE-2
1505 /* for encrypted APDUs we usually get authenticated status
1506 * bytes (4B), a MAC (11B) and a cryptogram with padding
1507 * indicator (3B without data). The cryptogram is always
1508 * padded to the block size. */
1509 -18) / iso_sm_ctx->block_length)
1510 * iso_sm_ctx->block_length - 1)))
1511 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT,
1512 ISO_UPDATE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
1513 else
1514 #endif
1515 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
1516 ISO_UPDATE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
1517
1518 if (write > ef_len) {
1519 apdu.datalen = ef_len;
1520 apdu.lc = ef_len;
1521 } else {
1522 apdu.datalen = write;
1523 apdu.lc = write;
1524 }
1525 apdu.data = ef;
1526
1527
1528 r = sc_transmit_apdu(card, &apdu);
1529 /* emulate the behaviour of sc_write_binary */
1530 if (r >= 0)
1531 r = apdu.datalen;
1532
1533 while (1) {
1534 if (r < 0 || ((size_t) r) > ef_len) {
1535 sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not update EF.");
1536 goto err;
1537 }
1538 if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
1539 break;
1540 wrote += r;
1541 apdu.data += r;
1542 if (wrote >= ef_len)
1543 break;
1544
1545 r = sc_update_binary(card, wrote, ef, write, 0);
1546 }
1547
1548 r = wrote;
1549
1550 err:
1551 return r;
1552 }
1553
iso7816_logout(sc_card_t * card,unsigned char pin_reference)1554 int iso7816_logout(sc_card_t *card, unsigned char pin_reference)
1555 {
1556 int r;
1557 sc_apdu_t apdu;
1558
1559 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0xFF, pin_reference);
1560
1561 r = sc_transmit_apdu(card, &apdu);
1562 if (r < 0)
1563 return r;
1564
1565 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1566
1567 return r;
1568 }
1569