/*
 * 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 PRBool
vcard_emul_alloc_arrays(unsigned char ***certsp, int **cert_lenp,
                        VCardKey ***keysp, int cert_count)
{
    *certsp = NULL;
    *cert_lenp = NULL;
    *keysp = NULL;
    *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);
    return PR_TRUE;
}

/*
 * 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;
    PRBool ret;
    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 */
    ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, cert_count);
    if (ret == PR_FALSE) {
        return NULL;
    }

    /* 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 ret, 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;

        ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
                                      options->vreader[i].cert_count);
        if (ret == PR_FALSE) {
            continue;
        }
        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");
}
