qemu/libcacard/vcard.c
<<
>>
Prefs
   1/*
   2 * implement the Java card standard.
   3 *
   4 * This work is licensed under the terms of 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_7816t.h"
  13
  14struct VCardAppletStruct {
  15    VCardApplet   *next;
  16    VCardProcessAPDU process_apdu;
  17    VCardResetApplet reset_applet;
  18    unsigned char *aid;
  19    int aid_len;
  20    void *applet_private;
  21    VCardAppletPrivateFree applet_private_free;
  22};
  23
  24struct VCardStruct {
  25    int reference_count;
  26    VCardApplet *applet_list;
  27    VCardApplet *current_applet[MAX_CHANNEL];
  28    VCardBufferResponse *vcard_buffer_response;
  29    VCardType type;
  30    VCardEmul *vcard_private;
  31    VCardEmulFree vcard_private_free;
  32    VCardGetAtr vcard_get_atr;
  33};
  34
  35VCardBufferResponse *
  36vcard_buffer_response_new(unsigned char *buffer, int size)
  37{
  38    VCardBufferResponse *new_buffer;
  39
  40    new_buffer = (VCardBufferResponse *)g_malloc(sizeof(VCardBufferResponse));
  41    new_buffer->buffer = (unsigned char *)g_malloc(size);
  42    memcpy(new_buffer->buffer, buffer, size);
  43    new_buffer->buffer_len = size;
  44    new_buffer->current = new_buffer->buffer;
  45    new_buffer->len = size;
  46    return new_buffer;
  47}
  48
  49void
  50vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
  51{
  52    if (buffer_response == NULL) {
  53        return;
  54    }
  55    if (buffer_response->buffer) {
  56        g_free(buffer_response->buffer);
  57    }
  58    g_free(buffer_response);
  59}
  60
  61
  62/*
  63 * clean up state after a reset
  64 */
  65void
  66vcard_reset(VCard *card, VCardPower power)
  67{
  68    int i;
  69    VCardApplet *applet = NULL;
  70
  71    if (card->type ==  VCARD_DIRECT) {
  72        /* select the last applet */
  73        VCardApplet *current_applet = NULL;
  74        for (current_applet = card->applet_list; current_applet;
  75                                       current_applet = current_applet->next) {
  76            applet = current_applet;
  77        }
  78    }
  79    for (i = 0; i < MAX_CHANNEL; i++) {
  80        card->current_applet[i] = applet;
  81    }
  82    if (card->vcard_buffer_response) {
  83        vcard_buffer_response_delete(card->vcard_buffer_response);
  84        card->vcard_buffer_response = NULL;
  85    }
  86    vcard_emul_reset(card, power);
  87    if (applet) {
  88        applet->reset_applet(card, 0);
  89    }
  90}
  91
  92/* applet utilities */
  93
  94/*
  95 * applet utilities
  96 */
  97/* constructor */
  98VCardApplet *
  99vcard_new_applet(VCardProcessAPDU applet_process_function,
 100                 VCardResetApplet applet_reset_function,
 101                 unsigned char *aid, int aid_len)
 102{
 103    VCardApplet *applet;
 104
 105    applet = (VCardApplet *)g_malloc(sizeof(VCardApplet));
 106    applet->next = NULL;
 107    applet->applet_private = NULL;
 108    applet->applet_private_free = NULL;
 109    applet->process_apdu = applet_process_function;
 110    applet->reset_applet = applet_reset_function;
 111
 112    applet->aid = g_malloc(aid_len);
 113    memcpy(applet->aid, aid, aid_len);
 114    applet->aid_len = aid_len;
 115    return applet;
 116}
 117
 118/* destructor */
 119void
 120vcard_delete_applet(VCardApplet *applet)
 121{
 122    if (applet == NULL) {
 123        return;
 124    }
 125    if (applet->applet_private_free) {
 126        applet->applet_private_free(applet->applet_private);
 127        applet->applet_private = NULL;
 128    }
 129    if (applet->aid) {
 130        g_free(applet->aid);
 131        applet->aid = NULL;
 132    }
 133    g_free(applet);
 134}
 135
 136/* accessor */
 137void
 138vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
 139                         VCardAppletPrivateFree private_free)
 140{
 141    if (applet->applet_private_free) {
 142        applet->applet_private_free(applet->applet_private);
 143    }
 144    applet->applet_private = private;
 145    applet->applet_private_free = private_free;
 146}
 147
 148VCard *
 149vcard_new(VCardEmul *private, VCardEmulFree private_free)
 150{
 151    VCard *new_card;
 152    int i;
 153
 154    new_card = (VCard *)g_malloc(sizeof(VCard));
 155    new_card->applet_list = NULL;
 156    for (i = 0; i < MAX_CHANNEL; i++) {
 157        new_card->current_applet[i] = NULL;
 158    }
 159    new_card->vcard_buffer_response = NULL;
 160    new_card->type = VCARD_VM;
 161    new_card->vcard_private = private;
 162    new_card->vcard_private_free = private_free;
 163    new_card->vcard_get_atr = NULL;
 164    new_card->reference_count = 1;
 165    return new_card;
 166}
 167
 168VCard *
 169vcard_reference(VCard *vcard)
 170{
 171    if (vcard == NULL) {
 172        return NULL;
 173    }
 174    vcard->reference_count++;
 175    return vcard;
 176}
 177
 178void
 179vcard_free(VCard *vcard)
 180{
 181    VCardApplet *current_applet = NULL;
 182    VCardApplet *next_applet = NULL;
 183
 184    if (vcard == NULL) {
 185        return;
 186    }
 187    vcard->reference_count--;
 188    if (vcard->reference_count != 0) {
 189        return;
 190    }
 191    if (vcard->vcard_private_free) {
 192        (*vcard->vcard_private_free)(vcard->vcard_private);
 193        vcard->vcard_private_free = 0;
 194        vcard->vcard_private = 0;
 195    }
 196    for (current_applet = vcard->applet_list; current_applet;
 197                                        current_applet = next_applet) {
 198        next_applet = current_applet->next;
 199        vcard_delete_applet(current_applet);
 200    }
 201    vcard_buffer_response_delete(vcard->vcard_buffer_response);
 202    g_free(vcard);
 203}
 204
 205void
 206vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
 207{
 208    if (vcard->vcard_get_atr) {
 209        (*vcard->vcard_get_atr)(vcard, atr, atr_len);
 210        return;
 211    }
 212    vcard_emul_get_atr(vcard, atr, atr_len);
 213}
 214
 215void
 216vcard_set_atr_func(VCard *card, VCardGetAtr vcard_get_atr)
 217{
 218    card->vcard_get_atr = vcard_get_atr;
 219}
 220
 221
 222VCardStatus
 223vcard_add_applet(VCard *card, VCardApplet *applet)
 224{
 225    applet->next = card->applet_list;
 226    card->applet_list = applet;
 227    /* if our card-type is direct, always call the applet */
 228    if (card->type ==  VCARD_DIRECT) {
 229        int i;
 230
 231        for (i = 0; i < MAX_CHANNEL; i++) {
 232            card->current_applet[i] = applet;
 233        }
 234    }
 235    return VCARD_DONE;
 236}
 237
 238/*
 239 * manage applets
 240 */
 241VCardApplet *
 242vcard_find_applet(VCard *card, unsigned char *aid, int aid_len)
 243{
 244    VCardApplet *current_applet;
 245
 246    for (current_applet = card->applet_list; current_applet;
 247                                        current_applet = current_applet->next) {
 248        if (current_applet->aid_len != aid_len) {
 249            continue;
 250        }
 251        if (memcmp(current_applet->aid, aid, aid_len) == 0) {
 252            break;
 253        }
 254    }
 255    return current_applet;
 256}
 257
 258unsigned char *
 259vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
 260{
 261    if (applet == NULL) {
 262        return NULL;
 263    }
 264    *aid_len = applet->aid_len;
 265    return applet->aid;
 266}
 267
 268
 269void
 270vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
 271{
 272    assert(channel < MAX_CHANNEL);
 273    card->current_applet[channel] = applet;
 274    /* reset the applet */
 275    if (applet && applet->reset_applet) {
 276        applet->reset_applet(card, channel);
 277    }
 278}
 279
 280VCardAppletPrivate *
 281vcard_get_current_applet_private(VCard *card, int channel)
 282{
 283    VCardApplet *applet = card->current_applet[channel];
 284
 285    if (applet == NULL) {
 286        return NULL;
 287    }
 288    return applet->applet_private;
 289}
 290
 291VCardStatus
 292vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
 293                          VCardResponse **response)
 294{
 295    if (card->current_applet[apdu->a_channel]) {
 296        return card->current_applet[apdu->a_channel]->process_apdu(
 297                                                        card, apdu, response);
 298    }
 299    return VCARD_NEXT;
 300}
 301
 302/*
 303 * Accessor functions
 304 */
 305/* accessor functions for the response buffer */
 306VCardBufferResponse *
 307vcard_get_buffer_response(VCard *card)
 308{
 309    return card->vcard_buffer_response;
 310}
 311
 312void
 313vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
 314{
 315    card->vcard_buffer_response = buffer;
 316}
 317
 318
 319/* accessor functions for the type */
 320VCardType
 321vcard_get_type(VCard *card)
 322{
 323    return card->type;
 324}
 325
 326void
 327vcard_set_type(VCard *card, VCardType type)
 328{
 329    card->type = type;
 330}
 331
 332/* accessor for private data */
 333VCardEmul *
 334vcard_get_private(VCard *vcard)
 335{
 336    return vcard->vcard_private;
 337}
 338
 339