/*
 * This is the actual card emulator.
 *
 * These functions can be implemented in different ways on different platforms
 * using the underlying system primitives. For Linux it uses NSS, though direct
 * to PKCS #11, openssl+pkcs11, or even gnu crypto libraries+pkcs #11 could be
 * used. On Windows CAPI could be used.
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 */

/*
 * NSS headers
 */

/* avoid including prototypes.h that redefines uint32 */
#define NO_NSPR_10_SUPPORT

#include <nss.h>
#include <pk11pub.h>
#include <cert.h>
#include <key.h>
#include <secmod.h>
#include <prthread.h>
#include <secerr.h>

#include "qemu-common.h"

#include "vcard.h"
#include "card_7816t.h"
#include "vcard_emul.h"
#include "vreader.h"
#include "vevent.h"

#include "libcacard/vcardt_internal.h"


typedef enum {
    VCardEmulUnknown = -1,
    VCardEmulFalse = 0,
    VCardEmulTrue = 1
} VCardEmulTriState;

struct VCardKeyStruct {
    CERTCertificate *cert;
    PK11SlotInfo *slot;
    SECKEYPrivateKey *key;
    VCardEmulTriState failedX509;
};


typedef struct VirtualReaderOptionsStruct VirtualReaderOptions;

struct VReaderEmulStruct {
    PK11SlotInfo *slot;
    VCardEmulType default_type;
    char *type_params;
    PRBool present;
    int     series;
    VCard *saved_vcard;
};

/*
 *  NSS Specific options
 */
struct VirtualReaderOptionsStruct {
    char *name;
    char *vname;
    VCardEmulType card_type;
    char *type_params;
    char **cert_name;
    int cert_count;
};

struct VCardEmulOptionsStruct {
    void *nss_db;
    VirtualReaderOptions *vreader;
    int vreader_count;
    VCardEmulType hw_card_type;
    const char *hw_type_params;
    PRBool use_hw;
};

static int nss_emul_init;

/* if we have more that just the slot, define
 * VCardEmulStruct here */

/*
 * allocate the set of arrays for certs, cert_len, key
 */
static void
vcard_emul_alloc_arrays(unsigned char ***certsp, int **cert_lenp,
                        VCardKey ***keysp, int cert_count)
{
    *certsp = (unsigned char **)g_malloc(sizeof(unsigned char *)*cert_count);
    *cert_lenp = (int *)g_malloc(sizeof(int)*cert_count);
    *keysp = (VCardKey **)g_malloc(sizeof(VCardKey *)*cert_count);
}

/*
 * Emulator specific card information
 */
typedef struct CardEmulCardStruct CardEmulPrivate;

static VCardEmul *
vcard_emul_new_card(PK11SlotInfo *slot)
{
    PK11_ReferenceSlot(slot);
    /* currently we don't need anything other than the slot */
    return (VCardEmul *)slot;
}

static void
vcard_emul_delete_card(VCardEmul *vcard_emul)
{
    PK11SlotInfo *slot = (PK11SlotInfo *)vcard_emul;
    if (slot == NULL) {
        return;
    }
    PK11_FreeSlot(slot);
}

static PK11SlotInfo *
vcard_emul_card_get_slot(VCard *card)
{
    /* note, the card is holding the reference, no need to get another one */
    return (PK11SlotInfo *)vcard_get_private(card);
}


/*
 * key functions
 */
/* private constructure */
static VCardKey *
vcard_emul_make_key(PK11SlotInfo *slot, CERTCertificate *cert)
{
    VCardKey *key;

    key = (VCardKey *)g_malloc(sizeof(VCardKey));
    key->slot = PK11_ReferenceSlot(slot);
    key->cert = CERT_DupCertificate(cert);
    /* NOTE: if we aren't logged into the token, this could return NULL */
    /* NOTE: the cert is a temp cert, not necessarily the cert in the token,
     * use the DER version of this function */
    key->key = PK11_FindKeyByDERCert(slot, cert, NULL);
    key->failedX509 = VCardEmulUnknown;
    return key;
}

/* destructor */
void
vcard_emul_delete_key(VCardKey *key)
{
    if (!nss_emul_init || (key == NULL)) {
        return;
    }
    if (key->key) {
        SECKEY_DestroyPrivateKey(key->key);
        key->key = NULL;
    }
    if (key->cert) {
        CERT_DestroyCertificate(key->cert);
    }
    if (key->slot) {
        PK11_FreeSlot(key->slot);
    }
}

/*
 * grab the nss key from a VCardKey. If it doesn't exist, try to look it up
 */
static SECKEYPrivateKey *
vcard_emul_get_nss_key(VCardKey *key)
{
    if (key->key) {
        return key->key;
    }
    /* NOTE: if we aren't logged into the token, this could return NULL */
    key->key = PK11_FindPrivateKeyFromCert(key->slot, key->cert, NULL);
    return key->key;
}

/*
 * Map NSS errors to 7816 errors
 */
static vcard_7816_status_t
vcard_emul_map_error(int error)
{
    switch (error) {
    case SEC_ERROR_TOKEN_NOT_LOGGED_IN:
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    case SEC_ERROR_BAD_DATA:
    case SEC_ERROR_OUTPUT_LEN:
    case SEC_ERROR_INPUT_LEN:
    case SEC_ERROR_INVALID_ARGS:
    case SEC_ERROR_INVALID_ALGORITHM:
    case SEC_ERROR_NO_KEY:
    case SEC_ERROR_INVALID_KEY:
    case SEC_ERROR_DECRYPTION_DISALLOWED:
        return VCARD7816_STATUS_ERROR_DATA_INVALID;
    case SEC_ERROR_NO_MEMORY:
        return VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE;
    }
    return VCARD7816_STATUS_EXC_ERROR_CHANGE;
}

/* RSA sign/decrypt with the key, signature happens 'in place' */
vcard_7816_status_t
vcard_emul_rsa_op(VCard *card, VCardKey *key,
                  unsigned char *buffer, int buffer_size)
{
    SECKEYPrivateKey *priv_key;
    unsigned signature_len;
    PK11SlotInfo *slot;
    SECStatus rv;
    unsigned char buf[2048];
    unsigned char *bp = NULL;
    int pad_len;
    vcard_7816_status_t ret = VCARD7816_STATUS_SUCCESS;

    if ((!nss_emul_init) || (key == NULL)) {
        /* couldn't get the key, indicate that we aren't logged in */
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    }
    priv_key = vcard_emul_get_nss_key(key);
    if (priv_key == NULL) {
        /* couldn't get the key, indicate that we aren't logged in */
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    }
    slot = vcard_emul_card_get_slot(card);

    /*
     * this is only true of the rsa signature
     */
    signature_len = PK11_SignatureLen(priv_key);
    if (buffer_size != signature_len) {
        return  VCARD7816_STATUS_ERROR_DATA_INVALID;
    }
    /* be able to handle larger keys if necessariy */
    bp = &buf[0];
    if (sizeof(buf) < signature_len) {
        bp = g_malloc(signature_len);
    }

    /*
     * do the raw operations. Some tokens claim to do CKM_RSA_X_509, but then
     * choke when they try to do the actual operations. Try to detect
     * those cases and treat them as if the token didn't claim support for
     * X_509.
     */
    if (key->failedX509 != VCardEmulTrue
                              && PK11_DoesMechanism(slot, CKM_RSA_X_509)) {
        rv = PK11_PrivDecryptRaw(priv_key, bp, &signature_len, signature_len,
                                 buffer, buffer_size);
        if (rv == SECSuccess) {
            assert(buffer_size == signature_len);
            memcpy(buffer, bp, signature_len);
            key->failedX509 = VCardEmulFalse;
            goto cleanup;
        }
        /*
         * we've had a successful X509 operation, this failure must be
         * somethine else
         */
        if (key->failedX509 == VCardEmulFalse) {
            ret = vcard_emul_map_error(PORT_GetError());
            goto cleanup;
        }
        /*
         * key->failedX509 must be Unknown at this point, try the
         * non-x_509 case
         */
    }
    /* token does not support CKM_RSA_X509, emulate that with CKM_RSA_PKCS */
    /* is this a PKCS #1 formatted signature? */
    if ((buffer[0] == 0) && (buffer[1] == 1)) {
        int i;

        for (i = 2; i < buffer_size; i++) {
            /* rsa signature pad */
            if (buffer[i] != 0xff) {
                break;
            }
        }
        if ((i < buffer_size) && (buffer[i] == 0)) {
            /* yes, we have a properly formated PKCS #1 signature */
            /*
             * NOTE: even if we accidentally got an encrypt buffer, which
             * through shear luck started with 00, 01, ff, 00, it won't matter
             * because the resulting Sign operation will effectively decrypt
             * the real buffer.
             */
            SECItem signature;
            SECItem hash;

            i++;
            hash.data = &buffer[i];
            hash.len = buffer_size - i;
            signature.data = bp;
            signature.len = signature_len;
            rv = PK11_Sign(priv_key,  &signature, &hash);
            if (rv != SECSuccess) {
                ret = vcard_emul_map_error(PORT_GetError());
                goto cleanup;
            }
            assert(buffer_size == signature.len);
            memcpy(buffer, bp, signature.len);
            /*
             * we got here because either the X509 attempt failed, or the
             * token couldn't do the X509 operation, in either case stay
             * with the PKCS version for future operations on this key
             */
            key->failedX509 = VCardEmulTrue;
            goto cleanup;
        }
    }
    pad_len = buffer_size - signature_len;
    assert(pad_len < 4);
    /*
     * OK now we've decrypted the payload, package it up in PKCS #1 for the
     * upper layer.
     */
    buffer[0] = 0;
    buffer[1] = 2; /* RSA_encrypt  */
    pad_len -= 3; /* format is 0 || 2 || pad || 0 || data */
    /*
     * padding for PKCS #1 encrypted data is a string of random bytes. The
     * random butes protect against potential decryption attacks against RSA.
     * Since PrivDecrypt has already stripped those bytes, we can't reconstruct
     * them. This shouldn't matter to the upper level code which should just
     * strip this code out anyway, so We'll pad with a constant 3.
     */
    memset(&buffer[2], 0x03, pad_len);
    pad_len += 2; /* index to the end of the pad */
    buffer[pad_len] = 0;
    pad_len++; /* index to the start of the data */
    memcpy(&buffer[pad_len], bp, signature_len);
    /*
     * we got here because either the X509 attempt failed, or the
     * token couldn't do the X509 operation, in either case stay
     * with the PKCS version for future operations on this key
     */
    key->failedX509 = VCardEmulTrue;
cleanup:
    if (bp != buf) {
        g_free(bp);
    }
    return ret;
}

/*
 * Login functions
 */
/* return the number of login attempts still possible on the card. if unknown,
 * return -1 */
int
vcard_emul_get_login_count(VCard *card)
{
    return -1;
}

/* login into the card, return the 7816 status word (sw2 || sw1) */
vcard_7816_status_t
vcard_emul_login(VCard *card, unsigned char *pin, int pin_len)
{
    PK11SlotInfo *slot;
    unsigned char *pin_string = NULL;
    int i;
    SECStatus rv;

    if (!nss_emul_init) {
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    }
    slot = vcard_emul_card_get_slot(card);
     /* We depend on the PKCS #11 module internal login state here because we
      * create a separate process to handle each guest instance. If we needed
      * to handle multiple guests from one process, then we would need to keep
      * a lot of extra state in our card structure
      * */
    pin_string = g_malloc(pin_len+1);
    memcpy(pin_string, pin, pin_len);
    pin_string[pin_len] = 0;

    /* handle CAC expanded pins correctly */
    for (i = pin_len-1; i >= 0 && (pin_string[i] == 0xff); i--) {
        pin_string[i] = 0;
    }

    rv = PK11_Authenticate(slot, PR_FALSE, pin_string);
    memset(pin_string, 0, pin_len);  /* don't let the pin hang around in memory
                                        to be snooped */
    g_free(pin_string);
    if (rv == SECSuccess) {
        return VCARD7816_STATUS_SUCCESS;
    }
    /* map the error from port get error */
    return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
}

void
vcard_emul_reset(VCard *card, VCardPower power)
{
    PK11SlotInfo *slot;

    if (!nss_emul_init) {
        return;
    }

    /*
     * if we reset the card (either power on or power off), we lose our login
     * state
     */
    /* TODO: we may also need to send insertion/removal events? */
    slot = vcard_emul_card_get_slot(card);
    PK11_Logout(slot); /* NOTE: ignoring SECStatus return value */
}


static VReader *
vcard_emul_find_vreader_from_slot(PK11SlotInfo *slot)
{
    VReaderList *reader_list = vreader_get_reader_list();
    VReaderListEntry *current_entry = NULL;

    if (reader_list == NULL) {
        return NULL;
    }
    for (current_entry = vreader_list_get_first(reader_list); current_entry;
                        current_entry = vreader_list_get_next(current_entry)) {
        VReader *reader = vreader_list_get_reader(current_entry);
        VReaderEmul *reader_emul = vreader_get_private(reader);
        if (reader_emul->slot == slot) {
            return reader;
        }
        vreader_free(reader);
    }

    return NULL;
}

/*
 * create a new reader emul
 */
static VReaderEmul *
vreader_emul_new(PK11SlotInfo *slot, VCardEmulType type, const char *params)
{
    VReaderEmul *new_reader_emul;

    new_reader_emul = (VReaderEmul *)g_malloc(sizeof(VReaderEmul));

    new_reader_emul->slot = PK11_ReferenceSlot(slot);
    new_reader_emul->default_type = type;
    new_reader_emul->type_params = g_strdup(params);
    new_reader_emul->present = PR_FALSE;
    new_reader_emul->series = 0;
    new_reader_emul->saved_vcard = NULL;
    return new_reader_emul;
}

static void
vreader_emul_delete(VReaderEmul *vreader_emul)
{
    if (vreader_emul == NULL) {
        return;
    }
    if (vreader_emul->slot) {
        PK11_FreeSlot(vreader_emul->slot);
    }
    if (vreader_emul->type_params) {
        g_free(vreader_emul->type_params);
    }
    g_free(vreader_emul);
}

/*
 *  TODO: move this to emulater non-specific file
 */
static VCardEmulType
vcard_emul_get_type(VReader *vreader)
{
    VReaderEmul *vreader_emul;

    vreader_emul = vreader_get_private(vreader);
    if (vreader_emul && vreader_emul->default_type != VCARD_EMUL_NONE) {
        return vreader_emul->default_type;
    }

    return vcard_emul_type_select(vreader);
}
/*
 *  TODO: move this to emulater non-specific file
 */
static const char *
vcard_emul_get_type_params(VReader *vreader)
{
    VReaderEmul *vreader_emul;

    vreader_emul = vreader_get_private(vreader);
    if (vreader_emul && vreader_emul->type_params) {
        return vreader_emul->type_params;
    }

    return "";
}

/* pull the slot out of the reader private data */
static PK11SlotInfo *
vcard_emul_reader_get_slot(VReader *vreader)
{
    VReaderEmul *vreader_emul = vreader_get_private(vreader);
    if (vreader_emul == NULL) {
        return NULL;
    }
    return vreader_emul->slot;
}

/*
 *  Card ATR's map to physical cards. vcard_alloc_atr will set appropriate
 *  historical bytes for any software emulated card. The remaining bytes can be
 *  used to indicate the actual emulator
 */
static unsigned char *nss_atr;
static int nss_atr_len;

void
vcard_emul_get_atr(VCard *card, unsigned char *atr, int *atr_len)
{
    int len;
    assert(atr != NULL);

    if (nss_atr == NULL) {
        nss_atr = vcard_alloc_atr("NSS", &nss_atr_len);
    }
    len = MIN(nss_atr_len, *atr_len);
    memcpy(atr, nss_atr, len);
    *atr_len = len;
}

/*
 * create a new card from certs and keys
 */
static VCard *
vcard_emul_make_card(VReader *reader,
                     unsigned char * const *certs, int *cert_len,
                     VCardKey *keys[], int cert_count)
{
    VCardEmul *vcard_emul;
    VCard *vcard;
    PK11SlotInfo *slot;
    VCardEmulType type;
    const char *params;

    type = vcard_emul_get_type(reader);

    /* ignore the inserted card */
    if (type == VCARD_EMUL_NONE) {
        return NULL;
    }
    slot = vcard_emul_reader_get_slot(reader);
    if (slot == NULL) {
        return NULL;
    }

    params = vcard_emul_get_type_params(reader);
    /* params these can be NULL */

    vcard_emul = vcard_emul_new_card(slot);
    if (vcard_emul == NULL) {
        return NULL;
    }
    vcard = vcard_new(vcard_emul, vcard_emul_delete_card);
    if (vcard == NULL) {
        vcard_emul_delete_card(vcard_emul);
        return NULL;
    }
    vcard_init(reader, vcard, type, params, certs, cert_len, keys, cert_count);
    return vcard;
}


/*
 * 'clone' a physical card as a virtual card
 */
static VCard *
vcard_emul_mirror_card(VReader *vreader)
{
    /*
     * lookup certs using the C_FindObjects. The Stan Cert handle won't give
     * us the real certs until we log in.
     */
    PK11GenericObject *firstObj, *thisObj;
    int cert_count;
    unsigned char **certs;
    int *cert_len;
    VCardKey **keys;
    PK11SlotInfo *slot;
    VCard *card;

    slot = vcard_emul_reader_get_slot(vreader);
    if (slot == NULL) {
        return NULL;
    }

    firstObj = PK11_FindGenericObjects(slot, CKO_CERTIFICATE);
    if (firstObj == NULL) {
        return NULL;
    }

    /* count the certs */
    cert_count = 0;
    for (thisObj = firstObj; thisObj;
                             thisObj = PK11_GetNextGenericObject(thisObj)) {
        cert_count++;
    }

    if (cert_count == 0) {
        PK11_DestroyGenericObjects(firstObj);
        return NULL;
    }

    /* allocate the arrays */
    vcard_emul_alloc_arrays(&certs, &cert_len, &keys, cert_count);

    /* fill in the arrays */
    cert_count = 0;
    for (thisObj = firstObj; thisObj;
                             thisObj = PK11_GetNextGenericObject(thisObj)) {
        SECItem derCert;
        CERTCertificate *cert;
        SECStatus rv;

        rv = PK11_ReadRawAttribute(PK11_TypeGeneric, thisObj,
                                   CKA_VALUE, &derCert);
        if (rv != SECSuccess) {
            continue;
        }
        /* create floating temp cert. This gives us a cert structure even if
         * the token isn't logged in */
        cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCert,
                                       NULL, PR_FALSE, PR_TRUE);
        SECITEM_FreeItem(&derCert, PR_FALSE);
        if (cert == NULL) {
            continue;
        }

        certs[cert_count] = cert->derCert.data;
        cert_len[cert_count] = cert->derCert.len;
        keys[cert_count] = vcard_emul_make_key(slot, cert);
        cert_count++;
        CERT_DestroyCertificate(cert); /* key obj still has a reference */
    }

    /* now create the card */
    card = vcard_emul_make_card(vreader, certs, cert_len, keys, cert_count);
    g_free(certs);
    g_free(cert_len);
    g_free(keys);

    return card;
}

static VCardEmulType default_card_type = VCARD_EMUL_NONE;
static const char *default_type_params = "";

/*
 * This thread looks for card and reader insertions and puts events on the
 * event queue
 */
static void
vcard_emul_event_thread(void *arg)
{
    PK11SlotInfo *slot;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    VCard *vcard;
    SECMODModule *module = (SECMODModule *)arg;

    do {
        /*
         * XXX - the latency value doesn't matter one bit. you only get no
         * blocking (flags |= CKF_DONT_BLOCK) or PKCS11_WAIT_LATENCY (==500),
         * hard coded in coolkey.  And it isn't coolkey's fault - the timeout
         * value we pass get's dropped on the floor before C_WaitForSlotEvent
         * is called.
         */
        slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500);
        if (slot == NULL) {
            /* this could be just a no event indication */
            if (PORT_GetError() == SEC_ERROR_NO_EVENT) {
                continue;
            }
            break;
        }
        vreader = vcard_emul_find_vreader_from_slot(slot);
        if (vreader == NULL) {
            /* new vreader */
            vreader_emul = vreader_emul_new(slot, default_card_type,
                                            default_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            PK11_FreeSlot(slot);
            slot = NULL;
            vreader_add_reader(vreader);
            vreader_free(vreader);
            continue;
        }
        /* card remove/insert */
        vreader_emul = vreader_get_private(vreader);
        if (PK11_IsPresent(slot)) {
            int series = PK11_GetSlotSeries(slot);
            if (series != vreader_emul->series) {
                if (vreader_emul->present) {
                    vreader_insert_card(vreader, NULL);
                }
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_free(vcard);
            }
            vreader_emul->series = series;
            vreader_emul->present = 1;
            vreader_free(vreader);
            PK11_FreeSlot(slot);
            continue;
        }
        if (vreader_emul->present) {
            vreader_insert_card(vreader, NULL);
        }
        vreader_emul->series = 0;
        vreader_emul->present = 0;
        PK11_FreeSlot(slot);
        vreader_free(vreader);
    } while (1);
}

/* if the card is inserted when we start up, make sure our state is correct */
static void
vcard_emul_init_series(VReader *vreader, VCard *vcard)
{
    VReaderEmul *vreader_emul = vreader_get_private(vreader);
    PK11SlotInfo *slot = vreader_emul->slot;

    vreader_emul->present = PK11_IsPresent(slot);
    vreader_emul->series = PK11_GetSlotSeries(slot);
    if (vreader_emul->present == 0) {
        vreader_insert_card(vreader, NULL);
    }
}

/*
 * each module has a separate wait call, create a thread for each module that
 * we are using.
 */
static void
vcard_emul_new_event_thread(SECMODModule *module)
{
    PR_CreateThread(PR_SYSTEM_THREAD, vcard_emul_event_thread,
                     module, PR_PRIORITY_HIGH, PR_GLOBAL_THREAD,
                     PR_UNJOINABLE_THREAD, 0);
}

static const VCardEmulOptions default_options = {
    .nss_db = NULL,
    .vreader = NULL,
    .vreader_count = 0,
    .hw_card_type = VCARD_EMUL_CAC,
    .hw_type_params = "",
    .use_hw = PR_TRUE
};


/*
 *  NSS needs the app to supply a password prompt. In our case the only time
 *  the password is supplied is as part of the Login APDU. The actual password
 *  is passed in the pw_arg in that case. In all other cases pw_arg should be
 *  NULL.
 */
static char *
vcard_emul_get_password(PK11SlotInfo *slot, PRBool retries, void *pw_arg)
{
    /* if it didn't work the first time, don't keep trying */
    if (retries) {
        return NULL;
    }
    /* we are looking up a password when we don't have one in hand */
    if (pw_arg == NULL) {
        return NULL;
    }
    /* TODO: we really should verify that were are using the right slot */
    return PORT_Strdup(pw_arg);
}

/* Force a card removal even if the card is not physically removed */
VCardEmulError
vcard_emul_force_card_remove(VReader *vreader)
{
    if (!nss_emul_init || (vreader_card_is_present(vreader) != VREADER_OK)) {
        return VCARD_EMUL_FAIL; /* card is already removed */
    }

    /* OK, remove it */
    vreader_insert_card(vreader, NULL);
    return VCARD_EMUL_OK;
}

/* Re-insert of a card that has been removed by force removal */
VCardEmulError
vcard_emul_force_card_insert(VReader *vreader)
{
    VReaderEmul *vreader_emul;
    VCard *vcard;

    if (!nss_emul_init || (vreader_card_is_present(vreader) == VREADER_OK)) {
        return VCARD_EMUL_FAIL; /* card is already removed */
    }
    vreader_emul = vreader_get_private(vreader);

    /* if it's a softcard, get the saved vcard from the reader emul structure */
    if (vreader_emul->saved_vcard) {
        vcard = vcard_reference(vreader_emul->saved_vcard);
    } else {
        /* it must be a physical card, rebuild it */
        if (!PK11_IsPresent(vreader_emul->slot)) {
            /* physical card has been removed, not way to reinsert it */
            return VCARD_EMUL_FAIL;
        }
        vcard = vcard_emul_mirror_card(vreader);
    }
    vreader_insert_card(vreader, vcard);
    vcard_free(vcard);

    return VCARD_EMUL_OK;
}


static PRBool
module_has_removable_hw_slots(SECMODModule *mod)
{
    int i;
    PRBool ret = PR_FALSE;
    SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();

    if (!moduleLock) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return ret;
    }
    SECMOD_GetReadLock(moduleLock);
    for (i = 0; i < mod->slotCount; i++) {
        PK11SlotInfo *slot = mod->slots[i];
        if (PK11_IsRemovable(slot) && PK11_IsHW(slot)) {
            ret = PR_TRUE;
            break;
        }
    }
    SECMOD_ReleaseReadLock(moduleLock);
    return ret;
}

/* Previously we returned FAIL if no readers found. This makes
 * no sense when using hardware, since there may be no readers connected
 * at the time vcard_emul_init is called, but they will be properly
 * recognized later. So Instead return FAIL only if no_hw==1 and no
 * vcards can be created (indicates error with certificates provided
 * or db), or if any other higher level error (NSS error, missing coolkey). */
static int vcard_emul_init_called;

VCardEmulError
vcard_emul_init(const VCardEmulOptions *options)
{
    SECStatus rv;
    PRBool has_readers = PR_FALSE;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    SECMODListLock *module_lock;
    SECMODModuleList *module_list;
    SECMODModuleList *mlp;
    int i;

    if (vcard_emul_init_called) {
        return VCARD_EMUL_INIT_ALREADY_INITED;
    }
    vcard_emul_init_called = 1;
    vreader_init();
    vevent_queue_init();

    if (options == NULL) {
        options = &default_options;
    }

    /* first initialize NSS */
    if (options->nss_db) {
        rv = NSS_Init(options->nss_db);
    } else {
        gchar *path;
#ifndef _WIN32
        path = g_strdup("/etc/pki/nssdb");
#else
        if (g_get_system_config_dirs() == NULL ||
            g_get_system_config_dirs()[0] == NULL) {
            return VCARD_EMUL_FAIL;
        }

        path = g_build_filename(
            g_get_system_config_dirs()[0], "pki", "nssdb", NULL);
#endif

        rv = NSS_Init(path);
        g_free(path);
    }
    if (rv != SECSuccess) {
        return VCARD_EMUL_FAIL;
    }
    /* Set password callback function */
    PK11_SetPasswordFunc(vcard_emul_get_password);

    /* set up soft cards emulated by software certs rather than physical cards
     * */
    for (i = 0; i < options->vreader_count; i++) {
        int j;
        int cert_count;
        unsigned char **certs;
        int *cert_len;
        VCardKey **keys;
        PK11SlotInfo *slot;

        slot = PK11_FindSlotByName(options->vreader[i].name);
        if (slot == NULL) {
            continue;
        }
        vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type,
                                        options->vreader[i].type_params);
        vreader = vreader_new(options->vreader[i].vname, vreader_emul,
                              vreader_emul_delete);
        vreader_add_reader(vreader);
        cert_count = options->vreader[i].cert_count;

        vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                options->vreader[i].cert_count);

        cert_count = 0;
        for (j = 0; j < options->vreader[i].cert_count; j++) {
            /* we should have a better way of identifying certs than by
             * nickname here */
            CERTCertificate *cert = PK11_FindCertFromNickname(
                                        options->vreader[i].cert_name[j],
                                        NULL);
            if (cert == NULL) {
                continue;
            }
            certs[cert_count] = cert->derCert.data;
            cert_len[cert_count] = cert->derCert.len;
            keys[cert_count] = vcard_emul_make_key(slot, cert);
            /* this is safe because the key is still holding a cert reference */
            CERT_DestroyCertificate(cert);
            cert_count++;
        }
        if (cert_count) {
            VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len,
                                                keys, cert_count);
            vreader_insert_card(vreader, vcard);
            vcard_emul_init_series(vreader, vcard);
            /* allow insertion and removal of soft cards */
            vreader_emul->saved_vcard = vcard_reference(vcard);
            vcard_free(vcard);
            vreader_free(vreader);
            has_readers = PR_TRUE;
        }
        g_free(certs);
        g_free(cert_len);
        g_free(keys);
    }

    /* if we aren't suppose to use hw, skip looking up hardware tokens */
    if (!options->use_hw) {
        nss_emul_init = has_readers;
        return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL;
    }

    /* make sure we have some PKCS #11 module loaded */
    module_lock = SECMOD_GetDefaultModuleListLock();
    module_list = SECMOD_GetDefaultModuleList();
    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        if (module_has_removable_hw_slots(module)) {
            break;
        }
    }
    SECMOD_ReleaseReadLock(module_lock);

    /* now examine all the slots, finding which should be readers */
    /* We should control this with options. For now we mirror out any
     * removable hardware slot */
    default_card_type = options->hw_card_type;
    default_type_params = g_strdup(options->hw_type_params);

    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;

        /* Ignore the internal module */
        if (module == NULL || module == SECMOD_GetInternalModule()) {
            continue;
        }

        for (i = 0; i < module->slotCount; i++) {
            PK11SlotInfo *slot = module->slots[i];

            /* only map removable HW slots */
            if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
                continue;
            }
            if (strcmp("E-Gate 0 0", PK11_GetSlotName(slot)) == 0) {
                /*
                 * coolkey <= 1.1.0-20 emulates this reader if it can't find
                 * any hardware readers. This causes problems, warn user of
                 * problems.
                 */
                fprintf(stderr, "known bad coolkey version - see "
                        "https://bugzilla.redhat.com/show_bug.cgi?id=802435\n");
                continue;
            }
            vreader_emul = vreader_emul_new(slot, options->hw_card_type,
                                            options->hw_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            vreader_add_reader(vreader);

            if (PK11_IsPresent(slot)) {
                VCard *vcard;
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_emul_init_series(vreader, vcard);
                vcard_free(vcard);
            }
        }
        vcard_emul_new_event_thread(module);
    }
    SECMOD_ReleaseReadLock(module_lock);
    nss_emul_init = PR_TRUE;

    return VCARD_EMUL_OK;
}

/* Recreate card insert events for all readers (user should
 * deduce implied reader insert. perhaps do a reader insert as well?)
 */
void
vcard_emul_replay_insertion_events(void)
{
    VReaderListEntry *current_entry;
    VReaderListEntry *next_entry = NULL;
    VReaderList *list = vreader_get_reader_list();

    for (current_entry = vreader_list_get_first(list); current_entry;
            current_entry = next_entry) {
        VReader *vreader = vreader_list_get_reader(current_entry);
        next_entry = vreader_list_get_next(current_entry);
        vreader_queue_card_event(vreader);
    }
}

/*
 *  Silly little functions to help parsing our argument string
 */
static int
count_tokens(const char *str, char token, char token_end)
{
    int count = 0;

    for (; *str; str++) {
        if (*str == token) {
            count++;
        }
        if (*str == token_end) {
            break;
        }
    }
    return count;
}

static const char *
strip(const char *str)
{
    for (; *str && isspace(*str); str++) {
    }
    return str;
}

static const char *
find_blank(const char *str)
{
    for (; *str && !isspace(*str); str++) {
    }
    return str;
}


/*
 *  We really want to use some existing argument parsing library here. That
 *  would give us a consistent look */
static VCardEmulOptions options;
#define READER_STEP 4

/* Expects "args" to be at the beginning of a token (ie right after the ','
 * ending the previous token), and puts the next token start in "token",
 * and its length in "token_length". "token" will not be nul-terminated.
 * After calling the macro, "args" will be advanced to the beginning of
 * the next token.
 * This macro may call continue or break.
 */
#define NEXT_TOKEN(token) \
            (token) = args; \
            args = strpbrk(args, ",)"); \
            if (*args == 0) { \
                break; \
            } \
            if (*args == ')') { \
                args++; \
                continue; \
            } \
            (token##_length) = args - (token); \
            args = strip(args+1);

VCardEmulOptions *
vcard_emul_options(const char *args)
{
    int reader_count = 0;
    VCardEmulOptions *opts;

    /* Allow the future use of allocating the options structure on the fly */
    memcpy(&options, &default_options, sizeof(options));
    opts = &options;

    do {
        args = strip(args); /* strip off the leading spaces */
        if (*args == ',') {
            continue;
        }
        /* soft=(slot_name,virt_name,emul_type,emul_flags,cert_1, (no eol)
         *       cert_2,cert_3...) */
        if (strncmp(args, "soft=", 5) == 0) {
            const char *name;
            size_t name_length;
            const char *vname;
            size_t vname_length;
            const char *type_params;
            size_t type_params_length;
            char type_str[100];
            VCardEmulType type;
            int count, i;
            VirtualReaderOptions *vreaderOpt = NULL;

            args = strip(args + 5);
            if (*args != '(') {
                continue;
            }
            args = strip(args+1);

            NEXT_TOKEN(name)
            NEXT_TOKEN(vname)
            NEXT_TOKEN(type_params)
            type_params_length = MIN(type_params_length, sizeof(type_str)-1);
            pstrcpy(type_str, type_params_length, type_params);
            type = vcard_emul_type_from_string(type_str);

            NEXT_TOKEN(type_params)

            if (*args == 0) {
                break;
            }

            if (opts->vreader_count >= reader_count) {
                reader_count += READER_STEP;
                vreaderOpt = realloc(opts->vreader,
                                reader_count * sizeof(*vreaderOpt));
                if (vreaderOpt == NULL) {
                    return opts; /* we're done */
                }
            }
            opts->vreader = vreaderOpt;
            vreaderOpt = &vreaderOpt[opts->vreader_count];
            vreaderOpt->name = g_strndup(name, name_length);
            vreaderOpt->vname = g_strndup(vname, vname_length);
            vreaderOpt->card_type = type;
            vreaderOpt->type_params =
                g_strndup(type_params, type_params_length);
            count = count_tokens(args, ',', ')') + 1;
            vreaderOpt->cert_count = count;
            vreaderOpt->cert_name = (char **)g_malloc(count*sizeof(char *));
            for (i = 0; i < count; i++) {
                const char *cert = args;
                args = strpbrk(args, ",)");
                vreaderOpt->cert_name[i] = g_strndup(cert, args - cert);
                args = strip(args+1);
            }
            if (*args == ')') {
                args++;
            }
            opts->vreader_count++;
        /* use_hw= */
        } else if (strncmp(args, "use_hw=", 7) == 0) {
            args = strip(args+7);
            if (*args == '0' || *args == 'N' || *args == 'n' || *args == 'F') {
                opts->use_hw = PR_FALSE;
            } else {
                opts->use_hw = PR_TRUE;
            }
            args = find_blank(args);
        /* hw_type= */
        } else if (strncmp(args, "hw_type=", 8) == 0) {
            args = strip(args+8);
            opts->hw_card_type = vcard_emul_type_from_string(args);
            args = find_blank(args);
        /* hw_params= */
        } else if (strncmp(args, "hw_params=", 10) == 0) {
            const char *params;
            args = strip(args+10);
            params = args;
            args = find_blank(args);
            opts->hw_type_params = g_strndup(params, args-params);
        /* db="/data/base/path" */
        } else if (strncmp(args, "db=", 3) == 0) {
            const char *db;
            args = strip(args+3);
            if (*args != '"') {
                continue;
            }
            args++;
            db = args;
            args = strpbrk(args, "\"\n");
            opts->nss_db = g_strndup(db, args-db);
            if (*args != 0) {
                args++;
            }
        } else {
            args = find_blank(args);
        }
    } while (*args != 0);

    return opts;
}

void
vcard_emul_usage(void)
{
   fprintf(stderr,
"emul args: comma separated list of the following arguments\n"
" db={nss_database}               (default sql:/etc/pki/nssdb)\n"
" use_hw=[yes|no]                 (default yes)\n"
" hw_type={card_type_to_emulate}  (default CAC)\n"
" hw_param={param_for_card}       (default \"\")\n"
" soft=({slot_name},{vreader_name},{card_type_to_emulate},{params_for_card},\n"
"       {cert1},{cert2},{cert3}    (default none)\n"
"\n"
"  {nss_database}          The location of the NSS cert & key database\n"
"  {card_type_to_emulate}  What card interface to present to the guest\n"
"  {param_for_card}        Card interface specific parameters\n"
"  {slot_name}             NSS slot that contains the certs\n"
"  {vreader_name}          Virtual reader name to present to the guest\n"
"  {certN}                 Nickname of the certificate n on the virtual card\n"
"\n"
"These parameters come as a single string separated by blanks or newlines."
"\n"
"Unless use_hw is set to no, all tokens that look like removable hardware\n"
"tokens will be presented to the guest using the emulator specified by\n"
"hw_type, and parameters of hw_param.\n"
"\n"
"If more one or more soft= parameters are specified, these readers will be\n"
"presented to the guest\n");
}
