Features/Smartcard
Smartcard support
Future smart card support will be based on:
- CCID specification for USB Smart card reader device implemented as a ccid bus (-device usb-ccid)
- passthru protocol to connect to remote computer carrying physical (or virtual) smartcard (-device ccid-card-passthru)
- emulated card using NSS backend with certificates or real hardware on qemu running host (-device ccid-card-emulated)
This page is mainly about documention the protocol used for remote reader and card support.
The protocol header is libcacard/vscard_common.h.
VSCard protocol
A header/payload protocol between the ccid-card-passthru device and a remote client. The protocol is APDU oriented.
This page contains the header file in a form easy to extract, so this page can stay up to date with the source.
To create the include file run: {{{ xsel | gawk 'BEGIN { x=0 }; /^{{{$/ { x+=1 }; /^}}}$/ { x-=1; print ""; }; x==1 && ! /{{{/ { print }' > libcacard/vscard_common.h }}}
Preamble
{{{ /* Virtual Smart Card protocol definition
* * This protocol is between a host using virtual smart card readers, * and a client providing the smart cards, perhaps by emulating them or by * access to real cards. * * The current implementation passes the raw APDU's from 7816 and additionally * contains messages to setup and teardown readers, handle insertion and * removal of cards, negotiate the protocol via capabilities and provide for error responses. * * Copyright (c) 2011 Red Hat. * * This code is licensed under the LGPL. */
- ifndef VSCARD_COMMON_H
- define VSCARD_COMMON_H
- include <stdint.h>
}}}
Message Types
{{{ typedef enum {
VSC_Init = 1, VSC_Error, VSC_ReaderAdd, VSC_ReaderAddResponse, VSC_ReaderRemove, VSC_ATR, VSC_CardRemove, VSC_APDU, VSC_Reconnect
} VSCMsgType; }}}
Error Codes
{{{ typedef enum {
VSC_NO_ERROR=0, VSC_GENERAL_ERROR=1, VSC_CANNOT_ADD_MORE_READERS, VSC_CARD_ALREAY_INSERTED,
} VSCErrorCode; }}}
Reserved Reader ID numbers
{{{
- define VSCARD_UNDEFINED_READER_ID 0xffffffff
- define VSCARD_MINIMAL_READER_ID 0
}}}
Other Constants
{{{
- define VSCARD_MAGIC (*(uint32_t*)"VSCD")
}}}
Header struct
{{{ /* Header
* Each message starts with the header. The reader_id * value is only relevant */
typedef struct VSCMsgHeader {
uint32_t type; uint32_t reader_id; uint32_t length; uint8_t data[0];
} VSCMsgHeader; }}}
Messages
Init
{{{ /* VSCMsgInit Client <-> Host
* Client sends it on connection, Host replies with VSCMsgInit. * Client fills its capabilities, host replies with its own. * * It is not meant to be used for negotiation, i.e. sending more then * once from any side, but could be used for that in the future. * */
typedef struct VSCMsgInit {
uint32_t magic; uint32_t version; uint32_t capabilities[1]; /* receiver must check length, array may grow in the future*/
} VSCMsgInit; }}}
Error
{{{ /* VSCMsgError Client <-> Host
* This message is a possible response to any of: * Reader Add * Reader Remove * Card Remove * At any point there can be a * */
typedef struct VSCMsgAck {
uint32_t code;
} VSCMsgAck; }}}
Reader Add
{{{ /* VSCMsgReaderAdd Client -> Host
* Host replies with allocated reader id in ReaderAddResponse * name - name of the reader on client side, UTF-8 encoded. Only used * for client presentation (may be translated to the device presented to the guest), * protocol wise only reader_id * */
typedef struct VSCMsgReaderAdd {
uint8_t name[0];
} VSCMsgReaderAdd; }}}
Reader Add Response
{{{ /* VSCMsgReaderAddResponse Host -> Client
* Reply to ReaderAdd. The reader_id provided in this message * will be used to identify the new reader. Since there are no * message id's in the protocol there can be only a single outstanding * ReaderAdd message. * */
typedef struct VSCMsgReaderAddResponse { } VSCMsgReaderAddResponse; }}}
Reader Remove
{{{ /* VSCMsgReaderRemove Client -> Host
* */
typedef struct VSCMsgReaderRemove { } VSCMsgReaderRemove; }}}
ATR
{{{ /* VSCMsgATR Client -> Host
* Answer to reset. Sent for card insertion or card reset. * */
typedef struct VSCMsgATR {
uint8_t atr[0];
} VSCMsgATR; }}}
Card Remove
{{{ /* VSCMsgCardRemove Client -> Host
* */
typedef struct VSCMsgCardRemove { } VSCMsgCardRemove; }}}
APDU
{{{ /* VSCMsgAPDU Client <-> Host
* Main reason of existance. Transfer a single APDU in either direction. * * */
typedef struct VSCMsgAPDU {
uint8_t data[0];
} VSCMsgAPDU; }}}
Reconnect
{{{ /* VSCMsgReconnect Host -> Client
* Host request client to disconnect from it and connect to another * host. * Contains new host address as two strings for IPv4 and * IPv6 support. * */
typedef struct VSCMsgReconnect {
char host[128]; char port[128];
} VSCMsgReconnect; }}}