Features/Smartcard: Difference between revisions
m (moved Features/Smartcard/Specification to Features/Smartcard) |
(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. */
- 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; }}}