qemu/hw/usb/ccid-card-passthru.c

424 lines
13 KiB
C
Raw Normal View History

ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
/*
* CCID Passthru Card Device emulation
*
* Copyright (c) 2011 Red Hat.
* Written by Alon Levy.
*
* This work is licensed under the terms of the GNU GPL, version 2.1 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/units.h"
#include <libcacard.h>
#include "chardev/char-fe.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/sockets.h"
#include "ccid.h"
#include "qapi/error.h"
#include "qom/object.h"
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
#define DPRINTF(card, lvl, fmt, ...) \
do { \
if (lvl <= card->debug) { \
printf("ccid-card-passthru: " fmt , ## __VA_ARGS__); \
} \
} while (0)
#define D_WARN 1
#define D_INFO 2
#define D_MORE_INFO 3
#define D_VERBOSE 4
/* TODO: do we still need this? */
static const uint8_t DEFAULT_ATR[] = {
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
/*
* From some example somewhere
* 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
*/
/* From an Athena smart card */
0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21,
0x13, 0x08
};
#define VSCARD_IN_SIZE (64 * KiB)
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
/* maximum size of ATR - from 7816-3 */
#define MAX_ATR_SIZE 40
typedef struct PassthruState PassthruState;
struct PassthruState {
CCIDCardState base;
CharBackend cs;
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
uint8_t vscard_in_data[VSCARD_IN_SIZE];
uint32_t vscard_in_pos;
uint32_t vscard_in_hdr;
uint8_t atr[MAX_ATR_SIZE];
uint8_t atr_length;
uint8_t debug;
};
#define TYPE_CCID_PASSTHRU "ccid-card-passthru"
DECLARE_INSTANCE_CHECKER(PassthruState, PASSTHRU_CCID_CARD,
TYPE_CCID_PASSTHRU)
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
/*
* VSCard protocol over chardev
* This code should not depend on the card type.
*/
static void ccid_card_vscard_send_msg(PassthruState *s,
VSCMsgType type, uint32_t reader_id,
const uint8_t *payload, uint32_t length)
{
VSCMsgHeader scr_msg_header;
scr_msg_header.type = htonl(type);
scr_msg_header.reader_id = htonl(reader_id);
scr_msg_header.length = htonl(length);
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(&s->cs, (uint8_t *)&scr_msg_header,
sizeof(VSCMsgHeader));
qemu_chr_fe_write_all(&s->cs, payload, length);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
}
static void ccid_card_vscard_send_apdu(PassthruState *s,
const uint8_t *apdu, uint32_t length)
{
ccid_card_vscard_send_msg(
s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, length);
}
static void ccid_card_vscard_send_error(PassthruState *s,
uint32_t reader_id, VSCErrorCode code)
{
VSCMsgError msg = {.code = htonl(code)};
ccid_card_vscard_send_msg(
s, VSC_Error, reader_id, (uint8_t *)&msg, sizeof(msg));
}
static void ccid_card_vscard_send_init(PassthruState *s)
{
VSCMsgInit msg = {
.version = htonl(VSCARD_VERSION),
.magic = VSCARD_MAGIC,
.capabilities = {0}
};
ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
(uint8_t *)&msg, sizeof(msg));
}
static int ccid_card_vscard_can_read(void *opaque)
{
PassthruState *card = opaque;
return VSCARD_IN_SIZE >= card->vscard_in_pos ?
VSCARD_IN_SIZE - card->vscard_in_pos : 0;
}
static void ccid_card_vscard_handle_init(
PassthruState *card, VSCMsgHeader *hdr, VSCMsgInit *init)
{
uint32_t *capabilities;
int num_capabilities;
int i;
capabilities = init->capabilities;
num_capabilities =
1 + ((hdr->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
init->version = ntohl(init->version);
for (i = 0 ; i < num_capabilities; ++i) {
capabilities[i] = ntohl(capabilities[i]);
}
if (init->magic != VSCARD_MAGIC) {
error_report("wrong magic");
/* we can't disconnect the chardev */
}
if (init->version != VSCARD_VERSION) {
DPRINTF(card, D_WARN,
"got version %d, have %d", init->version, VSCARD_VERSION);
}
/* future handling of capabilities, none exist atm */
ccid_card_vscard_send_init(card);
}
static int check_atr(PassthruState *card, uint8_t *data, int len)
{
int historical_length, opt_bytes;
int td_count = 0;
int td;
if (len < 2) {
return 0;
}
historical_length = data[1] & 0xf;
opt_bytes = 0;
if (data[0] != 0x3b && data[0] != 0x3f) {
DPRINTF(card, D_WARN, "atr's T0 is 0x%X, not in {0x3b, 0x3f}\n",
data[0]);
return 0;
}
td_count = 0;
td = data[1] >> 4;
while (td && td_count < 2 && opt_bytes + historical_length + 2 < len) {
td_count++;
if (td & 0x1) {
opt_bytes++;
}
if (td & 0x2) {
opt_bytes++;
}
if (td & 0x4) {
opt_bytes++;
}
if (td & 0x8) {
opt_bytes++;
td = data[opt_bytes + 2] >> 4;
}
}
if (len < 2 + historical_length + opt_bytes) {
DPRINTF(card, D_WARN,
"atr too short: len %d, but historical_len %d, T1 0x%X\n",
len, historical_length, data[1]);
return 0;
}
if (len > 2 + historical_length + opt_bytes) {
DPRINTF(card, D_WARN,
"atr too long: len %d, but hist/opt %d/%d, T1 0x%X\n",
len, historical_length, opt_bytes, data[1]);
/* let it through */
}
DPRINTF(card, D_VERBOSE,
"atr passes check: %d total length, %d historical, %d optional\n",
len, historical_length, opt_bytes);
return 1;
}
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
static void ccid_card_vscard_handle_message(PassthruState *card,
VSCMsgHeader *scr_msg_header)
{
uint8_t *data = (uint8_t *)&scr_msg_header[1];
switch (scr_msg_header->type) {
case VSC_ATR:
DPRINTF(card, D_INFO, "VSC_ATR %d\n", scr_msg_header->length);
if (scr_msg_header->length > MAX_ATR_SIZE) {
error_report("ATR size exceeds spec, ignoring");
ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
VSC_GENERAL_ERROR);
break;
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
}
if (!check_atr(card, data, scr_msg_header->length)) {
error_report("ATR is inconsistent, ignoring");
ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
VSC_GENERAL_ERROR);
break;
}
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
memcpy(card->atr, data, scr_msg_header->length);
card->atr_length = scr_msg_header->length;
ccid_card_card_inserted(&card->base);
ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
VSC_SUCCESS);
break;
case VSC_APDU:
ccid_card_send_apdu_to_guest(
&card->base, data, scr_msg_header->length);
break;
case VSC_CardRemove:
DPRINTF(card, D_INFO, "VSC_CardRemove\n");
ccid_card_card_removed(&card->base);
ccid_card_vscard_send_error(card,
scr_msg_header->reader_id, VSC_SUCCESS);
break;
case VSC_Init:
ccid_card_vscard_handle_init(
card, scr_msg_header, (VSCMsgInit *)data);
break;
case VSC_Error:
ccid_card_card_error(&card->base, *(uint32_t *)data);
break;
case VSC_ReaderAdd:
if (ccid_card_ccid_attach(&card->base) < 0) {
ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
VSC_CANNOT_ADD_MORE_READERS);
} else {
ccid_card_vscard_send_error(card, VSCARD_MINIMAL_READER_ID,
VSC_SUCCESS);
}
break;
case VSC_ReaderRemove:
ccid_card_ccid_detach(&card->base);
ccid_card_vscard_send_error(card,
scr_msg_header->reader_id, VSC_SUCCESS);
break;
default:
printf("usb-ccid: chardev: unexpected message of type %X\n",
scr_msg_header->type);
ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
VSC_GENERAL_ERROR);
}
}
static void ccid_card_vscard_drop_connection(PassthruState *card)
{
qemu_chr_fe_deinit(&card->cs, true);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
card->vscard_in_pos = card->vscard_in_hdr = 0;
}
static void ccid_card_vscard_read(void *opaque, const uint8_t *buf, int size)
{
PassthruState *card = opaque;
VSCMsgHeader *hdr;
if (card->vscard_in_pos + size > VSCARD_IN_SIZE) {
error_report("no room for data: pos %u + size %d > %" PRId64 "."
" dropping connection.",
card->vscard_in_pos, size, VSCARD_IN_SIZE);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
ccid_card_vscard_drop_connection(card);
return;
}
assert(card->vscard_in_pos < VSCARD_IN_SIZE);
assert(card->vscard_in_hdr < VSCARD_IN_SIZE);
memcpy(card->vscard_in_data + card->vscard_in_pos, buf, size);
card->vscard_in_pos += size;
hdr = (VSCMsgHeader *)(card->vscard_in_data + card->vscard_in_hdr);
while ((card->vscard_in_pos - card->vscard_in_hdr >= sizeof(VSCMsgHeader))
&&(card->vscard_in_pos - card->vscard_in_hdr >=
sizeof(VSCMsgHeader) + ntohl(hdr->length))) {
hdr->reader_id = ntohl(hdr->reader_id);
hdr->length = ntohl(hdr->length);
hdr->type = ntohl(hdr->type);
ccid_card_vscard_handle_message(card, hdr);
card->vscard_in_hdr += hdr->length + sizeof(VSCMsgHeader);
hdr = (VSCMsgHeader *)(card->vscard_in_data + card->vscard_in_hdr);
}
if (card->vscard_in_hdr == card->vscard_in_pos) {
card->vscard_in_pos = card->vscard_in_hdr = 0;
}
}
static void ccid_card_vscard_event(void *opaque, QEMUChrEvent event)
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
{
PassthruState *card = opaque;
switch (event) {
case CHR_EVENT_BREAK:
card->vscard_in_pos = card->vscard_in_hdr = 0;
break;
case CHR_EVENT_OPENED:
DPRINTF(card, D_INFO, "%s: CHR_EVENT_OPENED\n", __func__);
break;
case CHR_EVENT_MUX_IN:
case CHR_EVENT_MUX_OUT:
case CHR_EVENT_CLOSED:
/* Ignore */
break;
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
}
}
/* End VSCard handling */
static void passthru_apdu_from_guest(
CCIDCardState *base, const uint8_t *apdu, uint32_t len)
{
PassthruState *card = PASSTHRU_CCID_CARD(base);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
if (!qemu_chr_fe_backend_connected(&card->cs)) {
printf("ccid-passthru: no chardev, discarding apdu length %u\n", len);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
return;
}
ccid_card_vscard_send_apdu(card, apdu, len);
}
static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
{
PassthruState *card = PASSTHRU_CCID_CARD(base);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
*len = card->atr_length;
return card->atr;
}
static void passthru_realize(CCIDCardState *base, Error **errp)
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
{
PassthruState *card = PASSTHRU_CCID_CARD(base);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
card->vscard_in_pos = 0;
card->vscard_in_hdr = 0;
if (qemu_chr_fe_backend_connected(&card->cs)) {
DPRINTF(card, D_INFO, "ccid-card-passthru: initing chardev");
qemu_chr_fe_set_handlers(&card->cs,
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
ccid_card_vscard_can_read,
ccid_card_vscard_read,
ccid_card_vscard_event, NULL, card, NULL, true);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
ccid_card_vscard_send_init(card);
} else {
error_setg(errp, "missing chardev");
return;
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
}
card->debug = parse_debug_env("QEMU_CCID_PASSTHRU_DEBUG", D_VERBOSE,
card->debug);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
assert(sizeof(DEFAULT_ATR) <= MAX_ATR_SIZE);
memcpy(card->atr, DEFAULT_ATR, sizeof(DEFAULT_ATR));
card->atr_length = sizeof(DEFAULT_ATR);
}
static VMStateDescription passthru_vmstate = {
.name = "ccid-card-passthru",
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_BUFFER(vscard_in_data, PassthruState),
VMSTATE_UINT32(vscard_in_pos, PassthruState),
VMSTATE_UINT32(vscard_in_hdr, PassthruState),
VMSTATE_BUFFER(atr, PassthruState),
VMSTATE_UINT8(atr_length, PassthruState),
VMSTATE_END_OF_LIST()
}
};
static Property passthru_card_properties[] = {
DEFINE_PROP_CHR("chardev", PassthruState, cs),
DEFINE_PROP_UINT8("debug", PassthruState, debug, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void passthru_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
CCIDCardClass *cc = CCID_CARD_CLASS(klass);
cc->realize = passthru_realize;
cc->get_atr = passthru_get_atr;
cc->apdu_from_guest = passthru_apdu_from_guest;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
dc->desc = "passthrough smartcard";
dc->vmsd = &passthru_vmstate;
device_class_set_props(dc, passthru_card_properties);
}
static const TypeInfo passthru_card_info = {
.name = TYPE_CCID_PASSTHRU,
.parent = TYPE_CCID_CARD,
.instance_size = sizeof(PassthruState),
.class_init = passthru_class_initfn,
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
};
static void ccid_card_passthru_register_types(void)
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
{
type_register_static(&passthru_card_info);
ccid: add passthru card device The passthru ccid card is a device sitting on the usb-ccid bus and using a chardevice to communicate with a remote device using the VSCard protocol defined in libcacard/vscard_common.h Usage docs available in following patch in docs/ccid.txt Signed-off-by: Alon Levy <alevy@redhat.com> --- Changes from v23->v24: * fixed double license line in header. Changes from v20->v21: (Jes Sorensen review) * add reference to COPYING in header * long comment reformatting Changes from v19->v20: * checkpatch.pl Changes from v18->v19: * add qdev.desc * remove .qdev.unplug (no hot unplug support for ccid bus) Changes from v16->v17: * fix wrong cast when receiving VSC_Error * ccid-card-passthru: force chardev user wakeup by sending Init see lengthy comment below. Changes from v15->v16: Behavioral changes: * return correct size * return error instead of assert if client sent too large ATR * don't assert if client sent too large a size, but add asserts for indices to buffer * reset vscard_in indices on chardev disconnect * handle init from client * error if no chardev supplied * use ntoh, hton * eradicate reader_id_t * remove Reconnect usage (removed from VSCARD protocol) * send VSC_SUCCESS on card insert/remove and reader add/remove Style fixes: * width of line fix * update copyright * remove old TODO's * update file header comment * use macros for debug levels * c++ style comment replacement * update copyright license * fix ATR size comment * fix whitespace in struct def * fix DPRINTF prefix * line width fix ccid-card-passthru: force chardev user wakeup by sending Init The problem: how to wakeup the user of the smartcard when the smartcard device is initialized? Long term solution: have a callback interface. This was done via the deprecated so called chardev ioctl interface. Short term solution: do a write. Specifically we write an Init message. And we change the client to send it's own Init message regardless of receiving this one. Additional Init messages will be regarded as acceptable, the first one received after connection establishment is the determining one wrt capabilities.
2010-10-17 15:10:32 +04:00
}
type_init(ccid_card_passthru_register_types)