/*
 * Implement the 7816 portion of the card spec
 *
 * This code is licensed under the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 */

#include "qemu-common.h"

#include "vcard.h"
#include "vcard_emul.h"
#include "card_7816.h"

/*
 * set the status bytes based on the status word
 */
static void
vcard_response_set_status(VCardResponse *response, vcard_7816_status_t status)
{
    unsigned char sw1, sw2;
    response->b_status = status; /* make sure the status and swX representations
                                  * are consistent */
    sw1 = (status >> 8) & 0xff;
    sw2 = status & 0xff;
    response->b_sw1 = sw1;
    response->b_sw2 = sw2;
    response->b_data[response->b_len] = sw1;
    response->b_data[response->b_len+1] = sw2;
}

/*
 * set the status bytes in a response buffer
 */
static void
vcard_response_set_status_bytes(VCardResponse *response,
                               unsigned char sw1, unsigned char sw2)
{
    response->b_status = sw1 << 8 | sw2;
    response->b_sw1 = sw1;
    response->b_sw2 = sw2;
    response->b_data[response->b_len] = sw1;
    response->b_data[response->b_len+1] = sw2;
}

/*
 * allocate a VCardResponse structure, plus space for the data buffer, and
 * set up everything but the resonse bytes.
 */
VCardResponse *
vcard_response_new_data(unsigned char *buf, int len)
{
    VCardResponse *new_response;

    new_response = g_new(VCardResponse, 1);
    new_response->b_data = g_malloc(len + 2);
    memcpy(new_response->b_data, buf, len);
    new_response->b_total_len = len+2;
    new_response->b_len = len;
    new_response->b_type = VCARD_MALLOC;
    return new_response;
}

static VCardResponse *
vcard_init_buffer_response(VCard *card, unsigned char *buf, int len)
{
    VCardResponse *response;
    VCardBufferResponse *buffer_response;

    buffer_response = vcard_get_buffer_response(card);
    if (buffer_response) {
        vcard_set_buffer_response(card, NULL);
        vcard_buffer_response_delete(buffer_response);
    }
    buffer_response = vcard_buffer_response_new(buf, len);
    if (buffer_response == NULL) {
        return NULL;
    }
    response = vcard_response_new_status_bytes(VCARD7816_SW1_RESPONSE_BYTES,
                                               len > 255 ? 0 : len);
    if (response == NULL) {
        return NULL;
    }
    vcard_set_buffer_response(card, buffer_response);
    return response;
}

/*
 * general buffer to hold results from APDU calls
 */
VCardResponse *
vcard_response_new(VCard *card, unsigned char *buf,
                   int len, int Le, vcard_7816_status_t status)
{
    VCardResponse *new_response;

    if (len > Le) {
        return vcard_init_buffer_response(card, buf, len);
    }
    new_response = vcard_response_new_data(buf, len);
    if (new_response == NULL) {
        return NULL;
    }
    vcard_response_set_status(new_response, status);
    return new_response;
}

/*
 * general buffer to hold results from APDU calls
 */
VCardResponse *
vcard_response_new_bytes(VCard *card, unsigned char *buf, int len, int Le,
                         unsigned char sw1, unsigned char sw2)
{
    VCardResponse *new_response;

    if (len > Le) {
        return vcard_init_buffer_response(card, buf, len);
    }
    new_response = vcard_response_new_data(buf, len);
    if (new_response == NULL) {
        return NULL;
    }
    vcard_response_set_status_bytes(new_response, sw1, sw2);
    return new_response;
}

/*
 * get a new Response buffer that only has a status.
 */
static VCardResponse *
vcard_response_new_status(vcard_7816_status_t status)
{
    VCardResponse *new_response;

    new_response = g_new(VCardResponse, 1);
    new_response->b_data = &new_response->b_sw1;
    new_response->b_len = 0;
    new_response->b_total_len = 2;
    new_response->b_type = VCARD_MALLOC_STRUCT;
    vcard_response_set_status(new_response, status);
    return new_response;
}

/*
 * same as above, but specify the status as separate bytes
 */
VCardResponse *
vcard_response_new_status_bytes(unsigned char sw1, unsigned char sw2)
{
    VCardResponse *new_response;

    new_response = g_new(VCardResponse, 1);
    new_response->b_data = &new_response->b_sw1;
    new_response->b_len = 0;
    new_response->b_total_len = 2;
    new_response->b_type = VCARD_MALLOC_STRUCT;
    vcard_response_set_status_bytes(new_response, sw1, sw2);
    return new_response;
}


/*
 * free the response buffer. The Buffer has a type to handle the buffer
 * allocated in other ways than through malloc.
 */
void
vcard_response_delete(VCardResponse *response)
{
    if (response == NULL) {
        return;
    }
    switch (response->b_type) {
    case VCARD_MALLOC:
        /* everything was malloc'ed */
        if (response->b_data) {
            g_free(response->b_data);
        }
        g_free(response);
        break;
    case VCARD_MALLOC_DATA:
        /* only the data buffer was malloc'ed */
        if (response->b_data) {
            g_free(response->b_data);
        }
        break;
    case VCARD_MALLOC_STRUCT:
        /* only the structure was malloc'ed */
        g_free(response);
        break;
    case VCARD_STATIC:
        break;
    }
}

/*
 * decode the class bit and set our generic type field, channel, and
 * secure messaging values.
 */
static vcard_7816_status_t
vcard_apdu_set_class(VCardAPDU *apdu) {
    apdu->a_channel = 0;
    apdu->a_secure_messaging = 0;
    apdu->a_type = apdu->a_cla & 0xf0;
    apdu->a_gen_type = VCARD_7816_ISO;

    /* parse the class  tables 8 & 9 of the 7816-4 Part 4 spec */
    switch (apdu->a_type) {
        /* we only support the basic types */
    case 0x00:
    case 0x80:
    case 0x90:
    case 0xa0:
        apdu->a_channel = apdu->a_cla & 3;
        apdu->a_secure_messaging = apdu->a_cla & 0xe;
        break;
    case 0xb0:
    case 0xc0:
        break;

    case 0x10:
    case 0x20:
    case 0x30:
    case 0x40:
    case 0x50:
    case 0x60:
    case 0x70:
        /* Reserved for future use */
        apdu->a_gen_type = VCARD_7816_RFU;
        break;
    case 0xd0:
    case 0xe0:
    case 0xf0:
    default:
        apdu->a_gen_type =
            (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPRIETARY;
        break;
    }
    return VCARD7816_STATUS_SUCCESS;
}

/*
 * set the Le and Lc fields according to table 5 of the
 * 7816-4 part 4 spec
 */
static vcard_7816_status_t
vcard_apdu_set_length(VCardAPDU *apdu)
{
    int L, Le;

    /* process according to table 5 of the 7816-4 Part 4 spec.
     * variable names match the variables in the spec */
    L = apdu->a_len-4; /* fixed APDU header */
    apdu->a_Lc = 0;
    apdu->a_Le = 0;
    apdu->a_body = NULL;
    switch (L) {
    case 0:
        /* 1 minimal apdu */
        return VCARD7816_STATUS_SUCCESS;
    case 1:
        /* 2S only return values apdu */
        /*   zero maps to 256 here */
        apdu->a_Le = apdu->a_header->ah_Le ?
                         apdu->a_header->ah_Le : 256;
        return VCARD7816_STATUS_SUCCESS;
    default:
        /* if the ah_Le byte is zero and we have more than
         * 1 byte in the header, then we must be using extended Le and Lc.
         * process the extended now. */
        if (apdu->a_header->ah_Le == 0) {
            if (L < 3) {
                /* coding error, need at least 3 bytes */
                return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
            }
            /* calculate the first extended value. Could be either Le or Lc */
            Le = (apdu->a_header->ah_body[0] << 8)
               || apdu->a_header->ah_body[1];
            if (L == 3) {
                /* 2E extended, return data only */
                /*   zero maps to 65536 */
                apdu->a_Le = Le ? Le : 65536;
                return VCARD7816_STATUS_SUCCESS;
            }
            if (Le == 0) {
                /* reserved for future use, probably for next time we need
                 * to extend the lengths */
                return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
            }
            /* we know that the first extended value is Lc now */
            apdu->a_Lc = Le;
            apdu->a_body = &apdu->a_header->ah_body[2];
            if (L == Le+3) {
                /* 3E extended, only body parameters */
                return VCARD7816_STATUS_SUCCESS;
            }
            if (L == Le+5) {
                /* 4E extended, parameters and return data */
                Le = (apdu->a_data[apdu->a_len-2] << 8)
                   || apdu->a_data[apdu->a_len-1];
                apdu->a_Le = Le ? Le : 65536;
                return VCARD7816_STATUS_SUCCESS;
            }
            return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
        }
        /* not extended */
        apdu->a_Lc = apdu->a_header->ah_Le;
        apdu->a_body = &apdu->a_header->ah_body[0];
        if (L ==  apdu->a_Lc + 1) {
            /* 3S only body parameters */
            return VCARD7816_STATUS_SUCCESS;
        }
        if (L ==  apdu->a_Lc + 2) {
            /* 4S parameters and return data */
            Le = apdu->a_data[apdu->a_len-1];
            apdu->a_Le = Le ?  Le : 256;
            return VCARD7816_STATUS_SUCCESS;
        }
        break;
    }
    return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
}

/*
 * create a new APDU from a raw set of bytes. This will decode all the
 * above fields. users of VCARDAPDU's can then depend on the already decoded
 * values.
 */
VCardAPDU *
vcard_apdu_new(unsigned char *raw_apdu, int len, vcard_7816_status_t *status)
{
    VCardAPDU *new_apdu;

    *status = VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE;
    if (len < 4) {
        *status = VCARD7816_STATUS_ERROR_WRONG_LENGTH;
        return NULL;
    }

    new_apdu = g_new(VCardAPDU, 1);
    new_apdu->a_data = g_memdup(raw_apdu, len);
    new_apdu->a_len = len;
    *status = vcard_apdu_set_class(new_apdu);
    if (*status != VCARD7816_STATUS_SUCCESS) {
        g_free(new_apdu);
        return NULL;
    }
    *status = vcard_apdu_set_length(new_apdu);
    if (*status != VCARD7816_STATUS_SUCCESS) {
        g_free(new_apdu);
        new_apdu = NULL;
    }
    return new_apdu;
}

void
vcard_apdu_delete(VCardAPDU *apdu)
{
    if (apdu == NULL) {
        return;
    }
    if (apdu->a_data) {
        g_free(apdu->a_data);
    }
    g_free(apdu);
}


/*
 * declare response buffers for all the 7816 defined error codes
 */
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_SUCCESS)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_RET_CORUPT)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_CHANGE)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_FILE_FILLED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR_CHANGE)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_LENGTH)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED)
VCARD_RESPONSE_NEW_STATIC_STATUS(
                    VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_INVALID)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_NO_EF)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS)
VCARD_RESPONSE_NEW_STATIC_STATUS(
                            VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_FILE_NOT_FOUND)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_P1_P2_INCORRECT)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_NOT_FOUND)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_INS_CODE_INVALID)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CLA_INVALID)
VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_GENERAL)

/*
 * return a single response code. This function cannot fail. It will always
 * return a response.
 */
VCardResponse *
vcard_make_response(vcard_7816_status_t status)
{
    VCardResponse *response;

    switch (status) {
    /* known 7816 response codes */
    case VCARD7816_STATUS_SUCCESS:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_SUCCESS);
    case VCARD7816_STATUS_WARNING:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING);
    case VCARD7816_STATUS_WARNING_RET_CORUPT:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING_RET_CORUPT);
    case VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE);
    case VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED);
    case VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID);
    case VCARD7816_STATUS_WARNING_CHANGE:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING_CHANGE);
    case VCARD7816_STATUS_WARNING_FILE_FILLED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_WARNING_FILE_FILLED);
    case VCARD7816_STATUS_EXC_ERROR:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_EXC_ERROR);
    case VCARD7816_STATUS_EXC_ERROR_CHANGE:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_EXC_ERROR_CHANGE);
    case VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
    case VCARD7816_STATUS_ERROR_WRONG_LENGTH:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_WRONG_LENGTH);
    case VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED);
    case VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED);
    case VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED);
    case VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
    case VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE);
    case VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED);
    case VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED);
    case VCARD7816_STATUS_ERROR_DATA_INVALID:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_DATA_INVALID);
    case VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
    case VCARD7816_STATUS_ERROR_DATA_NO_EF:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_DATA_NO_EF);
    case VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING);
    case VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT);
    case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_WRONG_PARAMETERS);
    case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA);
    case VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED);
    case VCARD7816_STATUS_ERROR_FILE_NOT_FOUND:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
    case VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND);
    case VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE);
    case VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT);
    case VCARD7816_STATUS_ERROR_P1_P2_INCORRECT:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
    case VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT);
    case VCARD7816_STATUS_ERROR_DATA_NOT_FOUND:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
    case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2);
    case VCARD7816_STATUS_ERROR_INS_CODE_INVALID:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_INS_CODE_INVALID);
    case VCARD7816_STATUS_ERROR_CLA_INVALID:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_CLA_INVALID);
    case VCARD7816_STATUS_ERROR_GENERAL:
        return VCARD_RESPONSE_GET_STATIC(
                    VCARD7816_STATUS_ERROR_GENERAL);
    default:
        /* we don't know this status code, create a response buffer to
         * hold it */
        response = vcard_response_new_status(status);
        if (response == NULL) {
            /* couldn't allocate the buffer, return memmory error */
            return VCARD_RESPONSE_GET_STATIC(
                        VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
        }
        return response;
    }
}

/*
 * Add File card support here if you need it.
 */
static VCardStatus
vcard7816_file_system_process_apdu(VCard *card, VCardAPDU *apdu,
                                   VCardResponse **response)
{
    /* TODO: if we want to support a virtual file system card, we do it here.
     * It would probably be a pkcs #15 card type */
    *response = vcard_make_response(
                    VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
    return VCARD_DONE;
}

/*
 * VM card (including java cards)
 */
static VCardStatus
vcard7816_vm_process_apdu(VCard *card, VCardAPDU *apdu,
                          VCardResponse **response)
{
    int bytes_to_copy, next_byte_count, count;
    VCardApplet *current_applet;
    VCardBufferResponse *buffer_response;
    vcard_7816_status_t status;

    /* parse the class first */
    if (apdu->a_gen_type !=  VCARD_7816_ISO) {
        *response = vcard_make_response(
                        VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
        return VCARD_DONE;
    }

    /* use a switch so that if we need to support secure channel stuff later,
     * we know where to put it */
    switch (apdu->a_secure_messaging) {
    case 0x0: /* no SM */
        break;
    case 0x4: /* proprietary SM */
    case 0x8: /* header not authenticated */
    case 0xc: /* header authenticated */
    default:
        /* for now, don't try to support secure channel stuff in the
         * virtual card. */
        *response = vcard_make_response(
                        VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED);
        return VCARD_DONE;
    }

    /* now parse the instruction */
    switch (apdu->a_ins) {
    case  VCARD7816_INS_MANAGE_CHANNEL: /* secure channel op */
    case  VCARD7816_INS_EXTERNAL_AUTHENTICATE: /* secure channel op */
    case  VCARD7816_INS_GET_CHALLENGE: /* secure channel op */
    case  VCARD7816_INS_INTERNAL_AUTHENTICATE: /* secure channel op */
    case  VCARD7816_INS_ERASE_BINARY: /* applet control op */
    case  VCARD7816_INS_READ_BINARY: /* applet control op */
    case  VCARD7816_INS_WRITE_BINARY: /* applet control op */
    case  VCARD7816_INS_UPDATE_BINARY: /* applet control op */
    case  VCARD7816_INS_READ_RECORD: /* file op */
    case  VCARD7816_INS_WRITE_RECORD: /* file op */
    case  VCARD7816_INS_UPDATE_RECORD: /* file op */
    case  VCARD7816_INS_APPEND_RECORD: /* file op */
    case  VCARD7816_INS_ENVELOPE:
    case  VCARD7816_INS_PUT_DATA:
        *response = vcard_make_response(
                            VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
        break;

    case  VCARD7816_INS_SELECT_FILE:
        if (apdu->a_p1 != 0x04) {
            *response = vcard_make_response(
                            VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED);
            break;
        }

        /* side effect, deselect the current applet if no applet has been found
         * */
        current_applet = vcard_find_applet(card, apdu->a_body, apdu->a_Lc);
        vcard_select_applet(card, apdu->a_channel, current_applet);
        if (current_applet) {
            unsigned char *aid;
            int aid_len;
            aid = vcard_applet_get_aid(current_applet, &aid_len);
            *response = vcard_response_new(card, aid, aid_len, apdu->a_Le,
                                          VCARD7816_STATUS_SUCCESS);
        } else {
            *response = vcard_make_response(
                             VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
        }
        break;

    case  VCARD7816_INS_VERIFY:
        if ((apdu->a_p1 != 0x00) || (apdu->a_p2 != 0x00)) {
            *response = vcard_make_response(
                            VCARD7816_STATUS_ERROR_WRONG_PARAMETERS);
        } else {
            if (apdu->a_Lc == 0) {
                /* handle pin count if possible */
                count = vcard_emul_get_login_count(card);
                if (count < 0) {
                    *response = vcard_make_response(
                                    VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
                } else {
                    if (count > 0xf) {
                        count = 0xf;
                    }
                    *response = vcard_response_new_status_bytes(
                                                VCARD7816_SW1_WARNING_CHANGE,
                                                                0xc0 | count);
                    if (*response == NULL) {
                        *response = vcard_make_response(
                                    VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
                    }
                }
            } else {
                    status = vcard_emul_login(card, apdu->a_body, apdu->a_Lc);
                *response = vcard_make_response(status);
            }
        }
        break;

    case VCARD7816_INS_GET_RESPONSE:
        buffer_response = vcard_get_buffer_response(card);
        if (!buffer_response) {
            *response = vcard_make_response(
                            VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
            /* handle error */
            break;
        }
        bytes_to_copy = MIN(buffer_response->len, apdu->a_Le);
        next_byte_count = MIN(256, buffer_response->len - bytes_to_copy);
        *response = vcard_response_new_bytes(
                        card, buffer_response->current, bytes_to_copy,
                        apdu->a_Le,
                        next_byte_count ?
                        VCARD7816_SW1_RESPONSE_BYTES : VCARD7816_SW1_SUCCESS,
                        next_byte_count);
        buffer_response->current += bytes_to_copy;
        buffer_response->len -= bytes_to_copy;
        if (*response == NULL || (next_byte_count == 0)) {
            vcard_set_buffer_response(card, NULL);
            vcard_buffer_response_delete(buffer_response);
        }
        if (*response == NULL) {
            *response =
                vcard_make_response(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
        }
        break;

    case VCARD7816_INS_GET_DATA:
        *response =
            vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
        break;

    default:
        *response =
            vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
        break;
    }

    /* response should have been set somewhere */
    assert(*response != NULL);
    return VCARD_DONE;
}


/*
 * APDU processing starts here. This routes the card processing stuff to the
 * right location.
 */
VCardStatus
vcard_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
{
    VCardStatus status;
    VCardBufferResponse *buffer_response;

    /* first handle any PTS commands, which aren't really APDU's */
    if (apdu->a_type == VCARD_7816_PTS) {
        /* the PTS responses aren't really responses either */
        *response = vcard_response_new_data(apdu->a_data, apdu->a_len);
        /* PTS responses have no status bytes */
        (*response)->b_total_len = (*response)->b_len;
        return VCARD_DONE;
    }
    buffer_response = vcard_get_buffer_response(card);
    if (buffer_response && apdu->a_ins != VCARD7816_INS_GET_RESPONSE) {
        /* clear out buffer_response, return an error */
        vcard_set_buffer_response(card, NULL);
        vcard_buffer_response_delete(buffer_response);
        *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR);
        return VCARD_DONE;
    }

    status = vcard_process_applet_apdu(card, apdu, response);
    if (status != VCARD_NEXT) {
        return status;
    }
    switch (vcard_get_type(card)) {
    case VCARD_FILE_SYSTEM:
        return vcard7816_file_system_process_apdu(card, apdu, response);
    case VCARD_VM:
        return vcard7816_vm_process_apdu(card, apdu, response);
    case VCARD_DIRECT:
        /* if we are type direct, then the applet should handle everything */
        assert(!"VCARD_DIRECT: applet failure");
        break;
    }
    *response =
        vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
    return VCARD_DONE;
}
