summaryrefslogtreecommitdiffstats
path: root/qemu/libcacard/vreader.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/libcacard/vreader.c')
-rw-r--r--qemu/libcacard/vreader.c578
1 files changed, 0 insertions, 578 deletions
diff --git a/qemu/libcacard/vreader.c b/qemu/libcacard/vreader.c
deleted file mode 100644
index 9725f46a7..000000000
--- a/qemu/libcacard/vreader.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * emulate the reader
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifdef G_LOG_DOMAIN
-#undef G_LOG_DOMAIN
-#endif
-#define G_LOG_DOMAIN "libcacard"
-
-#include "glib-compat.h"
-
-#include <string.h>
-
-#include "vcard.h"
-#include "vcard_emul.h"
-#include "card_7816.h"
-#include "vreader.h"
-#include "vevent.h"
-#include "cac.h" /* just for debugging defines */
-
-#define LIBCACARD_LOG_DOMAIN "libcacard"
-
-struct VReaderStruct {
- int reference_count;
- VCard *card;
- char *name;
- vreader_id_t id;
- CompatGMutex lock;
- VReaderEmul *reader_private;
- VReaderEmulFree reader_private_free;
-};
-
-/*
- * Debug helpers
- */
-
-static const char *
-apdu_ins_to_string(int ins)
-{
- switch (ins) {
- case VCARD7816_INS_MANAGE_CHANNEL:
- return "manage channel";
- case VCARD7816_INS_EXTERNAL_AUTHENTICATE:
- return "external authenticate";
- case VCARD7816_INS_GET_CHALLENGE:
- return "get challenge";
- case VCARD7816_INS_INTERNAL_AUTHENTICATE:
- return "internal authenticate";
- case VCARD7816_INS_ERASE_BINARY:
- return "erase binary";
- case VCARD7816_INS_READ_BINARY:
- return "read binary";
- case VCARD7816_INS_WRITE_BINARY:
- return "write binary";
- case VCARD7816_INS_UPDATE_BINARY:
- return "update binary";
- case VCARD7816_INS_READ_RECORD:
- return "read record";
- case VCARD7816_INS_WRITE_RECORD:
- return "write record";
- case VCARD7816_INS_UPDATE_RECORD:
- return "update record";
- case VCARD7816_INS_APPEND_RECORD:
- return "append record";
- case VCARD7816_INS_ENVELOPE:
- return "envelope";
- case VCARD7816_INS_PUT_DATA:
- return "put data";
- case VCARD7816_INS_GET_DATA:
- return "get data";
- case VCARD7816_INS_SELECT_FILE:
- return "select file";
- case VCARD7816_INS_VERIFY:
- return "verify";
- case VCARD7816_INS_GET_RESPONSE:
- return "get response";
- case CAC_GET_PROPERTIES:
- return "get properties";
- case CAC_GET_ACR:
- return "get acr";
- case CAC_READ_BUFFER:
- return "read buffer";
- case CAC_UPDATE_BUFFER:
- return "update buffer";
- case CAC_SIGN_DECRYPT:
- return "sign decrypt";
- case CAC_GET_CERTIFICATE:
- return "get certificate";
- }
- return "unknown";
-}
-
-/* manage locking */
-static inline void
-vreader_lock(VReader *reader)
-{
- g_mutex_lock(&reader->lock);
-}
-
-static inline void
-vreader_unlock(VReader *reader)
-{
- g_mutex_unlock(&reader->lock);
-}
-
-/*
- * vreader constructor
- */
-VReader *
-vreader_new(const char *name, VReaderEmul *private,
- VReaderEmulFree private_free)
-{
- VReader *reader;
-
- reader = g_new(VReader, 1);
- g_mutex_init(&reader->lock);
- reader->reference_count = 1;
- reader->name = g_strdup(name);
- reader->card = NULL;
- reader->id = (vreader_id_t)-1;
- reader->reader_private = private;
- reader->reader_private_free = private_free;
- return reader;
-}
-
-/* get a reference */
-VReader*
-vreader_reference(VReader *reader)
-{
- if (reader == NULL) {
- return NULL;
- }
- vreader_lock(reader);
- reader->reference_count++;
- vreader_unlock(reader);
- return reader;
-}
-
-/* free a reference */
-void
-vreader_free(VReader *reader)
-{
- if (reader == NULL) {
- return;
- }
- vreader_lock(reader);
- if (reader->reference_count-- > 1) {
- vreader_unlock(reader);
- return;
- }
- vreader_unlock(reader);
- g_mutex_clear(&reader->lock);
- if (reader->card) {
- vcard_free(reader->card);
- }
- g_free(reader->name);
- if (reader->reader_private_free) {
- reader->reader_private_free(reader->reader_private);
- }
- g_free(reader);
-}
-
-static VCard *
-vreader_get_card(VReader *reader)
-{
- VCard *card;
-
- vreader_lock(reader);
- card = vcard_reference(reader->card);
- vreader_unlock(reader);
- return card;
-}
-
-VReaderStatus
-vreader_card_is_present(VReader *reader)
-{
- VCard *card = vreader_get_card(reader);
-
- if (card == NULL) {
- return VREADER_NO_CARD;
- }
- vcard_free(card);
- return VREADER_OK;
-}
-
-vreader_id_t
-vreader_get_id(VReader *reader)
-{
- if (reader == NULL) {
- return (vreader_id_t)-1;
- }
- return reader->id;
-}
-
-VReaderStatus
-vreader_set_id(VReader *reader, vreader_id_t id)
-{
- if (reader == NULL) {
- return VREADER_NO_CARD;
- }
- reader->id = id;
- return VREADER_OK;
-}
-
-const char *
-vreader_get_name(VReader *reader)
-{
- if (reader == NULL) {
- return NULL;
- }
- return reader->name;
-}
-
-VReaderEmul *
-vreader_get_private(VReader *reader)
-{
- return reader->reader_private;
-}
-
-static VReaderStatus
-vreader_reset(VReader *reader, VCardPower power, unsigned char *atr, int *len)
-{
- VCard *card = vreader_get_card(reader);
-
- if (card == NULL) {
- return VREADER_NO_CARD;
- }
- /*
- * clean up our state
- */
- vcard_reset(card, power);
- if (atr) {
- vcard_get_atr(card, atr, len);
- }
- vcard_free(card); /* free our reference */
- return VREADER_OK;
-}
-
-VReaderStatus
-vreader_power_on(VReader *reader, unsigned char *atr, int *len)
-{
- return vreader_reset(reader, VCARD_POWER_ON, atr, len);
-}
-
-VReaderStatus
-vreader_power_off(VReader *reader)
-{
- return vreader_reset(reader, VCARD_POWER_OFF, NULL, 0);
-}
-
-
-VReaderStatus
-vreader_xfr_bytes(VReader *reader,
- unsigned char *send_buf, int send_buf_len,
- unsigned char *receive_buf, int *receive_buf_len)
-{
- VCardAPDU *apdu;
- VCardResponse *response = NULL;
- VCardStatus card_status;
- unsigned short status;
- VCard *card = vreader_get_card(reader);
-
- if (card == NULL) {
- return VREADER_NO_CARD;
- }
-
- apdu = vcard_apdu_new(send_buf, send_buf_len, &status);
- if (apdu == NULL) {
- response = vcard_make_response(status);
- card_status = VCARD_DONE;
- } else {
- g_debug("%s: CLS=0x%x,INS=0x%x,P1=0x%x,P2=0x%x,Lc=%d,Le=%d %s",
- __func__, apdu->a_cla, apdu->a_ins, apdu->a_p1, apdu->a_p2,
- apdu->a_Lc, apdu->a_Le, apdu_ins_to_string(apdu->a_ins));
- card_status = vcard_process_apdu(card, apdu, &response);
- if (response) {
- g_debug("%s: status=%d sw1=0x%x sw2=0x%x len=%d (total=%d)",
- __func__, response->b_status, response->b_sw1,
- response->b_sw2, response->b_len, response->b_total_len);
- }
- }
- assert(card_status == VCARD_DONE && response);
- int size = MIN(*receive_buf_len, response->b_total_len);
- memcpy(receive_buf, response->b_data, size);
- *receive_buf_len = size;
- vcard_response_delete(response);
- vcard_apdu_delete(apdu);
- vcard_free(card); /* free our reference */
- return VREADER_OK;
-}
-
-struct VReaderListStruct {
- VReaderListEntry *head;
- VReaderListEntry *tail;
-};
-
-struct VReaderListEntryStruct {
- VReaderListEntry *next;
- VReaderListEntry *prev;
- VReader *reader;
-};
-
-
-static VReaderListEntry *
-vreader_list_entry_new(VReader *reader)
-{
- VReaderListEntry *new_reader_list_entry;
-
- new_reader_list_entry = g_new0(VReaderListEntry, 1);
- new_reader_list_entry->reader = vreader_reference(reader);
- return new_reader_list_entry;
-}
-
-static void
-vreader_list_entry_delete(VReaderListEntry *entry)
-{
- if (entry == NULL) {
- return;
- }
- vreader_free(entry->reader);
- g_free(entry);
-}
-
-
-static VReaderList *
-vreader_list_new(void)
-{
- VReaderList *new_reader_list;
-
- new_reader_list = g_new0(VReaderList, 1);
- return new_reader_list;
-}
-
-void
-vreader_list_delete(VReaderList *list)
-{
- VReaderListEntry *current_entry;
- VReaderListEntry *next_entry;
- for (current_entry = vreader_list_get_first(list); current_entry;
- current_entry = next_entry) {
- next_entry = vreader_list_get_next(current_entry);
- vreader_list_entry_delete(current_entry);
- }
- g_free(list);
-}
-
-
-VReaderListEntry *
-vreader_list_get_first(VReaderList *list)
-{
- return list ? list->head : NULL;
-}
-
-VReaderListEntry *
-vreader_list_get_next(VReaderListEntry *current)
-{
- return current ? current->next : NULL;
-}
-
-VReader *
-vreader_list_get_reader(VReaderListEntry *entry)
-{
- return entry ? vreader_reference(entry->reader) : NULL;
-}
-
-static void
-vreader_queue(VReaderList *list, VReaderListEntry *entry)
-{
- if (entry == NULL) {
- return;
- }
- entry->next = NULL;
- entry->prev = list->tail;
- if (list->head) {
- list->tail->next = entry;
- } else {
- list->head = entry;
- }
- list->tail = entry;
-}
-
-static void
-vreader_dequeue(VReaderList *list, VReaderListEntry *entry)
-{
- if (entry == NULL) {
- return;
- }
- if (entry->next == NULL) {
- list->tail = entry->prev;
- } else if (entry->prev == NULL) {
- list->head = entry->next;
- } else {
- entry->prev->next = entry->next;
- entry->next->prev = entry->prev;
- }
- if ((list->tail == NULL) || (list->head == NULL)) {
- list->head = list->tail = NULL;
- }
- entry->next = entry->prev = NULL;
-}
-
-static VReaderList *vreader_list;
-static CompatGMutex vreader_list_mutex;
-
-static void
-vreader_list_init(void)
-{
- vreader_list = vreader_list_new();
-}
-
-static void
-vreader_list_lock(void)
-{
- g_mutex_lock(&vreader_list_mutex);
-}
-
-static void
-vreader_list_unlock(void)
-{
- g_mutex_unlock(&vreader_list_mutex);
-}
-
-static VReaderList *
-vreader_copy_list(VReaderList *list)
-{
- VReaderList *new_list;
- VReaderListEntry *current_entry;
-
- new_list = vreader_list_new();
- if (new_list == NULL) {
- return NULL;
- }
- for (current_entry = vreader_list_get_first(list); current_entry;
- current_entry = vreader_list_get_next(current_entry)) {
- VReader *reader = vreader_list_get_reader(current_entry);
- VReaderListEntry *new_entry = vreader_list_entry_new(reader);
-
- vreader_free(reader);
- vreader_queue(new_list, new_entry);
- }
- return new_list;
-}
-
-VReaderList *
-vreader_get_reader_list(void)
-{
- VReaderList *new_reader_list;
-
- vreader_list_lock();
- new_reader_list = vreader_copy_list(vreader_list);
- vreader_list_unlock();
- return new_reader_list;
-}
-
-VReader *
-vreader_get_reader_by_id(vreader_id_t id)
-{
- VReader *reader = NULL;
- VReaderListEntry *current_entry;
-
- if (id == (vreader_id_t) -1) {
- return NULL;
- }
-
- vreader_list_lock();
- for (current_entry = vreader_list_get_first(vreader_list); current_entry;
- current_entry = vreader_list_get_next(current_entry)) {
- VReader *creader = vreader_list_get_reader(current_entry);
- if (creader->id == id) {
- reader = creader;
- break;
- }
- vreader_free(creader);
- }
- vreader_list_unlock();
- return reader;
-}
-
-VReader *
-vreader_get_reader_by_name(const char *name)
-{
- VReader *reader = NULL;
- VReaderListEntry *current_entry;
-
- vreader_list_lock();
- for (current_entry = vreader_list_get_first(vreader_list); current_entry;
- current_entry = vreader_list_get_next(current_entry)) {
- VReader *creader = vreader_list_get_reader(current_entry);
- if (strcmp(creader->name, name) == 0) {
- reader = creader;
- break;
- }
- vreader_free(creader);
- }
- vreader_list_unlock();
- return reader;
-}
-
-/* called from card_emul to initialize the readers */
-VReaderStatus
-vreader_add_reader(VReader *reader)
-{
- VReaderListEntry *reader_entry;
-
- reader_entry = vreader_list_entry_new(reader);
- if (reader_entry == NULL) {
- return VREADER_OUT_OF_MEMORY;
- }
- vreader_list_lock();
- vreader_queue(vreader_list, reader_entry);
- vreader_list_unlock();
- vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT, reader, NULL));
- return VREADER_OK;
-}
-
-
-VReaderStatus
-vreader_remove_reader(VReader *reader)
-{
- VReaderListEntry *current_entry;
-
- vreader_list_lock();
- for (current_entry = vreader_list_get_first(vreader_list); current_entry;
- current_entry = vreader_list_get_next(current_entry)) {
- if (current_entry->reader == reader) {
- break;
- }
- }
- vreader_dequeue(vreader_list, current_entry);
- vreader_list_unlock();
- vreader_list_entry_delete(current_entry);
- vevent_queue_vevent(vevent_new(VEVENT_READER_REMOVE, reader, NULL));
- return VREADER_OK;
-}
-
-/*
- * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
- * state. Separated from vreader_insert_card to allow replaying events
- * for a given state.
- */
-void
-vreader_queue_card_event(VReader *reader)
-{
- vevent_queue_vevent(vevent_new(
- reader->card ? VEVENT_CARD_INSERT : VEVENT_CARD_REMOVE, reader,
- reader->card));
-}
-
-/*
- * insert/remove a new card. for removal, card == NULL
- */
-VReaderStatus
-vreader_insert_card(VReader *reader, VCard *card)
-{
- vreader_lock(reader);
- if (reader->card) {
- /* decrement reference count */
- vcard_free(reader->card);
- reader->card = NULL;
- }
- reader->card = vcard_reference(card);
- vreader_unlock(reader);
- vreader_queue_card_event(reader);
- return VREADER_OK;
-}
-
-/*
- * initialize all the static reader structures
- */
-void
-vreader_init(void)
-{
- vreader_list_init();
-}
-