These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / libcacard / cac.c
diff --git a/qemu/libcacard/cac.c b/qemu/libcacard/cac.c
deleted file mode 100644 (file)
index bc84534..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * implement the applets for the CAC card.
- *
- * This code is licensed under the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "glib-compat.h"
-
-#include <string.h>
-#include <stdbool.h>
-
-#include "cac.h"
-#include "vcard.h"
-#include "vcard_emul.h"
-#include "card_7816.h"
-
-/* private data for PKI applets */
-typedef struct CACPKIAppletDataStruct {
-    unsigned char *cert;
-    int cert_len;
-    unsigned char *cert_buffer;
-    int cert_buffer_len;
-    unsigned char *sign_buffer;
-    int sign_buffer_len;
-    VCardKey *key;
-} CACPKIAppletData;
-
-/*
- * CAC applet private data
- */
-struct VCardAppletPrivateStruct {
-    union {
-        CACPKIAppletData pki_data;
-        void *reserved;
-    } u;
-};
-
-/*
- * handle all the APDU's that are common to all CAC applets
- */
-static VCardStatus
-cac_common_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
-{
-    int ef;
-    VCardStatus ret = VCARD_FAIL;
-
-    switch (apdu->a_ins) {
-    case VCARD7816_INS_SELECT_FILE:
-        if (apdu->a_p1 != 0x02) {
-            /* let the 7816 code handle applet switches */
-            ret = VCARD_NEXT;
-            break;
-        }
-        /* handle file id setting */
-        if (apdu->a_Lc != 2) {
-            *response = vcard_make_response(
-                VCARD7816_STATUS_ERROR_DATA_INVALID);
-            ret = VCARD_DONE;
-            break;
-        }
-        /* CAC 1.0 only supports ef = 0 */
-        ef = apdu->a_body[0] | (apdu->a_body[1] << 8);
-        if (ef != 0) {
-            *response = vcard_make_response(
-                VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
-            ret = VCARD_DONE;
-            break;
-        }
-        *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
-        ret = VCARD_DONE;
-        break;
-    case VCARD7816_INS_GET_RESPONSE:
-    case VCARD7816_INS_VERIFY:
-        /* let the 7816 code handle these */
-        ret = VCARD_NEXT;
-        break;
-    case CAC_GET_PROPERTIES:
-    case CAC_GET_ACR:
-        /* skip these for now, this will probably be needed */
-        *response = vcard_make_response(VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
-        ret = VCARD_DONE;
-        break;
-    default:
-        *response = vcard_make_response(
-            VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
-        ret = VCARD_DONE;
-        break;
-    }
-    return ret;
-}
-
-/*
- *  reset the inter call state between applet selects
- */
-static VCardStatus
-cac_applet_pki_reset(VCard *card, int channel)
-{
-    VCardAppletPrivate *applet_private;
-    CACPKIAppletData *pki_applet;
-    applet_private = vcard_get_current_applet_private(card, channel);
-    assert(applet_private);
-    pki_applet = &(applet_private->u.pki_data);
-
-    pki_applet->cert_buffer = NULL;
-    g_free(pki_applet->sign_buffer);
-    pki_applet->sign_buffer = NULL;
-    pki_applet->cert_buffer_len = 0;
-    pki_applet->sign_buffer_len = 0;
-    return VCARD_DONE;
-}
-
-static VCardStatus
-cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
-                            VCardResponse **response)
-{
-    CACPKIAppletData *pki_applet;
-    VCardAppletPrivate *applet_private;
-    int size, next;
-    unsigned char *sign_buffer;
-    bool retain_sign_buffer = FALSE;
-    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);
-            retain_sign_buffer = TRUE;
-            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;
-        }
-        if (!retain_sign_buffer) {
-            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;
-}
-
-
-static VCardStatus
-cac_applet_id_process_apdu(VCard *card, VCardAPDU *apdu,
-                           VCardResponse **response)
-{
-    VCardStatus ret = VCARD_FAIL;
-
-    switch (apdu->a_ins) {
-    case CAC_UPDATE_BUFFER:
-        *response = vcard_make_response(
-                        VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
-        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;
-}
-
-
-/*
- * TODO: if we ever want to support general CAC middleware, we will need to
- * implement the various containers.
- */
-static VCardStatus
-cac_applet_container_process_apdu(VCard *card, VCardAPDU *apdu,
-                                  VCardResponse **response)
-{
-    VCardStatus ret = VCARD_FAIL;
-
-    switch (apdu->a_ins) {
-    case CAC_READ_BUFFER:
-    case CAC_UPDATE_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;
-}
-
-/*
- * utilities for creating and destroying the private applet data
- */
-static void
-cac_delete_pki_applet_private(VCardAppletPrivate *applet_private)
-{
-    CACPKIAppletData *pki_applet_data;
-
-    if (applet_private == NULL) {
-        return;
-    }
-    pki_applet_data = &(applet_private->u.pki_data);
-    g_free(pki_applet_data->cert);
-    g_free(pki_applet_data->sign_buffer);
-    if (pki_applet_data->key != NULL) {
-        vcard_emul_delete_key(pki_applet_data->key);
-    }
-    g_free(applet_private);
-}
-
-static VCardAppletPrivate *
-cac_new_pki_applet_private(const unsigned char *cert,
-                           int cert_len, VCardKey *key)
-{
-    CACPKIAppletData *pki_applet_data;
-    VCardAppletPrivate *applet_private;
-
-    applet_private = g_new0(VCardAppletPrivate, 1);
-    pki_applet_data = &(applet_private->u.pki_data);
-    pki_applet_data->cert = (unsigned char *)g_malloc(cert_len+1);
-    /*
-     * if we want to support compression, then we simply change the 0 to a 1
-     * and compress the cert data with libz
-     */
-    pki_applet_data->cert[0] = 0; /* not compressed */
-    memcpy(&pki_applet_data->cert[1], cert, cert_len);
-    pki_applet_data->cert_len = cert_len+1;
-
-    pki_applet_data->key = key;
-    return applet_private;
-}
-
-
-/*
- * create a new cac applet which links to a given cert
- */
-static VCardApplet *
-cac_new_pki_applet(int i, const unsigned char *cert,
-                   int cert_len, VCardKey *key)
-{
-    VCardAppletPrivate *applet_private;
-    VCardApplet *applet;
-    unsigned char pki_aid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00 };
-    int pki_aid_len = sizeof(pki_aid);
-
-    pki_aid[pki_aid_len-1] = i;
-
-    applet_private = cac_new_pki_applet_private(cert, cert_len, key);
-    if (applet_private == NULL) {
-        goto failure;
-    }
-    applet = vcard_new_applet(cac_applet_pki_process_apdu, cac_applet_pki_reset,
-                              pki_aid, pki_aid_len);
-    if (applet == NULL) {
-        goto failure;
-    }
-    vcard_set_applet_private(applet, applet_private,
-                             cac_delete_pki_applet_private);
-    applet_private = NULL;
-
-    return applet;
-
-failure:
-    if (applet_private != NULL) {
-        cac_delete_pki_applet_private(applet_private);
-    }
-    return NULL;
-}
-
-
-static unsigned char cac_default_container_aid[] = {
-    0xa0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00 };
-static unsigned char cac_id_aid[] = {
-    0xa0, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00 };
-/*
- * Initialize the cac card. This is the only public function in this file. All
- * the rest are connected through function pointers.
- */
-VCardStatus
-cac_card_init(VReader *reader, VCard *card,
-              const char *params,
-              unsigned char * const *cert,
-              int cert_len[],
-              VCardKey *key[] /* adopt the keys*/,
-              int cert_count)
-{
-    int i;
-    VCardApplet *applet;
-
-    /* CAC Cards are VM Cards */
-    vcard_set_type(card, VCARD_VM);
-
-    /* create one PKI applet for each cert */
-    for (i = 0; i < cert_count; i++) {
-        applet = cac_new_pki_applet(i, cert[i], cert_len[i], key[i]);
-        if (applet == NULL) {
-            goto failure;
-        }
-        vcard_add_applet(card, applet);
-    }
-
-    /* create a default blank container applet */
-    applet = vcard_new_applet(cac_applet_container_process_apdu,
-                              NULL, cac_default_container_aid,
-                              sizeof(cac_default_container_aid));
-    if (applet == NULL) {
-        goto failure;
-    }
-    vcard_add_applet(card, applet);
-
-    /* create a default blank container applet */
-    applet = vcard_new_applet(cac_applet_id_process_apdu,
-                              NULL, cac_id_aid,
-                              sizeof(cac_id_aid));
-    if (applet == NULL) {
-        goto failure;
-    }
-    vcard_add_applet(card, applet);
-    return VCARD_DONE;
-
-failure:
-    return VCARD_FAIL;
-}
-