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 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 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.
