|
|
1.1 root 1: /*
2: * Implement the 7816 portion of the card spec
3: *
4: * This code is licensed under the GNU LGPL, version 2.1 or later.
5: * See the COPYING.LIB file in the top-level directory.
6: */
7:
8: #include "qemu-common.h"
9:
10: #include "vcard.h"
11: #include "vcard_emul.h"
12: #include "card_7816.h"
13:
14: /*
15: * set the status bytes based on the status word
16: */
17: static void
18: vcard_response_set_status(VCardResponse *response, vcard_7816_status_t status)
19: {
20: unsigned char sw1, sw2;
21: response->b_status = status; /* make sure the status and swX representations
22: * are consistent */
23: sw1 = (status >> 8) & 0xff;
24: sw2 = status & 0xff;
25: response->b_sw1 = sw1;
26: response->b_sw2 = sw2;
27: response->b_data[response->b_len] = sw1;
28: response->b_data[response->b_len+1] = sw2;
29: }
30:
31: /*
32: * set the status bytes in a response buffer
33: */
34: static void
35: vcard_response_set_status_bytes(VCardResponse *response,
36: unsigned char sw1, unsigned char sw2)
37: {
38: response->b_status = sw1 << 8 | sw2;
39: response->b_sw1 = sw1;
40: response->b_sw2 = sw2;
41: response->b_data[response->b_len] = sw1;
42: response->b_data[response->b_len+1] = sw2;
43: }
44:
45: /*
46: * allocate a VCardResponse structure, plus space for the data buffer, and
47: * set up everything but the resonse bytes.
48: */
49: VCardResponse *
50: vcard_response_new_data(unsigned char *buf, int len)
51: {
52: VCardResponse *new_response;
53:
1.1.1.2 ! root 54: new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
! 55: new_response->b_data = g_malloc(len + 2);
1.1 root 56: memcpy(new_response->b_data, buf, len);
57: new_response->b_total_len = len+2;
58: new_response->b_len = len;
59: new_response->b_type = VCARD_MALLOC;
60: return new_response;
61: }
62:
63: static VCardResponse *
64: vcard_init_buffer_response(VCard *card, unsigned char *buf, int len)
65: {
66: VCardResponse *response;
67: VCardBufferResponse *buffer_response;
68:
69: buffer_response = vcard_get_buffer_response(card);
70: if (buffer_response) {
71: vcard_set_buffer_response(card, NULL);
72: vcard_buffer_response_delete(buffer_response);
73: }
74: buffer_response = vcard_buffer_response_new(buf, len);
75: if (buffer_response == NULL) {
76: return NULL;
77: }
78: response = vcard_response_new_status_bytes(VCARD7816_SW1_RESPONSE_BYTES,
79: len > 255 ? 0 : len);
80: if (response == NULL) {
81: return NULL;
82: }
83: vcard_set_buffer_response(card, buffer_response);
84: return response;
85: }
86:
87: /*
88: * general buffer to hold results from APDU calls
89: */
90: VCardResponse *
91: vcard_response_new(VCard *card, unsigned char *buf,
92: int len, int Le, vcard_7816_status_t status)
93: {
94: VCardResponse *new_response;
95:
96: if (len > Le) {
97: return vcard_init_buffer_response(card, buf, len);
98: }
99: new_response = vcard_response_new_data(buf, len);
100: if (new_response == NULL) {
101: return NULL;
102: }
103: vcard_response_set_status(new_response, status);
104: return new_response;
105: }
106:
107: /*
108: * general buffer to hold results from APDU calls
109: */
110: VCardResponse *
111: vcard_response_new_bytes(VCard *card, unsigned char *buf, int len, int Le,
112: unsigned char sw1, unsigned char sw2)
113: {
114: VCardResponse *new_response;
115:
116: if (len > Le) {
117: return vcard_init_buffer_response(card, buf, len);
118: }
119: new_response = vcard_response_new_data(buf, len);
120: if (new_response == NULL) {
121: return NULL;
122: }
123: vcard_response_set_status_bytes(new_response, sw1, sw2);
124: return new_response;
125: }
126:
127: /*
128: * get a new Reponse buffer that only has a status.
129: */
130: static VCardResponse *
131: vcard_response_new_status(vcard_7816_status_t status)
132: {
133: VCardResponse *new_response;
134:
1.1.1.2 ! root 135: new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
1.1 root 136: new_response->b_data = &new_response->b_sw1;
137: new_response->b_len = 0;
138: new_response->b_total_len = 2;
139: new_response->b_type = VCARD_MALLOC_STRUCT;
140: vcard_response_set_status(new_response, status);
141: return new_response;
142: }
143:
144: /*
145: * same as above, but specify the status as separate bytes
146: */
147: VCardResponse *
148: vcard_response_new_status_bytes(unsigned char sw1, unsigned char sw2)
149: {
150: VCardResponse *new_response;
151:
1.1.1.2 ! root 152: new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
1.1 root 153: new_response->b_data = &new_response->b_sw1;
154: new_response->b_len = 0;
155: new_response->b_total_len = 2;
156: new_response->b_type = VCARD_MALLOC_STRUCT;
157: vcard_response_set_status_bytes(new_response, sw1, sw2);
158: return new_response;
159: }
160:
161:
162: /*
163: * free the response buffer. The Buffer has a type to handle the buffer
164: * allocated in other ways than through malloc.
165: */
166: void
167: vcard_response_delete(VCardResponse *response)
168: {
169: if (response == NULL) {
170: return;
171: }
172: switch (response->b_type) {
173: case VCARD_MALLOC:
174: /* everything was malloc'ed */
175: if (response->b_data) {
1.1.1.2 ! root 176: g_free(response->b_data);
1.1 root 177: }
1.1.1.2 ! root 178: g_free(response);
1.1 root 179: break;
180: case VCARD_MALLOC_DATA:
181: /* only the data buffer was malloc'ed */
182: if (response->b_data) {
1.1.1.2 ! root 183: g_free(response->b_data);
1.1 root 184: }
185: break;
186: case VCARD_MALLOC_STRUCT:
187: /* only the structure was malloc'ed */
1.1.1.2 ! root 188: g_free(response);
1.1 root 189: break;
190: case VCARD_STATIC:
191: break;
192: }
193: }
194:
195: /*
196: * decode the class bit and set our generic type field, channel, and
197: * secure messaging values.
198: */
199: static vcard_7816_status_t
200: vcard_apdu_set_class(VCardAPDU *apdu) {
201: apdu->a_channel = 0;
202: apdu->a_secure_messaging = 0;
203: apdu->a_type = apdu->a_cla & 0xf0;
204: apdu->a_gen_type = VCARD_7816_ISO;
205:
206: /* parse the class tables 8 & 9 of the 7816-4 Part 4 spec */
207: switch (apdu->a_type) {
208: /* we only support the basic types */
209: case 0x00:
210: case 0x80:
211: case 0x90:
212: case 0xa0:
213: apdu->a_channel = apdu->a_cla & 3;
214: apdu->a_secure_messaging = apdu->a_cla & 0xe;
215: break;
216: case 0xb0:
217: case 0xc0:
218: break;
219:
220: case 0x10:
221: case 0x20:
222: case 0x30:
223: case 0x40:
224: case 0x50:
225: case 0x60:
226: case 0x70:
227: /* Reserved for future use */
228: apdu->a_gen_type = VCARD_7816_RFU;
229: break;
230: case 0xd0:
231: case 0xe0:
232: case 0xf0:
233: default:
234: apdu->a_gen_type =
235: (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPIETARY;
236: break;
237: }
238: return VCARD7816_STATUS_SUCCESS;
239: }
240:
241: /*
242: * set the Le and Lc fiels according to table 5 of the
243: * 7816-4 part 4 spec
244: */
245: static vcard_7816_status_t
246: vcard_apdu_set_length(VCardAPDU *apdu)
247: {
248: int L, Le;
249:
250: /* process according to table 5 of the 7816-4 Part 4 spec.
251: * variable names match the variables in the spec */
252: L = apdu->a_len-4; /* fixed APDU header */
253: apdu->a_Lc = 0;
254: apdu->a_Le = 0;
255: apdu->a_body = NULL;
256: switch (L) {
257: case 0:
258: /* 1 minimal apdu */
259: return VCARD7816_STATUS_SUCCESS;
260: case 1:
261: /* 2S only return values apdu */
262: /* zero maps to 256 here */
263: apdu->a_Le = apdu->a_header->ah_Le ?
264: apdu->a_header->ah_Le : 256;
265: return VCARD7816_STATUS_SUCCESS;
266: default:
267: /* if the ah_Le byte is zero and we have more than
268: * 1 byte in the header, then we must be using extended Le and Lc.
269: * process the extended now. */
270: if (apdu->a_header->ah_Le == 0) {
271: if (L < 3) {
272: /* coding error, need at least 3 bytes */
273: return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
274: }
275: /* calculate the first extended value. Could be either Le or Lc */
276: Le = (apdu->a_header->ah_body[0] << 8)
277: || apdu->a_header->ah_body[1];
278: if (L == 3) {
279: /* 2E extended, return data only */
280: /* zero maps to 65536 */
281: apdu->a_Le = Le ? Le : 65536;
282: return VCARD7816_STATUS_SUCCESS;
283: }
284: if (Le == 0) {
285: /* reserved for future use, probably for next time we need
286: * to extend the lengths */
287: return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
288: }
289: /* we know that the first extended value is Lc now */
290: apdu->a_Lc = Le;
291: apdu->a_body = &apdu->a_header->ah_body[2];
292: if (L == Le+3) {
293: /* 3E extended, only body parameters */
294: return VCARD7816_STATUS_SUCCESS;
295: }
296: if (L == Le+5) {
297: /* 4E extended, parameters and return data */
298: Le = (apdu->a_data[apdu->a_len-2] << 8)
299: || apdu->a_data[apdu->a_len-1];
300: apdu->a_Le = Le ? Le : 65536;
301: return VCARD7816_STATUS_SUCCESS;
302: }
303: return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
304: }
305: /* not extended */
306: apdu->a_Lc = apdu->a_header->ah_Le;
307: apdu->a_body = &apdu->a_header->ah_body[0];
308: if (L == apdu->a_Lc + 1) {
309: /* 3S only body parameters */
310: return VCARD7816_STATUS_SUCCESS;
311: }
312: if (L == apdu->a_Lc + 2) {
313: /* 4S parameters and return data */
314: Le = apdu->a_data[apdu->a_len-1];
315: apdu->a_Le = Le ? Le : 256;
316: return VCARD7816_STATUS_SUCCESS;
317: }
318: break;
319: }
320: return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
321: }
322:
323: /*
324: * create a new APDU from a raw set of bytes. This will decode all the
325: * above fields. users of VCARDAPDU's can then depend on the already decoded
326: * values.
327: */
328: VCardAPDU *
329: vcard_apdu_new(unsigned char *raw_apdu, int len, vcard_7816_status_t *status)
330: {
331: VCardAPDU *new_apdu;
332:
333: *status = VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE;
334: if (len < 4) {
335: *status = VCARD7816_STATUS_ERROR_WRONG_LENGTH;
336: return NULL;
337: }
338:
1.1.1.2 ! root 339: new_apdu = (VCardAPDU *)g_malloc(sizeof(VCardAPDU));
! 340: new_apdu->a_data = g_malloc(len);
1.1 root 341: memcpy(new_apdu->a_data, raw_apdu, len);
342: new_apdu->a_len = len;
343: *status = vcard_apdu_set_class(new_apdu);
344: if (*status != VCARD7816_STATUS_SUCCESS) {
1.1.1.2 ! root 345: g_free(new_apdu);
1.1 root 346: return NULL;
347: }
348: *status = vcard_apdu_set_length(new_apdu);
349: if (*status != VCARD7816_STATUS_SUCCESS) {
1.1.1.2 ! root 350: g_free(new_apdu);
1.1 root 351: new_apdu = NULL;
352: }
353: return new_apdu;
354: }
355:
356: void
357: vcard_apdu_delete(VCardAPDU *apdu)
358: {
359: if (apdu == NULL) {
360: return;
361: }
362: if (apdu->a_data) {
1.1.1.2 ! root 363: g_free(apdu->a_data);
1.1 root 364: }
1.1.1.2 ! root 365: g_free(apdu);
1.1 root 366: }
367:
368:
369: /*
370: * declare response buffers for all the 7816 defined error codes
371: */
372: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_SUCCESS)
373: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING)
374: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_RET_CORUPT)
375: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE)
376: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED)
377: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID)
378: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_CHANGE)
379: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_FILE_FILLED)
380: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR)
381: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR_CHANGE)
382: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE)
383: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_LENGTH)
384: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED)
385: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED)
386: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED)
387: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED)
388: VCARD_RESPONSE_NEW_STATIC_STATUS(
389: VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE)
390: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED)
391: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED)
392: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_INVALID)
393: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED)
394: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_NO_EF)
395: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING)
396: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT)
397: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS)
398: VCARD_RESPONSE_NEW_STATIC_STATUS(
399: VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA)
400: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED)
401: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_FILE_NOT_FOUND)
402: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND)
403: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE)
404: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT)
405: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_P1_P2_INCORRECT)
406: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT)
407: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_NOT_FOUND)
408: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2)
409: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_INS_CODE_INVALID)
410: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CLA_INVALID)
411: VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_GENERAL)
412:
413: /*
414: * return a single response code. This function cannot fail. It will always
415: * return a response.
416: */
417: VCardResponse *
418: vcard_make_response(vcard_7816_status_t status)
419: {
420: VCardResponse *response = NULL;
421:
422: switch (status) {
423: /* known 7816 response codes */
424: case VCARD7816_STATUS_SUCCESS:
425: return VCARD_RESPONSE_GET_STATIC(
426: VCARD7816_STATUS_SUCCESS);
427: case VCARD7816_STATUS_WARNING:
428: return VCARD_RESPONSE_GET_STATIC(
429: VCARD7816_STATUS_WARNING);
430: case VCARD7816_STATUS_WARNING_RET_CORUPT:
431: return VCARD_RESPONSE_GET_STATIC(
432: VCARD7816_STATUS_WARNING_RET_CORUPT);
433: case VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE:
434: return VCARD_RESPONSE_GET_STATIC(
435: VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE);
436: case VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED:
437: return VCARD_RESPONSE_GET_STATIC(
438: VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED);
439: case VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID:
440: return VCARD_RESPONSE_GET_STATIC(
441: VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID);
442: case VCARD7816_STATUS_WARNING_CHANGE:
443: return VCARD_RESPONSE_GET_STATIC(
444: VCARD7816_STATUS_WARNING_CHANGE);
445: case VCARD7816_STATUS_WARNING_FILE_FILLED:
446: return VCARD_RESPONSE_GET_STATIC(
447: VCARD7816_STATUS_WARNING_FILE_FILLED);
448: case VCARD7816_STATUS_EXC_ERROR:
449: return VCARD_RESPONSE_GET_STATIC(
450: VCARD7816_STATUS_EXC_ERROR);
451: case VCARD7816_STATUS_EXC_ERROR_CHANGE:
452: return VCARD_RESPONSE_GET_STATIC(
453: VCARD7816_STATUS_EXC_ERROR_CHANGE);
454: case VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE:
455: return VCARD_RESPONSE_GET_STATIC(
456: VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
457: case VCARD7816_STATUS_ERROR_WRONG_LENGTH:
458: return VCARD_RESPONSE_GET_STATIC(
459: VCARD7816_STATUS_ERROR_WRONG_LENGTH);
460: case VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED:
461: return VCARD_RESPONSE_GET_STATIC(
462: VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED);
463: case VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED:
464: return VCARD_RESPONSE_GET_STATIC(
465: VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED);
466: case VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED:
467: return VCARD_RESPONSE_GET_STATIC(
468: VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED);
469: case VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED:
470: return VCARD_RESPONSE_GET_STATIC(
471: VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
472: case VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE:
473: return VCARD_RESPONSE_GET_STATIC(
474: VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE);
475: case VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED:
476: return VCARD_RESPONSE_GET_STATIC(
477: VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED);
478: case VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED:
479: return VCARD_RESPONSE_GET_STATIC(
480: VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED);
481: case VCARD7816_STATUS_ERROR_DATA_INVALID:
482: return VCARD_RESPONSE_GET_STATIC(
483: VCARD7816_STATUS_ERROR_DATA_INVALID);
484: case VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED:
485: return VCARD_RESPONSE_GET_STATIC(
486: VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
487: case VCARD7816_STATUS_ERROR_DATA_NO_EF:
488: return VCARD_RESPONSE_GET_STATIC(
489: VCARD7816_STATUS_ERROR_DATA_NO_EF);
490: case VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING:
491: return VCARD_RESPONSE_GET_STATIC(
492: VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING);
493: case VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT:
494: return VCARD_RESPONSE_GET_STATIC(
495: VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT);
496: case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS:
497: return VCARD_RESPONSE_GET_STATIC(
498: VCARD7816_STATUS_ERROR_WRONG_PARAMETERS);
499: case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA:
500: return VCARD_RESPONSE_GET_STATIC(
501: VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA);
502: case VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED:
503: return VCARD_RESPONSE_GET_STATIC(
504: VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED);
505: case VCARD7816_STATUS_ERROR_FILE_NOT_FOUND:
506: return VCARD_RESPONSE_GET_STATIC(
507: VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
508: case VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND:
509: return VCARD_RESPONSE_GET_STATIC(
510: VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND);
511: case VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE:
512: return VCARD_RESPONSE_GET_STATIC(
513: VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE);
514: case VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT:
515: return VCARD_RESPONSE_GET_STATIC(
516: VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT);
517: case VCARD7816_STATUS_ERROR_P1_P2_INCORRECT:
518: return VCARD_RESPONSE_GET_STATIC(
519: VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
520: case VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT:
521: return VCARD_RESPONSE_GET_STATIC(
522: VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT);
523: case VCARD7816_STATUS_ERROR_DATA_NOT_FOUND:
524: return VCARD_RESPONSE_GET_STATIC(
525: VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
526: case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2:
527: return VCARD_RESPONSE_GET_STATIC(
528: VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2);
529: case VCARD7816_STATUS_ERROR_INS_CODE_INVALID:
530: return VCARD_RESPONSE_GET_STATIC(
531: VCARD7816_STATUS_ERROR_INS_CODE_INVALID);
532: case VCARD7816_STATUS_ERROR_CLA_INVALID:
533: return VCARD_RESPONSE_GET_STATIC(
534: VCARD7816_STATUS_ERROR_CLA_INVALID);
535: case VCARD7816_STATUS_ERROR_GENERAL:
536: return VCARD_RESPONSE_GET_STATIC(
537: VCARD7816_STATUS_ERROR_GENERAL);
538: default:
539: /* we don't know this status code, create a response buffer to
540: * hold it */
541: response = vcard_response_new_status(status);
542: if (response == NULL) {
543: /* couldn't allocate the buffer, return memmory error */
544: return VCARD_RESPONSE_GET_STATIC(
545: VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
546: }
547: }
548: assert(response);
549: return response;
550: }
551:
552: /*
553: * Add File card support here if you need it.
554: */
555: static VCardStatus
556: vcard7816_file_system_process_apdu(VCard *card, VCardAPDU *apdu,
557: VCardResponse **response)
558: {
559: /* TODO: if we want to support a virtual file system card, we do it here.
560: * It would probably be a pkcs #15 card type */
561: *response = vcard_make_response(
562: VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
563: return VCARD_DONE;
564: }
565:
566: /*
567: * VM card (including java cards)
568: */
569: static VCardStatus
570: vcard7816_vm_process_apdu(VCard *card, VCardAPDU *apdu,
571: VCardResponse **response)
572: {
573: int bytes_to_copy, next_byte_count, count;
574: VCardApplet *current_applet;
575: VCardBufferResponse *buffer_response;
576: vcard_7816_status_t status;
577:
578: /* parse the class first */
579: if (apdu->a_gen_type != VCARD_7816_ISO) {
580: *response = vcard_make_response(
581: VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
582: return VCARD_DONE;
583: }
584:
585: /* use a switch so that if we need to support secure channel stuff later,
586: * we know where to put it */
587: switch (apdu->a_secure_messaging) {
588: case 0x0: /* no SM */
589: break;
590: case 0x4: /* proprietary SM */
591: case 0x8: /* header not authenticated */
592: case 0xc: /* header authenticated */
593: default:
594: /* for now, don't try to support secure channel stuff in the
595: * virtual card. */
596: *response = vcard_make_response(
597: VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED);
598: return VCARD_DONE;
599: }
600:
601: /* now parse the instruction */
602: switch (apdu->a_ins) {
603: case VCARD7816_INS_MANAGE_CHANNEL: /* secure channel op */
604: case VCARD7816_INS_EXTERNAL_AUTHENTICATE: /* secure channel op */
605: case VCARD7816_INS_GET_CHALLENGE: /* secure channel op */
606: case VCARD7816_INS_INTERNAL_AUTHENTICATE: /* secure channel op */
607: case VCARD7816_INS_ERASE_BINARY: /* applet control op */
608: case VCARD7816_INS_READ_BINARY: /* applet control op */
609: case VCARD7816_INS_WRITE_BINARY: /* applet control op */
610: case VCARD7816_INS_UPDATE_BINARY: /* applet control op */
611: case VCARD7816_INS_READ_RECORD: /* file op */
612: case VCARD7816_INS_WRITE_RECORD: /* file op */
613: case VCARD7816_INS_UPDATE_RECORD: /* file op */
614: case VCARD7816_INS_APPEND_RECORD: /* file op */
615: case VCARD7816_INS_ENVELOPE:
616: case VCARD7816_INS_PUT_DATA:
617: *response = vcard_make_response(
618: VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
619: break;
620:
621: case VCARD7816_INS_SELECT_FILE:
622: if (apdu->a_p1 != 0x04) {
623: *response = vcard_make_response(
624: VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED);
625: break;
626: }
627:
628: /* side effect, deselect the current applet if no applet has been found
629: * */
630: current_applet = vcard_find_applet(card, apdu->a_body, apdu->a_Lc);
631: vcard_select_applet(card, apdu->a_channel, current_applet);
632: if (current_applet) {
633: unsigned char *aid;
634: int aid_len;
635: aid = vcard_applet_get_aid(current_applet, &aid_len);
636: *response = vcard_response_new(card, aid, aid_len, apdu->a_Le,
637: VCARD7816_STATUS_SUCCESS);
638: } else {
639: *response = vcard_make_response(
640: VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
641: }
642: break;
643:
644: case VCARD7816_INS_VERIFY:
645: if ((apdu->a_p1 != 0x00) || (apdu->a_p2 != 0x00)) {
646: *response = vcard_make_response(
647: VCARD7816_STATUS_ERROR_WRONG_PARAMETERS);
648: } else {
649: if (apdu->a_Lc == 0) {
650: /* handle pin count if possible */
651: count = vcard_emul_get_login_count(card);
652: if (count < 0) {
653: *response = vcard_make_response(
654: VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
655: } else {
656: if (count > 0xf) {
657: count = 0xf;
658: }
659: *response = vcard_response_new_status_bytes(
660: VCARD7816_SW1_WARNING_CHANGE,
661: 0xc0 | count);
662: if (*response == NULL) {
663: *response = vcard_make_response(
664: VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
665: }
666: }
667: } else {
668: status = vcard_emul_login(card, apdu->a_body, apdu->a_Lc);
669: *response = vcard_make_response(status);
670: }
671: }
672: break;
673:
674: case VCARD7816_INS_GET_RESPONSE:
675: buffer_response = vcard_get_buffer_response(card);
676: if (!buffer_response) {
677: *response = vcard_make_response(
678: VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
679: /* handle error */
680: break;
681: }
682: bytes_to_copy = MIN(buffer_response->len, apdu->a_Le);
683: next_byte_count = MIN(256, buffer_response->len - bytes_to_copy);
684: *response = vcard_response_new_bytes(
685: card, buffer_response->current, bytes_to_copy,
686: apdu->a_Le,
687: next_byte_count ?
688: VCARD7816_SW1_RESPONSE_BYTES : VCARD7816_SW1_SUCCESS,
689: next_byte_count);
690: buffer_response->current += bytes_to_copy;
691: buffer_response->len -= bytes_to_copy;
692: if (*response == NULL || (next_byte_count == 0)) {
693: vcard_set_buffer_response(card, NULL);
694: vcard_buffer_response_delete(buffer_response);
695: }
696: if (*response == NULL) {
697: *response =
698: vcard_make_response(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
699: }
700: break;
701:
702: case VCARD7816_INS_GET_DATA:
703: *response =
704: vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
705: break;
706:
707: default:
708: *response =
709: vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
710: break;
711: }
712:
713: /* response should have been set somewhere */
714: assert(*response != NULL);
715: return VCARD_DONE;
716: }
717:
718:
719: /*
720: * APDU processing starts here. This routes the card processing stuff to the
721: * right location.
722: */
723: VCardStatus
724: vcard_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
725: {
726: VCardStatus status;
727: VCardBufferResponse *buffer_response;
728:
729: /* first handle any PTS commands, which aren't really APDU's */
730: if (apdu->a_type == VCARD_7816_PTS) {
731: /* the PTS responses aren't really responses either */
732: *response = vcard_response_new_data(apdu->a_data, apdu->a_len);
733: /* PTS responses have no status bytes */
734: (*response)->b_total_len = (*response)->b_len;
735: return VCARD_DONE;
736: }
737: buffer_response = vcard_get_buffer_response(card);
738: if (buffer_response && apdu->a_ins != VCARD7816_INS_GET_RESPONSE) {
739: /* clear out buffer_response, return an error */
740: vcard_set_buffer_response(card, NULL);
741: vcard_buffer_response_delete(buffer_response);
742: *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR);
743: return VCARD_DONE;
744: }
745:
746: status = vcard_process_applet_apdu(card, apdu, response);
747: if (status != VCARD_NEXT) {
748: return status;
749: }
750: switch (vcard_get_type(card)) {
751: case VCARD_FILE_SYSTEM:
752: return vcard7816_file_system_process_apdu(card, apdu, response);
753: case VCARD_VM:
754: return vcard7816_vm_process_apdu(card, apdu, response);
755: case VCARD_DIRECT:
756: /* if we are type direct, then the applet should handle everything */
1.1.1.2 ! root 757: assert(!"VCARD_DIRECT: applet failure");
1.1 root 758: break;
759: }
760: *response =
761: vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
762: return VCARD_DONE;
763: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.