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