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 replacable 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 replacable 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 it's own implementation that connects to it's 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 it's reference when it is
  finished with vreader_free().

      void vreader_free(VReader *reader);

   This function frees a reference to a reader. Reader's 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 functions simulates a card power on. Virtual cards do 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 functions send 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 it's aid, and then commands will be
  routed to it VCardProcessAPDU function. This function adopts the applet the
  passed int applet. Note: 2 applets with the same AID should not be added to
  the same card. It's 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 logins into the card and return 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 it's 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.
