Robert Relyea | 65794b4 | 2011-03-17 16:39:46 +0200 | [diff] [blame] | 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 | |
| 13 | The emulator is structured to allow multiple replacable or additional pieces, |
| 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 | |
| 35 | The current implementation contains a replacable module vscclient.c. The |
| 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 |
| 45 | with it's own implementation that connects to it's own CCID reader. The calls |
| 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 |
| 75 | a new reference to a reader. The caller must free it's reference when it is |
| 76 | finished with vreader_free(). |
| 77 | |
| 78 | void vreader_free(VReader *reader); |
| 79 | |
| 80 | This function frees a reference to a reader. Reader's are reference counted |
| 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 | |
| 90 | This functions simulates a card power on. Virtual cards do not care about |
| 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 | |
| 107 | This functions send a raw apdu to a card and returns the card's response. |
| 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: |
| 173 | card - the virtual card structure which will prepresent this card. |
| 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 |
| 182 | cert[0] is cert_len[0] long and has the corresponsing private key of key[0]. |
| 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 |
| 220 | has been added, it can be selected by it's aid, and then commands will be |
| 221 | routed to it VCardProcessAPDU function. This function adopts the applet the |
| 222 | passed int applet. Note: 2 applets with the same AID should not be added to |
| 223 | the same card. It's permissible to add more than one applet. Multiple applets |
| 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). |
| 264 | apdu->a_secure_messaging_type - The decoded secure messagin type |
| 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. |
| 276 | Reponses could be as simple as returning a 2 byte status word response, to as |
| 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 |
| 284 | return a response the consists soley one 2 byte status code. If that status |
| 285 | code is defined in card_7816t.h, then this function is guarrenteed to |
| 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 |
| 290 | guarrenteed to return a valid VCardResponse. |
| 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 | |
| 330 | This function returns the the number of remaing login attempts for this |
| 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 | |
| 338 | This function logins into the card and return the standard 7816 status |
| 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 |
| 376 | mapped to the options. The actual structure is defined by the virutal card |
| 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 | |
| 402 | To create a new card, the virtual card emulator will call a similiar |
| 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 | |
| 427 | Finally the card is associated with it's reader by the call: |
| 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. |