cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,

                            VCardResponse **response)

{

    CACPKIAppletData *pki_applet = NULL;

    VCardAppletPrivate *applet_private = NULL;

    int size, next;

    unsigned char *sign_buffer;

    vcard_7816_status_t status;

    VCardStatus ret = VCARD_FAIL;



    applet_private = vcard_get_current_applet_private(card, apdu->a_channel);

    assert(applet_private);

    pki_applet = &(applet_private->u.pki_data);



    switch (apdu->a_ins) {

    case CAC_UPDATE_BUFFER:

        *response = vcard_make_response(

            VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);

        ret = VCARD_DONE;

        break;

    case CAC_GET_CERTIFICATE:

        if ((apdu->a_p2 != 0) || (apdu->a_p1 != 0)) {

            *response = vcard_make_response(

                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        assert(pki_applet->cert != NULL);

        size = apdu->a_Le;

        if (pki_applet->cert_buffer == NULL) {

            pki_applet->cert_buffer = pki_applet->cert;

            pki_applet->cert_buffer_len = pki_applet->cert_len;

        }

        size = MIN(size, pki_applet->cert_buffer_len);

        next = MIN(255, pki_applet->cert_buffer_len - size);

        *response = vcard_response_new_bytes(

                        card, pki_applet->cert_buffer, size,

                        apdu->a_Le, next ?

                        VCARD7816_SW1_WARNING_CHANGE :

                        VCARD7816_SW1_SUCCESS,

                        next);

        pki_applet->cert_buffer += size;

        pki_applet->cert_buffer_len -= size;

        if ((*response == NULL) || (next == 0)) {

            pki_applet->cert_buffer = NULL;

        }

        if (*response == NULL) {

            *response = vcard_make_response(

                            VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);

        }

        ret = VCARD_DONE;

        break;

    case CAC_SIGN_DECRYPT:

        if (apdu->a_p2 != 0) {

            *response = vcard_make_response(

                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        size = apdu->a_Lc;



        sign_buffer = g_realloc(pki_applet->sign_buffer,

                                pki_applet->sign_buffer_len + size);

        memcpy(sign_buffer+pki_applet->sign_buffer_len, apdu->a_body, size);

        size += pki_applet->sign_buffer_len;

        switch (apdu->a_p1) {

        case  0x80:

            /* p1 == 0x80 means we haven't yet sent the whole buffer, wait for

             * the rest */

            pki_applet->sign_buffer = sign_buffer;

            pki_applet->sign_buffer_len = size;

            *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);

            break;

        case 0x00:

            /* we now have the whole buffer, do the operation, result will be

             * in the sign_buffer */

            status = vcard_emul_rsa_op(card, pki_applet->key,

                                       sign_buffer, size);

            if (status != VCARD7816_STATUS_SUCCESS) {

                *response = vcard_make_response(status);

                break;

            }

            *response = vcard_response_new(card, sign_buffer, size, apdu->a_Le,

                                                     VCARD7816_STATUS_SUCCESS);

            if (*response == NULL) {

                *response = vcard_make_response(

                                VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);

            }

            break;

        default:

           *response = vcard_make_response(

                                VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        g_free(sign_buffer);

        pki_applet->sign_buffer = NULL;

        pki_applet->sign_buffer_len = 0;

        ret = VCARD_DONE;

        break;

    case CAC_READ_BUFFER:

        /* new CAC call, go ahead and use the old version for now */

        /* TODO: implement */

        *response = vcard_make_response(

                                VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);

        ret = VCARD_DONE;

        break;

    default:

        ret = cac_common_process_apdu(card, apdu, response);

        break;

    }

    return ret;

}

cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,

                            VCardResponse **response)

{

    CACPKIAppletData *pki_applet = NULL;

    VCardAppletPrivate *applet_private = NULL;

    int size, next;

    unsigned char *sign_buffer;

    vcard_7816_status_t status;

    VCardStatus ret = VCARD_FAIL;



    applet_private = vcard_get_current_applet_private(card, apdu->a_channel);

    assert(applet_private);

    pki_applet = &(applet_private->u.pki_data);



    switch (apdu->a_ins) {

    case CAC_UPDATE_BUFFER:

        *response = vcard_make_response(

            VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);

        ret = VCARD_DONE;

        break;

    case CAC_GET_CERTIFICATE:

        if ((apdu->a_p2 != 0) || (apdu->a_p1 != 0)) {

            *response = vcard_make_response(

                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        assert(pki_applet->cert != NULL);

        size = apdu->a_Le;

        if (pki_applet->cert_buffer == NULL) {

            pki_applet->cert_buffer = pki_applet->cert;

            pki_applet->cert_buffer_len = pki_applet->cert_len;

        }

        size = MIN(size, pki_applet->cert_buffer_len);

        next = MIN(255, pki_applet->cert_buffer_len - size);

        *response = vcard_response_new_bytes(

                        card, pki_applet->cert_buffer, size,

                        apdu->a_Le, next ?

                        VCARD7816_SW1_WARNING_CHANGE :

                        VCARD7816_SW1_SUCCESS,

                        next);

        pki_applet->cert_buffer += size;

        pki_applet->cert_buffer_len -= size;

        if ((*response == NULL) || (next == 0)) {

            pki_applet->cert_buffer = NULL;

        }

        if (*response == NULL) {

            *response = vcard_make_response(

                            VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);

        }

        ret = VCARD_DONE;

        break;

    case CAC_SIGN_DECRYPT:

        if (apdu->a_p2 != 0) {

            *response = vcard_make_response(

                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        size = apdu->a_Lc;



        sign_buffer = g_realloc(pki_applet->sign_buffer,

                                pki_applet->sign_buffer_len + size);

        memcpy(sign_buffer+pki_applet->sign_buffer_len, apdu->a_body, size);

        size += pki_applet->sign_buffer_len;

        switch (apdu->a_p1) {

        case  0x80:

            



            pki_applet->sign_buffer = sign_buffer;

            pki_applet->sign_buffer_len = size;

            *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);

            break;

        case 0x00:

            



            status = vcard_emul_rsa_op(card, pki_applet->key,

                                       sign_buffer, size);

            if (status != VCARD7816_STATUS_SUCCESS) {

                *response = vcard_make_response(status);

                break;

            }

            *response = vcard_response_new(card, sign_buffer, size, apdu->a_Le,

                                                     VCARD7816_STATUS_SUCCESS);

            if (*response == NULL) {

                *response = vcard_make_response(

                                VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);

            }

            break;

        default:

           *response = vcard_make_response(

                                VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        g_free(sign_buffer);

        pki_applet->sign_buffer = NULL;

        pki_applet->sign_buffer_len = 0;

        ret = VCARD_DONE;

        break;

    case CAC_READ_BUFFER:

        

        

        *response = vcard_make_response(

                                VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);

        ret = VCARD_DONE;

        break;

    default:

        ret = cac_common_process_apdu(card, apdu, response);

        break;

    }

    return ret;

}

FUNC_0(VCard *VAR_0, VCardAPDU *VAR_1,

                            VCardResponse **VAR_2)

{

    CACPKIAppletData *pki_applet = NULL;

    VCardAppletPrivate *applet_private = NULL;

    int VAR_3, VAR_4;

    unsigned char *VAR_5;

    vcard_7816_status_t status;

    VCardStatus ret = VCARD_FAIL;



    applet_private = vcard_get_current_applet_private(VAR_0, VAR_1->a_channel);

    assert(applet_private);

    pki_applet = &(applet_private->u.pki_data);



    switch (VAR_1->a_ins) {

    case CAC_UPDATE_BUFFER:

        *VAR_2 = vcard_make_response(

            VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);

        ret = VCARD_DONE;

        break;

    case CAC_GET_CERTIFICATE:

        if ((VAR_1->a_p2 != 0) || (VAR_1->a_p1 != 0)) {

            *VAR_2 = vcard_make_response(

                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        assert(pki_applet->cert != NULL);

        VAR_3 = VAR_1->a_Le;

        if (pki_applet->cert_buffer == NULL) {

            pki_applet->cert_buffer = pki_applet->cert;

            pki_applet->cert_buffer_len = pki_applet->cert_len;

        }

        VAR_3 = MIN(VAR_3, pki_applet->cert_buffer_len);

        VAR_4 = MIN(255, pki_applet->cert_buffer_len - VAR_3);

        *VAR_2 = vcard_response_new_bytes(

                        VAR_0, pki_applet->cert_buffer, VAR_3,

                        VAR_1->a_Le, VAR_4 ?

                        VCARD7816_SW1_WARNING_CHANGE :

                        VCARD7816_SW1_SUCCESS,

                        VAR_4);

        pki_applet->cert_buffer += VAR_3;

        pki_applet->cert_buffer_len -= VAR_3;

        if ((*VAR_2 == NULL) || (VAR_4 == 0)) {

            pki_applet->cert_buffer = NULL;

        }

        if (*VAR_2 == NULL) {

            *VAR_2 = vcard_make_response(

                            VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);

        }

        ret = VCARD_DONE;

        break;

    case CAC_SIGN_DECRYPT:

        if (VAR_1->a_p2 != 0) {

            *VAR_2 = vcard_make_response(

                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        VAR_3 = VAR_1->a_Lc;



        VAR_5 = g_realloc(pki_applet->VAR_5,

                                pki_applet->sign_buffer_len + VAR_3);

        memcpy(VAR_5+pki_applet->sign_buffer_len, VAR_1->a_body, VAR_3);

        VAR_3 += pki_applet->sign_buffer_len;

        switch (VAR_1->a_p1) {

        case  0x80:

            



            pki_applet->VAR_5 = VAR_5;

            pki_applet->sign_buffer_len = VAR_3;

            *VAR_2 = vcard_make_response(VCARD7816_STATUS_SUCCESS);

            break;

        case 0x00:

            



            status = vcard_emul_rsa_op(VAR_0, pki_applet->key,

                                       VAR_5, VAR_3);

            if (status != VCARD7816_STATUS_SUCCESS) {

                *VAR_2 = vcard_make_response(status);

                break;

            }

            *VAR_2 = vcard_response_new(VAR_0, VAR_5, VAR_3, VAR_1->a_Le,

                                                     VCARD7816_STATUS_SUCCESS);

            if (*VAR_2 == NULL) {

                *VAR_2 = vcard_make_response(

                                VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);

            }

            break;

        default:

           *VAR_2 = vcard_make_response(

                                VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);

            break;

        }

        g_free(VAR_5);

        pki_applet->VAR_5 = NULL;

        pki_applet->sign_buffer_len = 0;

        ret = VCARD_DONE;

        break;

    case CAC_READ_BUFFER:

        

        

        *VAR_2 = vcard_make_response(

                                VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);

        ret = VCARD_DONE;

        break;

    default:

        ret = cac_common_process_apdu(VAR_0, VAR_1, VAR_2);

        break;

    }

    return ret;

}

FUNC_0(VCard *VAR_0, VCardAPDU *VAR_1,
VCardResponse **VAR_2)
{ CACPKIAppletData *pki_applet = NULL; VCardAppletPrivate *applet_private = NULL; int VAR_3, VAR_4; unsigned char *VAR_5; vcard_7816_status_t status; VCardStatus ret = VCARD_FAIL; applet_private = vcard_get_current_applet_private(VAR_0, VAR_1->a_channel); assert(applet_private); pki_applet = &(applet_private->u.pki_data); switch (VAR_1->a_ins) { case CAC_UPDATE_BUFFER:
*VAR_2 = vcard_make_response(
VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED); ret = VCARD_DONE; break; case CAC_GET_CERTIFICATE:
if ((VAR_1->a_p2 != 0) || (VAR_1->a_p1 != 0)) { *VAR_2 = vcard_make_response(
VCARD7816_STATUS_ERROR_P1_P2_INCORRECT); break; } assert(pki_applet->cert != NULL); VAR_3 = VAR_1->a_Le; if (pki_applet->cert_buffer == NULL) { pki_applet->cert_buffer = pki_applet->cert; pki_applet->cert_buffer_len = pki_applet->cert_len; } VAR_3 = MIN(VAR_3, pki_applet->cert_buffer_len); VAR_4 = MIN(255, pki_applet->cert_buffer_len - VAR_3); *VAR_2 = vcard_response_new_bytes(
VAR_0, pki_applet->cert_buffer, VAR_3,
VAR_1->a_Le, VAR_4 ?
VCARD7816_SW1_WARNING_CHANGE :
VCARD7816_SW1_SUCCESS,
VAR_4); pki_applet->cert_buffer += VAR_3; pki_applet->cert_buffer_len -= VAR_3; if ((*VAR_2 == NULL) || (VAR_4 == 0)) { pki_applet->cert_buffer = NULL; } if (*VAR_2 == NULL) { *VAR_2 = vcard_make_response(
VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE); } ret = VCARD_DONE; break; case CAC_SIGN_DECRYPT:
if (VAR_1->a_p2 != 0) { *VAR_2 = vcard_make_response(
VCARD7816_STATUS_ERROR_P1_P2_INCORRECT); break; } VAR_3 = VAR_1->a_Lc; VAR_5 = g_realloc(pki_applet->VAR_5,
pki_applet->sign_buffer_len + VAR_3); memcpy(VAR_5+pki_applet->sign_buffer_len, VAR_1->a_body, VAR_3); VAR_3 += pki_applet->sign_buffer_len; switch (VAR_1->a_p1) { case  0x80:
pki_applet->VAR_5 = VAR_5; pki_applet->sign_buffer_len = VAR_3; *VAR_2 = vcard_make_response(VCARD7816_STATUS_SUCCESS); break; case 0x00:
status = vcard_emul_rsa_op(VAR_0, pki_applet->key,
VAR_5, VAR_3); if (status != VCARD7816_STATUS_SUCCESS) { *VAR_2 = vcard_make_response(status); break; } *VAR_2 = vcard_response_new(VAR_0, VAR_5, VAR_3, VAR_1->a_Le,
VCARD7816_STATUS_SUCCESS); if (*VAR_2 == NULL) { *VAR_2 = vcard_make_response(
VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE); } break; default:
*VAR_2 = vcard_make_response(
VCARD7816_STATUS_ERROR_P1_P2_INCORRECT); break; } g_free(VAR_5); pki_applet->VAR_5 = NULL; pki_applet->sign_buffer_len = 0; ret = VCARD_DONE; break; case CAC_READ_BUFFER:
*VAR_2 = vcard_make_response(
VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED); ret = VCARD_DONE; break; default:
ret = cac_common_process_apdu(VAR_0, VAR_1, VAR_2); break; } return ret; }