Features/Smartcard

From QEMU
Revision as of 22:07, 29 January 2011 by Alon (talk | contribs) (add VSCard protocol)

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.
*/
  1. ifndef VSCARD_COMMON_H
  2. define VSCARD_COMMON_H
  1. 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

{{{

  1. define VSCARD_UNDEFINED_READER_ID 0xffffffff
  2. define VSCARD_MINIMAL_READER_ID 0

}}}

Other Constants

{{{

  1. 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; }}}