]>
Commit | Line | Data |
---|---|---|
65794b43 RR |
1 | This file documents the CAC (Common Access Card) library in the libcacard |
2 | subdirectory. | |
3 | ||
4 | Virtual Smart Card Emulator | |
5 | ||
6 | This emulator is designed to provide emulation of actual smart cards to a | |
7 | virtual card reader running in a guest virtual machine. The emulated smart | |
8 | cards can be representations of real smart cards, where the necessary functions | |
9 | such as signing, card removal/insertion, etc. are mapped to real, physical | |
10 | cards which are shared with the client machine the emulator is running on, or | |
11 | the cards could be pure software constructs. | |
12 | ||
4a84ebe6 | 13 | The emulator is structured to allow multiple replaceable or additional pieces, |
65794b43 RR |
14 | so it can be easily modified for future requirements. The primary envisioned |
15 | modifications are: | |
16 | ||
17 | 1) The socket connection to the virtual card reader (presumably a CCID reader, | |
18 | but other ISO-7816 compatible readers could be used). The code that handles | |
19 | this is in vscclient.c. | |
20 | ||
21 | 2) The virtual card low level emulation. This is currently supplied by using | |
22 | NSS. This emulation could be replaced by implementations based on other | |
23 | security libraries, including but not limitted to openssl+pkcs#11 library, | |
24 | raw pkcs#11, Microsoft CAPI, direct opensc calls, etc. The code that handles | |
25 | this is in vcard_emul_nss.c. | |
26 | ||
27 | 3) Emulation for new types of cards. The current implementation emulates the | |
28 | original DoD CAC standard with separate pki containers. This emulator lives in | |
29 | cac.c. More than one card type emulator could be included. Other cards could | |
30 | be emulated as well, including PIV, newer versions of CAC, PKCS #15, etc. | |
31 | ||
32 | -------------------- | |
33 | Replacing the Socket Based Virtual Reader Interface. | |
34 | ||
4a84ebe6 | 35 | The current implementation contains a replaceable module vscclient.c. The |
65794b43 RR |
36 | current vscclient.c implements a sockets interface to the virtual ccid reader |
37 | on the guest. CCID commands that are pertinent to emulation are passed | |
38 | across the socket, and their responses are passed back along that same socket. | |
39 | The protocol that vscclient uses is defined in vscard_common.h and connects | |
40 | to a qemu ccid usb device. Since this socket runs as a client, vscclient.c | |
41 | implements a program with a main entry. It also handles argument parsing for | |
42 | the emulator. | |
43 | ||
44 | An application that wants to use the virtual reader can replace vscclient.c | |
4a84ebe6 | 45 | with its own implementation that connects to its own CCID reader. The calls |
65794b43 RR |
46 | that the CCID reader can call are: |
47 | ||
48 | VReaderList * vreader_get_reader_list(); | |
49 | ||
50 | This function returns a list of virtual readers. These readers may map to | |
51 | physical devices, or simulated devices depending on vcard the back end. Each | |
52 | reader in the list should represent a reader to the virtual machine. Virtual | |
53 | USB address mapping is left to the CCID reader front end. This call can be | |
54 | made any time to get an updated list. The returned list is a copy of the | |
55 | internal list that can be referenced by the caller without locking. This copy | |
56 | must be freed by the caller with vreader_list_delete when it is no longer | |
57 | needed. | |
58 | ||
59 | VReaderListEntry *vreader_list_get_first(VReaderList *); | |
60 | ||
61 | This function gets the first entry on the reader list. Along with | |
62 | vreader_list_get_next(), vreader_list_get_first() can be used to walk the | |
63 | reader list returned from vreader_get_reader_list(). VReaderListEntries are | |
64 | part of the list themselves and do not need to be freed separately from the | |
65 | list. If there are no entries on the list, it will return NULL. | |
66 | ||
67 | VReaderListEntry *vreader_list_get_next(VReaderListEntry *); | |
68 | ||
69 | This function gets the next entry in the list. If there are no more entries | |
70 | it will return NULL. | |
71 | ||
72 | VReader * vreader_list_get_reader(VReaderListEntry *) | |
73 | ||
74 | This function returns the reader stored in the reader List entry. Caller gets | |
4a84ebe6 | 75 | a new reference to a reader. The caller must free its reference when it is |
65794b43 RR |
76 | finished with vreader_free(). |
77 | ||
78 | void vreader_free(VReader *reader); | |
79 | ||
4a84ebe6 | 80 | This function frees a reference to a reader. Readers are reference counted |
65794b43 RR |
81 | and are automatically deleted when the last reference is freed. |
82 | ||
83 | void vreader_list_delete(VReaderList *list); | |
84 | ||
85 | This function frees the list, all the elements on the list, and all the | |
86 | reader references held by the list. | |
87 | ||
88 | VReaderStatus vreader_power_on(VReader *reader, char *atr, int *len); | |
89 | ||
4a84ebe6 | 90 | This function simulates a card power on. A virtual card does not care about |
65794b43 RR |
91 | the actual voltage and other physical parameters, but it does care that the |
92 | card is actually on or off. Cycling the card causes the card to reset. If | |
93 | the caller provides enough space, vreader_power_on will return the ATR of | |
94 | the virtual card. The amount of space provided in atr should be indicated | |
95 | in *len. The function modifies *len to be the actual length of of the | |
96 | returned ATR. | |
97 | ||
98 | VReaderStatus vreader_power_off(VReader *reader); | |
99 | ||
100 | This function simulates a power off of a virtual card. | |
101 | ||
102 | VReaderStatus vreader_xfer_bytes(VReader *reader, unsigne char *send_buf, | |
103 | int send_buf_len, | |
104 | unsigned char *receive_buf, | |
105 | int receive_buf_len); | |
106 | ||
4a84ebe6 | 107 | This function sends a raw apdu to a card and returns the card's response. |
65794b43 RR |
108 | The CCID front end should return the response back. Most of the emulation |
109 | is driven from these APDUs. | |
110 | ||
111 | VReaderStatus vreader_card_is_present(VReader *reader); | |
112 | ||
113 | This function returns whether or not the reader has a card inserted. The | |
114 | vreader_power_on, vreader_power_off, and vreader_xfer_bytes will return | |
115 | VREADER_NO_CARD. | |
116 | ||
117 | const char *vreader_get_name(VReader *reader); | |
118 | ||
119 | This function returns the name of the reader. The name comes from the card | |
120 | emulator level and is usually related to the name of the physical reader. | |
121 | ||
122 | VReaderID vreader_get_id(VReader *reader); | |
123 | ||
124 | This function returns the id of a reader. All readers start out with an id | |
125 | of -1. The application can set the id with vreader_set_id. | |
126 | ||
127 | VReaderStatus vreader_get_id(VReader *reader, VReaderID id); | |
128 | ||
129 | This function sets the reader id. The application is responsible for making | |
130 | sure that the id is unique for all readers it is actively using. | |
131 | ||
132 | VReader *vreader_find_reader_by_id(VReaderID id); | |
133 | ||
134 | This function returns the reader which matches the id. If two readers match, | |
135 | only one is returned. The function returns NULL if the id is -1. | |
136 | ||
137 | Event *vevent_wait_next_vevent(); | |
138 | ||
139 | This function blocks waiting for reader and card insertion events. There | |
140 | will be one event for each card insertion, each card removal, each reader | |
141 | insertion and each reader removal. At start up, events are created for all | |
142 | the initial readers found, as well as all the cards that are inserted. | |
143 | ||
144 | Event *vevent_get_next_vevent(); | |
145 | ||
146 | This function returns a pending event if it exists, otherwise it returns | |
147 | NULL. It does not block. | |
148 | ||
149 | ---------------- | |
150 | Card Type Emulator: Adding a New Virtual Card Type | |
151 | ||
152 | The ISO 7816 card spec describes 2 types of cards: | |
153 | 1) File system cards, where the smartcard is managed by reading and writing | |
154 | data to files in a file system. There is currently only boiler plate | |
155 | implemented for file system cards. | |
156 | 2) VM cards, where the card has loadable applets which perform the card | |
157 | functions. The current implementation supports VM cards. | |
158 | ||
159 | In the case of VM cards, the difference between various types of cards is | |
160 | really what applets have been installed in that card. This structure is | |
161 | mirrored in card type emulators. The 7816 emulator already handles the basic | |
162 | ISO 7186 commands. Card type emulators simply need to add the virtual applets | |
163 | which emulate the real card applets. Card type emulators have exactly one | |
164 | public entry point: | |
165 | ||
166 | VCARDStatus xxx_card_init(VCard *card, const char *flags, | |
167 | const unsigned char *cert[], | |
168 | int cert_len[], | |
169 | VCardKey *key[], | |
170 | int cert_count); | |
171 | ||
172 | The parameters for this are: | |
e6d89f8c | 173 | card - the virtual card structure which will represent this card. |
65794b43 RR |
174 | flags - option flags that may be specific to this card type. |
175 | cert - array of binary certificates. | |
176 | cert_len - array of lengths of each of the certificates specified in cert. | |
177 | key - array of opaque key structures representing the private keys on | |
178 | the card. | |
179 | cert_count - number of entries in cert, cert_len, and key arrays. | |
180 | ||
181 | Any cert, cert_len, or key with the same index are matching sets. That is | |
e6d89f8c | 182 | cert[0] is cert_len[0] long and has the corresponding private key of key[0]. |
65794b43 RR |
183 | |
184 | The card type emulator is expected to own the VCardKeys, but it should copy | |
185 | any raw cert data it wants to save. It can create new applets and add them to | |
186 | the card using the following functions: | |
187 | ||
188 | VCardApplet *vcard_new_applet(VCardProcessAPDU apdu_func, | |
189 | VCardResetApplet reset_func, | |
190 | const unsigned char *aid, | |
191 | int aid_len); | |
192 | ||
193 | This function creates a new applet. Applet structures store the following | |
194 | information: | |
195 | 1) the AID of the applet (set by aid and aid_len). | |
196 | 2) a function to handle APDUs for this applet. (set by apdu_func, more on | |
197 | this below). | |
198 | 3) a function to reset the applet state when the applet is selected. | |
199 | (set by reset_func, more on this below). | |
200 | 3) applet private data, a data pointer used by the card type emulator to | |
201 | store any data or state it needs to complete requests. (set by a | |
202 | separate call). | |
203 | 4) applet private data free, a function used to free the applet private | |
204 | data when the applet itself is destroyed. | |
205 | The created applet can be added to the card with vcard_add_applet below. | |
206 | ||
207 | void vcard_set_applet_private(VCardApplet *applet, | |
208 | VCardAppletPrivate *private, | |
209 | VCardAppletPrivateFree private_free); | |
210 | This function sets the private data and the corresponding free function. | |
211 | VCardAppletPrivate is an opaque data structure to the rest of the emulator. | |
212 | The card type emulator can define it any way it wants by defining | |
213 | struct VCardAppletPrivateStruct {};. If there is already a private data | |
214 | structure on the applet, the old one is freed before the new one is set up. | |
215 | passing two NULL clear any existing private data. | |
216 | ||
217 | VCardStatus vcard_add_applet(VCard *card, VCardApplet *applet); | |
218 | ||
219 | Add an applet onto the list of applets attached to the card. Once an applet | |
4a84ebe6 SW |
220 | has been added, it can be selected by its AID, and then commands will be |
221 | routed to it VCardProcessAPDU function. This function adopts the applet that | |
222 | is passed into it. Note: 2 applets with the same AID should not be added to | |
223 | the same card. It is permissible to add more than one applet. Multiple applets | |
65794b43 RR |
224 | may have the same VCardPRocessAPDU entry point. |
225 | ||
226 | The certs and keys should be attached to private data associated with one or | |
227 | more appropriate applets for that card. Control will come to the card type | |
228 | emulators once one of its applets are selected through the VCardProcessAPDU | |
229 | function it specified when it created the applet. | |
230 | ||
231 | The signature of VCardResetApplet is: | |
232 | VCardStatus (*VCardResetApplet) (VCard *card, int channel); | |
233 | This function will reset the any internal applet state that needs to be | |
234 | cleared after a select applet call. It should return VCARD_DONE; | |
235 | ||
236 | The signature of VCardProcessAPDU is: | |
237 | VCardStatus (*VCardProcessAPDU)(VCard *card, VCardAPDU *apdu, | |
238 | VCardResponse **response); | |
239 | This function examines the APDU and determines whether it should process | |
240 | the apdu directly, reject the apdu as invalid, or pass the apdu on to | |
241 | the basic 7816 emulator for processing. | |
242 | If the 7816 emulator should process the apdu, then the VCardProcessAPDU | |
243 | should return VCARD_NEXT. | |
244 | If there is an error, then VCardProcessAPDU should return an error | |
245 | response using vcard_make_response and the appropriate 7816 error code | |
246 | (see card_7816t.h) or vcard_make_response with a card type specific error | |
247 | code. It should then return VCARD_DONE. | |
248 | If the apdu can be processed correctly, VCardProcessAPDU should do so, | |
249 | set the response value appropriately for that APDU, and return VCARD_DONE. | |
250 | VCardProcessAPDU should always set the response if it returns VCARD_DONE. | |
251 | It should always either return VCARD_DONE or VCARD_NEXT. | |
252 | ||
253 | Parsing the APDU -- | |
254 | ||
255 | Prior to processing calling the card type emulator's VCardProcessAPDU function, the emulator has already decoded the APDU header and set several fields: | |
256 | ||
257 | apdu->a_data - The raw apdu data bytes. | |
258 | apdu->a_len - The len of the raw apdu data. | |
259 | apdu->a_body - The start of any post header parameter data. | |
260 | apdu->a_Lc - The parameter length value. | |
261 | apdu->a_Le - The expected length of any returned data. | |
262 | apdu->a_cla - The raw apdu class. | |
263 | apdu->a_channel - The channel (decoded from the class). | |
e6d89f8c | 264 | apdu->a_secure_messaging_type - The decoded secure messaging type |
65794b43 RR |
265 | (from class). |
266 | apdu->a_type - The decode class type. | |
267 | apdu->a_gen_type - the generic class type (7816, PROPRIETARY, RFU, PTS). | |
268 | apdu->a_ins - The instruction byte. | |
269 | apdu->a_p1 - Parameter 1. | |
270 | apdu->a_p2 - Parameter 2. | |
271 | ||
272 | Creating a Response -- | |
273 | ||
274 | The expected result of any APDU call is a response. The card type emulator must | |
275 | set *response with an appropriate VCardResponse value if it returns VCARD_DONE. | |
e6d89f8c | 276 | Responses could be as simple as returning a 2 byte status word response, to as |
65794b43 RR |
277 | complex as returning a block of data along with a 2 byte response. Which is |
278 | returned will depend on the semantics of the APDU. The following functions will | |
279 | create card responses. | |
280 | ||
281 | VCardResponse *vcard_make_response(VCard7816Status status); | |
282 | ||
283 | This is the most basic function to get a response. This function will | |
4238e264 | 284 | return a response the consists solely one 2 byte status code. If that status |
e6d89f8c | 285 | code is defined in card_7816t.h, then this function is guaranteed to |
65794b43 RR |
286 | return a response with that status. If a cart type specific status code |
287 | is passed and vcard_make_response fails to allocate the appropriate memory | |
288 | for that response, then vcard_make_response will return a VCardResponse | |
289 | of VCARD7816_STATUS_EXC_ERROR_MEMORY. In any case, this function is | |
e6d89f8c | 290 | guaranteed to return a valid VCardResponse. |
65794b43 RR |
291 | |
292 | VCardResponse *vcard_response_new(unsigned char *buf, int len, | |
293 | VCard7816Status status); | |
294 | ||
295 | This function is similar to vcard_make_response except it includes some | |
296 | returned data with the response. It could also fail to allocate enough | |
297 | memory, in which case it will return NULL. | |
298 | ||
299 | VCardResponse *vcard_response_new_status_bytes(unsigned char sw1, | |
300 | unsigned char sw2); | |
301 | ||
302 | Sometimes in 7816 the response bytes are treated as two separate bytes with | |
303 | split meanings. This function allows you to create a response based on | |
304 | two separate bytes. This function could fail, in which case it will return | |
305 | NULL. | |
306 | ||
307 | VCardResponse *vcard_response_new_bytes(unsigned char *buf, int len, | |
308 | unsigned char sw1, | |
309 | unsigned char sw2); | |
310 | ||
311 | This function is the same as vcard_response_new except you may specify | |
312 | the status as two separate bytes like vcard_response_new_status_bytes. | |
313 | ||
314 | ||
315 | Implementing functionality --- | |
316 | ||
317 | The following helper functions access information about the current card | |
318 | and applet. | |
319 | ||
320 | VCARDAppletPrivate *vcard_get_current_applet_private(VCard *card, | |
321 | int channel); | |
322 | ||
323 | This function returns any private data set by the card type emulator on | |
324 | the currently selected applet. The card type emulator keeps track of the | |
325 | current applet state in this data structure. Any certs and keys associated | |
326 | with a particular applet is also stored here. | |
327 | ||
328 | int vcard_emul_get_login_count(VCard *card); | |
329 | ||
4238e264 | 330 | This function returns the the number of remaining login attempts for this |
65794b43 RR |
331 | card. If the card emulator does not know, or the card does not have a |
332 | way of giving this information, this function returns -1. | |
333 | ||
334 | ||
335 | VCard7816Status vcard_emul_login(VCard *card, unsigned char *pin, | |
336 | int pin_len); | |
337 | ||
4a84ebe6 | 338 | This function logs into the card and returns the standard 7816 status |
65794b43 RR |
339 | word depending on the success or failure of the call. |
340 | ||
341 | void vcard_emul_delete_key(VCardKey *key); | |
342 | ||
343 | This function frees the VCardKey passed in to xxxx_card_init. The card | |
344 | type emulator is responsible for freeing this key when it no longer needs | |
345 | it. | |
346 | ||
347 | VCard7816Status vcard_emul_rsa_op(VCard *card, VCardKey *key, | |
348 | unsigned char *buffer, | |
349 | int buffer_size); | |
350 | ||
351 | This function does a raw rsa op on the buffer with the given key. | |
352 | ||
353 | The sample card type emulator is found in cac.c. It implements the cac specific | |
354 | applets. Only those applets needed by the coolkey pkcs#11 driver on the guest | |
355 | have been implemented. To support the full range CAC middleware, a complete CAC | |
356 | card according to the CAC specs should be implemented here. | |
357 | ||
358 | ------------------------------ | |
359 | Virtual Card Emulator | |
360 | ||
361 | This code accesses both real smart cards and simulated smart cards through | |
362 | services provided on the client. The current implementation uses NSS, which | |
363 | already knows how to talk to various PKCS #11 modules on the client, and is | |
364 | portable to most operating systems. A particular emulator can have only one | |
365 | virtual card implementation at a time. | |
366 | ||
367 | The virtual card emulator consists of a series of virtual card services. In | |
368 | addition to the services describe above (services starting with | |
369 | vcard_emul_xxxx), the virtual card emulator also provides the following | |
370 | functions: | |
371 | ||
372 | VCardEmulError vcard_emul_init(cont VCardEmulOptions *options); | |
373 | ||
374 | The options structure is built by another function in the virtual card | |
375 | interface where a string of virtual card emulator specific strings are | |
4238e264 | 376 | mapped to the options. The actual structure is defined by the virtual card |
65794b43 RR |
377 | emulator and is used to determine the configuration of soft cards, or to |
378 | determine which physical cards to present to the guest. | |
379 | ||
380 | The vcard_emul_init function will build up sets of readers, create any | |
381 | threads that are needed to watch for changes in the reader state. If readers | |
382 | have cards present in them, they are also initialized. | |
383 | ||
384 | Readers are created with the function. | |
385 | ||
386 | VReader *vreader_new(VReaderEmul *reader_emul, | |
387 | VReaderEmulFree reader_emul_free); | |
388 | ||
389 | The freeFunc is used to free the VReaderEmul * when the reader is | |
390 | destroyed. The VReaderEmul structure is an opaque structure to the | |
391 | rest of the code, but defined by the virtual card emulator, which can | |
392 | use it to store any reader specific state. | |
393 | ||
394 | Once the reader has been created, it can be added to the front end with the | |
395 | call: | |
396 | ||
397 | VReaderStatus vreader_add_reader(VReader *reader); | |
398 | ||
399 | This function will automatically generate the appropriate new reader | |
400 | events and add the reader to the list. | |
401 | ||
b5e4946f | 402 | To create a new card, the virtual card emulator will call a similar |
65794b43 RR |
403 | function. |
404 | ||
405 | VCard *vcard_new(VCardEmul *card_emul, | |
406 | VCardEmulFree card_emul_free); | |
407 | ||
408 | Like vreader_new, this function takes a virtual card emulator specific | |
409 | structure which it uses to keep track of the card state. | |
410 | ||
411 | Once the card is created, it is attached to a card type emulator with the | |
412 | following function: | |
413 | ||
414 | VCardStatus vcard_init(VCard *vcard, VCardEmulType type, | |
415 | const char *flags, | |
416 | unsigned char *const *certs, | |
417 | int *cert_len, | |
418 | VCardKey *key[], | |
419 | int cert_count); | |
420 | ||
421 | The vcard is the value returned from vcard_new. The type is the | |
422 | card type emulator that this card should presented to the guest as. | |
423 | The flags are card type emulator specific options. The certs, | |
424 | cert_len, and keys are all arrays of length cert_count. These are the | |
425 | the same of the parameters xxxx_card_init() accepts. | |
426 | ||
4a84ebe6 | 427 | Finally the card is associated with its reader by the call: |
65794b43 RR |
428 | |
429 | VReaderStatus vreader_insert_card(VReader *vreader, VCard *vcard); | |
430 | ||
431 | This function, like vreader_add_reader, will take care of any event | |
432 | notification for the card insert. | |
433 | ||
434 | ||
435 | VCardEmulError vcard_emul_force_card_remove(VReader *vreader); | |
436 | ||
437 | Force a card that is present to appear to be removed to the guest, even if | |
438 | that card is a physical card and is present. | |
439 | ||
440 | ||
441 | VCardEmulError vcard_emul_force_card_insert(VReader *reader); | |
442 | ||
443 | Force a card that has been removed by vcard_emul_force_card_remove to be | |
444 | reinserted from the point of view of the guest. This will only work if the | |
445 | card is physically present (which is always true fro a soft card). | |
446 | ||
447 | void vcard_emul_get_atr(Vcard *card, unsigned char *atr, int *atr_len); | |
448 | ||
449 | Return the virtual ATR for the card. By convention this should be the value | |
450 | VCARD_ATR_PREFIX(size) followed by several ascii bytes related to this | |
451 | particular emulator. For instance the NSS emulator returns | |
452 | {VCARD_ATR_PREFIX(3), 'N', 'S', 'S' }. Do ot return more data then *atr_len; | |
453 | ||
454 | void vcard_emul_reset(VCard *card, VCardPower power) | |
455 | ||
456 | Set the state of 'card' to the current power level and reset its internal | |
457 | state (logout, etc). | |
458 | ||
459 | ------------------------------------------------------- | |
460 | List of files and their function: | |
461 | README - This file | |
462 | card_7816.c - emulate basic 7816 functionality. Parse APDUs. | |
463 | card_7816.h - apdu and response services definitions. | |
464 | card_7816t.h - 7816 specific structures, types and definitions. | |
465 | event.c - event handling code. | |
466 | event.h - event handling services definitions. | |
467 | eventt.h - event handling structures and types | |
468 | vcard.c - handle common virtual card services like creation, destruction, and | |
469 | applet management. | |
470 | vcard.h - common virtual card services function definitions. | |
471 | vcardt.h - comon virtual card types | |
472 | vreader.c - common virtual reader services. | |
473 | vreader.h - common virtual reader services definitions. | |
474 | vreadert.h - comon virtual reader types. | |
475 | vcard_emul_type.c - manage the card type emulators. | |
476 | vcard_emul_type.h - definitions for card type emulators. | |
477 | cac.c - card type emulator for CAC cards | |
478 | vcard_emul.h - virtual card emulator service definitions. | |
479 | vcard_emul_nss.c - virtual card emulator implementation for nss. | |
480 | vscclient.c - socket connection to guest qemu usb driver. | |
481 | vscard_common.h - common header with the guest qemu usb driver. | |
482 | mutex.h - header file for machine independent mutexes. | |
483 | link_test.c - static test to make sure all the symbols are properly defined. |