Annotation of qemu/libcacard/card_7816.c, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com