Features/Smartcard: Difference between revisions
(add VSCard protocol) |
(fix moinmoinisms) |
||
Line 17: | Line 17: | ||
To create the include file run: | To create the include file run: | ||
xsel | gawk 'BEGIN { x=0 }; /^ | <pre>xsel | gawk 'BEGIN { x=0 }; /^<pre>$/ { x+=1 }; /^<\/pre>$/ { x-=1; print ""; }; x==1 && ! /<pre>/ { print }' > libcacard/vscard_common.h</pre> | ||
=Preamble= | =Preamble= | ||
<pre> | |||
/* Virtual Smart Card protocol definition | /* Virtual Smart Card protocol definition | ||
* | * | ||
Line 42: | Line 41: | ||
#include <stdint.h> | #include <stdint.h> | ||
</pre> | |||
=Message Types= | =Message Types= | ||
<pre> | |||
typedef enum { | typedef enum { | ||
VSC_Init = 1, | VSC_Init = 1, | ||
Line 56: | Line 55: | ||
VSC_Reconnect | VSC_Reconnect | ||
} VSCMsgType; | } VSCMsgType; | ||
</pre> | |||
=Error Codes= | =Error Codes= | ||
<pre> | |||
typedef enum { | typedef enum { | ||
VSC_NO_ERROR=0, | VSC_NO_ERROR=0, | ||
Line 65: | Line 64: | ||
VSC_CARD_ALREAY_INSERTED, | VSC_CARD_ALREAY_INSERTED, | ||
} VSCErrorCode; | } VSCErrorCode; | ||
</pre> | |||
=Reserved Reader ID numbers= | =Reserved Reader ID numbers= | ||
<pre> | |||
#define VSCARD_UNDEFINED_READER_ID 0xffffffff | #define VSCARD_UNDEFINED_READER_ID 0xffffffff | ||
#define VSCARD_MINIMAL_READER_ID 0 | #define VSCARD_MINIMAL_READER_ID 0 | ||
</pre> | |||
=Other Constants= | =Other Constants= | ||
<pre> | |||
#define VSCARD_MAGIC (*(uint32_t*)"VSCD") | #define VSCARD_MAGIC (*(uint32_t*)"VSCD") | ||
</pre> | |||
=Header struct= | =Header struct= | ||
<pre> | |||
/* Header | /* Header | ||
* Each message starts with the header. The reader_id | * Each message starts with the header. The reader_id | ||
Line 87: | Line 86: | ||
uint8_t data[0]; | uint8_t data[0]; | ||
} VSCMsgHeader; | } VSCMsgHeader; | ||
</pre> | |||
=Messages= | =Messages= | ||
==Init== | ==Init== | ||
<pre> | |||
/* VSCMsgInit Client <-> Host | /* VSCMsgInit Client <-> Host | ||
* Client sends it on connection, Host replies with VSCMsgInit. | * Client sends it on connection, Host replies with VSCMsgInit. | ||
Line 104: | Line 103: | ||
array may grow in the future*/ | array may grow in the future*/ | ||
} VSCMsgInit; | } VSCMsgInit; | ||
</pre> | |||
==Error== | ==Error== | ||
<pre> | |||
/* VSCMsgError Client <-> Host | /* VSCMsgError Client <-> Host | ||
* This message is a possible response to any of: | * This message is a possible response to any of: | ||
Line 117: | Line 116: | ||
uint32_t code; | uint32_t code; | ||
} VSCMsgAck; | } VSCMsgAck; | ||
</pre> | |||
==Reader Add== | ==Reader Add== | ||
<pre> | |||
/* VSCMsgReaderAdd Client -> Host | /* VSCMsgReaderAdd Client -> Host | ||
* Host replies with allocated reader id in ReaderAddResponse | * Host replies with allocated reader id in ReaderAddResponse | ||
Line 129: | Line 128: | ||
uint8_t name[0]; | uint8_t name[0]; | ||
} VSCMsgReaderAdd; | } VSCMsgReaderAdd; | ||
</pre> | |||
==Reader Add Response== | ==Reader Add Response== | ||
<pre> | |||
/* VSCMsgReaderAddResponse Host -> Client | /* VSCMsgReaderAddResponse Host -> Client | ||
* Reply to ReaderAdd. The reader_id provided in this message | * Reply to ReaderAdd. The reader_id provided in this message | ||
Line 140: | Line 139: | ||
typedef struct VSCMsgReaderAddResponse { | typedef struct VSCMsgReaderAddResponse { | ||
} VSCMsgReaderAddResponse; | } VSCMsgReaderAddResponse; | ||
</pre> | |||
==Reader Remove== | ==Reader Remove== | ||
<pre> | |||
/* VSCMsgReaderRemove Client -> Host | /* VSCMsgReaderRemove Client -> Host | ||
* */ | * */ | ||
typedef struct VSCMsgReaderRemove { | typedef struct VSCMsgReaderRemove { | ||
} VSCMsgReaderRemove; | } VSCMsgReaderRemove; | ||
</pre> | |||
==ATR== | ==ATR== | ||
<pre> | |||
/* VSCMsgATR Client -> Host | /* VSCMsgATR Client -> Host | ||
* Answer to reset. Sent for card insertion or card reset. | * Answer to reset. Sent for card insertion or card reset. | ||
Line 156: | Line 155: | ||
uint8_t atr[0]; | uint8_t atr[0]; | ||
} VSCMsgATR; | } VSCMsgATR; | ||
</pre> | |||
==Card Remove== | ==Card Remove== | ||
<pre> | |||
/* VSCMsgCardRemove Client -> Host | /* VSCMsgCardRemove Client -> Host | ||
* */ | * */ | ||
typedef struct VSCMsgCardRemove { | typedef struct VSCMsgCardRemove { | ||
} VSCMsgCardRemove; | } VSCMsgCardRemove; | ||
</pre> | |||
==APDU== | ==APDU== | ||
<pre> | |||
/* VSCMsgAPDU Client <-> Host | /* VSCMsgAPDU Client <-> Host | ||
* Main reason of existance. Transfer a single APDU in either direction. | * Main reason of existance. Transfer a single APDU in either direction. | ||
Line 173: | Line 172: | ||
uint8_t data[0]; | uint8_t data[0]; | ||
} VSCMsgAPDU; | } VSCMsgAPDU; | ||
</pre> | |||
==Reconnect== | ==Reconnect== | ||
<pre> | |||
/* VSCMsgReconnect Host -> Client | /* VSCMsgReconnect Host -> Client | ||
* Host request client to disconnect from it and connect to another | * Host request client to disconnect from it and connect to another | ||
Line 186: | Line 185: | ||
char port[128]; | char port[128]; | ||
} VSCMsgReconnect; | } VSCMsgReconnect; | ||
</pre> |
Revision as of 22:18, 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 }; /^<pre>$/ { x+=1 }; /^<\/pre>$/ { x-=1; print ""; }; x==1 && ! /<pre>/ { 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;