mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 04:06:46 +00:00 
			
		
		
		
	 4a84ebe6a6
			
		
	
	
		4a84ebe6a6
		
	
	
	
	
		
			
			* it's -> its * it's -> it is (that's no fix, but makes future checks easier) * this functions -> this function * replacable -> replaceable * reader's -> readers * logins into -> logs into v2: Also replace 'aid' by 'AID' (thanks to Peter Maydell for this hint). v3: Fix sentence (contributed by Alon Levy / Robert Relyea). Cc: Alon Levy <alevy@redhat.com> Cc: Robert Relyea <rrelyea@redhat.com> Cc: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Stefan Weil <sw@weilnetz.de> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
		
			
				
	
	
		
			484 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			484 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| This file documents the CAC (Common Access Card) library in the libcacard
 | |
| subdirectory.
 | |
| 
 | |
| Virtual Smart Card Emulator
 | |
| 
 | |
| This emulator is designed to provide emulation of actual smart cards to a
 | |
| virtual card reader running in a guest virtual machine. The emulated smart
 | |
| cards can be representations of real smart cards, where the necessary functions
 | |
| such as signing, card removal/insertion, etc. are mapped to real, physical
 | |
| cards which are shared with the client machine the emulator is running on, or
 | |
| the cards could be pure software constructs.
 | |
| 
 | |
| The emulator is structured to allow multiple replaceable or additional pieces,
 | |
| so it can be easily modified for future requirements. The primary envisioned
 | |
| modifications are:
 | |
| 
 | |
| 1) The socket connection to the virtual card reader (presumably a CCID reader,
 | |
| but other ISO-7816 compatible readers could be used). The code that handles
 | |
| this is in vscclient.c.
 | |
| 
 | |
| 2) The virtual card low level emulation. This is currently supplied by using
 | |
| NSS. This emulation could be replaced by implementations based on other
 | |
| security libraries, including but not limitted to openssl+pkcs#11 library,
 | |
| raw pkcs#11, Microsoft CAPI, direct opensc calls, etc. The code that handles
 | |
| this is in vcard_emul_nss.c.
 | |
| 
 | |
| 3) Emulation for new types of cards. The current implementation emulates the
 | |
| original DoD CAC standard with separate pki containers. This emulator lives in
 | |
| cac.c. More than one card type emulator could be included. Other cards could
 | |
| be emulated as well, including PIV, newer versions of CAC, PKCS #15, etc.
 | |
| 
 | |
| --------------------
 | |
| Replacing the Socket Based Virtual Reader Interface.
 | |
| 
 | |
| The current implementation contains a replaceable module vscclient.c. The
 | |
| current vscclient.c implements a sockets interface to the virtual ccid reader
 | |
| on the guest. CCID commands that are pertinent to emulation are passed
 | |
| across the socket, and their responses are passed back along that same socket.
 | |
| The protocol that vscclient uses is defined in vscard_common.h and connects
 | |
| to a qemu ccid usb device. Since this socket runs as a client, vscclient.c
 | |
| implements a program with a main entry. It also handles argument parsing for
 | |
| the emulator.
 | |
| 
 | |
| An application that wants to use the virtual reader can replace vscclient.c
 | |
| with its own implementation that connects to its own CCID reader.  The calls
 | |
| that the CCID reader can call are:
 | |
| 
 | |
|       VReaderList * vreader_get_reader_list();
 | |
| 
 | |
|   This function returns a list of virtual readers.  These readers may map to
 | |
|   physical devices, or simulated devices depending on vcard the back end. Each
 | |
|   reader in the list should represent a reader to the virtual machine. Virtual
 | |
|   USB address mapping is left to the CCID reader front end. This call can be
 | |
|   made any time to get an updated list. The returned list is a copy of the
 | |
|   internal list that can be referenced by the caller without locking. This copy
 | |
|   must be freed by the caller with vreader_list_delete when it is no longer
 | |
|   needed.
 | |
| 
 | |
|       VReaderListEntry *vreader_list_get_first(VReaderList *);
 | |
| 
 | |
|   This function gets the first entry on the reader list. Along with
 | |
|   vreader_list_get_next(), vreader_list_get_first() can be used to walk the
 | |
|   reader list returned from vreader_get_reader_list(). VReaderListEntries are
 | |
|   part of the list themselves and do not need to be freed separately from the
 | |
|   list. If there are no entries on the list, it will return NULL.
 | |
| 
 | |
|       VReaderListEntry *vreader_list_get_next(VReaderListEntry *);
 | |
| 
 | |
|   This function gets the next entry in the list. If there are no more entries
 | |
|   it will return NULL.
 | |
| 
 | |
|       VReader * vreader_list_get_reader(VReaderListEntry *)
 | |
| 
 | |
|   This function returns the reader stored in the reader List entry. Caller gets
 | |
|   a new reference to a reader. The caller must free its reference when it is
 | |
|   finished with vreader_free().
 | |
| 
 | |
|       void vreader_free(VReader *reader);
 | |
| 
 | |
|    This function frees a reference to a reader. Readers are reference counted
 | |
|    and are automatically deleted when the last reference is freed.
 | |
| 
 | |
|       void vreader_list_delete(VReaderList *list);
 | |
| 
 | |
|    This function frees the list, all the elements on the list, and all the
 | |
|    reader references held by the list.
 | |
| 
 | |
|       VReaderStatus vreader_power_on(VReader *reader, char *atr, int *len);
 | |
| 
 | |
|   This function simulates a card power on. A virtual card does not care about
 | |
|   the actual voltage and other physical parameters, but it does care that the
 | |
|   card is actually on or off. Cycling the card causes the card to reset. If
 | |
|   the caller provides enough space, vreader_power_on will return the ATR of
 | |
|   the virtual card. The amount of space provided in atr should be indicated
 | |
|   in *len. The function modifies *len to be the actual length of of the
 | |
|   returned ATR.
 | |
| 
 | |
|       VReaderStatus vreader_power_off(VReader *reader);
 | |
| 
 | |
|   This function simulates a power off of a virtual card.
 | |
| 
 | |
|       VReaderStatus vreader_xfer_bytes(VReader *reader, unsigne char *send_buf,
 | |
|                                        int send_buf_len,
 | |
|                                        unsigned char *receive_buf,
 | |
|                                        int receive_buf_len);
 | |
| 
 | |
|   This function sends a raw apdu to a card and returns the card's response.
 | |
|   The CCID front end should return the response back. Most of the emulation
 | |
|   is driven from these APDUs.
 | |
| 
 | |
|       VReaderStatus vreader_card_is_present(VReader *reader);
 | |
| 
 | |
|   This function returns whether or not the reader has a card inserted. The
 | |
|   vreader_power_on, vreader_power_off, and vreader_xfer_bytes will return
 | |
|   VREADER_NO_CARD.
 | |
| 
 | |
|        const char *vreader_get_name(VReader *reader);
 | |
| 
 | |
|   This function returns the name of the reader. The name comes from the card
 | |
|   emulator level and is usually related to the name of the physical reader.
 | |
| 
 | |
|        VReaderID vreader_get_id(VReader *reader);
 | |
| 
 | |
|   This function returns the id of a reader. All readers start out with an id
 | |
|   of -1. The application can set the id with vreader_set_id.
 | |
| 
 | |
|        VReaderStatus vreader_get_id(VReader *reader, VReaderID id);
 | |
| 
 | |
|   This function sets the reader id. The application is responsible for making
 | |
|   sure that the id is unique for all readers it is actively using.
 | |
| 
 | |
|        VReader *vreader_find_reader_by_id(VReaderID id);
 | |
| 
 | |
|   This function returns the reader which matches the id. If two readers match,
 | |
|   only one is returned. The function returns NULL if the id is -1.
 | |
| 
 | |
|        Event *vevent_wait_next_vevent();
 | |
| 
 | |
|   This function blocks waiting for reader and card insertion events. There
 | |
|   will be one event for each card insertion, each card removal, each reader
 | |
|   insertion and each reader removal. At start up, events are created for all
 | |
|   the initial readers found, as well as all the cards that are inserted.
 | |
| 
 | |
|        Event *vevent_get_next_vevent();
 | |
| 
 | |
|   This function returns a pending event if it exists, otherwise it returns
 | |
|   NULL. It does not block.
 | |
| 
 | |
| ----------------
 | |
| Card Type Emulator: Adding a New Virtual Card Type
 | |
| 
 | |
| The ISO 7816 card spec describes 2 types of cards:
 | |
|  1) File system cards, where the smartcard is managed by reading and writing
 | |
| data to files in a file system. There is currently only boiler plate
 | |
| implemented for file system cards.
 | |
|  2) VM cards, where the card has loadable applets which perform the card
 | |
| functions. The current implementation supports VM cards.
 | |
| 
 | |
| In the case of VM cards, the difference between various types of cards is
 | |
| really what applets have been installed in that card. This structure is
 | |
| mirrored in card type emulators. The 7816 emulator already handles the basic
 | |
| ISO 7186 commands. Card type emulators simply need to add the virtual applets
 | |
| which emulate the real card applets. Card type emulators have exactly one
 | |
| public entry point:
 | |
| 
 | |
|        VCARDStatus xxx_card_init(VCard *card, const char *flags,
 | |
|                                const unsigned char *cert[],
 | |
|                                int cert_len[],
 | |
|                                VCardKey *key[],
 | |
|                                int cert_count);
 | |
| 
 | |
|   The parameters for this are:
 | |
|   card       - the virtual card structure which will represent this card.
 | |
|   flags      - option flags that may be specific to this card type.
 | |
|   cert       - array of binary certificates.
 | |
|   cert_len   - array of lengths of each of the certificates specified in cert.
 | |
|   key        - array of opaque key structures representing the private keys on
 | |
|                the card.
 | |
|   cert_count - number of entries in cert, cert_len, and key arrays.
 | |
| 
 | |
|   Any cert, cert_len, or key with the same index are matching sets. That is
 | |
|   cert[0] is cert_len[0] long and has the corresponding private key of key[0].
 | |
| 
 | |
| The card type emulator is expected to own the VCardKeys, but it should copy
 | |
| any raw cert data it wants to save. It can create new applets and add them to
 | |
| the card using the following functions:
 | |
| 
 | |
|        VCardApplet *vcard_new_applet(VCardProcessAPDU apdu_func,
 | |
|                                      VCardResetApplet reset_func,
 | |
|                                      const unsigned char *aid,
 | |
|                                      int aid_len);
 | |
| 
 | |
|   This function creates a new applet. Applet structures store the following
 | |
|   information:
 | |
|      1) the AID of the applet (set by aid and aid_len).
 | |
|      2) a function to handle APDUs for this applet. (set by apdu_func, more on
 | |
|         this below).
 | |
|      3) a function to reset the applet state when the applet is selected.
 | |
|         (set by reset_func, more on this below).
 | |
|      3) applet private data, a data pointer used by the card type emulator to
 | |
|         store any data or state it needs to complete requests. (set by a
 | |
|         separate call).
 | |
|      4) applet private data free, a function used to free the applet private
 | |
|         data when the applet itself is destroyed.
 | |
|   The created applet can be added to the card with vcard_add_applet below.
 | |
| 
 | |
|         void vcard_set_applet_private(VCardApplet *applet,
 | |
|                                       VCardAppletPrivate *private,
 | |
|                                       VCardAppletPrivateFree private_free);
 | |
|   This function sets the private data and the corresponding free function.
 | |
|   VCardAppletPrivate is an opaque data structure to the rest of the emulator.
 | |
|   The card type emulator can define it any way it wants by defining
 | |
|   struct VCardAppletPrivateStruct {};. If there is already a private data
 | |
|   structure on the applet, the old one is freed before the new one is set up.
 | |
|   passing two NULL clear any existing private data.
 | |
| 
 | |
|          VCardStatus vcard_add_applet(VCard *card, VCardApplet *applet);
 | |
| 
 | |
|   Add an applet onto the list of applets attached to the card. Once an applet
 | |
|   has been added, it can be selected by its AID, and then commands will be
 | |
|   routed to it VCardProcessAPDU function. This function adopts the applet that
 | |
|   is passed into it. Note: 2 applets with the same AID should not be added to
 | |
|   the same card. It is permissible to add more than one applet. Multiple applets
 | |
|   may have the same VCardPRocessAPDU entry point.
 | |
| 
 | |
| The certs and keys should be attached to private data associated with one or
 | |
| more appropriate applets for that card. Control will come to the card type
 | |
| emulators once one of its applets are selected through the VCardProcessAPDU
 | |
| function it specified when it created the applet.
 | |
| 
 | |
| The signature of VCardResetApplet is:
 | |
|         VCardStatus (*VCardResetApplet) (VCard *card, int channel);
 | |
|   This function will reset the any internal applet state that needs to be
 | |
|   cleared after a select applet call. It should return VCARD_DONE;
 | |
| 
 | |
| The signature of VCardProcessAPDU is:
 | |
|         VCardStatus (*VCardProcessAPDU)(VCard *card, VCardAPDU *apdu,
 | |
|                                          VCardResponse **response);
 | |
|   This function examines the APDU and determines whether it should process
 | |
|   the apdu directly, reject the apdu as invalid, or pass the apdu on to
 | |
|   the basic 7816 emulator for processing.
 | |
|       If the 7816 emulator should process the apdu, then the VCardProcessAPDU
 | |
|   should return VCARD_NEXT.
 | |
|       If there is an error, then VCardProcessAPDU should return an error
 | |
|   response using vcard_make_response and the appropriate 7816 error code
 | |
|   (see card_7816t.h) or vcard_make_response with a card type specific error
 | |
|   code. It should then return VCARD_DONE.
 | |
|       If the apdu can be processed correctly, VCardProcessAPDU should do so,
 | |
|   set the response value appropriately for that APDU, and return VCARD_DONE.
 | |
|   VCardProcessAPDU should always set the response if it returns VCARD_DONE.
 | |
|   It should always either return VCARD_DONE or VCARD_NEXT.
 | |
| 
 | |
| Parsing the APDU --
 | |
| 
 | |
| Prior to processing calling the card type emulator's VCardProcessAPDU function, the emulator has already decoded the APDU header and set several fields:
 | |
| 
 | |
|    apdu->a_data - The raw apdu data bytes.
 | |
|    apdu->a_len  - The len of the raw apdu data.
 | |
|    apdu->a_body - The start of any post header parameter data.
 | |
|    apdu->a_Lc   - The parameter length value.
 | |
|    apdu->a_Le   - The expected length of any returned data.
 | |
|    apdu->a_cla  - The raw apdu class.
 | |
|    apdu->a_channel - The channel (decoded from the class).
 | |
|    apdu->a_secure_messaging_type - The decoded secure messaging type
 | |
|                                    (from class).
 | |
|    apdu->a_type - The decode class type.
 | |
|    apdu->a_gen_type - the generic class type (7816, PROPRIETARY, RFU, PTS).
 | |
|    apdu->a_ins  - The instruction byte.
 | |
|    apdu->a_p1   - Parameter 1.
 | |
|    apdu->a_p2   - Parameter 2.
 | |
| 
 | |
| Creating a Response --
 | |
| 
 | |
| The expected result of any APDU call is a response. The card type emulator must
 | |
| set *response with an appropriate VCardResponse value if it returns VCARD_DONE.
 | |
| Responses could be as simple as returning a 2 byte status word response, to as
 | |
| complex as returning a block of data along with a 2 byte response. Which is
 | |
| returned will depend on the semantics of the APDU. The following functions will
 | |
| create card responses.
 | |
| 
 | |
|         VCardResponse *vcard_make_response(VCard7816Status status);
 | |
| 
 | |
|     This is the most basic function to get a response. This function will
 | |
|     return a response the consists solely one 2 byte status code. If that status
 | |
|     code is defined in card_7816t.h, then this function is guaranteed to
 | |
|     return a response with that status. If a cart type specific status code
 | |
|     is passed and vcard_make_response fails to allocate the appropriate memory
 | |
|     for that response, then vcard_make_response will return a VCardResponse
 | |
|     of VCARD7816_STATUS_EXC_ERROR_MEMORY. In any case, this function is
 | |
|     guaranteed to return a valid VCardResponse.
 | |
| 
 | |
|         VCardResponse *vcard_response_new(unsigned char *buf, int len,
 | |
|                                           VCard7816Status status);
 | |
| 
 | |
|     This function is similar to vcard_make_response except it includes some
 | |
|     returned data with the response. It could also fail to allocate enough
 | |
|     memory, in which case it will return NULL.
 | |
| 
 | |
|         VCardResponse *vcard_response_new_status_bytes(unsigned char sw1,
 | |
|                                                        unsigned char sw2);
 | |
| 
 | |
|     Sometimes in 7816 the response bytes are treated as two separate bytes with
 | |
|     split meanings. This function allows you to create a response based on
 | |
|     two separate bytes. This function could fail, in which case it will return
 | |
|     NULL.
 | |
| 
 | |
|        VCardResponse *vcard_response_new_bytes(unsigned char *buf, int len,
 | |
|                                                unsigned char sw1,
 | |
|                                                unsigned char sw2);
 | |
| 
 | |
|     This function is the same as vcard_response_new except you may specify
 | |
|     the status as two separate bytes like vcard_response_new_status_bytes.
 | |
| 
 | |
| 
 | |
| Implementing functionality ---
 | |
| 
 | |
| The following helper functions access information about the current card
 | |
| and applet.
 | |
| 
 | |
|         VCARDAppletPrivate *vcard_get_current_applet_private(VCard *card,
 | |
|                                                              int channel);
 | |
| 
 | |
|     This function returns any private data set by the card type emulator on
 | |
|     the currently selected applet. The card type emulator keeps track of the
 | |
|     current applet state in this data structure. Any certs and keys associated
 | |
|     with a particular applet is also stored here.
 | |
| 
 | |
|         int vcard_emul_get_login_count(VCard *card);
 | |
| 
 | |
|     This function returns the the number of remaining login attempts for this
 | |
|     card. If the card emulator does not know, or the card does not have a
 | |
|     way of giving this information, this function returns -1.
 | |
| 
 | |
| 
 | |
|          VCard7816Status vcard_emul_login(VCard *card, unsigned char *pin,
 | |
|                                           int pin_len);
 | |
| 
 | |
|     This function logs into the card and returns the standard 7816 status
 | |
|     word depending on the success or failure of the call.
 | |
| 
 | |
|          void vcard_emul_delete_key(VCardKey *key);
 | |
| 
 | |
|      This function frees the VCardKey passed in to xxxx_card_init. The card
 | |
|      type emulator is responsible for freeing this key when it no longer needs
 | |
|      it.
 | |
| 
 | |
|          VCard7816Status vcard_emul_rsa_op(VCard *card, VCardKey *key,
 | |
|                                            unsigned char *buffer,
 | |
|                                            int buffer_size);
 | |
| 
 | |
|      This function does a raw rsa op on the buffer with the given key.
 | |
| 
 | |
| The sample card type emulator is found in cac.c. It implements the cac specific
 | |
| applets.  Only those applets needed by the coolkey pkcs#11 driver on the guest
 | |
| have been implemented. To support the full range CAC middleware, a complete CAC
 | |
| card according to the CAC specs should be implemented here.
 | |
| 
 | |
| ------------------------------
 | |
| Virtual Card Emulator
 | |
| 
 | |
| This code accesses both real smart cards and simulated smart cards through
 | |
| services provided on the client. The current implementation uses NSS, which
 | |
| already knows how to talk to various PKCS #11 modules on the client, and is
 | |
| portable to most operating systems. A particular emulator can have only one
 | |
| virtual card implementation at a time.
 | |
| 
 | |
| The virtual card emulator consists of a series of virtual card services. In
 | |
| addition to the services describe above (services starting with
 | |
| vcard_emul_xxxx), the virtual card emulator also provides the following
 | |
| functions:
 | |
| 
 | |
|     VCardEmulError vcard_emul_init(cont VCardEmulOptions *options);
 | |
| 
 | |
|   The options structure is built by another function in the virtual card
 | |
|   interface where a string of virtual card emulator specific strings are
 | |
|   mapped to the options. The actual structure is defined by the virtual card
 | |
|   emulator and is used to determine the configuration of soft cards, or to
 | |
|   determine which physical cards to present to the guest.
 | |
| 
 | |
|   The vcard_emul_init function will build up sets of readers, create any
 | |
|   threads that are needed to watch for changes in the reader state. If readers
 | |
|   have cards present in them, they are also initialized.
 | |
| 
 | |
|   Readers are created with the function.
 | |
| 
 | |
|           VReader *vreader_new(VReaderEmul *reader_emul,
 | |
|                                VReaderEmulFree reader_emul_free);
 | |
| 
 | |
|       The freeFunc is used to free the VReaderEmul * when the reader is
 | |
|       destroyed.  The VReaderEmul structure is an opaque structure to the
 | |
|       rest of the code, but defined by the virtual card emulator, which can
 | |
|       use it to store any reader specific state.
 | |
| 
 | |
|   Once the reader has been created, it can be added to the front end with the
 | |
|   call:
 | |
| 
 | |
|            VReaderStatus vreader_add_reader(VReader *reader);
 | |
| 
 | |
|       This function will automatically generate the appropriate new reader
 | |
|       events and add the reader to the list.
 | |
| 
 | |
|   To create a new card, the virtual card emulator will call a similar
 | |
|   function.
 | |
| 
 | |
|            VCard *vcard_new(VCardEmul *card_emul,
 | |
|                             VCardEmulFree card_emul_free);
 | |
| 
 | |
|       Like vreader_new, this function takes a virtual card emulator specific
 | |
|       structure which it uses to keep track of the card state.
 | |
| 
 | |
|   Once the card is created, it is attached to a card type emulator with the
 | |
|   following function:
 | |
| 
 | |
|             VCardStatus vcard_init(VCard *vcard, VCardEmulType type,
 | |
|                                    const char *flags,
 | |
|                                    unsigned char *const *certs,
 | |
|                                    int *cert_len,
 | |
|                                    VCardKey *key[],
 | |
|                                    int cert_count);
 | |
| 
 | |
|       The vcard is the value returned from vcard_new. The type is the
 | |
|       card type emulator that this card should presented to the guest as.
 | |
|       The flags are card type emulator specific options. The certs,
 | |
|       cert_len, and keys are all arrays of length cert_count. These are the
 | |
|       the same of the parameters xxxx_card_init() accepts.
 | |
| 
 | |
|    Finally the card is associated with its reader by the call:
 | |
| 
 | |
|             VReaderStatus vreader_insert_card(VReader *vreader, VCard *vcard);
 | |
| 
 | |
|       This function, like vreader_add_reader, will take care of any event
 | |
|       notification for the card insert.
 | |
| 
 | |
| 
 | |
|     VCardEmulError vcard_emul_force_card_remove(VReader *vreader);
 | |
| 
 | |
|   Force a card that is present to appear to be removed to the guest, even if
 | |
|   that card is a physical card and is present.
 | |
| 
 | |
| 
 | |
|     VCardEmulError vcard_emul_force_card_insert(VReader *reader);
 | |
| 
 | |
|   Force a card that has been removed by vcard_emul_force_card_remove to be
 | |
|   reinserted from the point of view of the guest. This will only work if the
 | |
|   card is physically present (which is always true fro a soft card).
 | |
| 
 | |
|      void vcard_emul_get_atr(Vcard *card, unsigned char *atr, int *atr_len);
 | |
| 
 | |
|   Return the virtual ATR for the card. By convention this should be the value
 | |
|   VCARD_ATR_PREFIX(size) followed by several ascii bytes related to this
 | |
|   particular emulator. For instance the NSS emulator returns
 | |
|   {VCARD_ATR_PREFIX(3), 'N', 'S', 'S' }. Do ot return more data then *atr_len;
 | |
| 
 | |
|      void vcard_emul_reset(VCard *card, VCardPower power)
 | |
| 
 | |
|    Set the state of 'card' to the current power level and reset its internal
 | |
|    state (logout, etc).
 | |
| 
 | |
| -------------------------------------------------------
 | |
| List of files and their function:
 | |
| README - This file
 | |
| card_7816.c - emulate basic 7816 functionality. Parse APDUs.
 | |
| card_7816.h - apdu and response services definitions.
 | |
| card_7816t.h - 7816 specific structures, types and definitions.
 | |
| event.c - event handling code.
 | |
| event.h - event handling services definitions.
 | |
| eventt.h - event handling structures and types
 | |
| vcard.c - handle common virtual card services like creation, destruction, and
 | |
|           applet management.
 | |
| vcard.h - common virtual card services function definitions.
 | |
| vcardt.h - comon virtual card types
 | |
| vreader.c - common virtual reader services.
 | |
| vreader.h - common virtual reader services definitions.
 | |
| vreadert.h - comon virtual reader types.
 | |
| vcard_emul_type.c - manage the card type emulators.
 | |
| vcard_emul_type.h - definitions for card type emulators.
 | |
| cac.c - card type emulator for CAC cards
 | |
| vcard_emul.h - virtual card emulator service definitions.
 | |
| vcard_emul_nss.c - virtual card emulator implementation for nss.
 | |
| vscclient.c - socket connection to guest qemu usb driver.
 | |
| vscard_common.h - common header with the guest qemu usb driver.
 | |
| mutex.h - header file for machine independent mutexes.
 | |
| link_test.c - static test to make sure all the symbols are properly defined.
 |