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.
