Features/Smartcard: Difference between revisions

From QEMU
(add VSCard protocol)
Line 11: Line 11:


=VSCard protocol=
=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;
}}}

Revision as of 22:07, 29 January 2011

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